/** idle function */ int idle_func(gpointer idle_data) { LOOP_STR* ps = (LOOP_STR*)idle_data; char* pmsg = NULL; pmsg = g_strdup_printf("ENTERED D=%s", ps->name); twmsg(__func__, pmsg); g_free(pmsg); twmsg(__func__, "EXITING"); /* return T and it will be called ALL THE TIME return(TRUE); */ return(FALSE); // one-time call.... }
/** loop thread */ void* loop_thread(void* pv) { LOOP_STR* ps = NULL; if (pv == NULL) { twmsg(__func__, "ERROR pv=NULL"); } else { ps = (LOOP_STR*)pv; twmsg(__func__, "STARTING"); /* run the main loop for this thread */ g_main_loop_run(ps->main_loop); } twmsg(__func__, "EXITING"); g_thread_exit(NULL); return(NULL); }
/** timeout callback, see doc on g_timeout_add() * -- called until this returns FALSE when it will be removed */ gboolean tmo_callback(gpointer data) { //printf("%s\n", (char*)data); twmsg(__func__, (char*)data); /* send msg to loop 1 and 2 * - ideally check to see who caused the tmo */ MsgSend(&loop_1, "TMO1"); MsgSend(&loop_2, "TMO2"); return TRUE; }
/** send msg to a queue */ gboolean MsgSend(LOOP_STR* ps, char* msg) { gboolean res = FALSE; if (ps == NULL) { twmsg(__func__, "ERROR pv=NULL"); } else { /* create new copy of msg and send, then wakeup context */ char* msg_data = g_strdup(msg); g_async_queue_push(ps->Q, msg_data); g_main_context_wakeup(ps->main_context); res = TRUE; } return(res); }
/* time_window - * Realize the time window algorithm, only the steps in time window is valid. * There should be four continuous steps at begin. * */ static void time_window(char n) { twmsg(("\033[1;36m[twin] %s: ", (n==0) ? "x" : (n==1) ? "y" : "z")); twmsg(("(rule=%0d, interval=%03d) - ", rule, interval)); switch (rule) { case 2: // if it is the first step, add TempStep directly twmsg(("start")); TempSteps++; InvalidSteps = 0; interval = 0; rule = 1; break; case 1: if ((interval >= __ACC_TWIN_MIN) && (interval <= __ACC_TWIN_MAX)) { // if still not find the rule twmsg(("min < t < max")); TempSteps++; // make TempSteps add one if (TempSteps >= REGULATION) { // if TempSteps reach the regulation number twmsg((", TempSteps >= %0d", REGULATION)); STEPS = STEPS + TempSteps; // Update STEPS // STEPS = STEPS + 1; // Update STEPS TempSteps = 0; rule = 0; // Have found the rule } } else if (interval < __ACC_TWIN_MIN) { // if have not found the rule, the process looking for rule before is invalid, then search the rule again twmsg(("t < min")); TempSteps = 1; } else if (interval > __ACC_TWIN_MAX) { // if the interval more than upper threshold, the steps is interrupted, then searh the rule again twmsg(("t > max")); TempSteps = 1; } InvalidSteps = 0; interval = 0; break; case 0: if ((interval >= __ACC_TWIN_MIN) && (interval <= __ACC_TWIN_MAX)) { // if have found the rule, update STEPS directly twmsg(("min < t < max")); STEPS++; TempSteps = 0; InvalidSteps = 0; } else if (interval < __ACC_TWIN_MIN) { // if have found the rule twmsg(("t < min")); InvalidSteps++; // make InvalidSteps add one if (InvalidSteps >= INVALID) { // if InvalidSteps reach the INVALID number, search the rule again twmsg((", InvalidSteps >= %0d", INVALID)); TempSteps = 1; InvalidSteps = 0; rule = 1; } } else if (interval > __ACC_TWIN_MAX) { // if the interval more than upper threshold, the steps is interrupted, then searh the rule again twmsg(("t > max")); TempSteps = 1; InvalidSteps = 0; rule = 1; } interval = 0; break; } // if (rule == 2) { // // if it is the first step, add TempStep directly // twmsg(("(start)")); // TempSteps++; // interval = 0; // InvalidSteps = 0; // rule = 1; // // } else { // // if it is not the first step, process as below // if ((interval >= __ACC_TWIN_MIN) && (interval <= __ACC_TWIN_MAX)) { // // if the step interval in the time window // twmsg(("(min <= interval <= max)")); // InvalidSteps = 0; // if (rule == 1) { // // if still not find the rule // twmsg(("A")); // TempSteps++; // make TempSteps add one // if (TempSteps >= REGULATION) { // // if TempSteps reach the regulation number // STEPS = STEPS + TempSteps; // Update STEPS //// STEPS = STEPS + 1; // Update STEPS // TempSteps = 0; // rule = 0; // Have found the rule // } // interval = 0; // // } else if (rule == 0) { // // if have found the rule, Update STEPS directly // twmsg(("B")); // STEPS++; // TempSteps = 0; // interval = 0; // } // // } else if (interval < __ACC_TWIN_MIN) { // // if time interval less than the time window under threshold // twmsg(("interval < min")); // if (rule == 0) { // twmsg(("C")); // // if have found the rule // if (InvalidSteps < 255) { // InvalidSteps++; // make InvalidSteps add one // } // // if (InvalidSteps >= INVALID) { // // if InvalidSteps reach the INVALID number, search the rule again // twmsg(("E")); // TempSteps = 1; // interval = 0; // InvalidSteps = 0; // rule = 1; // // } else { // // otherwise, just discard this step // twmsg(("F")); // interval = 0; // } // // } else if (rule == 1) { // twmsg(("D")); // // if have not found the rule, the process looking for rule before is invalid, then search the rule again // TempSteps = 1; // interval = 0; // InvalidSteps = 0; // rule = 1; // } // // } else if (interval > __ACC_TWIN_MAX) { // // if the interval more than upper threshold, the steps is interrupted, then searh the rule again // twmsg(("interval > max")); // TempSteps = 1; // interval = 0; // InvalidSteps = 0; // rule = 1; // } // } twmsg(("\n\033[0m")); }
/* program main */ int main() { char* tmsg = NULL; int main_tmo = 5; int loop1_tmo = 2 * main_tmo; int loop2_tmo = 3; twmsg(__func__, "STARTING"); /* setup the main loop structure */ tmsg=g_strdup_printf("creating main context, TMO=%d", main_tmo); twmsg(__func__, tmsg); g_free(tmsg); loop_main.name = g_strdup("MAIN"); loop_main.tmo = main_tmo; /* seconds for callback */ loop_main.main_context = NULL; /* use default */ loop_main.main_loop = g_main_loop_new (loop_main.main_context, FALSE); loop_main.idle = g_idle_source_new(); g_source_set_callback(loop_main.idle, idle_func, &loop_main, NULL); g_source_attach(loop_main.idle, loop_main.main_context); loop_main.main_context = NULL; /* use default */ loop_main.Q = NULL; /* no queue, for now */ loop_main.TH = NULL; /* this is the main thread so no thread info */ /* interval, function callback, userdata * - internally creates source and attaches to main context */ g_timeout_add_seconds(loop_main.tmo, tmo_callback, "tmo_callback"); /* create info for the worker thread and set up its context, then run it */ tmsg=g_strdup_printf("creating loop1 context, TMO=%d", loop1_tmo); twmsg(__func__, tmsg); g_free(tmsg); loop_main.name = g_strdup("LOOP_1"); loop_1.tmo = loop1_tmo; loop_1.main_context = g_main_context_new(); loop_1.main_loop = g_main_loop_new(loop_1.main_context, FALSE); loop_1.idle = g_idle_source_new(); g_source_set_callback(loop_1.idle, idle_func, &loop_1, NULL); g_source_attach(loop_1.idle, loop_1.main_context); loop_1.Q = g_async_queue_new(); /* manually create new timeout source and attach to main context of nth Loop * - timeout is in ms so multiply seconds by 1000 * - set priority to 1 or 2 * - optionally set name */ GSource *source1 = g_timeout_source_new (loop_1.tmo*1000); g_source_set_priority (source1, 1); g_source_set_callback (source1, tmo_callback, "tmo_loop1_callback", NULL); g_source_set_name (source1, "LOOP1_TMO"); g_source_attach (source1, loop_1.main_context); /* run the thread which will run the main context */ loop_1.TH = g_thread_new("LOOP1_TH", loop_thread, &loop_1); /* create info for the second worker thread and set up its context, then run it */ tmsg=g_strdup_printf("creating loop2 context, TMO=%d", loop2_tmo); twmsg(__func__, tmsg); g_free(tmsg); /* init the data for the context */ loop_2.name = g_strdup("LOOP_2"); loop_2.tmo = loop2_tmo; loop_2.main_context = g_main_context_new(); loop_2.main_loop = g_main_loop_new(loop_2.main_context, FALSE); loop_2.idle = g_idle_source_new(); g_source_set_callback(loop_2.idle, idle_func, &loop_2, NULL); g_source_attach(loop_2.idle, loop_2.main_context); loop_2.Q = g_async_queue_new(); /* manually create new timeout source and attach to main context of nth Loop * - timeout is in ms so multiply seconds by 1000 * - set priority to 1 or 2 * - optionally set name */ GSource *source2 = g_timeout_source_new (loop_2.tmo*1000); g_source_set_priority (source2, 1); g_source_set_callback (source2, tmo_callback, "tmo_loop2_callback", NULL); g_source_set_name (source2, "LOOP2_TMO"); g_source_attach (source2, loop_2.main_context); /* run the second thread */ loop_2.TH = g_thread_new("LOOP2_TH", loop_thread, &loop_2); /* run the main loop */ g_main_loop_run(loop_main.main_loop); return 0; }