From e8a2ce2f219ffaf64775cca55e420cad947d05ce Mon Sep 17 00:00:00 2001 From: Fabio Sassi Date: Fri, 11 Oct 2019 13:39:13 +0200 Subject: [PATCH] removed ew_del, enhanced readability of ab_trie --- lib/ab_trie.c | 33 ++- lib/ab_trie.h | 87 +++---- lib/ew.h | 12 +- lib/ew_epoll.c | 2 + lib/ew_kqueue.c | 15 +- server.c | 4 - server.h | 2 +- zm.c | 602 +++++++++++++++++++----------------------------- zm.h | 59 ++--- 9 files changed, 341 insertions(+), 475 deletions(-) diff --git a/lib/ab_trie.c b/lib/ab_trie.c index 4612d38..aa5f720 100644 --- a/lib/ab_trie.c +++ b/lib/ab_trie.c @@ -103,9 +103,9 @@ static const char *ab_loStatusName(int status) AB_CASE(AB_LKUP_EMPTY); AB_CASE(AB_LKUP_FOUND); AB_CASE(AB_LKUP_NOVAL); - AB_CASE(AB_LKUP_BRANCH_A_AB); - AB_CASE(AB_LKUP_BRANCH_AB_A); - AB_CASE(AB_LKUP_BRANCH_AB_AC); + AB_CASE(AB_LKUP_BRANCH_OVER); + AB_CASE(AB_LKUP_BRANCH_INTO); + AB_CASE(AB_LKUP_BRANCH_DIFF); AB_CASE(AB_LKUP_NODE_NOITEM); AB_CASE(AB_LKUP_NODE_NOSUB); default: @@ -116,11 +116,6 @@ static const char *ab_loStatusName(int status) #undef AB_CASE - - - - - /* * DEBUG PRINT #SECTION */ @@ -441,8 +436,8 @@ static int ab_loBranch(ab_Look *lo) position inside this branch */ lo->ipos--; if (!next) { - /* branch = abc, data = abcdef */ - lo->status = AB_LKUP_BRANCH_A_AB; + /* branch = abc, lookup = abcdef */ + lo->status = AB_LKUP_BRANCH_OVER; return false; } @@ -456,7 +451,7 @@ static int ab_loBranch(ab_Look *lo) if (lo->key[lo->ipos] != b->kdata[lo->bpos]) { /* branch = abcdef, data = abcxyz */ - lo->status = AB_LKUP_BRANCH_AB_AC; + lo->status = AB_LKUP_BRANCH_DIFF; AB_D printf("lu-b: different char\n"); return false; } @@ -469,8 +464,8 @@ static int ab_loBranch(ab_Look *lo) else lo->status = AB_LKUP_NOVAL; } else { - /* branch = abcdef, data = abc */ - lo->status = AB_LKUP_BRANCH_AB_A; + /* branch = abcdef, lookup = abc */ + lo->status = AB_LKUP_BRANCH_INTO; } return false; } @@ -845,7 +840,7 @@ static void ab_addOnBranch(ab_Look *lo, void *value) switch(lo->status) { - case AB_LKUP_BRANCH_A_AB: { + case AB_LKUP_BRANCH_OVER: { /* bpos over branch length: abc + abcdef */ int off = lo->ipos + 1; @@ -857,7 +852,7 @@ static void ab_addOnBranch(ab_Look *lo, void *value) return; } - case AB_LKUP_BRANCH_AB_A: { + case AB_LKUP_BRANCH_INTO: { /* abcdef + abc */ ab_Branch *head; AB_D printf("branchAdd: abcdef + abc\n"); @@ -867,7 +862,7 @@ static void ab_addOnBranch(ab_Look *lo, void *value) break; } - case AB_LKUP_BRANCH_AB_AC: { + case AB_LKUP_BRANCH_DIFF: { /* abcdef + abcxyz */ ab_Node *node; ab_Wood *head; @@ -1493,9 +1488,9 @@ void* ab_set(ab_Look *lo, void *val) ab_setValue(lo, val); break; - case AB_LKUP_BRANCH_A_AB: - case AB_LKUP_BRANCH_AB_A: - case AB_LKUP_BRANCH_AB_AC: + case AB_LKUP_BRANCH_OVER: + case AB_LKUP_BRANCH_INTO: + case AB_LKUP_BRANCH_DIFF: case AB_LKUP_NODE_NOITEM: case AB_LKUP_NODE_NOSUB: ab_addOn(lo, val); diff --git a/lib/ab_trie.h b/lib/ab_trie.h index a284255..41f2202 100644 --- a/lib/ab_trie.h +++ b/lib/ab_trie.h @@ -40,13 +40,6 @@ #endif -typedef struct { - uint8_t flag; - char letter; - uint8_t n; - uint8_t v; -} ab_NodeItem; - #define AB_NODE 1 #define AB_BRANCH 2 @@ -59,6 +52,52 @@ typedef struct { #define AB_ITEM_SUB 4 #define AB_ITEM_MASK (AB_ITEM_ON | AB_ITEM_VAL | AB_ITEM_SUB) +#define AB_MIN(x, y) (((x) < (y)) ? (x) : (y)) + +enum { + /* lookup initialized but not performed */ + AB_LKUP_INIT, + + /* lookup out of sync - used in a set or del operation */ + AB_LKUP_UNSYNC, + + /* found - pattern exists in trie and have value */ + AB_LKUP_FOUND, + + /* not found - trie is empty */ + AB_LKUP_EMPTY, + + /* not found - reached leaf-branch end (b = ab, lk = abc) */ + AB_LKUP_BRANCH_OVER, + + /* not found - stand inside branch (b = abc, lk = ab) */ + AB_LKUP_BRANCH_INTO, + + /* not found - different chars in lookup branch (b = abc, lk = axy) */ + AB_LKUP_BRANCH_DIFF, + + /* not found - char not found in node */ + AB_LKUP_NODE_NOITEM, + + /* not found - reached a leaf-node */ + AB_LKUP_NODE_NOSUB, + + /* not found - pattern exists in trie but have no value */ + AB_LKUP_NOVAL +}; + + + +typedef struct { + uint8_t flag; + char letter; + uint8_t n; + uint8_t v; +} ab_NodeItem; + + + + typedef struct { uint8_t flag; @@ -91,37 +130,6 @@ typedef struct { -enum { - /* lookup initialized but not performed */ - AB_LKUP_INIT, - - /* lookup out of sync - used in a set or del operation */ - AB_LKUP_UNSYNC, - - /* found - pattern exists in trie and have value */ - AB_LKUP_FOUND, - - /* not found - trie is empty */ - AB_LKUP_EMPTY, - - /* not found - reached leaf-branch end (b = ab, lk = abc) */ - AB_LKUP_BRANCH_A_AB, - - /* not found - stand inside branch (b = abc, lk = ab) */ - AB_LKUP_BRANCH_AB_A, - - /* not found - different chars in lookup branch (b = abc, lk = axy) */ - AB_LKUP_BRANCH_AB_AC, - - /* not found - char not found in node */ - AB_LKUP_NODE_NOITEM, - - /* not found - reached a leaf-node */ - AB_LKUP_NODE_NOSUB, - - /* not found - pattern exists in trie but have no value */ - AB_LKUP_NOVAL -}; /* TODO @@ -157,7 +165,8 @@ typedef struct { ab_Cursor path[3]; } ab_Look; -#define AB_MIN(x, y) (((x) < (y)) ? (x) : (y)) + + void ab_printWood(ab_Wood *w, int indent, int recursive); void ab_printKeys(ab_Wood *w, int indent); diff --git a/lib/ew.h b/lib/ew.h index 861e7e7..00ab6dd 100644 --- a/lib/ew.h +++ b/lib/ew.h @@ -26,14 +26,15 @@ /* wrapping for trigger event notification system */ +#ifdef __sun + #error "Solaris based systems are not supported" +#endif + #ifdef __linux__ - #include + #include /* linux epoll */ typedef struct epoll_event ew_Event; #else - #ifdef __sun - #error "SunOS is not supported" - #endif - #include /* kqueue */ + #include /* xBSD kqueue */ typedef struct kevent ew_Event; #endif @@ -50,7 +51,6 @@ void* ew_data(ew_Event *ev); const char* ew_flags(ew_Event *ev); void ew_add(int efd, int sock, int flag, void *ptr); -void ew_del(int efd, int sock); int ew_wait(int epfd, ew_Event *events, int maxevents, int timeout); diff --git a/lib/ew_epoll.c b/lib/ew_epoll.c index 8677ab2..9b6cf66 100644 --- a/lib/ew_epoll.c +++ b/lib/ew_epoll.c @@ -50,11 +50,13 @@ void* ew_data(ew_Event *ev) } +#if 0 void ew_del(int efd, int fd) { if (epoll_ctl(efd, EPOLL_CTL_DEL, fd, NULL) == -1) ea_pfatal("ew_del: error in epoll_ctl del"); } +#endif void ew_add(int efd, int fd, int ewflag, void *ptr) { diff --git a/lib/ew_kqueue.c b/lib/ew_kqueue.c index 073ebd8..f5e2cfe 100644 --- a/lib/ew_kqueue.c +++ b/lib/ew_kqueue.c @@ -30,6 +30,8 @@ #include "ea.h" #include "ew.h" + +typedef struct kevent ew_Event; /*--------------------------------------------------------------------------- * epoll and socket @@ -59,6 +61,7 @@ void* ew_data(ew_Event *ev) return ((struct kevent*)ev)->udata; } +#if 0 void ew_del(int kq, int fd) { struct kevent kevdel; @@ -72,15 +75,6 @@ void ew_del(int kq, int fd) Levin sets always READ | WRITE so as a temporary workaround remove READ and WRITE */ - #if 0 - kevdel.ident = fd; - /* this is a temporary workaround for OpenBSD FIXME */ - kevdel.filter = EVFILT_READ | EVFILT_WRITE; - kevdel.fflags = 0; - kevdel.flags = EV_DELETE; - kevdel.data = 0; - kevdel.udata = NULL; - #else EV_SET(&kevdel, fd, EVFILT_READ, EV_DELETE, 0, 0, 0); if (kevent(kq, &kevdel, 1, NULL, 0, NULL) == -1) ea_pfatal("ew_del: error in kevent del"); @@ -89,9 +83,8 @@ void ew_del(int kq, int fd) EV_SET(&kevdel, fd, EVFILT_WRITE, EV_DELETE, 0, 0, 0); if (kevent(kq, &kevdel, 1, NULL, 0, NULL) == -1) ea_pfatal("ew_del: error in kevent del"); - #endif - } +#endif void ew_add(int kq, int fd, int flag, void *ptr) { diff --git a/server.c b/server.c index 36b28c8..3139304 100644 --- a/server.c +++ b/server.c @@ -58,8 +58,6 @@ void connClose(int fd) { DBG1 report("close connection socket user=%d", fd); - ew_del(evfd, fd); - io_closeConnectionSocket(fd); } @@ -163,8 +161,6 @@ static void closeListenSocket() { if (evfd) { DBG0 report("unregister listen socket"); - if (listensocket) - ew_del(evfd, listensocket); ew_free(evfd); evfd = 0; diff --git a/server.h b/server.h index 3a90d75..ac4e33c 100644 --- a/server.h +++ b/server.h @@ -39,7 +39,7 @@ #include "zm.h" #include "log.h" -#define LEVIN_VERSION "0.4" +#define LEVIN_VERSION "0.5" #define PORT 5210 #define LISTEN_BACKLOG 50 diff --git a/zm.c b/zm.c index a8fba04..c77bc2c 100644 --- a/zm.c +++ b/zm.c @@ -116,6 +116,9 @@ static struct { } zmg_mutex = {NULL, NULL}; +/* indentation-less special prefix char */ +#define ZM_ILS "<" + #define ZM_ELOCK_ON 1 #define ZM_ELOCK_OFF 2 @@ -186,21 +189,21 @@ static void zm_memfatal(const char *fmt, ...) -void *zm_malloc(size_t size, int memfatal) +void *zm_malloc(size_t size) { void *ptr = malloc(size); - if ((memfatal) && (!ptr)) + if (!ptr) zm_memfatal("zm_malloc: out of mem\n"); return ptr; } -void *zm_mrealloc(void *ptr, size_t size, int memfatal) +void *zm_mrealloc(void *ptr, size_t size) { ptr = realloc(ptr, size); - if ((memfatal) && (!ptr)) + if (!ptr) zm_memfatal("zm_mrealloc: out of mem\n"); return ptr; @@ -342,152 +345,62 @@ static zm_State* zm_queueFindPop(zm_StateQueue *q, zm_State *s, * --------------------------------------------------------------------------*/ -static int zm_hasPrintBuffer(zm_Print *out, int len) +void zm_initPrint(zm_Print *p, FILE *stream, int indent) { - if (!out->buffer.data) - return false; - - if (len < 0) { - zm_removePrintBuffer(out); - return false; - } - - /* add one byte for the terminal null byte */ - len += 1; - - if ((out->buffer.used + len) >= out->buffer.size) { - void *ptr = (void*)out->buffer.data; - size_t size = out->buffer.used + len + 512; - - ptr = zm_mrealloc(ptr, size, false); - - if (!ptr) { - zm_removePrintBuffer(out); - return false; - } - - out->buffer.data = (char*)ptr; - out->buffer.size = size; - } - - return true; + p->file = stream; + p->indent = indent; } -static int zm_vprintf(zm_Print *out, const char *fmt, va_list args) +void zm_setIndent(zm_Print *out, int indent) { - int len = vfprintf(out->file, fmt, args); - - fflush(out->file); - - return len; - + out->indent = indent; } -static void zm_vprintb(zm_Print *out, int len, const char *fmt, va_list args) + +void zm_addIndent(zm_Print *out, int indent) { - vsprintf(out->buffer.data + out->buffer.used, fmt, args); - out->buffer.used += len; + out->indent += indent; } -static void zm_printIndent(zm_Print *out) +/* + * Indent and print. If fmt starts with ZM_ILS the + * indentation is ignored. + */ +void zm_vprint(zm_Print *out, const char *fmt, va_list args) { - int i; - - for (i = 0; i < out->indent; i++) - fprintf(out->file, " "); - - if (zm_hasPrintBuffer(out, out->indent)) { - char *b = out->buffer.data + out->buffer.used; + if (fmt[0] != ZM_ILS[0]) { + #if 0 + int i; for (i = 0; i < out->indent; i++) - sprintf(b++, " "); - - out->buffer.used += out->indent; + fprintf(out->file, " "); + #else + if (out->indent > 0) + fprintf(out->file, "%.*s", + ((out->indent > 74) ? 74 : out->indent), + " " + " "); + #endif + } else { + fmt++; } -} -/* - * inline print (without identation) - */ -void zm_iprint(zm_Print *out, const char *fmt, ...) -{ - va_list args; - int len; - - va_start(args, fmt); - len = zm_vprintf(out, fmt, args); - va_end(args); + vfprintf(out->file, fmt, args); - if (zm_hasPrintBuffer(out, len)) { - va_start(args, fmt); - zm_vprintb(out, len, fmt, args); - va_end(args); - } + fflush(out->file); } - /* - * main print utility (with identation) + * Indent and print (see zm_vprint) */ void zm_print(zm_Print *out, const char *fmt, ...) { va_list args; - int len; - - zm_printIndent(out); - va_start(args, fmt); - len = zm_vprintf(out, fmt, args); + zm_vprint(out, fmt, args); va_end(args); - - if (zm_hasPrintBuffer(out, len)) { - va_start(args, fmt); - zm_vprintb(out, len, fmt, args); - va_end(args); - } -} - - -void zm_initPrint(zm_Print *p, FILE *stream, int indent, int buf) -{ - p->file = stream; - p->indent = indent; - - if (buf) { - p->buffer.data = (char*)zm_malloc(512, false); - p->buffer.used = 0; - p->buffer.size = 512; - } else { - p->buffer.data = NULL; - } -} - -void zm_setIndent(zm_Print *out, int indent) -{ - out->indent = indent; -} - -void zm_addIndent(zm_Print *out, int indent) -{ - out->indent += indent; -} - -char* zm_popPrintBuffer(zm_Print *out, size_t *size) -{ - char* b = out->buffer.data; - if (size) - *size = out->buffer.size; - - out->buffer.data = NULL; - return b; -} - -void zm_removePrintBuffer(zm_Print *out) -{ - zm_nfree(char, out->buffer.size, out->buffer.data); - out->buffer.data = NULL; } @@ -579,25 +492,25 @@ static const char* zm_fatalKind(zm_fatal_t kind) switch(kind) { case ZM_FATAL_U2: if (!zmg_err.first) - return "UNEXPECTED ERROR REPORTING ANOTHER ERROR"; + return "Unexpected (while reporting another error)"; case ZM_FATAL_U1: - return "UNEXPECTED ERROR"; + return "Unexpected"; case ZM_FATAL_UP: - return "UNEXPECTED ERROR IN PROCESS TASK"; + return "Unexpected during process task"; case ZM_FATAL_GCODE: - return "CODE ERROR"; + return "Error"; case ZM_FATAL_YCODE: - return "TASK CODE ERROR - WRONG CODE IN YIELD OR RAISE"; + return "Error in yield/raise"; case ZM_FATAL_TCODE: - return "TASK CODE ERROR - WRONG CODE INSIDE TASK"; + return "Error in task"; default: - return "??UNKNOW FATAL KIND??"; + return "??UNKNOW FATAL-KIND??"; } } @@ -610,12 +523,12 @@ static void zm_fatalPrintWhere(zm_Print *out, zm_fatal_t kind) if ((!zmg_err.ucode.reference) && (!zmg_err.ucode.filename) && (!state)) return; - zm_print(out, "\n\nError occured at:"); + zm_print(out, "Error occured at:"); if (zmg_err.ucode.reference) - zm_iprint(out, " %s\n", zmg_err.ucode.reference); + zm_print(out, ZM_ILS" %s\n", zmg_err.ucode.reference); else - zm_iprint(out, "\n"); + zm_print(out, ZM_ILS"\n"); zm_addIndent(out, 4); @@ -651,17 +564,20 @@ static void zm_fatalPrintWhere(zm_Print *out, zm_fatal_t kind) static void zm_fatalPrintError(zm_fatal_t kind, const char *ecode, - const char *fmt, va_list args) + const char *fmt, va_list args) { zm_Print out; - zm_initPrint(&out, stderr, 0, false); + zm_initPrint(&out, stderr, 0); - zm_print(&out, "\n\nZM %s\n", ZM_VERSION); + zm_print(&out, "\n[ZM ver %s] ZM FATAL ERROR: (%s)\n %s: ", + ZM_VERSION, ecode, + zm_fatalKind(kind) + ); - zm_print(&out, "%s:\n code=%s\n ", zm_fatalKind(kind), ecode); + zm_vprint(&out, fmt, args); - zm_vprintf(&out, fmt, args); + zm_print(&out, "\n\n"); zm_fatalPrintWhere(&out, kind); @@ -689,7 +605,7 @@ static int zm_fatalPrintDump(zm_fatal_t kind) if (zmg_err.vm) { zm_Print out; - zm_initPrint(&out, stderr, 0, false); + zm_initPrint(&out, stderr, 0); zm_printVM(&out, zmg_err.vm); return true; } @@ -708,7 +624,7 @@ static void zm_fatalTrigger() static void zm_fatalDo(zm_fatal_t kind, const char *ecode, - const char *fmt, ...) + const char *fmt, ...) { va_list args; @@ -743,7 +659,7 @@ void zm_fatalNoYield(zm_VM *vm, int out, const char *fn, int nl) if (out) { zm_fatalInitAt(vm, NULL, fn, nl); - zm_fatalDo(ZM_FATAL_YCODE, "UNDEFSTATE.BRK", + zm_fatalDo(ZM_FATAL_TCODE, "UNDEFSTATE.BRK", "jump over task definition, search " "for unbound `break` in zmstate %d", op); } else if (op == 0) { @@ -752,9 +668,9 @@ void zm_fatalNoYield(zm_VM *vm, int out, const char *fn, int nl) "reserved"); } else { zm_fatalInitAt(vm, NULL, fn, nl); - zm_fatalDo(ZM_FATAL_YCODE, "UNDEFSTATE.N", - "Reached end of the task definition" - "(zmstate %d not defined or it forgive " + zm_fatalDo(ZM_FATAL_TCODE, "UNDEFSTATE.N", + "reached end of the task definition " + "(zmstate %d not defined or forgive " "to zmyield/zmraise)", op); } @@ -777,7 +693,7 @@ static size_t zm_deep(zm_State *sub); zm_Print defaultout; \ if (!out) { \ out = &defaultout; \ - zm_initPrint(out, stdout, 0, false); \ + zm_initPrint(out, stdout, 0); \ } #define ZM_STRCASE(x) case x: return #x @@ -796,22 +712,6 @@ static const char *zm_exceptionKind(int kind) } -static const char *zm_yieldCommandName(int n) -{ - switch(ZM_B4(n)) { - ZM_STRCASE(ZM_TASK_CONTINUE); - ZM_STRCASE(ZM_TASK_SUSPEND); - ZM_STRCASE(ZM_TASK_SUSPEND_WAITING_SUBTASK); - ZM_STRCASE(ZM_TASK_END); - ZM_STRCASE(ZM_TASK_TERM); - ZM_STRCASE(ZM_TASK_SUSPEND_AND_RESUME_CALLER); - ZM_STRCASE(ZM_TASK_BUSY_WAITING_EVENT); - ZM_STRCASE(ZM_TASK_RAISE_CONTINUE_EXCEPTION); - ZM_STRCASE(ZM_TASK_RAISE_ABORT_EXCEPTION); - } - return "unknow yield command"; -} - static const char *zm_implodeFlagName(int implodeby) { switch (implodeby) { @@ -957,7 +857,7 @@ static void zm_printStateException(zm_Print *out, zm_VM *vm, zm_State *estate) } -#define ZM_CPRINT(c, e) zm_iprint(out, (compact) ? c : e) +#define ZM_CPRINT(c, e) zm_print(out, (compact) ? (ZM_ILS c) : (ZM_ILS e)) static void zm_printFlags(zm_Print* out, zm_State *s, int compact) @@ -978,7 +878,7 @@ static void zm_printFlags(zm_Print* out, zm_State *s, int compact) ZM_CPRINT("[ws]", "(waiting-subtask) "); } else { if (s->flag & ZM_STATE_EVENTLOCKED) - /* #EVB_FLAG*/ + /* #EVB_FLAG */ ZM_CPRINT("[evb]", "(event-binded) "); else ZM_CPRINT("[su]", "(suspend) "); @@ -1024,21 +924,21 @@ void zm_printStateCompact(zm_Print *out, zm_State *s) zm_printFlags(out, s, true); - zm_iprint(out, " "); + zm_print(out, ZM_ILS" "); - /*zm_iprint(out, "on:%d|%d|%d", s->on.resume, s->on.iter,s->on.c4tch);*/ + /*zm_print(out, "on:%d|%d|%d", s->on.resume, s->on.iter,s->on.c4tch);*/ if (zm_hasCaller(s)) - zm_iprint(out, "caller:%zx ", zm_caller(s)); + zm_print(out, ZM_ILS"caller:%zx ", zm_caller(s)); if (s->pmode != ZM_PMODE_NORMAL) - zm_iprint(out, "%s ", zm_getModeName(s, true)); + zm_print(out, ZM_ILS"%s ", zm_getModeName(s, true)); if (s->exception) - zm_iprint(out, "!%zx", s->exception); + zm_print(out, ZM_ILS"!%zx", s->exception); - zm_iprint(out, "\n"); + zm_print(out, ZM_ILS"\n"); } @@ -1084,18 +984,18 @@ void zm_printState(zm_Print *out, zm_VM *vm, zm_State *s) zm_print(out, "next: "); if (s->flag & ZM_STATE_RUN) { - zm_iprint(out, "(state)"); + zm_print(out, ZM_ILS"(state)"); } else { if (s->flag & ZM_STATE_EVENTLOCKED) { zm_EventBinder* evb = (zm_EventBinder*)s->next; - zm_iprint(out, "(eventbinder->worker: %s)", + zm_print(out, ZM_ILS"(eventbinder->worker: %s)", zm_workerName((zm_Worker*)evb->statenext)); } else { - zm_iprint(out, "(saved worker: %s)", + zm_print(out, ZM_ILS"(saved worker: %s)", zm_workerName((zm_Worker*)s->next)); } } - zm_iprint(out, " [ref: %zx]\n", s->next); + zm_print(out, ZM_ILS" [ref: %zx]\n", s->next); if (!s->exception) @@ -1281,7 +1181,7 @@ static void zm_checkFoundCaller(zm_VM *vm, zm_StateQueue *qiter, if (nmatch > 1) { zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_U2, "FINDCALL.NN", - "findCaller: found more than one " + "findCaller found more than one " "(%d) caller for task %zx", nmatch, state); } @@ -1325,15 +1225,13 @@ static void zm_printCheckConsistency(zm_VM *vm) if (!state->siblings.next) { zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_U2, "PRNTTASK.1", - "zm_printTasks: null ref in " - "siblings ring"); + "null ref in siblings ring"); } if (i++ > vm->nptask) { zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_U2, "PRNTTASK.2", - "zm_printTasks: siblings count " - "doesn't match"); + "siblings count doesn't match"); } runcount = zm_subcheckConsistency(state); @@ -1342,9 +1240,8 @@ static void zm_printCheckConsistency(zm_VM *vm) if (runcount > 1) { zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_U2, "PRNTTASK.RC", - "zm_printTask: more than one task " - "run in the same exec-context " - "(context: [ref %zx] count: %d)", + "more than one task run in the same" + "exec-context (ctx: [ref %zx] count: %d)", state, runcount); } @@ -1388,14 +1285,14 @@ void zm_printTasks(zm_Print *out, zm_VM *vm) } -static void zm_printDataBranchVM(zm_Print *out, zm_State *state, int deep) +static void zm_printDataTreeBranch(zm_Print *out, zm_State *state, int deep) { zm_State *s, *first; ZM_DEFAULT_STDOUT(out); if (deep > ZM_PRINTSTATE_MAXDEEP) { - zm_print(out, "zm_printStateRecursive: [WARNING] " + zm_print(out, "zm_printDataTreeBranch: [WARNING] " "deep = %d > MAX DEEP", deep); return; } @@ -1413,7 +1310,7 @@ static void zm_printDataBranchVM(zm_Print *out, zm_State *state, int deep) do { zm_addIndent(out, 5); - zm_printDataBranchVM(out, s, deep+1); + zm_printDataTreeBranch(out, s, deep+1); zm_addIndent(out, -5); s = s->siblings.next; @@ -1438,7 +1335,7 @@ void zm_printDataTree(zm_Print *out, zm_VM *vm) do { zm_addIndent(out, 1); - zm_printDataBranchVM(out, state, 0); + zm_printDataTreeBranch(out, state, 0); zm_addIndent(out, -1); @@ -1526,7 +1423,7 @@ static void zm_printCallerStackTitle(zm_Print *out, zm_VM *vm, zm_State *head) else if (zm_hasException(head, ZM_EXCEPTION_CONTINUEHEAD)) zm_print(out, "*** Continue Exception Stack:\n"); else - zm_print(out, "*** Unknow Caller Stack ????:\n"); + zm_print(out, "*** Suspended Tasks:\n"); } @@ -1549,13 +1446,14 @@ void zm_printCallerStack(zm_Print *out, zm_VM *vm) zm_StateList *sl = q->first; while(sl) { - zm_State *s = sl->state; + zm_State *head, *s = sl->state; + if (zm_hasCaller(s)) { sl = sl->next; continue; } - zm_State *head = zm_callerStackHead(s); + head = zm_callerStackHead(s); zm_queueFindPop(q, s, NULL); zm_printCallerStackTitle(out, vm, head); @@ -1612,9 +1510,7 @@ void zm_printActiveWorkers(zm_Print *out, zm_VM *vm) if ((w == w->next) && (w != vm->workercursor)){ zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_U2, "PRNTVM.1", - "inconsistency in " - "zm_printVM: worker " - "ring is not closed"); + "worker ring is not closed"); } #endif w = w->next; @@ -1624,8 +1520,7 @@ void zm_printActiveWorkers(zm_Print *out, zm_VM *vm) if (i != vm->nworker) { zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_U2, "PRNTVM.2", - "inconsistency: declared nworker = %d " - "but found nworker = %d", + "declared nworker = %d but found %d", vm->nworker, i); } #endif @@ -1709,7 +1604,7 @@ size_t zm_getDeep(zm_State *s) return (zm_isSubTask(s)) ? s->parent->stacksize : 0; } - +/* what can be used to? if have no meaning remove it TODO */ zm_State* izmGetParent(zm_VM *vm, size_t n, const char *fn, int nl) { zm_State *s = zm_getCurrentState(vm); @@ -1899,12 +1794,12 @@ int izmYieldTrace(zm_VM* vm, const char *name, int line) } - static zm_State* zm_getParent(zm_State *s) { return s->parent->stack[zm_deep(s) - 1]; } + static int zm_hasSameRoot(zm_State *s, zm_State *sub) { if (zm_isTask(s)) { @@ -1930,6 +1825,7 @@ static int zm_hasSameContext(zm_State *s1, zm_State *s2) return zm_hasSameRoot(s1, s2); } + static void zm_addWorker(zm_VM *vm, zm_Worker *w) { ZM_D("zm_addWorker [%zx] %s", w, w->machine->name); @@ -1974,8 +1870,6 @@ static void zm_unlinkWorker(zm_VM *vm, zm_Worker *w) } - - /* * can be used only in not empty ring */ @@ -2000,12 +1894,13 @@ static void zm_rewindWorkerStates(zm_VM *vm, zm_Worker* worker) if (worker->nstate == 0) return; + #ifdef ZM_CHECK_CONSISTENCY if (zm_hasntFlag(worker->states.current, ZM_STATE_RUN)) { zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_U1, "RWINDW.1", - "zm_rewindWorkerState: not found state " - "run flag"); + "worker contains task but isn't flagged as running"); } + #endif } @@ -2017,13 +1912,14 @@ static void zm_resumeState(zm_VM *vm, zm_State *s) /**** worker for a suspended state is temporary stored in s->next*/ zm_Worker* worker = (zm_Worker*)s->next; + #ifdef ZM_CHECK_CONSISTENCY /* this check is also done in RESBY.IL (should't fail)*/ if (s->flag & ZM_STATE_IMPLOSIONLOCK) { /* #UNBIND_IMLOCK */ if (s->on.resume != ZM_TERM) { zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_U1, "RESST.IL", - "in resume state: found locked " - "and implosion flag"); + "found lock and implode flag in not closed" + "task"); } } @@ -2031,15 +1927,16 @@ static void zm_resumeState(zm_VM *vm, zm_State *s) if (s->flag & ZM_STATE_RUN) { zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_U1, "RESST.R", - "in resume state: found run flag"); + "found run flag in suspended task"); } if (s->flag & ZM_STATE_EVENTLOCKED) { zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_U1, "RESST.EV", - "in resume state: found event-locked flag"); + "found event-locked flag in suspended task"); } + #endif s->flag |= ZM_STATE_RUN; @@ -2051,10 +1948,8 @@ static void zm_resumeState(zm_VM *vm, zm_State *s) if (!worker) { zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_U1, "RESST.NW", - "in resume state: " - "unable to resume state (null worker)\n" - " State is not yet associated to a worker\n" - " (possible cause: state as been free)"); + "task has a null worker (possible cause: " + "task as been free)"); } @@ -2086,11 +1981,12 @@ static void zm_resumeState(zm_VM *vm, zm_State *s) if (worker->states.current == NULL) { worker->states.current = f; zm_fatalInit(vm, NULL); - zm_fatalDo(ZM_FATAL_U1, "WSYLST.??", "TEST"); + zm_fatalDo(ZM_FATAL_U1, "WSYLST.??", + "current=null"); } else { zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_U1, "WSYLST.1", - "UNEXPECTED WSYNCLOST"); + "worker state list sync lost"); } } @@ -2114,20 +2010,20 @@ static void zm_resumeStateBy(zm_VM *vm, zm_State *s, void *argument, if (s->flag & ZM_STATE_RUN) { if (s == zm_getCurrentState(vm)) { zm_fatalInitAt(vm, ref, filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "RESBY.RRUN.S", - "try to self-resume"); + zm_fatalDo(ZM_FATAL_GCODE, "RESBY.RRUN.S", + "try to resume the current running task"); } zm_fatalInitAt(vm, ref, filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "RESBY.RRUN.J", - "try to active a just active state"); + zm_fatalDo(ZM_FATAL_GCODE, "RESBY.RRUN.J", + "try to resume a running task"); } if (s->flag & ZM_STATE_IMPLOSIONLOCK) { if (s->on.resume != ZM_TERM) { zm_fatalInitAt(vm, ref, filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "RESBY.IL", - "tring to resume a closing state"); + zm_fatalDo(ZM_FATAL_GCODE, "RESBY.IL", + "tring to resume a closed task"); } } @@ -2536,7 +2432,7 @@ static void zm_checkBusy(zm_VM *vm, zm_LockAndImplode* li, zm_State *s) zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_U1, "ILWCHK.UC", "continue exception head not found at the end " - "of waiting sub state chain"); + "of waiting subtaks chain"); } @@ -2564,8 +2460,7 @@ static void zm_checkContinue(zm_VM *vm, zm_LockAndImplode *li) if (broken) { zm_fatalInitByLI(vm, li); zm_fatalDo(ZM_FATAL_GCODE, "CONTBREAK", - "Close operation broke a continue-exception " - "suspended block"); + "close operation broke a continue-exception"); } @@ -2612,7 +2507,9 @@ static void zm_setImplodeLock(zm_VM *vm, zm_LockAndImplode* li, zm_State *state) size_t deep; if (state->flag & ZM_STATE_EVENTLOCKED) - zm_unbindEvent(vm, state, NULL, ZM_EVENT_UNBIND_ABORT); + zm_unbindEvent(vm, state, NULL, + ZM_EVENT_UNBIND_FORCE | + ZM_EVENT_UNBIND_ABORT); /** save current zmop in iter to be extract with zmGetCloseOp*/ state->on.iter = state->on.resume; @@ -2680,8 +2577,8 @@ static void zm_deepLockOverlap(zm_VM *vm, zm_LockAndImplode* li, zm_State *s) if (li->justlock.exception) { zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_U1, "DEEPOV.2E", - "deep lock found more than" - "one exception"); + "deep-lock found more than" + "one exceptions"); } li->justlock.exception = s->exception; @@ -2701,12 +2598,12 @@ static void zm_deepLockOverlap(zm_VM *vm, zm_LockAndImplode* li, zm_State *s) /* in SUB and CUR overlap should not be found */ zm_fatalInitByLI(vm, li); zm_fatalDo(ZM_FATAL_U1," DEEPOV.ILK", - "Unexpected lock and implode flag found " + "lock and implode flag found " "in sync deep lock"); default: zm_fatalInitByLI(vm, li); zm_fatalDo(ZM_FATAL_U1," DEEPOV.???", - "Unknow lock and implode flag"); + "unknow lock and implode flag"); } } @@ -2725,7 +2622,7 @@ static void zm_deepLock(zm_VM *vm, zm_State *state, zm_LockAndImplode *li) if ((vm->plock) && (state == zm_getCurrentState(vm))) { zm_fatalInitByLI(vm, li); zm_fatalDo(ZM_FATAL_U1, "DEEPLCK.SELF", - "unexpected self-close"); + "self-close"); } ZM_D("deepLock - lock %zx", state); @@ -2966,12 +2863,14 @@ static int zm_hasReset(zm_State *s) static void zm_lockByException(zm_VM *vm, zm_LockAndImplode *li, zm_State *s) { + #ifdef ZM_CHECK_CONSISTENCY if (zm_hasFlag(s, ZM_STATE_IMPLOSIONLOCK)) { zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_U1, "LCKBE.IL", - "unexpected lock and implode flag in exec-stack " - "(along exception trace)"); + "lock and implode flag in exec-stack " + "(along exception path)"); } + #endif if (zm_hasReset(s)) { /* zmRESET */ @@ -2981,13 +2880,14 @@ static void zm_lockByException(zm_VM *vm, zm_LockAndImplode *li, zm_State *s) s->on.resume = s->on.c4tch; s->on.iter = 0; + #ifdef ZM_CHECK_CONSISTENCY if (zm_isTask(s)) { zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_U1, "LCKBE.RS", - "unexpected exception-reset applied " - "to a ptask"); + "exception-reset applied to a ptask"); } + #endif /* a reset substate must be suspended: no waiting, no caller */ zm_disableFlag(s, ZM_STATE_WAITING); @@ -3216,10 +3116,10 @@ static void zm_abortTask(zm_VM *vm, zm_State *state, const char *refname) do { \ if (!zm_hasSameRoot(current, s)) { \ zm_fatalInitAt(vm, refname, filename, nline); \ - zm_fatalDo(ZM_FATAL_TCODE, ecode, nsamectx); \ + zm_fatalDo(ZM_FATAL_YCODE, ecode, nsamectx); \ } else { \ zm_fatalInitAt(vm, refname, filename, nline); \ - zm_fatalDo(ZM_FATAL_TCODE, ecode, wrongres); \ + zm_fatalDo(ZM_FATAL_YCODE, ecode, wrongres); \ } \ } while(0); @@ -3242,17 +3142,17 @@ static void zm_abortTask(zm_VM *vm, zm_State *state, const char *refname) * PTask * * yield down: - * @subsubsub: yield iterA [OK] - * @subsubsub: yield subsub3 [OK] - * @subsubsub: yield subiterA [WRONG] + * from subsubsub: yield iterA [OK] + * from subsubsub: yield subsub3 [OK] + * from subsubsub: yield subiterA [WRONG] * * yield up (child-yield): [OK] - * @sub1: yield subsub2 [OK] - * @sub1: yield subsubsub [WRONG] + * from sub1: yield subsub2 [OK] + * from sub1: yield subsubsub [WRONG] * * yield sibling: - * @subsub2: yield subsub3 [OK] - * @iterA: yield iterB [OK] + * from subsub2: yield subsub3 [OK] + * from iterA: yield iterB [OK] * */ @@ -3274,7 +3174,7 @@ static void zm_canBeContextStackPush(zm_VM *vm, zm_State *sub, if (!zm_hasSameRoot(current, sub)) { zm_fatalInitAt(vm, refname, filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "WRONGCTX.PT", nsamectx); + zm_fatalDo(ZM_FATAL_YCODE, "WRONGCTX.PT", nsamectx); } return; } @@ -3398,7 +3298,7 @@ void zm_uFree(zm_VM *vm, zm_Exception *e) default: zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_U1, "FREEX.EUN", - "exception->kind = (%s) %d", + "exception.kind = (%s) %d", zm_exceptionKind(e->kind), e->kind); } @@ -3432,10 +3332,9 @@ zm_Exception *izmCatch(zm_VM *vm, int ekindfilter, const char* refname, case ZM_EXCEPTION_CONTINUEHEAD: return NULL; default: - zm_fatalInit(vm, NULL); - zm_fatalDo(ZM_FATAL_U1, "XCATCH.UN", "%s: unexpected " - "exception kind = %d (%s)", refname, e->kind, - zm_exceptionKind(e->kind)); + zm_fatalInit(vm, refname); + zm_fatalDo(ZM_FATAL_U1, "XCATCH.UN", "exception.kind = %d (%s)", + e->kind, zm_exceptionKind(e->kind)); } if (ekindfilter) @@ -3458,7 +3357,7 @@ zm_yield_t izmDROP(zm_VM *vm, zm_Exception* e, const char *filename, int nline) if (e->kind != ZM_EXCEPTION_ABORT) { zm_fatalInitAt(vm, "zmDROP", filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "DROP.WK", + zm_fatalDo(ZM_FATAL_YCODE, "DROP.WK", "zmDROP need an abort-exception"); } @@ -3476,13 +3375,13 @@ zm_yield_t izmCLOSE(zm_VM *vm, zm_State *state, const char *filename, int nline) if (zm_isTask(state)) { zm_fatalInitAt(vm, "zmCLOSE", filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "ICLOSE.T", + zm_fatalDo(ZM_FATAL_YCODE, "ICLOSE.T", "expected a subtask but found a task"); } if (zm_getParent(state) != zm_getCurrentState(vm)) { zm_fatalInitAt(vm, "zmCLOSE", filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "ICLOSE.NC", + zm_fatalDo(ZM_FATAL_YCODE, "ICLOSE.NC", "zmCLOSE can close only its child"); } @@ -3525,7 +3424,7 @@ zm_yield_t izmEXCEPT(zm_VM *vm, int kind, int ecode, const char *msg, if (zm_getCurrentState(vm)->exception) { zm_fatalInitAt(vm, refname, filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "RAISENEW.JP", + zm_fatalDo(ZM_FATAL_YCODE, "RAISENEW.JP", "zmraise found a pending exception. A new exception " "can be raised only if the pending one as just been " "catched (use zmCatch)"); @@ -3546,7 +3445,7 @@ zm_yield_t izmUNRAISE(zm_VM *vm, zm_State* state, void *argument, /* #CONTINUE_EXCEPT*/ if (zm_isTask(state)) { zm_fatalInitAt(vm, "zmUNRAISE", fn, nl); - zm_fatalDo(ZM_FATAL_TCODE, "UNRAISE.S", + zm_fatalDo(ZM_FATAL_YCODE, "UNRAISE.S", "unraise can be applied only to subtask"); } @@ -3555,14 +3454,14 @@ zm_yield_t izmUNRAISE(zm_VM *vm, zm_State* state, void *argument, if (!state->exception) { zm_fatalInitAt(vm, "zmUNRAISE", fn, nl); - zm_fatalDo(ZM_FATAL_TCODE, "UNRAISE.NE", + zm_fatalDo(ZM_FATAL_YCODE, "UNRAISE.NE", "unraise can be applied only to subtask with " "continue-exception (no exception found)"); } if (state->exception->kind != ZM_EXCEPTION_CONTINUEHEAD) { zm_fatalInitAt(vm, "zmUNRAISE", fn, nl); - zm_fatalDo(ZM_FATAL_TCODE, "UNRAISE.WK", + zm_fatalDo(ZM_FATAL_YCODE, "UNRAISE.WK", "unraise can be applied only to subtask with " "continue-exception (exception: %s)", zm_exceptionKind(state->exception->kind)); @@ -3577,6 +3476,8 @@ zm_yield_t izmUNRAISE(zm_VM *vm, zm_State* state, void *argument, zm_State *izmContinueHead(zm_VM* vm, zm_Exception *e, const char *fn, int nl) { + ZM_ASSERT_VMLOCK("CONTHEAD.VLCK", "zmContinueHead", fn, nl); + if (e->kind != ZM_EXCEPTION_CONTINUE) { zm_fatalInitAt(vm, "zmContinueHead", fn, nl); zm_fatalDo(ZM_FATAL_TCODE, "CONTH.NC", @@ -3591,6 +3492,8 @@ zm_State *izmContinueHead(zm_VM* vm, zm_Exception *e, const char *fn, int nl) zm_State *izmContinueTail(zm_VM* vm, zm_Exception *e, const char *fn, int nl) { + ZM_ASSERT_VMLOCK("CONTTAIL.VLCK", "zmContinueTail", fn, nl); + if (e->kind != ZM_EXCEPTION_CONTINUE) { zm_fatalInitAt(vm, "zmContinueTail", fn, nl); zm_fatalDo(ZM_FATAL_TCODE, "CONTT.NC", @@ -3615,7 +3518,7 @@ zm_yield_t izmRESET(zm_VM* vm, int n, const char* filename, int nline) { if (zm_isTask(zm_getCurrentState(vm))) { zm_fatalInitAt(vm, "zmRESET", filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "RST.PT", + zm_fatalDo(ZM_FATAL_YCODE, "RST.PT", "zmRESET can be used " "only in subtask"); } @@ -3701,46 +3604,32 @@ static void zm_bindEvent(zm_Event *event, zm_State *s) } -static const char* zm_getUnbindEventScope(int flag) -{ - if (flag & ZM_EVENT_UNBIND_REQUEST) - return "ZM_UNBIND_REQUEST"; - if (flag & ZM_EVENT_UNBIND_ABORT) - return "ZM_UNBIND_ABORT"; - - /* this is impossible because unbindEvent is call only in lock and - implode and in unbind request with defined (const) scope value */ - return "[internal error]"; -} - -/* note: event binder free evb reference*/ +/* note: this method free evb reference */ static void zm_unbindEvent(zm_VM* vm, zm_State *s, void* argument, int scope) { zm_EventBinder *evb = ((zm_EventBinder*)s->next); - int unbindscope = (scope & ZM_EVENT_UNBIND); + int forced = (scope & ZM_EVENT_UNBIND_FORCE); - ZM_D("zm_unbindEvent: check flag"); + ZM_D("unbindEvent: check flag"); if (s->flag & ZM_STATE_EVENTLOCKED) { zm_disableFlag(s, ZM_STATE_EVENTLOCKED); } else { zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_U1, "UNBNDEV", - "event unbind (scope = %s): state doesn't " - " have a binded event", - zm_getUnbindEventScope(unbindscope)); + "zm_State doesn't have a binded event"); } - if ((unbindscope) && (evb->event->evcb)) - evb->event->evcb(vm, unbindscope, evb->event, s, argument); + if ((forced) && (evb->event->evcb)) + evb->event->evcb(scope, evb->event, s, argument); - /* check if evb is the first element of the bindlist*/ + /* check if evb is the first element of the bindlist */ if (evb->event->bindlist == evb) { if (evb->event->bindlist->next == evb) { - /* only one element*/ + /* only one element */ evb->event->bindlist = NULL; } else { /* set header pointer of the list to second element */ @@ -3758,18 +3647,19 @@ static void zm_unbindEvent(zm_VM* vm, zm_State *s, void* argument, int scope) evb->event->count--; s->next = (zm_State*)evb->statenext; - if ((unbindscope) && (s->on.iter)) + /* zmUNBIND */ + if ((forced) && (s->on.iter)) s->on.resume = s->on.iter; - ZM_D("zm_unbindEvent: resume"); + ZM_D("unbindEvent: resume"); /* #UNBIND_IMLOCK*/ zm_resumeState(vm, s); zm_setArgument(s, argument); - ZM_D("zm_unbindEvent: free event binder"); + ZM_D("unbindEvent: free event binder"); zm_free(zm_EventBinder, evb); - ZM_D("zm_unbindEvent: end"); + ZM_D("unbindEvent: end"); } @@ -3783,7 +3673,7 @@ static void zm_triggerWrongReturn(zm_VM *vm, int r) "pre-fetch"); else zm_fatalDo(ZM_FATAL_GCODE, "TRIGWRFL.UF", - "invalid return in trigger callback use: " + "invalid return in trigger callback use " "ZM_EVENT_ACCEPTED or ZM_EVENT_REFUSED"); } } @@ -3795,10 +3685,10 @@ static int zm_triggerEVB(zm_VM *vm, zm_EventBinder *evb, void *arg) zm_State *s = evb->owner; int r = ZM_EVENT_ACCEPTED; - if (zm_hasFlag(event, ZM_EVENT_TRIGGER) && (event->evcb)) { + if (event->evcb) { ZM_D("zm_trigger: cb(state = [ref %zx])", s); - r = event->evcb(vm, ZM_EVENT_TRIGGER, event, s, arg); + r = event->evcb(ZM_EVENT_TRIGGER, event, s, arg); /* event trigger can return ZM_EVENT_ACCEPT or ZM_EVENT_REFUSE: if the event is accepted the relative task will be resumed @@ -3810,7 +3700,6 @@ static int zm_triggerEVB(zm_VM *vm, zm_EventBinder *evb, void *arg) return r; } - /* no trigger callback: resume state */ zm_unbindEvent(vm, s, arg, ZM_EVENT_TRIGGER | ZM_EVENT_ACCEPTED); return r; @@ -3819,14 +3708,12 @@ static int zm_triggerEVB(zm_VM *vm, zm_EventBinder *evb, void *arg) static int zm_trigger0(zm_VM *vm, zm_Event *event, void *arg) { - ZM_D("zm_trigger0:"); - - if (zm_hasFlag(event, ZM_EVENT_TRIGGER) && (event->evcb)) - return event->evcb(vm, ZM_EVENT_TRIGGER, event, NULL, arg); - - ZM_D("zm_trigger0: no callback event->flag = %d cb = %zx", event->flag, - event->evcb); + if (event->evcb) { + ZM_D("zm_trigger0: call event-callback"); + return event->evcb(ZM_EVENT_TRIGGER, event, NULL, arg); + } + ZM_D("zm_trigger0: no event-callback"); return ZM_EVENT_ACCEPTED; } @@ -3895,57 +3782,57 @@ size_t zm_trigger(zm_VM *vm, zm_Event *event, void *argument) } -zm_Event* zm_newEvent(void *data) +zm_Event* zm_newEvent(zm_event_cb callback, void *data) { zm_Event *event = zm_alloc(zm_Event); event->bindlist = NULL; event->count = 0; - event->flag = 0; - event->evcb = NULL; + event->evcb = callback; event->data = data; return event; } -void zm_setEventCB(zm_VM *vm, zm_Event* event, zm_event_cb cb, int scope) -{ - /* TODO check consitency between cb and scope argument */ - event->flag = scope; - event->evcb = cb; -} -size_t zm_unbindAll(zm_VM *vm, zm_Event *event, void *argument) +/* + * Force unbind of one task from an event. If the event have TODO + TODO TODO TODO + with event-callback scope flag ZM_EVENT_UNBIND_FORCE + * If task pointer `s` is NULL unbind all tasks and return the number of + * unbinded task (equals to event->count). + */ +size_t zm_unbind(zm_VM *vm, zm_Event *event, zm_State* s, void *arg) { - size_t n = event->count; - - while(event->bindlist) { - zm_State *s = event->bindlist->owner; - zm_unbindEvent(vm, s, argument, ZM_EVENT_UNBIND_REQUEST); - } - - #ifdef ZM_CHECK_CONSISTENCY - if (event->count != 0) { - zm_fatalInit(vm, NULL); - zm_fatalDo(ZM_FATAL_U1, "UNBIND.STL", - "event counter bind list check fail"); - } - #endif - - return n; -} + if (s) { + /* unbind task `s` */ + if (zm_hasntFlag(s, ZM_STATE_EVENTLOCKED)) + return 0; + zm_unbindEvent(vm, s, arg, ZM_EVENT_UNBIND_FORCE); + return 1; + } else { + /* unbind all tasks */ + size_t n = event->count; -size_t zm_unbind(zm_VM *vm, zm_Event *event, zm_State* s, void *argument) -{ + while(event->bindlist) { + s = event->bindlist->owner; + zm_unbindEvent(vm, s, arg, ZM_EVENT_UNBIND_FORCE); + } - if (zm_hasntFlag(s, ZM_STATE_EVENTLOCKED)) - return 0; + #ifdef ZM_CHECK_CONSISTENCY + if (event->count) { + zm_fatalInit(vm, NULL); + zm_fatalDo(ZM_FATAL_U1, "UNBIND.STL", + "event counter is not 0 " + "after unbind all"); + } + #endif - zm_unbindEvent(vm, s, argument, ZM_EVENT_UNBIND_REQUEST); - return 1; + return n; + } } @@ -3954,12 +3841,12 @@ void zm_freeEvent(zm_VM *vm, zm_Event *event) if (event->count) { zm_fatalInit(vm, "zm_freeEvent"); zm_fatalDo(ZM_FATAL_GCODE, "FREEEV.NE", - "Try to free an event with some binded task"); + "try to free an event with some binded task"); } - if (zm_hasFlag(event, ZM_EVENT_UNBIND) && (event->evcb)) - event->evcb(vm, ZM_EVENT_UNBIND_REQUEST, event, NULL, NULL); + if (event->evcb) + event->evcb(ZM_EVENT_UNBIND_FORCE, event, NULL, NULL); zm_free(zm_Event, event); @@ -3977,8 +3864,9 @@ zm_yield_t izmEVENT(zm_VM* vm, zm_Event *e, const char *filename, int nline) ZM_D("zm_listenEvent - event bind for state: [ref %zx]", s); if (s->flag & ZM_STATE_EVENTLOCKED) { + /* TODO this is not an unexpected behaviour ?? */ zm_fatalInitAt(vm, "zmEVENT", filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "LISTEV.1", + zm_fatalDo(ZM_FATAL_YCODE, "LISTEV.1", "this state is just associated to an event"); } @@ -4190,6 +4078,7 @@ static void zm_addStateToSiblingsRing(zm_State **first, zm_State *state) } + static void zm_addParent(zm_VM *vm, zm_State* s, const char *ref, const char *filename, int nline) { @@ -4200,7 +4089,7 @@ static void zm_addParent(zm_VM *vm, zm_State* s, const char *ref, if (zm_hasFlag(current, ZM_STATE_IMPLOSIONLOCK)) { zm_fatalInitAt(vm, ref, filename, nline); zm_fatalDo(ZM_FATAL_TCODE, "ADDTASK.P", - "cannot create task in a close zmstate"); + "cannot create task in ZM_TERM"); } parent->stacksize = deep; @@ -4226,7 +4115,7 @@ static void zm_runInit(zm_VM *vm, zm_Worker *worker, zm_State *s, int sub) if (ZM_B4(y.cmd) != ZM_TASK_INIT) { zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_YCODE, "YDONE.WY", - "A task in constructor mode (ZM_INIT) can yield " + "task in constructor mode (ZM_INIT) can yield " "only to zmDONE"); } } @@ -4298,12 +4187,12 @@ static int zm_requestFreeState(zm_VM *vm, zm_State *state, const char* refname) if (zm_hasFlag(state, ZM_STATE_AUTOFREE)) { zm_fatalInit(vm, refname); zm_fatalDo(ZM_FATAL_GCODE, "RFREEST.AF", - "Cannot request to free a state " + "cannot request to free a state " "that is just marked to be free"); } if (state->pmode == ZM_PMODE_OFF) { - /*** this pmode is set by ZM_PMODE_END*/ + /*** this pmode is set by ZM_PMODE_END */ /*** then is possible to free state in a sync way*/ zm_free(zm_State, state); return true; @@ -4371,7 +4260,7 @@ zm_yield_t izmSUB(zm_VM* vm, zm_State *s, void* argument, int allowunraise, if (zm_isTask(s)) { zm_fatalInitAt(vm, rn, filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "ACTSUB.NS", + zm_fatalDo(ZM_FATAL_YCODE, "ACTSUB.NS", "expected a subtask but found a task " "(use instead: zm_resume)"); @@ -4379,7 +4268,7 @@ zm_yield_t izmSUB(zm_VM* vm, zm_State *s, void* argument, int allowunraise, if (zm_hasFlag(s, ZM_STATE_IMPLOSIONLOCK)) { zm_fatalInitAt(vm, rn, filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "ACTSUB.LI", + zm_fatalDo(ZM_FATAL_YCODE, "ACTSUB.LI", "try to resume a closed subtask"); } @@ -4389,7 +4278,7 @@ zm_yield_t izmSUB(zm_VM* vm, zm_State *s, void* argument, int allowunraise, if (zm_hasException(s, ZM_EXCEPTION_CONTINUEHEAD)) { if (!allowunraise) { zm_fatalInitAt(vm, rn, filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "ACTSUB.C", + zm_fatalDo(ZM_FATAL_YCODE, "ACTSUB.C", "try to resume a subtask " "with a continue-exception " "(use instead zmUNRAISE or " @@ -4403,27 +4292,27 @@ zm_yield_t izmSUB(zm_VM* vm, zm_State *s, void* argument, int allowunraise, if (zm_getParent(zm_getCurrentState(vm)) == s) { zm_fatalInitAt(vm, rn, filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "ACTSUB.WP", + zm_fatalDo(ZM_FATAL_YCODE, "ACTSUB.WP", "try to resume a subtask that is the " "previous element in execution-stack; " "use instead zmyield zmCALLER"); } else if (allowunraise) { if (zm_hasException(s, ZM_EXCEPTION_CONTINUE)) { zm_fatalInitAt(vm, rn, filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "ACTSUB.WT", + zm_fatalDo(ZM_FATAL_YCODE, "ACTSUB.WT", "try to resume a waiting subtask or " "unraise the continue-exception " "tail"); } else { zm_fatalInitAt(vm, rn, filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "ACTSUB.WR", + zm_fatalDo(ZM_FATAL_YCODE, "ACTSUB.WR", "try to resume a waiting subtask " "or unraise a subtask without " "continue-exception"); } } else { zm_fatalInitAt(vm, rn, filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "ACTSUB.WS", + zm_fatalDo(ZM_FATAL_YCODE, "ACTSUB.WS", "try to resume a waiting subtask"); } } @@ -4445,18 +4334,18 @@ zm_yield_t izm_resume(const char *fname, zm_VM* vm, zm_State *s, void *argument, if (zm_hasFlag(s, ZM_STATE_RUN | ZM_STATE_WAITING)) { if (zm_hasFlag(s, ZM_STATE_RUN)) { zm_fatalInitAt(vm, fname, filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "ACTTASK.R", + zm_fatalDo(ZM_FATAL_GCODE, "ACTTASK.R", "try to active a just active task"); } else { zm_fatalInitAt(vm, fname, filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "ACTTASK.WS", + zm_fatalDo(ZM_FATAL_GCODE, "ACTTASK.WS", "try to resume a busy-waiting task"); } } if (zm_isSubTask(s)) { zm_fatalInitAt(vm, fname, filename, nline); - zm_fatalDo(ZM_FATAL_TCODE, "ACTTASK.NP", + zm_fatalDo(ZM_FATAL_GCODE, "ACTTASK.NP", "expected a task but found a subtask " "(use instead: zmSUB)"); } @@ -4539,9 +4428,7 @@ int zm_closeVM(zm_VM* vm) /* can be replaced with ZM_ASSERT_VMUNLOCK TODO */ zm_fatalInit(vm, "zm_closeVM"); zm_fatalDo(ZM_FATAL_TCODE, "CLSVM.LCK", - "cannot invoke a vm close during task " - "execution (operation permitted only " - "outside task definition)"); + "cannot invoke a closeVM during task execution"); } do { @@ -4648,7 +4535,7 @@ static void zm_checkInnerYield(zm_VM *vm, zm_State *state, zm_Yield result) if (result.resume == ZM_TERM) { zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_YCODE, "YINN.TRM", - "a task cannot yield directly to ZM_TERM " + "task cannot yield directly to ZM_TERM " "use instead: zmTERM"); } } @@ -4704,7 +4591,7 @@ static void zm_freeUnlockedException(zm_VM *vm, zm_Exception *e) if (e->elock == ZM_ELOCK_ON) { zm_fatalInit(vm, NULL); - zm_fatalDo(ZM_FATAL_YCODE, "YNOCATHC.1", + zm_fatalDo(ZM_FATAL_TCODE, "YNOCATHC.1", "exception not catched in the " "catch state (use zmCatch)"); } @@ -4744,7 +4631,7 @@ static zm_Yield zm_runTask(zm_VM *vm, zm_Worker *worker, zm_State *state) if (state->on.resume == 0) { zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_YCODE, "YRES.0", - "resume zmstate is set 0 (possible cause: " + "resume zmstate is set to 0 (possible cause: " "last zmyield hasn't define the " "proper resume point)"); } @@ -4944,10 +4831,8 @@ static int zm_normalYield(zm_VM *vm, zm_Worker *worker, zm_State *state, default: zm_fatalInit(vm, NULL); - zm_fatalDo(ZM_FATAL_UP, "WCMOP.U", - "Unexpected zmyield %s (normal mode)", - zm_yieldCommandName(result.cmd) - ); + zm_fatalDo(ZM_FATAL_UP, "WCMOP.U", "unknow yield directive %d", + result.cmd); return 0; } } @@ -4970,9 +4855,7 @@ static int zm_closeYield(zm_VM *vm, zm_Worker *worker, zm_State *state, if (zm_hasntFlag(state, ZM_STATE_IMPLOSIONLOCK)) { zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_UP, "YEND.NLI", - "task not in close mode with pmode=" - "ZM_PMODE_CLOSE" - ); + "task not implode-locked in close mode"); } state->pmode = ZM_PMODE_END; @@ -5054,8 +4937,7 @@ static int zm_processTask(zm_VM *vm, zm_Worker *worker, zm_State *state) * kind != continueref ... something has going wrong */ zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_UP, "PPS.EEN", - "exception still present in " - "ZM_PMODE_END"); + "exception still present in ZM_PMODE_END"); } if (zm_hasFlag(state, ZM_STATE_AUTOFREE)) { @@ -5092,14 +4974,13 @@ static int zm_processTask(zm_VM *vm, zm_Worker *worker, zm_State *state) case ZM_PMODE_OFF: zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_UP, "PPS.NMTD", - "unexpected pmode in processState" - "(pmode = ZM_PMODE_OFF)"); + "pmode = ZM_PMODE_OFF in processState"); return 0; default: zm_fatalInit(vm, NULL); zm_fatalDo(ZM_FATAL_UP, "PPS.UVMOP", - "unexpected pmode in processState (pmode = %d)", + "unknow pmode = %d in processState", state->pmode); return 0; } @@ -5163,9 +5044,8 @@ static zm_Worker* zm_goGetWorker(zm_VM* vm) #ifdef ZM_CHECK_CONSISTENCY if (worker->nstate < 0) { zm_fatalInit(vm, NULL); - zm_fatalDo(ZM_FATAL_U1, "WGO.WNS", - "zm_go: inconsistency error: " - "worker->nstate = %d", worker->nstate); + zm_fatalDo(ZM_FATAL_U1, "WGO.WNS", "worker->nstate = %d", + worker->nstate); } #endif diff --git a/zm.h b/zm.h index d42bc20..978bda6 100644 --- a/zm.h +++ b/zm.h @@ -33,7 +33,7 @@ #define __ZM_VM_H__ -#define ZM_VERSION "0.1.5" +#define ZM_VERSION "0.1.7" #include #include @@ -145,7 +145,6 @@ enum { - /* * Special zmstate * */ #define ZM_FIRST 1 #define ZM_INIT 254 @@ -188,14 +187,12 @@ enum { #define ZM_EVENT_STOP 32 /* stop eval other binded task */ #define ZM_EVENT_TRIGGER 256 -#define ZM_EVENT_UNBIND_REQUEST 512 +#define ZM_EVENT_UNBIND_FORCE 512 #define ZM_EVENT_UNBIND_ABORT 1024 -#define ZM_EVENT_UNBIND (ZM_EVENT_UNBIND_REQUEST | ZM_EVENT_UNBIND_ABORT) #define ZM_TRIGGER ZM_EVENT_TRIGGER -#define ZM_UNBIND_REQUEST ZM_EVENT_UNBIND_REQUEST +#define ZM_UNBIND ZM_EVENT_UNBIND_FORCE #define ZM_UNBIND_ABORT ZM_EVENT_UNBIND_ABORT -#define ZM_UNBIND ZM_EVENT_UNBIND /* **** RUN RETURN FLAG *** */ #define ZM_RUN_IDLE 0 @@ -321,15 +318,14 @@ typedef struct zm_Event_ zm_Event; typedef struct zm_EventBinder_ zm_EventBinder; /* event callback (trigger and unbind) */ -typedef int (*zm_event_cb)(zm_VM *vm, - int scope, +typedef int (*zm_event_cb)(int scope, zm_Event *event, zm_State *state, void *argument); struct zm_Event_ { - int flag; + int unused_flag; int count; zm_EventBinder *bindlist; @@ -396,23 +392,22 @@ struct zm_Exception_ { /* * A machine is like a symbol in global scope that rappresent a task class. - * As a class, a machine allow to instance many task. process is done + * As a class, a machine allow to instance many task, this is done * in 3 step: * - * class definition: ZMTASKDEF(X) define a zm_Machine and a pointer X to it - * to be used as class definition symbol. - * task instance: zm_newTask(vm, X, ...) create, only at the first - * invocation with the class X, a zm_Worker associated to X. - * This is the reference of X inside a vm (zm_VM) and will - * be used in successive task instance procedure. - * zm_newTask return an instance task (zm_State) associated - * to the worker X and to vm. + * class definition: ZMTASKDEF(X) define a zm_Machine and a pointer X + * to this struct to be used as class definition symbol. + * + * worker instance: During the first X-task instance, zm_newTask create + * a zm_Worker that is a rappresentation of class X inside + * a zm_VM. * - * In a vm there is only one worker for each machine. An associative array - * (mwh) inside vm allow to match a machine with relative zm_Worker. + * task instance: zm_newTask(vm, X, ...) return an instance task (zm_State) + * relative to vm and machine X. + * + * In any vm there is only one worker for each machine (these associations + * are store in the vm associative array mwh). * - * In this way user can use global machine symbol as the reference to - * the relative zm_Worker instance (for example to instance new task). */ typedef struct { int id; @@ -678,25 +673,23 @@ typedef void (*zm_tlock_cb)(FILE *f, void *data, int lock); /* memory utilty */ -#define zm_alloc(s) ((s*)zm_malloc(sizeof(s), true)) +#define zm_alloc(s) ((s*)zm_malloc(sizeof(s))) #define zm_free(s, ptr) zm_mfree(sizeof(s), ptr) -#define zm_nalloc(s, n) ((s*)zm_malloc(sizeof(s) * (n), true)) -#define zm_nrealloc(ptr, s, n) ((s*)zm_mrealloc((ptr), sizeof(s) * (n), true)) +#define zm_nalloc(s, n) ((s*)zm_malloc(sizeof(s) * (n))) +#define zm_nrealloc(ptr, s, n) ((s*)zm_mrealloc((ptr), sizeof(s) * (n))) #define zm_nfree(s, n, ptr) zm_mfree(sizeof(s) * (n), ptr) -void *zm_malloc(size_t size, int memfatal); -void *zm_mrealloc(void *ptr, size_t size, int memfatal); +void *zm_malloc(size_t size); +void *zm_mrealloc(void *ptr, size_t size); void zm_mfree(size_t size, void *ptr); /* indent and buffer print utilty */ -void zm_initPrint(zm_Print *p, FILE *stream, int indent, int b); +void zm_initPrint(zm_Print *p, FILE *stream, int indent); void zm_setIndent(zm_Print *out, int indent); void zm_addIndent(zm_Print *out, int indent); -void zm_iprint(zm_Print *out, const char *fmt, ...); void zm_print(zm_Print *out, const char *fmt, ...); -char* zm_popPrintBuffer(zm_Print *out, size_t *size); -void zm_removePrintBuffer(zm_Print *out); +void zm_vprint(zm_Print *out, const char *fmt, va_list args); /* report fatal utility */ typedef void (*zm_fatal_cb)(const char *zname, void *zdata, void *data); @@ -772,9 +765,7 @@ zm_State *izmContinueTail(zm_VM* vm, zm_Exception *e, const char *fn, int nl); /* event */ -zm_Event* zm_newEvent(void *data); - -void zm_setEventCB(zm_VM *vm, zm_Event* event, zm_event_cb cb, int scope); +zm_Event* zm_newEvent(zm_event_cb callback, void *data); void zm_freeEvent(zm_VM *vm, zm_Event *event);