static void zone0150_thread1_routine(void) { L4_MsgTag_t result; L4_ThreadId_t thread0_tid; okl4_init_thread(); while (zone0150_children_can_run == 0) { /* spin */ } thread0_tid.raw = thread0_cap.raw; result = L4_Receive(thread0_tid); fail_unless(L4_IpcSucceeded(result) != 0, "thread1 L4_Receive() failed."); result = L4_Send(thread0_tid); fail_unless(L4_IpcSucceeded(result) != 0, "thread1 L4_Send() failed."); result = L4_Call(thread0_tid); fail_unless(L4_IpcSucceeded(result) != 0, "thread1 L4_Call() failed."); zone0150_child_thread_run++; L4_WaitForever(); }
static void run_copying_thread(L4_Word_t direction, int small_remote_buffer, int unmapped) { L4_MsgTag_t tag; memset(copying_thread_buffer, COPYING_THREAD_PATTERN, sizeof(copying_thread_buffer)); tag = L4_Niltag; L4_Set_MemoryCopy(&tag); L4_LoadMR(0, tag.raw); if (unmapped) { L4_LoadMR(1, (word_t)unmapped_address); } else { L4_LoadMR(1, (word_t)copying_thread_buffer); } if (small_remote_buffer) { L4_LoadMR(2, SMALL_BUFFER_SIZE); } else { L4_LoadMR(2, sizeof(copying_thread_buffer)); } L4_LoadMR(3, direction); tag = L4_Call(test_tid); assert(L4_IpcSucceeded(tag)); }
static void pager (void) { L4_ThreadId_t tid; L4_MsgTag_t tag; L4_Msg_t msg; L4_Send(master_tid); for (;;) { tag = L4_Wait(&tid); for (;;) { L4_Word_t faddr, fip; L4_MsgStore(tag, &msg); if (L4_UntypedWords (tag) != 2 || !L4_IpcSucceeded (tag)) { printf ("Malformed pagefault IPC from %p (tag=%p)\n", (void *) tid.raw, (void *) tag.raw); L4_KDB_Enter ("malformed pf"); break; } faddr = L4_MsgWord(&msg, 0); fip = L4_MsgWord (&msg, 1); L4_MsgClear(&msg); { L4_MapItem_t map; L4_SpaceId_t space; L4_Word_t seg, offset, cache, rwx, size; int r; seg = get_seg(KBENCH_SPACE, faddr, &offset, &cache, &rwx); assert(seg != ~0UL); size = L4_GetMinPageBits(); faddr &= ~((1ul << size)-1); offset &= ~((1ul << size)-1); space.raw = __L4_TCR_SenderSpace(); L4_MapItem_Map(&map, seg, offset, faddr, size, cache, rwx); r = L4_ProcessMapItem(space, map); assert(r == 1); } L4_MsgLoad(&msg); // tag = L4_ReplyWait (tid, &tid); tag = L4_MsgTag(); L4_Set_SendBlock(&tag); L4_Set_ReceiveBlock(&tag); tag = L4_Ipc(tid, L4_anythread, tag, &tid); } } }
/* * The medium thread tries to acquire a mutex, releases it once acquired and then * receives from highest priority thread in scenario 1. It increments 2 counters * on success, one for each operation. * It acquires a mutex at initialisation time and waits for any thread before * releasing the mutex in scenario 2. It increments 2 counters on success, * one for each operation. */ void mixed_pi_medium(int argc, char **argv) { L4_ThreadId_t any_thread, tid; L4_MsgTag_t tag; int counter = 10000; while (!libs_ready) ; while (L4_IsNilThread(medium1_prio_thread)) ; tid = medium1_prio_thread; //printf("Middle thread %lx/%lx starts PI test\n", me, pi_main.raw); while (1) { // Initialisation if (scenario2) { //printf("Middle thread %lx/%lx acquires mutex for resource\n", me, pi_main.raw); okl4_libmutex_count_lock(resource_mutex); cnt_m1++; } //printf("(Initialisation) Medium thread %lx/%lx blocks open receiving\n", me, pi_main.raw); L4_Wait(&any_thread); //printf("(Initialisation) Medium thread %lx/%lx received from 0x%lx\n", me, pi_main.raw, any_thread.raw); L4_LoadMR(0, 0); L4_Send(tid); L4_Yield(); /*** Start test ***/ while (stop_spinning) ; wait_a_bit(counter); if (scenario1) { okl4_libmutex_count_lock(resource_mutex); cnt_m1++; wait_a_bit(counter); } else if (scenario2) { //printf("Middle thread %lx/%lx blocks open receiving\n", me, pi_main.raw); tag = L4_Wait(&any_thread); if (L4_IpcSucceeded(tag) && (any_thread.raw == low_prio_thread.raw)) cnt_m2++; wait_a_bit(counter); } okl4_libmutex_count_unlock(resource_mutex); if (!flag1 && (counter < LIMIT)) { counter *= 2; } if (scenario1) { cnt_m2++; tag = L4_Receive(high_prio_thread); if (L4_IpcFailed(tag)) cnt_m2--; } L4_Yield(); tid = pi_main; } }
__USER_TEXT void *pong_thread(void *arg) { L4_MsgTag_t tag; L4_Msg_t msg; while (1) { tag = L4_Receive_Timeout(threads[PING_THREAD], L4_TimePeriod(1000 * 1000)); L4_MsgStore(tag, &msg); if (!L4_IpcSucceeded(tag)) { printf("%p: recv ipc fails\n", L4_MyGlobalId()); printf("%p: ErrorCode = 0x%x\n", L4_MyGlobalId(), L4_ErrorCode()); } } }
/* * The highest priority thread blocks sending to medium thread in the * first scenario. It increments a counter on success. * It tries to acquire a mutex in the second scenario. It increments a counter on success. */ void mixed_pi_high(int argc, char **argv) { L4_MsgTag_t tag; while (!libs_ready) ; L4_Receive(pi_main); //printf("High thread %lx/%lx starts PI test\n", me, pi_main.raw); while (1) { while (stop_spinning) ; if (scenario1) { L4_LoadMR(0, 0); tag = L4_Send(medium2_prio_thread); if (L4_IpcSucceeded(tag)) cnt_h++; } else if (scenario2) { //printf("High thread %lx/%lx acquiring mutex for resource, current holder: 0x%lx\n", me, pi_main.raw, resource_mutex->holder); okl4_libmutex_count_lock(resource_mutex); //printf("High thread %lx/%lx acquired mutex for resource\n", me, pi_main.raw); cnt_h++; } // If intermediate threads have run, then increment respective counter. if (flag1) cnt_i1++; if (flag3) cnt_i2++; if (scenario2) okl4_libmutex_count_unlock(resource_mutex); // Tell main thread iteration is done. L4_LoadMR(0, 0); L4_Call(pi_main); // Re-initialise. if (flag1) { L4_Receive_Nonblocking(medium1_prio_thread); flag1 = 0; } if (flag3) { L4_Receive_Nonblocking(medium3_prio_thread); flag3 = 0; } } }
__USER_TEXT void *pong_thread(void *arg) { L4_MsgTag_t tag; L4_Msg_t msg; while (1) { tag = L4_Receive_Timeout(threads[PING_THREAD], L4_TimePeriod(1000 * 1000)); L4_MsgStore(tag, &msg); if (!L4_IpcSucceeded(tag)) { printf("%p: recv ipc fails\n", L4_MyGlobalId()); printf("%p: ErrorCode = 0x%x\n", L4_MyGlobalId(), L4_ErrorCode()); } /* FIXME: workaround solution to avoid scheduler starvation */ L4_Sleep(L4_TimePeriod(500 * 1000)); } }
__USER_TEXT void *ping_thread(void *arg) { L4_Msg_t msg; L4_MsgTag_t tag; L4_MsgClear(&msg); L4_MsgLoad(&msg); while (1) { tag = L4_Send_Timeout(threads[PONG_THREAD], L4_TimePeriod(1000 * 1000)); if (!L4_IpcSucceeded(tag)) { printf("%p: send ipc fails\n", L4_MyGlobalId()); printf("%p: ErrorCode = 0x%x\n", L4_MyGlobalId(), L4_ErrorCode()); } } }
int okl4_message_wait(void *recv_buff, okl4_word_t recv_buff_size, okl4_word_t *recv_bytes, okl4_kcap_t *reply_cap) { L4_MsgTag_t tag; L4_ThreadId_t from; okl4_word_t bytes_received; /* Ensure buffer is word-aligned. */ assert((okl4_word_t)recv_buff % sizeof(okl4_word_t) == 0); /* Perform the wait. */ L4_Set_NotifyMask(0); tag = L4_Wait(&from); if (!L4_IpcSucceeded(tag)) { return _okl4_message_errno(tag, L4_ErrorCode()); } /* Determine the number of words received, which is in the label. */ bytes_received = L4_Label(tag); /* Ensure that the number of bytes the message claims to contain is roughly * the same as the number of words we received. */ assert(ROUND_UP(bytes_received, sizeof(okl4_word_t)) == L4_UntypedWords(tag) * sizeof(okl4_word_t)); /* Copy to the buffer. */ _okl4_message_copy_mrs_to_buff(recv_buff, min(recv_buff_size, bytes_received)); /* Give parameters back to the caller. */ if (recv_bytes != NULL) { *recv_bytes = bytes_received; } if (reply_cap != NULL) { *reply_cap = from; } return OKL4_OK; }
static void pager (void) { L4_ThreadId_t tid; L4_MsgTag_t tag; L4_Msg_t msg; int count = 0; for (;;) { tag = L4_Wait(&tid); for (;;) { L4_Word_t faddr, fip; L4_MsgStore(tag, &msg); if (L4_Label(tag) == START_LABEL) { // Startup notification, start ping and pong thread void (*start_addr)(void); void (*pong_start_addr)(void); L4_Word_t *pong_stack_addr = pong_stack; if (pagertimer) { start_addr = ping_thread_pager; } else if (pagertimer_simulated) { start_addr = ping_thread_simulated; } else if (fass_buffer) { start_addr = ping_thread_buffer; } else if (fault_test) { count = 0; start_addr = NULL; } else if (intra_close) { start_addr = ping_thread_close; } else if (intra_open) { start_addr = ping_thread_open; } else if (intra_rpc) { start_addr = ping_thread_rpc_server; } else if (intra_ovh) { start_addr = ping_thread_ovh; } else if (intra_async) { start_addr = ping_thread_async; } else if (intra_async_ovh) { start_addr = ping_thread_async_ovh; } else { start_addr = ping_thread; } if (start_addr != NULL) { /*printf("ping_start_addr: %lx ping_stack_addr: %lx\n", START_ADDR (start_addr), (L4_Word_t) ping_stack);*/ send_startup_ipc (ping_tid, START_ADDR(start_addr), (L4_Word_t) ping_stack + sizeof (ping_stack) - 32); L4_ThreadSwitch(ping_tid); } if (fass_buffer) { pong_start_addr = pong_thread_buffer; pong_stack_addr = pong_stack_fass; } else if (fass) { pong_start_addr = pong_thread_fass; pong_stack_addr = pong_stack_fass; } else if (fault_test) { pong_stack_addr = pong_stack_fass; pong_start_addr = pong_thread_faulter; } else if (intra_close) { pong_start_addr = pong_thread_close; } else if (intra_open) { pong_start_addr = pong_thread_open; } else if (intra_rpc) { pong_start_addr = pong_thread_close; } else if (intra_ovh) { pong_start_addr = pong_thread_ovh; } else if (intra_async) { pong_start_addr = pong_thread_async; } else if (intra_async_ovh) { pong_start_addr = pong_thread_async_ovh; } else { pong_start_addr = pong_thread; } if (!pagertimer) { /*printf("pong_start_addr: %lx pong_stack_addr: %lx\n", START_ADDR (pong_start_addr), (L4_Word_t) pong_stack_addr);*/ L4_Set_Priority(ping_tid, 100); L4_Set_Priority(pong_tid, 99); send_startup_ipc (pong_tid, START_ADDR (pong_start_addr), (L4_Word_t) pong_stack_addr + sizeof (ping_stack) - 32); } break; } if (L4_UntypedWords (tag) != 2 || !L4_IpcSucceeded (tag)) { printf ("pingpong: malformed pagefault IPC from %p (tag=%p)\n", (void *) tid.raw, (void *) tag.raw); L4_KDB_Enter ("malformed pf"); break; } faddr = L4_MsgWord(&msg, 0); fip = L4_MsgWord (&msg, 1); L4_MsgClear(&msg); if (fault_test && (faddr == (uintptr_t) fault_area)) { if (count < num_iterations) { count++; } else { /* Tell master that we're finished */ L4_Set_MsgTag (L4_Niltag); L4_Send (master_tid); break; } } else { L4_MapItem_t map; L4_SpaceId_t space; L4_Word_t seg, offset, cache, rwx, size; int r; seg = get_seg(KBENCH_SPACE, faddr, &offset, &cache, &rwx); //if can not find mapping, must be page fault test, //just map any valid address, since fault address is dummy. if (seg == ~0UL) seg = get_seg(KBENCH_SPACE, (L4_Word_t) fault_area, &offset, &cache, &rwx); if (tid.raw == ping_th.raw) space = ping_space; else if (tid.raw == pong_th.raw) { if (pong_space.raw != L4_nilspace.raw) space = pong_space; else //pong_space is not created, only ping_space is used. space = ping_space; } else space = KBENCH_SPACE; size = L4_GetMinPageBits(); faddr &= ~((1ul << size)-1); offset &= ~((1ul << size)-1); L4_MapItem_Map(&map, seg, offset, faddr, size, cache, rwx); r = L4_ProcessMapItem(space, map); assert(r == 1); } L4_MsgLoad(&msg); tag = L4_ReplyWait (tid, &tid); } } }
int main(void) { int i = 0; int res = 1; L4_SpaceId_t space; okl4_allocator_attr_t attr; L4_Word_t end, result; L4_CapId_t sender; L4_MsgTag_t tag; L4_Msg_t msg; struct okl4_bitmap_allocator *spaceid_pool = okl4_env_get("MAIN_SPACE_ID_POOL"); HEAP_EXHAUSTION_CLIST = L4_ClistId(*(OKL4_ENV_GET_MAIN_CLISTID("MAIN_CLIST_ID"))); while(res == 1) { result = okl4_kspaceid_allocany(spaceid_pool, &space); if (result != OKL4_OK) { printf("Failed to allocate space id\n"); } res = create_address_space(space, L4_Fpage(0xb10000, 0x1000)); if (res != 1) { printf("SpaceControl failed, space id=%lu, Error code: %lu\n", space.space_no, L4_ErrorCode()); break; } /* 2gb mapping of 512k pages*/ res = map_series(space, 0x80000, 4096, 0, 0); i++; } printf("Created %d address spaces\n", i); if (i == 0) { okl4_kspaceid_free(spaceid_pool, space); res = 0; goto ipc_ktest; } /* clean up */ okl4_kspaceid_getattribute(spaceid_pool, &attr); end = attr.base + attr.size; for (i = attr.base; i < end; i++) { L4_SpaceId_t id = L4_SpaceId(i); if (okl4_kspaceid_isallocated(spaceid_pool, id)) { L4_SpaceControl(id, L4_SpaceCtrl_delete, HEAP_EXHAUSTION_CLIST, L4_Nilpage, 0, NULL); okl4_kspaceid_free(spaceid_pool, id); } } res = 1; ipc_ktest: tag = L4_Wait(&sender); L4_MsgClear(&msg); L4_MsgAppendWord(&msg, (L4_Word_t)res); L4_MsgLoad(&msg); L4_Reply(sender); assert(L4_IpcSucceeded(tag)); L4_WaitForever(); }