Skip to content

协程支持 #286

@Chronostasys

Description

@Chronostasys

目标实现无栈协程,这需要编译器能自动将异步函数编译为异步状态机

考虑下方函数:

async fn test() {
  let a = 1;
  await some_async_io();
  a = a + 1;
}

在编译的时候,test会变成:

struct test_ctx{
    step:i64;
    a: i64;
}

fn test_init() test_ctx {
  return test_ctx{};
}

fn test_move_next(ctx: test_ctx) bool {
  switch ctx.step {
    case 0:
      ctx.a = 1;
      event_loop_register(some_async_io);
    case 1:
      ctx.a = ctx.a + 1;
  }
  ctx.step += 1;
  return ctx.step == 1;
}

在调用test的时候,生成代码为:

let ctx = test_init();
test_move_next(ctx);

event_loop_register会把异步操作注册到evloop里,在该操作完成之后,evloop会通知调度器,调度器继续执行test_move_next(ctx)

为了保证gc正确性,evloop线程不要跑pl代码或者函数,只跑rust代码。

关于调度器

我们把异步状态机记为Task,那么一个纯异步程序中(main也是async的),实际上所有线程都不是直接跑用户代码,而是运行调度器,而调度器对用户代码进行调度和运行。

下方假设我们使用一个全局的task 队列,那么调度器伪代码如下:

loop {
  let task = queue.dequeue();
  if task != null {
    task.move_next();
  }
}

evloop在一个异步操作完成后,需要queue.enqueue(task)

Metadata

Metadata

Labels

Type

No type

Projects

Status

🏗 In progress

Relationships

None yet

Development

No branches or pull requests

Issue actions