Presentations/arduino_proto_threads/tp_serre/pt.h

77 lines
2.6 KiB
C

#ifndef __PT_H__
#define __PT_H__
typedef unsigned short lc_t;
#define LC_INIT(s) s = 0; // LC_INIT
#define LC_RESUME(s) switch(s) { case 0: // LC_RESUME
#define LC_SET(s) s = __LINE__; case __LINE__: // LC_SET line
#define LC_END(s) } // LC_END
struct pt { lc_t lc; };
#define PT_WAITING 0
#define PT_YIELDED 1
#define PT_EXITED 2
#define PT_ENDED 3
#define PT_INIT(pt) LC_INIT((pt)->lc) // INIT
#define PT_THREAD(name_args) char name_args // THREAD
#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc) // BEGIN
#define PT_END(pt) LC_END((pt)->lc); \
PT_YIELD_FLAG = 0; \
PT_INIT(pt); return PT_ENDED; } // END
#define PT_WAIT_UNTIL(pt, condition) \
do { \
LC_SET((pt)->lc); \
if(!(condition)) { \
return PT_WAITING; \
} \
} while(0) // WAIT_UNTIL
#define PT_WAIT_WHILE(pt, cond) \
PT_WAIT_UNTIL((pt), !(cond)) // WAIT_WHILE
#define PT_WAIT_THREAD(pt, thread) \
PT_WAIT_WHILE((pt), PT_SCHEDULE(thread)) // WAIT_THREAD
#define PT_SPAWN(pt, child, thread) \
do { \
PT_INIT((child)); \
PT_WAIT_THREAD((pt), (thread)); \
} while(0) // SPAWN
#define PT_RESTART(pt) \
do { \
PT_INIT(pt); \
return PT_WAITING; \
} while(0) // RESTART
#define PT_EXIT(pt) \
do { \
PT_INIT(pt); \
return PT_EXITED; \
} while(0) // EXIT
#define PT_SCHEDULE(f) ((f) < PT_EXITED) // SCHEDULE
#define PT_YIELD(pt) \
do { \
PT_YIELD_FLAG = 0; \
LC_SET((pt)->lc); \
if(PT_YIELD_FLAG == 0) { \
return PT_YIELDED; \
} \
} while(0) // YIELD
#define PT_YIELD_UNTIL(pt, cond) \
do { \
PT_YIELD_FLAG = 0; \
LC_SET((pt)->lc); \
if((PT_YIELD_FLAG == 0) || !(cond)) { \
return PT_YIELDED; \
} \
} while(0) // YIELD_UNTIL
// checked for n calls in a thread : seems OK
#define PT_DELAY(pt, ms) \
do { \
static unsigned long _PTTTL_ ; \
_PTTTL_ = millis() + (unsigned int)(ms); \
PT_WAIT_UNTIL((pt), (millis() > _PTTTL_)); \
} while(0) // DELAY
#define PT_SYNC(pt, mark, ms) \
do { \
PT_WAIT_UNTIL((pt), (millis() - (mark) > (ms) )); \
} while(0) // SYNC
#endif /* __PT_H__ */