diff --git a/README.md b/README.md index dcf7c8e..c357868 100644 --- a/README.md +++ b/README.md @@ -29,8 +29,9 @@ Function|Description I ported the examples found in the protothreads distribution to async.h. Here is the async.h equivalent of the protothreads sample on the home page: -```C +```c #include "async.h" +#include "async-time.h" struct async pt; struct timer timer; @@ -40,7 +41,7 @@ async example(struct async *pt) { while(1) { if(initiate_io()) { - timer_start(&timer); + timer_set(&timer); await(io_completed() || timer_expired(&timer)); read_data(); } @@ -54,12 +55,13 @@ to accept the async structure/local continuation as an argument. Here is the same example as above, but where the timer is lifted to a local parameter: -```C +```c #include "async.h" +#include "async-time.h" typedef struct { async_state; // declare the asynchronous state - timer timer; // declare local state + struct timer timer; // declare local state } example_state; example_state pt; @@ -68,7 +70,7 @@ async example(example_state *pt) { while(1) { if(initiate_io()) { - timer_start(&pt->timer); + timer_set(&pt->timer); await(io_completed() || timer_expired(&pt->timer)); read_data(); } diff --git a/async/Makefile b/async/Makefile index c664808..45c3f60 100644 --- a/async/Makefile +++ b/async/Makefile @@ -2,7 +2,7 @@ CC = gcc CCFlags = -Wall BUILD_DIR = build -SRC = example-buffer.c example-codelock.c example-small.c main.c +SRC = async-time.c example-buffer.c example-codelock.c example-small.c main.c OBJ = $(patsubst %.c,$(BUILD_DIR)/%.o,$(SRC)) all : $(OBJ) diff --git a/async/async-time.c b/async/async-time.c new file mode 100644 index 0000000..7d64d12 --- /dev/null +++ b/async/async-time.c @@ -0,0 +1,49 @@ +#ifdef _WIN32 +#include +#else +#include +#include +#endif + +#include "async.h" +#include "async-time.h" + +#ifdef _WIN32 + +static int clock_time(void) +{ + return (int)GetTickCount(); +} + +#else /* _WIN32 */ + +static int clock_time(void) +{ + struct timeval tv; + struct timezone tz; + gettimeofday(&tv, &tz); + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} + +#endif /* _WIN32 */ + +int timer_expired(struct timer *t) +{ + return (int)(clock_time() - t->start) >= (int)t->interval; +} + +void timer_set(struct timer *t, unsigned int interval) +{ + t->interval = interval; + t->start = clock_time(); +} + +async async_sleep(struct async_sleep_state *state, unsigned int usecs) +{ + async_begin(state); + + timer_set(&state->timer, usecs); + await(timer_expired(&state->timer)); + + async_end; +} diff --git a/async/async-time.h b/async/async-time.h new file mode 100644 index 0000000..02accec --- /dev/null +++ b/async/async-time.h @@ -0,0 +1,42 @@ +#include "async.h" + +/** + * Timer structure for tracking when a timer has expired + */ +struct timer +{ + unsigned int start; + unsigned int interval; +}; + +/** + * State structure for calls to the async_sleep function + */ +struct async_sleep_state +{ + async_state; + struct timer timer; +}; + +/** + * Initialize a timer with a specified time duration + * + * @param t timer struct to initialize + * @param usecs number of milliseconds the timer is good for + */ +void timer_set(struct timer *t, unsigned int usecs); + +/** + * Determine if the supplied timer is expired + * + * @param t timer struct to examine for expiration + */ +int timer_expired(struct timer *t); + +/** + * Sleep asynchronously for a specified duration + * + * @param state async_sleep_state structure to hold state of operation + * @param usecs number of milliseconds to sleep for + */ +async async_sleep(struct async_sleep_state *state, unsigned int usecs); \ No newline at end of file diff --git a/async/example-codelock.c b/async/example-codelock.c index aeac93b..21ee82c 100644 --- a/async/example-codelock.c +++ b/async/example-codelock.c @@ -61,16 +61,8 @@ #include #include "async.h" +#include "async-time.h" -/*---------------------------------------------------------------------------*/ -/* - * The following definitions are just for the simple timer library - * used in this example. The actual implementation of the functions - * can be found at the end of this file. - */ -struct timer { int start, interval; }; -static int timer_expired(struct timer *t); -static void timer_set(struct timer *t, int usecs); /*---------------------------------------------------------------------------*/ /* * This example uses two timers: one for the code lock async and @@ -385,30 +377,4 @@ example_codelock(void) return 0; } -/*---------------------------------------------------------------------------*/ -/* - * Finally, the implementation of the simple timer library follows. - */ -#ifdef _WIN32 - -static int clock_time(void) -{ return (int)GetTickCount(); } -#else /* _WIN32 */ - -static int clock_time(void) -{ - struct timeval tv; - struct timezone tz; - gettimeofday(&tv, &tz); - return tv.tv_sec * 1000 + tv.tv_usec / 1000; -} - -#endif /* _WIN32 */ - -static int timer_expired(struct timer *t) -{ return (int)(clock_time() - t->start) >= (int)t->interval; } - -static void timer_set(struct timer *t, int interval) -{ t->interval = interval; t->start = clock_time(); } -/*---------------------------------------------------------------------------*/