Motr  M0
m0_co_context Struct Reference

#include <coroutine.h>

Collaboration diagram for m0_co_context:
Collaboration graph

Data Fields

void * mc_stack [M0_MCC_STACK_NR]
 
void * mc_locals [M0_MCC_STACK_NR]
 
uint64_t mc_frame
 
bool mc_yield
 
int mc_co_end_ret
 
uint64_t mc_yield_frame
 
struct m0_co_locals_allocator mc_alloc
 

Detailed Description

Coroutine context.

Saves current state, including coroutine local variables, control flow data, other state variables w.r.t. restore this state after reentering the stack of functions coroutines are used in.

While working with coroutines, user has to use local on-stack variables with understanding, that after yield their values have to be resorted manually. Instead he has to put M0_CO_REENTER() inside the beginning of every function, and inside every function in every function-stack which is being yielded.

‘Restorable variables’ are used like locals and can be declared inside M0_CO_REENTER(). The following code can be inside one of yielded functions:

static void foo(struct m0_co_context *context, ...)
{
M0_CO_REENTER(context,
int a;
char b[100];
int rc;
);
...
}

By design, ‘restorable variables’ can be accessed with M0_CO_FRAME_DATA(), which can be redefined and used like in the following example:

#define F M0_CO_FRAME_DATA
static void foo(struct m0_co_context *context, ...)
{
M0_CO_REENTER(context, ...
);
...
F(rc) = -EINVAL;
F(a) = 0xb100df100d;
strncpy(F(b), "sillybuff", ARRAY_SIZE(F(b)));
...
}

It can be seen, that user has to maintain ‘struct m0_co_context context’ inside his own structures. For motr code, it's is implied to be related to FOM or FOM objects. m0_co_context_{init,fini}() used for these purposes.

Every function, which potentially can be unwinded during yield has to be wrapped with M0_CO_FUN().

Every place inside underlying functions wrapped by M0_CO_FUN() can be yielded with M0_CO_YIELD(). After this call, function stack is being unwinded up to the place in code where top-level coroutine call is being performed. Our code assumes this place to be near by FOM tick()-function:

int foo_tick(struct m0_fom *fom)
{ ...
M0_CO_START(&context);
top_rc = toplevel_foo(&context); // calls foo()->foo0()->...->foo_n()
co_rc = M0_CO_END(&context);
...
}

User controls execution of coroutine by checking ‘M0_CO_END(&context)’-value. Coroutine is in progress if -EAGAIN is returned, if 0 – it is succeeded.

Definition at line 136 of file coroutine.h.

Field Documentation

◆ mc_alloc

struct m0_co_locals_allocator mc_alloc

simple pool allocator for locals

Definition at line 150 of file coroutine.h.

◆ mc_co_end_ret

int mc_co_end_ret

code returned from M0_CO_END() macro, set in M0_CO_YIELD()

Definition at line 146 of file coroutine.h.

◆ mc_frame

uint64_t mc_frame

current frame pointer

Definition at line 142 of file coroutine.h.

◆ mc_locals

void* mc_locals[M0_MCC_STACK_NR]

frame locals stack

Definition at line 140 of file coroutine.h.

◆ mc_stack

void* mc_stack[M0_MCC_STACK_NR]

frame address stack

Definition at line 138 of file coroutine.h.

◆ mc_yield

bool mc_yield

true if stack is unwinding

Definition at line 144 of file coroutine.h.

◆ mc_yield_frame

uint64_t mc_yield_frame

current frame pointer during reentering

Definition at line 148 of file coroutine.h.


The documentation for this struct was generated from the following file: