Macros | Typedefs | Enumerations
Coroutines in C

Macros

#define CORO_CONTEXT(name)   co_t co_##name
 Define the coroutine context (a pointer to label). More...
 
#define CORO_CONTEXT_INIT(name)
 
#define CORO_LOCAL   static
 Declare the local variable that preserves a value across a coroutine switching.
 
#define CORO_DEFINE(name)   int coro_##name( co_t *co_p )
 Define the coroutine. More...
 
#define CORO_BEGIN(initial)
 The coroutine beginning. More...
 
#define CORO_END(final)
 The coroutine end. More...
 
#define CORO_YIELD(final)
 Switching to the next coroutine. More...
 
#define CORO_WAIT(cond, ...)
 Waiting for the condition is true. More...
 
#define CORO_RESTART(final)
 Restart the coroutine. More...
 
#define CORO_QUIT(final)   CORO_END( final )
 Quit the coroutine. More...
 
#define CORO_CALL(name)   coro_##name( &co_##name )
 Call the coroutine. More...
 
#define CORO_ALIVE(coro)   (( coro ) < CO_END )
 Checking the coroutine is not completed. More...
 
#define CORO_WAIT_CORO(coro, ...)   CORO_WAIT( !CORO_ALIVE( coro ), ## __VA_ARGS__ )
 Start and waiting for the child coroutine is completed. More...
 
#define SEMAPHORE_INIT(name, val)
 Initialize the semaphore. More...
 
#define SEMAPHORE_ACQUIRE(name, ...)
 Waiting and acquire the semaphore. More...
 
#define SEMAPHORE_RELEASE(name)
 Release the semaphore. More...
 

Typedefs

typedef void * co_t
 
typedef unsigned int semaphore_t
 

Enumerations

enum  {
  CO_READY, CO_WAIT, CO_YIELD, CO_END,
  CO_SKIP
}
 

Detailed Description

Coroutine mechanics, implemented using the C language extensions "Labels as Values", "Statements and Declarations in Expressions" and "Locally Declared Labels". Based on Simon Tatham "Coroutines in C".

{
for ( ; ; ) {
// ...
}
}
{
CORO_LOCAL int b;
for ( ; ; ) {
// ...
CORO_WAIT( cond );
}
}
int main( void )
{
for ( ; ; ) {
CORO_CALL( A );
CORO_CALL( B );
}
return 0;
}

Any local variables which need to be persistent across a coroutine switching must be declared static (CORO_LOCAL).

Macro Definition Documentation

#define CORO_ALIVE (   coro)    (( coro ) < CO_END )

Checking the coroutine is not completed.

Parameters
coroResult of the coroutine call.
Returns
Alive flag.
#define CORO_BEGIN (   initial)
Value:
({ \
initial; \
if ( *co_p ) goto **co_p; \
})

The coroutine beginning.

Parameters
initialThe initial operation, executed whenever enter in the coroutine.
Examples:
drive.c, and remote.c.
#define CORO_CALL (   name)    coro_##name( &co_##name )

Call the coroutine.

Parameters
nameCoroutine name.
Examples:
drive.c, and remote.c.
#define CORO_CONTEXT (   name)    co_t co_##name

Define the coroutine context (a pointer to label).

Parameters
nameCoroutine name.
Examples:
drive.c, and remote.c.
#define CORO_CONTEXT_INIT (   name)
Value:
({ \
co_##name = NULL; \
})
#define CORO_DEFINE (   name)    int coro_##name( co_t *co_p )

Define the coroutine.

Parameters
nameCoroutine name.
Examples:
drive.c, and remote.c.
#define CORO_END (   final)

The coroutine end.

Parameters
finalThe final operation, executed whenever exit from the coroutine.
Examples:
drive.c, and remote.c.
#define CORO_QUIT (   final)    CORO_END( final )

Quit the coroutine.

Parameters
finalFinal operation.
Examples:
drive.c, and remote.c.
#define CORO_RESTART (   final)
Value:
({ \
*co_p = NULL; \
final; \
return CO_YIELD; \
})

Restart the coroutine.

Parameters
finalFinal operation.
#define CORO_WAIT (   cond,
  ... 
)
Value:
({ \
__label__ L; \
*co_p = &&L; \
L: \
if (!( cond )) { \
__VA_ARGS__; /* final */ \
return CO_WAIT; \
} \
})

Waiting for the condition is true.

Parameters
condCondition.
...Final operation.
Examples:
drive.c, and remote.c.
#define CORO_WAIT_CORO (   coro,
  ... 
)    CORO_WAIT( !CORO_ALIVE( coro ), ## __VA_ARGS__ )

Start and waiting for the child coroutine is completed.

Parameters
coroChild coroutine.
...Final operation.
#define CORO_YIELD (   final)
Value:
({ \
__label__ L; \
*co_p = &&L; \
final; \
return CO_YIELD; \
L:; \
})

Switching to the next coroutine.

Parameters
finalFinal operation.
Examples:
drive.c, and remote.c.
#define SEMAPHORE_ACQUIRE (   name,
  ... 
)
Value:
({ \
CORO_WAIT(( name > 0 ), ## __VA_ARGS__ ); \
--name; \
})
#define CORO_WAIT(cond,...)
Waiting for the condition is true.
Definition: coroutine.h:131

Waiting and acquire the semaphore.

Parameters
nameSemaphore name.
...Final operation.
#define SEMAPHORE_INIT (   name,
  val 
)
Value:
({ \
name = val; \
})

Initialize the semaphore.

Parameters
nameSemaphore name.
valSemaphore capacity.
#define SEMAPHORE_RELEASE (   name)
Value:
({ \
++name; \
})

Release the semaphore.

Parameters
nameSemaphore name.