/* * mysql.sched * * A MySQL scheduler that gives priority to 'New Order' transactions. */ scheduler pth { thread { int state; int is_neworder; } data { threadref current; /* current thread */ threadref next; /* next thread (named yield) */ queue reg_ready; /* regular ready threads */ queue new_order_ready; /* new order ready threads */ queue WQ; /* waiting for event */ queue SQ; /* suspended */ int table_list_internal = 0; int field_list_internal = 0; const int READY = 1; const int WAITING = 2; const int DEAD = 3; const int SUSPENDED = 4; } imports { int table_list default 0; int field_list default 0; } event init { /* no-op */ } event newthread(t) { t.state = READY; t.is_neworder = 0; t => reg_ready; } event schedule { /* Find next thread to run */ if (|next| == 1) next => current; else if (|new_order_ready| > 0) new_order_ready => current; else reg_ready => current; dispatch current; } event switch_out { /* Copy imported variable for easier use in verbatim statements */ table_list_internal = table_list; field_list_internal = field_list; /* Transaction start trigger? */ if ((* field_list_internal && 0 == strncmp((char* )field_list_internal, "w_tax", 5) *)) current.is_neworder = 1; /* TODO: Find finish trigger */ if ((current.is_neworder == 1) && (* field_list_internal && 0 == strncmp((char* )field_list_internal, "1", 1) *) != 0) current.is_neworder = 0; /* Cleanup */ {* *((char*)field_list_internal) = *((char*)table_list_internal) = '\0'; *} field_list = field_list_internal; table_list = table_list_internal; /* Did the last thread end? */ if (current.state == DEAD) { destroy current; } else if (current.state == WAITING) { current => WQ; } else if (current.is_neworder == 1) { current => new_order_ready; } else { current => reg_ready; } } event event_raised(t) { t.state = READY; if (t.is_neworder == 1) t => new_order_ready; else t => reg_ready; } event set_next_thread(t) { t => next; } query threads_new { return 0; } query threads_ready { return |new_order_ready| + |reg_ready|; } query threads_waiting { return |WQ|; } query threads_suspended { return |SQ|; } query threads_total { return |new_order_ready| + |reg_ready| + |WQ| + |SQ| + 1; } event set_waiting(fixed tid) { tid.state = WAITING; } event set_dead(fixed tid) { tid.state = DEAD; } query is_new(tid) { return false; } query is_ready(tid) { return tid.state == READY; } query is_waiting(tid) { return tid.state == WAITING; } query first_waiting { return *WQ; } query can_switch_to(tid) { return (tid.state == READY); } event suspend_thread(tid) { tid.state = SUSPENDED; tid => SQ; } event resume_thread(tid) { tid.state = READY; if (tid.is_neworder == 1) tid => new_order_ready; else tid => reg_ready; } } // vim: filetype=c