/* context.c */ #include #include #include #if 0 /* Here's the beginnings of a simple evaluation engine. I may complete it, so * that I can see how get/setcontext() can be used in Tcl. */ typedef enum variable_type { VT_INTEGER, VT_BOOLEAN } variable_type_t; typedef struct variable { char* name; variable_type_t type; union { struct integer { int val; }; struct boolean { int val; }; } data; } variable_t; typedef enum operation { OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_MOD, OP_NEG, OP_EQ , OP_NE , OP_GT , OP_GE , OP_LT , OP_LE , OP_AND, OP_IOR, OP_XOR, OP_NOT, OP_IF , OP_SET } operation_t; typedef enum node_type { NT_OPERATION, NT_INTEGER , NT_BOOLEAN , NT_VARIABLE } node_type_t; struct node; typedef struct node node_t; struct node { node_type_t type; union { struct operation { operation_t op; node_t* args[3]; }; struct integer { int val; }; struct boolean { int val; }; struct variable { variable_t* var; }; } data; } typedef struct thread { variable_t* variables; int variables_num, variables_cap; node_t* tree; } thread_t; #endif static int sem; static ucontext_t bravo_uc; static ucontext_t delta_uc; static ucontext_t main_uc ; static void alpha (void); static void bravo (void); static void charlie(void); static void delta (void); static void alpha(void) { printf("alpha : entering\n"); bravo(); printf("alpha : returning\n"); } static void bravo(void) { static int count = 0; printf("bravo : entering\n"); if (getcontext(&bravo_uc) != 0) { perror("getcontext"); exit(EXIT_FAILURE); } if (sem) { printf("bravo : resuming\n"); } ++count; printf("bravo : count = %d\n", count); if (sem) { sem = 0; printf("bravo : leaving\n"); setcontext(&main_uc); } printf("bravo : returning\n"); } static void charlie(void) { printf("charlie: entering\n"); delta(); printf("charlie: returning\n"); } static void delta(void) { static int count = 0; printf("delta : entering\n"); if (getcontext(&delta_uc) != 0) { perror("getcontext"); exit(EXIT_FAILURE); } if (sem) { printf("delta : resuming\n"); } ++count; printf("delta : count = %d\n", count); if (sem) { sem = 0; printf("delta : leaving\n"); setcontext(&main_uc); } printf("delta : returning\n"); } int main(void) { printf("main : entering\n"); alpha (); charlie(); printf("main : beginning loop\n"); while (1) { printf("main : b)ravo; d)elta; q)uit --> "); fflush(stdout); again: switch (getchar()) { case 'b': sem = 1; getcontext(&main_uc); if (sem) { setcontext(&bravo_uc); } else { printf("main : resuming\n"); } break; case 'd': sem = 1; getcontext(&main_uc); if (sem) { setcontext(&delta_uc); } else { printf("main : resuming\n"); } break; case 'q': printf("main : terminating\n"); exit(EXIT_SUCCESS); break; default: goto again; } } } /* vim: set ts=4 sts=4 sw=4 tw=80 et: */