Skip to content

Commit

Permalink
prefixes for coroutine-related functions added
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Sustrik <sustrik@250bpm.com>
  • Loading branch information
sustrik committed Jun 11, 2016
1 parent 5bb6a07 commit bce5130
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 78 deletions.
26 changes: 13 additions & 13 deletions cr.c
Expand Up @@ -45,8 +45,8 @@ size_t mill_valbuf_size = 128;
/* Valbuf for tha main coroutine. */
char mill_main_valbuf[128];

volatile int mill_unoptimisable1 = 1;
volatile void *mill_unoptimisable2 = NULL;
volatile int mill_unoptimisable1_ = 1;
volatile void *mill_unoptimisable2_ = NULL;

struct mill_cr mill_main = {0};

Expand Down Expand Up @@ -78,7 +78,7 @@ static void *mill_getvalbuf(struct mill_cr *cr, size_t size) {
return cr->valbuf;
}

void mill_goprepare(int count, size_t stack_size, size_t val_size) {
void mill_goprepare_(int count, size_t stack_size, size_t val_size) {
if(mill_slow(mill_hascrs())) {errno = EAGAIN; return;}
/* Allocate any resources needed by the polling mechanism. */
mill_poller_init();
Expand Down Expand Up @@ -131,7 +131,7 @@ void mill_resume(struct mill_cr *cr, int result) {
mill_slist_push_back(&mill_ready, &cr->ready);
}

/* dill_prologue() and dill_epilogue() live in the same scope with
/* mill_prologue_() and mill_epilogue_() live in the same scope with
libdill's stack-switching black magic. As such, they are extremely
fragile. Therefore, the optimiser is prohibited to touch them. */
#if defined __clang__
Expand All @@ -142,14 +142,14 @@ void mill_resume(struct mill_cr *cr, int result) {
#error "Unsupported compiler!"
#endif

sigjmp_buf *mill_getctx(void) {
sigjmp_buf *mill_getctx_(void) {
return &mill_running->ctx;
}

/* The intial part of go(). Starts the new coroutine.
Returns the pointer to the top of its stack. */
__attribute__((noinline)) dill_noopt
void *mill_go_prologue(const char *created) {
void *mill_prologue_(const char *created) {
/* Ensure that debug functions are available whenever a single go()
statement is present in the user's code. */
mill_preserve_debug();
Expand All @@ -167,7 +167,7 @@ void *mill_go_prologue(const char *created) {
cr->is_ready = 0;
cr->valbuf = NULL;
cr->valbuf_sz = 0;
cr->cls = NULL;
cr->clsval = NULL;
cr->timer.expiry = -1;
cr->fd = -1;
cr->events = 0;
Expand All @@ -182,7 +182,7 @@ void *mill_go_prologue(const char *created) {

/* The final part of go(). Cleans up after the coroutine is finished. */
__attribute__((noinline)) dill_noopt
void mill_go_epilogue(void) {
void mill_epilogue_(void) {
mill_trace(NULL, "go() done");
mill_unregister_cr(&mill_running->debug);
if(mill_running->valbuf)
Expand All @@ -197,7 +197,7 @@ void mill_go_epilogue(void) {
mill_suspend();
}

void mill_yield(const char *current) {
void mill_yield_(const char *current) {
mill_trace(current, "yield()");
mill_set_current(&mill_running->debug, current);
/* This looks fishy, but yes, we can resume the coroutine even before
Expand All @@ -213,12 +213,12 @@ void *mill_valbuf(struct mill_cr *cr, size_t size) {
return ptr;
}

void *cls(void) {
return mill_running->cls;
void *mill_cls_(void) {
return mill_running->clsval;
}

void setcls(void *val) {
mill_running->cls = val;
void mill_setcls_(void *val) {
mill_running->clsval = val;
}

void mill_cr_postfork(void) {
Expand Down
2 changes: 1 addition & 1 deletion cr.h
Expand Up @@ -94,7 +94,7 @@ struct mill_cr {
size_t valbuf_sz;

/* Coroutine-local storage. */
void *cls;
void *clsval;

#if defined MILL_VALGRIND
/* Valgrind stack identifier. */
Expand Down
127 changes: 69 additions & 58 deletions libmill.h
Expand Up @@ -59,6 +59,10 @@ extern "C" {
/* Symbol visibility */
/******************************************************************************/

#if !defined __GNUC__ && !defined __clang__
#error "Unsupported compiler!"
#endif

#if defined MILL_NO_EXPORTS
# define MILL_EXPORT
#else
Expand All @@ -84,6 +88,10 @@ extern "C" {
/* Helpers */
/******************************************************************************/

#define mill_string2(x) #x
#define mill_string(x) mill_string2(x)
#define MILL_HERE (__FILE__ ":" mill_string(__LINE__))

MILL_EXPORT int64_t mill_now(
void);
MILL_EXPORT pid_t mfork(
Expand All @@ -93,78 +101,83 @@ MILL_EXPORT pid_t mfork(
/* Coroutines */
/******************************************************************************/

MILL_EXPORT void mill_goprepare(
int count,
size_t stack_size,
size_t val_size);
#define MILL_FDW_IN_ 1
#define MILL_FDW_OUT_ 2
#define MILL_FDW_ERR_ 4

MILL_EXPORT extern volatile int mill_unoptimisable1;
MILL_EXPORT extern volatile void *mill_unoptimisable2;
MILL_EXPORT extern volatile int mill_unoptimisable1_;
MILL_EXPORT extern volatile void *mill_unoptimisable2_;

MILL_EXPORT sigjmp_buf *mill_getctx(
MILL_EXPORT sigjmp_buf *mill_getctx_(
void);
MILL_EXPORT __attribute__((noinline)) void *mill_go_prologue(
MILL_EXPORT __attribute__((noinline)) void *mill_prologue_(
const char *created);
MILL_EXPORT __attribute__((noinline)) void mill_go_epilogue(
MILL_EXPORT __attribute__((noinline)) void mill_epilogue_(
void);

#define mill_string2(x) #x
#define mill_string(x) mill_string2(x)

#if defined __GNUC__ || defined __clang__
#define coroutine __attribute__((noinline))
#else
#error "Unsupported compiler!"
#endif

#define MILL_HERE (__FILE__ ":" mill_string(__LINE__))

#define mill_go(fn) \
do {\
void *mill_sp;\
if(!sigsetjmp(*mill_getctx(), 0)) {\
mill_sp = mill_go_prologue(MILL_HERE);\
int mill_anchor[mill_unoptimisable1];\
mill_unoptimisable2 = &mill_anchor;\
char mill_filler[(char*)&mill_anchor - (char*)(mill_sp)];\
mill_unoptimisable2 = &mill_filler;\
fn;\
mill_go_epilogue();\
}\
} while(0)

#define yield() mill_yield(MILL_HERE)

MILL_EXPORT void mill_yield(
MILL_EXPORT void mill_goprepare_(
int count,
size_t stack_size,
size_t val_size);
MILL_EXPORT void mill_yield_(
const char *current);

#define msleep(deadline) mill_msleep((deadline), MILL_HERE)

MILL_EXPORT void mill_msleep(
MILL_EXPORT void mill_msleep_(
int64_t deadline,
const char *current);

#define fdwait(fd, events, deadline) \
mill_fdwait((fd), (events), (deadline), MILL_HERE)

MILL_EXPORT void fdclean(
int fd);

#define FDW_IN 1
#define FDW_OUT 2
#define FDW_ERR 4

MILL_EXPORT int mill_fdwait(
MILL_EXPORT int mill_fdwait_(
int fd,
int events,
int64_t deadline,
const char *current);

MILL_EXPORT void *cls(
MILL_EXPORT void mill_fdclean_(
int fd);
MILL_EXPORT void *mill_cls_(
void);
MILL_EXPORT void setcls(
MILL_EXPORT void mill_setcls_(
void *val);

#define mill_go_(fn) \
do {\
void *mill_sp;\
if(!sigsetjmp(*mill_getctx_(), 0)) {\
mill_sp = mill_prologue_(MILL_HERE);\
int mill_anchor[mill_unoptimisable1_];\
mill_unoptimisable2_ = &mill_anchor;\
char mill_filler[(char*)&mill_anchor - (char*)(mill_sp)];\
mill_unoptimisable2_ = &mill_filler;\
fn;\
mill_epilogue_();\
}\
} while(0)

#if defined MILL_USE_PREFIX
#define MILL_FDW_IN MILL_FDW_IN_
#define MILL_FDW_OUT MILL_FDW_OUT_
#define MILL_FDW_ERR MILL_FDW_ERR_
#define mill_coroutine __attribute__((noinline))
#define mill_go(fn) mill_go_(fn)
#define mill_goprepare mill_goprepare_
#define mill_yield() mill_yield_(MILL_HERE)
#define mill_msleep(dd) mill_msleep_((dd), MILL_HERE)
#define mill_fdwait(fd, ev, dd) mill_fdwait_((fd), (ev), (dd), MILL_HERE)
#define mill_fdclean mill_fdclean_
#define mill_cls mill_cls_
#define mill_setcls mill_setcls_
#else
#define FDW_IN MILL_FDW_IN_
#define FDW_OUT MILL_FDW_OUT_
#define FDW_ERR MILL_FDW_ERR_
#define coroutine __attribute__((noinline))
#define go(fn) mill_go_(fn)
#define goprepare mill_goprepare_
#define yield() mill_yield_(MILL_HERE)
#define msleep(deadline) mill_msleep_((deadline), MILL_HERE)
#define fdwait(fd, ev, dd) mill_fdwait_((fd), (ev), (dd), MILL_HERE)
#define fdclean mill_fdclean_
#define cls mill_cls_
#define setcls mill_setcls_
#endif

/******************************************************************************/
/* Channels */
/******************************************************************************/
Expand Down Expand Up @@ -306,8 +319,6 @@ MILL_EXPORT void mill_chclose(
# define mill_otherwise mill_internal__otherwise(__COUNTER__)
#else
# define now mill_now
# define goprepare(cnt, stcksz, valsz) mill_goprepare((cnt), (stcksz), (valsz))
# define go(fn) mill_go(fn)
# define choose mill_choose
# define end mill_end
# define in(chan, type, name) mill_internal__in((chan), type, name, __COUNTER__)
Expand Down
8 changes: 4 additions & 4 deletions poller.c
Expand Up @@ -54,8 +54,8 @@ do {\
} while(0)

/* Pause current coroutine for a specified time interval. */
void mill_msleep(int64_t deadline, const char *current) {
mill_fdwait(-1, 0, deadline, current);
void mill_msleep_(int64_t deadline, const char *current) {
mill_fdwait_(-1, 0, deadline, current);
}

static void mill_poller_callback(struct mill_timer *timer) {
Expand All @@ -65,7 +65,7 @@ static void mill_poller_callback(struct mill_timer *timer) {
mill_poller_rm(cr);
}

int mill_fdwait(int fd, int events, int64_t deadline, const char *current) {
int mill_fdwait_(int fd, int events, int64_t deadline, const char *current) {
check_poller_initialised();
/* If required, start waiting for the timeout. */
if(deadline >= 0)
Expand All @@ -89,7 +89,7 @@ int mill_fdwait(int fd, int events, int64_t deadline, const char *current) {
return 0;
}

void fdclean(int fd) {
void mill_fdclean_(int fd) {
check_poller_initialised();
mill_poller_clean(fd);
}
Expand Down
4 changes: 2 additions & 2 deletions tests/unix.c
Expand Up @@ -30,11 +30,11 @@
#define MILL_USE_PREFIX
#include "../libmill.h"

coroutine void client(const char *addr) {
mill_coroutine void client(const char *addr) {
mill_unixsock cs = mill_unixconnect(addr);
assert(cs);

msleep(mill_now() + 100);
mill_msleep(mill_now() + 100);

char buf[16];
size_t sz = mill_unixrecv(cs, buf, 3, -1);
Expand Down

0 comments on commit bce5130

Please sign in to comment.