/* Initialise the buffering subsystem */ bool buffering_reset(char *buf, size_t buflen) { if (!buf || !buflen) return false; buffer = buf; /* Preserve alignment when wrapping around */ buffer_len = STORAGE_ALIGN_DOWN(buflen); guard_buffer = buf + buflen; buf_widx = 0; buf_ridx = 0; first_handle = NULL; cur_handle = NULL; cached_handle = NULL; num_handles = 0; base_handle_id = -1; /* Set the high watermark as 75% full...or 25% empty :) */ #if MEM > 8 high_watermark = 3*buflen / 4; #endif thread_thaw(buffering_thread_id); return true; }
static void _futex_wake_threads(uint32_t thread_count, uintptr_t futex_vaddr) { thread_t *thread = process_current->threads; while (0 != thread && thread_count > 0) { // Is sleeping because of this futex? if (thread->sleep_mode == THREAD_SLEEP_FUTEX && (uintptr_t) thread->sleep_ctx == futex_vaddr) { // Wake thread up thread->sleep_mode = 0; thread_thaw(thread, 0); // Decrease number of remaining threads --thread_count; } // Next thread = thread->next; } }
/* Unfreeze the codec thread */ void codec_thread_resume(void) { thread_thaw(codec_thread_id); }
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); }
/* Unfreeze the voice thread */ void voice_thread_resume(void) { logf("Thawing voice thread"); thread_thaw(voice_thread_id); }