/* * prevent all other threads from running */ void jthread_suspendall(void) { l4_umword_t old_eflags; l4_umword_t dummy; l4_msgdope_t result; l4_threadid_t src; l4_threadid_t preempter = L4_INVALID_ID; l4_threadid_t pager = L4_INVALID_ID; jthread_t current = live; l4thread_t myself = l4thread_myself(); leaflet.gc = l4_myself(); // LOG("suspendall"); /* * ex-regs all threads and save their state */ while (current) { /** * NoHeapRealtimeThreads will not be stopped */ if (current->daemon==0 && #ifdef REALTIME_EXTENSION current->threadtype != THREADTYPE_NOHEAPREAL && #endif !l4thread_equal(current->l4thread,myself)) { l4_thread_ex_regs(l4thread_l4_id(current->l4thread), (unsigned long)_l4threads_suspendall, (l4_umword_t)-1, &preempter, &pager, &old_eflags,¤t->eip,¤t->esp); } current = current -> next; } /* * Waiting for the notification IPC of the last stopped thread */ { l4_ipc_wait(&src, L4_IPC_SHORT_MSG, &dummy, &dummy, L4_IPC_NEVER,&result); }while(!l4_tasknum_equal(leaflet.gc, src) || L4_IPC_ERROR(result) == L4_IPC_RECANCELED || L4_IPC_ERROR(result) == L4_IPC_REABORTED); // LOG("suspendall-complete"); }
static void *updater_thread(void *data) { l4_umword_t l; (void)data; l4_thread_control_start(); l4_thread_control_ux_host_syscall(1); l4_thread_control_commit(pthread_getl4cap(pthread_self())); while (1) { if (l4_ipc_error(l4_ipc_wait(l4_utcb(), &l, L4_IPC_NEVER), l4_utcb())) printf("updater_thread: l4_ipc_wait failed\n"); l4_sleep(30); lx_kill(ux_con_pid, LX_SIGUSR1); waiting = 0; } return NULL; }
/** * preempter thread for each Java thread */ static void NONRETURNING jthread_preempter(void * obj) { l4_rt_preemption_t dw; l4_threadid_t src; l4_msgdope_t result; int error; l4_threadid_t self = l4_myself(); l4thread_started(obj); while (1) { /* wait for request */ error = l4_ipc_wait(&src, L4_IPC_SHORT_MSG, &dw.lh.low, &dw.lh.high, L4_IPC_NEVER, &result); if (error == 0 && leaflet.misshandler != NULL) { if (l4_tasknum_equal(self, src)) { switch(dw.p.type){ case L4_RT_PREEMPT_TIMESLICE: // LOG("TimeSlice "l4util_idfmt"/%d", l4util_idstr(src), dw.p.id); jthread_preemption(src, leaflet.wcetover); break; case L4_RT_PREEMPT_DEADLINE: // LOG("DeadLine "l4util_idfmt, l4util_idstr(src)); jthread_preemption(src, leaflet.deadover); break; default: LOG("unknown preemption"); } } } } }
static void L4_CV timer_thread(void *data) { l4_timeout_t to; l4_utcb_t *u = l4_utcb(); l4_cap_idx_t irq_cap = *(l4_cap_idx_t *)data; l4_msgtag_t t; l4_umword_t l; l4_msg_regs_t *v = l4_utcb_mr_u(u); l4timer_time_t increment = 0; l4_cpu_time_t next_to = 0; enum { idx_at = 2, idx_increment = idx_at + sizeof(l4timer_time_t) / sizeof(v->mr[0]), }; to = L4_IPC_NEVER; t = l4_ipc_wait(u, &l, to); while (1) { int reply = 1; int r = 0; if (l4_ipc_error(t, u) == L4_IPC_RETIMEOUT) { if (l4_error(l4_irq_trigger_u(irq_cap, u)) != -1) LOG_printf("IRQ timer trigger failed\n"); if (increment) { next_to += increment; to = l4_timeout(L4_IPC_TIMEOUT_0, l4_timeout_abs_u(next_to, 1, u)); } else to = L4_IPC_NEVER; reply = 0; } else if (l4_error(t) == L4_PROTO_TIMER) { switch (v->mr[0]) { case L4_TIMER_OP_START: next_to = *(l4timer_time_t *)&v->mr[idx_at]; to = l4_timeout(L4_IPC_TIMEOUT_0, l4_timeout_abs_u(next_to, 1, u)); increment = *(l4timer_time_t *)&v->mr[idx_increment]; r = 0; break; case L4_TIMER_OP_STOP: to = L4_IPC_NEVER; increment = 0; r = 0; break; default: LOG_printf("l4timer: invalid opcode\n"); r = -ENOSYS; break; }; } else LOG_printf("l4timer: msg r=%ld\n", l4_error(t)); t = l4_msgtag(r, 0, 0, 0); if (reply) t = l4_ipc_reply_and_wait(u, t, &l, to); else t = l4_ipc_wait(u, &l, to); } }