void do_run(void) { event_t *event = NULL; while (1) { /* synchronize nodes */ worldsens_synchronize(); /* catch exceptions */ if (exception != NO_EXCEPTION) { return; } /* get next event */ event = scheduler_next(); /* eventually jump in time */ if (event->clock > g_clock) { do_clockadvance(event->clock); } /* do event */ do_event(event); /* catch exceptions */ if (exception != NO_EXCEPTION) { return; } /* release nodes */ worldsens_scheduler_release(); } }
static void yield() { thread_t *t = scheduler_next(); if (!t) return; if (t->request_kill) { t->state = THREAD_DEAD; yield(); assert(0 && "Unreachable!"); return; } t->state = THREAD_RUN; longjmp(t->jmpbuf, 1); }
/** * Fault Handler: General Protection Fault * * Kernel: Panic * User: Terminate Process */ void fault_gp(cpu_int_state_t *state) { // Is in kernel? if (state->cs == 0x8) { console_print("PANIC: General Protection Fault in kernel at "); console_print_hex(state->rip); console_print(" (error code: "); console_print_hex(state->error_code); console_print(").\n"); while (1); } // TODO: Remove this debug warning DEBUG("General Protection Fault at "); DEBUG_HEX(state->rip); DEBUG(" (error code: "); DEBUG_HEX(state->error_code); DEBUG(").\n"); // Terminate process process_terminate(process_current->pid); thread_switch(scheduler_next(), state); }
/* ************************************************** */ static void worldsens_rm_duplicate_pk(event_t *event) { if (ws_count) { event_t *next_event = scheduler_see_next(); /* A packet sent by a node has the same id for each receiving nodes. So if we find a packet with same source node, same clock and differents ids, it is a duplicated packet (because of a backtrack) and we have to skip it. */ while(next_event->priority == PRIORITY_RX_BEGIN && next_event->u.rx.packet->node == event->u.rx.packet->node && next_event->u.rx.packet->clock0 == event->u.rx.packet->clock0 && next_event->u.rx.packet->id != event->u.rx.packet->id) { /* get out of the fifo the duplicated packet */ event_t *trash_event = scheduler_next(); worldsens_rdv_update(trash_event); WSNET_S_DBG_DBG("WSNET2:: --> RX BEGIN: same packet found in fifo, skip it (src ip:%d, data:0x%02x, freq:%ghz, wsim modul:%d)\n", worldsens_get_wsim_node_id(next_event->u.rx.packet->node), *(next_event->u.rx.packet->data), next_event->u.rx.packet->worldsens_freq, next_event->u.rx.packet->worldsens_mod); mem_fs_dealloc(mem_event, trash_event); dbg.c_events--; next_event = scheduler_see_next(); } } }
void syscall_ipc_respond(cpu_int_state_t *state) { // Check thread role if (THREAD_ROLE_IPC_RECEIVER != thread_current->role) SYSCALL_RETURN_ERROR(1); // Extract arguments uint16_t flags = (uint16_t) state->state.rbx; uint32_t length = (uint32_t) state->state.rcx; // Check length if (length > thread_current->ipc_buffer_sz[IPC_BUFFER_SEND]) SYSCALL_RETURN_ERROR(2); // Extract info from role ctx ipc_role_ctx_t *role_ctx = (ipc_role_ctx_t *) thread_current->role_ctx; uint32_t sender_pid = role_ctx->sender_process; uint32_t sender_tid = role_ctx->sender_thread; // Sender process still exists? process_t *sender_process = process_get(sender_pid); if (0 == sender_process) { thread_stop(process_current, thread_current); thread_switch(scheduler_next(), state); return; } // Sender thread still exists? thread_t *sender_thread = thread_get(sender_process, sender_tid); if (0 == sender_thread) { thread_stop(process_current, thread_current); thread_switch(scheduler_next(), state); return; } // Response ignored? if (0 != (role_ctx->flags & IPC_FLAG_IGNORE_RESPONSE)) { thread_stop(process_current, thread_current); thread_switch(sender_thread, state); return; } // Move buffer to sender thread (if length > 0) if (length > 0) ipc_buffer_move( thread_current, IPC_BUFFER_SEND, sender_thread, IPC_BUFFER_RECV, sender_process); // Write header to registers ipc_message_header( IPC_BUFFER_RECV, length, flags, process_current->pid, sender_thread->tid, &sender_thread->state); // Thaw thread thread_thaw(sender_thread, 0); // Stop current thread and switch to sender thread_stop(process_current, thread_current); thread_switch(sender_thread, state); }