static gboolean run_timer (gpointer data) { SourceInfo *info = data; if (is_greater_than (&last_runtime, &info->intended_runtime)) { g_error ("out-of-order timer execution: expected to be run at %u.%03ums, " "it already got event intended for time %u.%03ums", ((guint) info->intended_runtime.tv_sec - init_second) * 1000 + (guint) info->intended_runtime.tv_usec / 1000, (guint) info->intended_runtime.tv_usec % 1000, ((guint) last_runtime.tv_sec - init_second) * 1000 + (guint) last_runtime.tv_usec / 1000, (guint) last_runtime.tv_usec % 1000); } last_runtime = info->intended_runtime; if (info->period == -1 || rand() < RAND_MAX / 100 * PERCENT_ODDS_OF_STOPPING) { info->period = -1; return FALSE; } if (rand() < RAND_MAX / 10) { info->period = rand () / (RAND_MAX / MAX_RANDOM_PERIOD); gsk_source_adjust_timer (info->source, info->period, info->period); info->intended_runtime = gsk_main_loop_default()->current_time; } add_ms (&info->intended_runtime, info->period); return TRUE; }
clock::clock( int days, int hours, int minutes, int seconds, int milliseconds ) { m_time = 0; add_days( days ); add_hours( hours ); add_min( minutes ); add_s( seconds ); add_ms( milliseconds ); }
int main(int argc, char *argv[]) { int h,l; get_time(h,l); add_ms(h,l,10); delay_until(h,l); return 0; }
static void make_random_source (void) { SourceInfo *info = g_new0 (SourceInfo, 1); int rt_ms = rand () / (RAND_MAX / MAX_RANDOM_PERIOD); info->period = rand () / (RAND_MAX / MAX_RANDOM_PERIOD) - 1; info->intended_runtime = gsk_main_loop_default()->current_time; add_ms (&info->intended_runtime, rt_ms); info->source = gsk_main_loop_add_timer (gsk_main_loop_default(), run_timer, info, destroy_timer, rt_ms, info->period); source_count++; }
int main(int argc, char *argv[]) { int h,l; // High and low 32-bit time values get_time(h,l); // Current time in nano seconds while(1){ // Repeat control loop forever add_ms(h,l,10); // Add 10ms exception_on_expire(h,l,missed_deadline_handler); // Upper timing bound. Exception handler compute_task(); // Sense, compute, and actuate delay_until(h,l); // Delay until start of next period } return 0; }
int main(void) { unsigned int ns_h = 0; unsigned int ns_l = 100000; unsigned int message; // Synchronize. delay_until(ns_h, ns_l); while(1) { message = tohost_id(THREAD, 4); mtpcr(30, message); message = tohost_time(get_time_low()); mtpcr(30, message); taskA4_main(); message = tohost_id(THREAD, 14); mtpcr(30, message); message = tohost_time(get_time_low()); mtpcr(30, message); add_ms(ns_h, ns_l, 200); delay_until(ns_h, ns_l); } return 0; }
int main(void) { unsigned int ns_h = 0; unsigned int ns_l = 100000; unsigned int i = 0; unsigned int message; // Synchronize. delay_until(ns_h, ns_l); while(1) { message = tohost_id(THREAD, 1); mtpcr(30, message); message = tohost_time(get_time_low()); mtpcr(30, message); taskB1_main(); message = tohost_id(THREAD, 11); mtpcr(30, message); message = tohost_time(get_time_low()); mtpcr(30, message); if(i == 0) { message = tohost_id(THREAD, 2); mtpcr(30, message); message = tohost_time(get_time_low()); mtpcr(30, message); taskB2_main(); message = tohost_id(THREAD, 12); mtpcr(30, message); message = tohost_time(get_time_low()); mtpcr(30, message); i++; } else { message = tohost_id(THREAD, 3); mtpcr(30, message); message = tohost_time(get_time_low()); mtpcr(30, message); taskB3_main(); message = tohost_id(THREAD, 13); mtpcr(30, message); message = tohost_time(get_time_low()); mtpcr(30, message); i = 0; } add_ms(ns_h, ns_l, 25); delay_until(ns_h, ns_l); } return 0; }
int32_t ppb_message_loop_run_int(PP_Resource message_loop, int nested, int increase_depth) { if (this_thread_message_loop != message_loop) { trace_error("%s, not attached to current thread\n", __func__); return PP_ERROR_WRONG_THREAD; } struct pp_message_loop_s *ml = pp_resource_acquire(message_loop, PP_RESOURCE_MESSAGE_LOOP); if (!ml) { trace_error("%s, bad resource\n", __func__); return PP_ERROR_BADRESOURCE; } // prevent nested loops if (!nested && ml->running) { trace_error("%s, trying to run nested loop without declaring as nested\n", __func__); pp_resource_release(message_loop); return PP_ERROR_INPROGRESS; } struct { int running; int teardown; } saved_state = { .running = ml->running, .teardown = ml->teardown, }; ml->running = 1; ml->teardown = 0; if (increase_depth) ml->depth++; int teardown = 0; int destroy_ml = 0; int depth = ml->depth; pp_resource_ref(message_loop); GAsyncQueue *async_q = ml->async_q; GQueue *int_q = ml->int_q; pp_resource_release(message_loop); while (1) { struct timespec now; struct message_loop_task_s *task = g_queue_peek_head(int_q); gint64 timeout = 1000 * 1000; if (task) { clock_gettime(CLOCK_REALTIME, &now); timeout = (task->when.tv_sec - now.tv_sec) * 1000 * 1000 + (task->when.tv_nsec - now.tv_nsec) / 1000; if (timeout <= 0) { // remove task from the queue g_queue_pop_head(int_q); // check if depth is correct if (task->depth > 0 && task->depth < depth) { // wrong, reschedule it a bit later task->when = add_ms(now, 10); g_queue_insert_sorted(int_q, task, time_compare_func, NULL); continue; } if (task->terminate) { if (depth > 1) { // exit at once, all remaining task will be processed by outer loop g_slice_free(struct message_loop_task_s, task); break; } // it's the outermost loop, we should wait for all tasks to be run ml = pp_resource_acquire(message_loop, PP_RESOURCE_MESSAGE_LOOP); if (ml) { ml->teardown = 1; teardown = 1; destroy_ml = task->should_destroy_ml; pp_resource_release(message_loop); } g_slice_free(struct message_loop_task_s, task); continue; } // run task const struct PP_CompletionCallback ccb = task->ccb; if (ccb.func) { ccb.func(ccb.user_data, task->result_to_pass); } // free task g_slice_free(struct message_loop_task_s, task); continue; // run cycle again } } else if (teardown) { // teardown, no tasks in queue left break; } task = g_async_queue_timeout_pop(async_q, timeout); if (task) g_queue_insert_sorted(int_q, task, time_compare_func, NULL); } // mark thread as non-running ml = pp_resource_acquire(message_loop, PP_RESOURCE_MESSAGE_LOOP); if (ml) { if (increase_depth) ml->depth--; ml->running = 0; if (nested) { ml->running = saved_state.running; ml->teardown = saved_state.teardown; } pp_resource_release(message_loop); } pp_resource_unref(message_loop); if (destroy_ml) pp_resource_unref(message_loop); return PP_OK; } int32_t ppb_message_loop_post_work_with_result(PP_Resource message_loop, struct PP_CompletionCallback callback, int64_t delay_ms, int32_t result_to_pass, int depth) { if (callback.func == NULL) { trace_error("%s, callback.func == NULL\n", __func__); return PP_ERROR_BADARGUMENT; } struct pp_message_loop_s *ml = pp_resource_acquire(message_loop, PP_RESOURCE_MESSAGE_LOOP); if (!ml) { trace_error("%s, bad resource\n", __func__); return PP_ERROR_BADRESOURCE; } if (ml->running && ml->teardown) { // message loop is in a teardown state pp_resource_release(message_loop); trace_error("%s, quit request received, no additional work could be posted\n", __func__); return PP_ERROR_FAILED; } struct message_loop_task_s *task = g_slice_alloc0(sizeof(*task)); task->result_to_pass = result_to_pass; task->ccb = callback; task->depth = depth; // calculate absolute time callback should be run at clock_gettime(CLOCK_REALTIME, &task->when); task->when.tv_sec += delay_ms / 1000; task->when.tv_nsec += (delay_ms % 1000) * 1000 * 1000; while (task->when.tv_nsec >= 1000 * 1000 * 1000) { task->when.tv_sec += 1; task->when.tv_nsec -= 1000 * 1000 * 1000; } g_async_queue_push(ml->async_q, task); pp_resource_release(message_loop); return PP_OK; } int32_t ppb_message_loop_post_work(PP_Resource message_loop, struct PP_CompletionCallback callback, int64_t delay_ms) { return ppb_message_loop_post_work_with_result(message_loop, callback, delay_ms, PP_OK, 0); } int32_t ppb_message_loop_post_quit_depth(PP_Resource message_loop, PP_Bool should_destroy, int depth) { struct pp_message_loop_s *ml = pp_resource_acquire(message_loop, PP_RESOURCE_MESSAGE_LOOP); if (!ml) { trace_error("%s, bad resource\n", __func__); return PP_ERROR_BADRESOURCE; } struct message_loop_task_s *task = g_slice_alloc0(sizeof(*task)); task->terminate = 1; task->depth = depth; task->should_destroy_ml = should_destroy; task->result_to_pass = PP_OK; clock_gettime(CLOCK_REALTIME, &task->when); // run as early as possible g_async_queue_push(ml->async_q, task); pp_resource_release(message_loop); return PP_OK; } int32_t ppb_message_loop_post_quit(PP_Resource message_loop, PP_Bool should_destroy) { int depth = ppb_message_loop_get_depth(message_loop); return ppb_message_loop_post_quit_depth(message_loop, should_destroy, depth); }