static void waiting_notify_thread(void *arg) { L4_Word_t notifybits; L4_MsgTag_t tag; L4_Word_t mask; tag = L4_Receive(main_tid); notifybits = L4_Label(tag); L4_Set_NotifyMask(notifybits); L4_Accept(L4_NotifyMsgAcceptor); L4_LoadMR(0, 0); L4_Send(main_tid); tag = L4_WaitNotify(&mask); if (L4_IpcFailed(tag)) { FAILED(); return; } L4_Set_Label(&tag, notifybits); L4_Set_MsgTag(tag); L4_Call(main_tid); while (1) { } }
static void lock_mutex_thread(void) { L4_MsgTag_t tag; L4_Word_t label; L4_Word_t res; tag = L4_Receive(main_thread); while (1) { label = L4_Label(tag); if (label == 0xa) { res = L4_Lock(m); fail_unless(res == 1, "L4_Lock() failed"); L4_Unlock(m); } if (label == 0xb) { res = L4_TryLock(m); fail_unless(res == 0, "L4_TryLock() did not fail"); fail_unless(L4_ErrorCode() == L4_ErrMutexBusy, "Wrong error code"); } tag = L4_Call(main_thread); } L4_WaitForever(); }
static void measure_effective_prio(L4_Word_t expect_prio) { L4_Word_t label, prio; L4_ThreadId_t any_thread; L4_MsgTag_t tag; prio = 9; do { prio--; L4_Set_Priority(measure_thread, prio); tag = L4_Wait(&any_thread); label = L4_Label(tag); } while ((label != 0x1) && (prio > 1)); _fail_unless(prio == expect_prio, __FILE__, __LINE__, "Wrong effective priority: %lu", prio); }
static void runnable_main_thread(void) { L4_Word_t result, label; L4_MsgTag_t tag; label = 0; result = L4_Lock(mutex1); fail_unless(result == 1, "L4_Lock() failed"); while (1) { if (label == 0x3) { L4_Unlock(mutex1); } tag = L4_Make_MsgTag(0x1, 0); L4_Set_MsgTag(tag); L4_Send(setup_thread); tag = L4_Receive(setup_thread); label = L4_Label(tag); } }
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 sending_thread(void) { L4_Word_t result; L4_MsgTag_t tag; if (L4_UserDefinedHandle()) { result = L4_Lock(mutex2); fail_unless(result == 1, "L4_Lock() failed"); } L4_LoadMR(0, 0); L4_Send(main_thread); tag = L4_Receive(setup_thread); if (L4_Label(tag) == 0x3) { L4_Unlock(mutex2); L4_LoadMR(0, 0); L4_Send(main_thread); } L4_WaitForever(); while(1) ; }
static void create_delete_mutex_thread(void) { L4_MsgTag_t tag; L4_Word_t label; L4_Word_t res; tag = L4_Receive(main_thread); label = L4_Label(tag); if (label == 0xc) { res = L4_CreateMutex(m); fail_unless(res == 0, "L4_CreateMutex() did not fail"); fail_unless(L4_ErrorCode() == L4_ErrInvalidSpace, "Wrong error code on create"); } if (label == 0xd) { res = L4_DeleteMutex(m); fail_unless(res == 0, "L4_DeleteMutex() did not fail"); fail_unless(L4_ErrorCode() == L4_ErrInvalidSpace, "Wrong error code on delete"); } L4_Call(main_thread); L4_WaitForever(); }
int main(int argc, char **argv) { struct okl4_libmutex rm; L4_ThreadId_t tid; int i, max_iteration, eg_num, server_on; L4_Word_t me; L4_MsgTag_t tag = L4_Niltag; /*** Initialisation ***/ pi_main = thread_l4tid(env_thread(iguana_getenv("MAIN"))); me = pi_main.raw; eg_num = max_iteration = server_on = 0; if (argc == 3) { eg_num = atoi(argv[0]); max_iteration = atoi(argv[1]); server_on = atoi(argv[2]); } else { printf("(%s 0x%lx) Error: Argument(s) missing!\n", test_name, me); return 1; } resource_mutex = &rm; okl4_libmutex_init(resource_mutex); high_prio_thread = medium1_prio_thread = medium2_prio_thread = medium3_prio_thread = low_prio_thread = L4_nilthread; high_prio_thread = thread_l4tid(env_thread(iguana_getenv("MIXED_PI_HIGH"))); medium3_prio_thread = thread_l4tid(env_thread(iguana_getenv("MIXED_PI_INTERMEDIATE_2"))); medium2_prio_thread = thread_l4tid(env_thread(iguana_getenv("MIXED_PI_MEDIUM"))); medium1_prio_thread = thread_l4tid(env_thread(iguana_getenv("MIXED_PI_INTERMEDIATE_1"))); low_prio_thread = thread_l4tid(env_thread(iguana_getenv("MIXED_PI_LOW"))); // Tell other threads that it is safe to use libraries libs_ready = 1; if (!server_on) printf("Start %s test #%d(0x%lx)\n", test_name, eg_num, me); /*** Start test ***/ scenario1 = 1; for (i = 0; i < 2 * max_iteration; i++) { // Wait for threads to be ready tag = L4_Wait(&tid); // If one thread had a problem while initialisation, then stop the test and notify // server that the test is dead. if (L4_Label(tag) == 0xdead) { rtos_init(); test_died(test_name, eg_num); rtos_cleanup(); return 1; } // Tell high prio thread to start the next iteration. L4_LoadMR(0, 0); tag = L4_Send(high_prio_thread); stop_spinning = 0; // Wait for the iteration to finish. L4_Receive(high_prio_thread); stop_spinning = 1; // If end of iterations for scenario1, then report results to RTOS server if server is on. if (i == (max_iteration - 1)) { if (server_on) { rtos_init(); mixed_priority_inversion_results(eg_num, 1, max_iteration, cnt_h, cnt_m1, cnt_m2, cnt_l, cnt_i1, cnt_i2); } else print_metrics(max_iteration); // Start scenario2 cnt_h = cnt_m1 = cnt_m2 = cnt_l = cnt_i1 = cnt_i2 = 0; scenario1 = 0; scenario2 = 1; } } /*** Test finished ***/ thread_delete(medium1_prio_thread); thread_delete(medium3_prio_thread); thread_delete(high_prio_thread); thread_delete(medium2_prio_thread); thread_delete(low_prio_thread); /* Clean up allocated mutexes. */ okl4_libmutex_free(resource_mutex); // If RTOS server is on, report results to it. if (server_on) { mixed_priority_inversion_results(eg_num, 2, max_iteration, cnt_h, cnt_m1, cnt_m2, cnt_l, cnt_i1, cnt_i2); rtos_cleanup(); } else { print_metrics(max_iteration); printf("%s test #%d(0x%lx) finished\n", test_name, eg_num, me); } return 0; }
int main(int argc, char **argv) { int i, tmp, eg_num, nb_philosophers, nb_dinners, server_on; L4_ThreadId_t *philo_tids; L4_ThreadId_t tid, any_thread; L4_MsgTag_t tag = L4_Niltag; /*** Initialisation ***/ dp_main = thread_l4tid(env_thread(iguana_getenv("MAIN"))); eg_num = nb_philosophers = nb_dinners = server_on = 0; if (argc == 3) { eg_num = atoi(argv[0]); nb_philosophers = atoi(argv[1]); server_on = atoi(argv[2]); } else { printf("(%s 0x%lx) Error: Argument(s) missing!\n", test_name, dp_main.raw); return 1; } if (!server_on) printf("Start %s test #%d(0x%lx): %d philosophers\n", test_name, eg_num, dp_main.raw, nb_philosophers); chopstick = malloc((nb_philosophers + 1) * sizeof(okl4_libmutex_t)); philo_tids = malloc(nb_philosophers * sizeof(L4_ThreadId_t)); for (i = 0; i < nb_philosophers; i++) { chopstick[i] = malloc (sizeof(struct okl4_libmutex)); okl4_libmutex_init(chopstick[i]); } chopstick[nb_philosophers] = NULL; // Tell other threads that it is safe to use libraries and mutexes libs_ready = 1; // Retrieve philosophers thread Ids and give them a go for (i = 0; i < nb_philosophers; i++) { L4_Wait(&tid); philo_tids[i] = tid; } /*** Start test ***/ meal_served = 1; tmp = nb_philosophers; while (tmp) { tag = L4_Wait(&any_thread); for (i = 0; i < nb_philosophers; i++) { if (any_thread.raw == philo_tids[i].raw) { thread_delete(any_thread); tmp--; if (L4_Label(tag) == 0xfed) { // Philosopher finished eating nb_dinners++; } break; } } } /*** Test finished ***/ free(philo_tids); for (i = 0; i < nb_philosophers; i++) { okl4_libmutex_free(chopstick[i]); free(chopstick[i]); } //free(*chopstick); // If RTOS server is on, report results to it. if (server_on) { rtos_init(); dining_philosophers_results(eg_num, nb_philosophers, nb_dinners); rtos_cleanup(); } else printf("%s test #%d(0x%lx) finished\n", test_name, eg_num, dp_main.raw); return 0; }
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); } } }
/* * Function invoked by roottask on pagefault */ int pager(L4_ThreadId_t tid, L4_Msg_t *msgP) { send = 1; // Get the faulting address L4_Word_t addr = L4_MsgWord(msgP, 0); L4_Word_t physicalAddress = 0; L4_Word_t permission = 0; L4_MsgTag_t tag; // Alignment addr = (addr / PAGESIZE)*PAGESIZE; tag = L4_MsgMsgTag(msgP); L4_Word_t access_type = L4_Label(tag) & 0x07; //printf("pager invoked addr=%lx by %lx %lx for access 0x%lx\n", addr,L4_ThreadNo(tid),tid.raw,access_type); // Construct fpage IPC message L4_Fpage_t targetFpage = L4_FpageLog2(addr, 12); if(VIRTUAL(addr)) { if(addr >= BASE_CODE_SEGMENT_ADDRESS) { //Code segment int inPage = isInPage(tid,targetFpage); if(inPage == -1) { //It should be in page table so this should not happen printf("Panic !!! Cannot load the code segment"); } else { physicalAddress = new_low + inPage*PAGESIZE; permission = L4_FullyAccessible; } } else { //Heap and stack int inPage = isInPage(tid, targetFpage); if (inPage == -1) { //We need to check if the page is in swap inPage = isInSwap(tid,targetFpage); mapAddress(tid, targetFpage,inPage); //We dont need to map any addresses here as mapAddresses maps the addresses return send; } else { physicalAddress = new_low+inPage*PAGESIZE; targetFpage = page_table[inPage].pageNo; page_table[inPage].referenced = 1; if(access_type & L4_Writable) { //We now need to set the dirty bit and provide read write access page_table[inPage].dirty = 1; permission = L4_ReadWriteOnly; } else { permission = L4_Readable; } } } } else { // we need to map physical addresses 1:1 physicalAddress = addr; if(addr < new_low) { // This is beyond the low memory range ie the page table // and some other addresses which is below the low range permission = L4_FullyAccessible; } else { // This would be the code segment between the new_low and high permission = L4_Readable; } } L4_Set_Rights(&targetFpage,permission); L4_PhysDesc_t phys = L4_PhysDesc(physicalAddress, L4_DefaultMemory); if ( !L4_MapFpage(tid, targetFpage, phys) ) { sos_print_error(L4_ErrorCode()); printf(" Can't map page at %lx\n", addr); } return send; }
/* * Get current value, request timeout for different threads, check all notified * correctly. */ static void test02(void) { uint32_t cur_value; L4_Word_t result, i; thread_ref_t thread1, thread2, thread3; L4_ThreadId_t tid1, tid2, tid3, any_thread; L4_Word_t notifybits1 = 0x1; L4_Word_t notifybits2 = 0x2; L4_Word_t notifybits3 = 0x3; L4_MsgTag_t tag; L4_Word_t label; printf("%s: ", __func__); thread1 = thread_create_simple(waiting_notify_thread, NULL, 99); thread2 = thread_create_simple(waiting_notify_thread, NULL, 99); thread3 = thread_create_simple(waiting_notify_thread, NULL, 99); tid1 = thread_l4tid(thread1); tid2 = thread_l4tid(thread2); tid3 = thread_l4tid(thread3); tag = L4_Make_MsgTag(notifybits1, 0); L4_Set_MsgTag(tag); tag = L4_Call(tid1); tag = L4_Make_MsgTag(notifybits2, 0); L4_Set_MsgTag(tag); tag = L4_Call(tid2); tag = L4_Make_MsgTag(notifybits3, 0); L4_Set_MsgTag(tag); tag = L4_Call(tid3); result = counter_current_value(&cur_value); if (result == 0) { FAILED(); return; } result = counter_request(cur_value + 10, tid1, notifybits1); if (result == 0) { FAILED(); return; } result = counter_request(cur_value + 12, tid2, notifybits2); if (result == 0) { FAILED(); return; } result = counter_request(cur_value + 14, tid3, notifybits3); if (result == 0) { FAILED(); return; } for (i = 0; i < 3; i++) { tag = L4_Wait(&any_thread); label = L4_Label(tag); if (((i == 0) && (label != 0x1)) || ((i == 1) && (label != 0x2)) || ((i == 2) && (label != 0x3))) { thread_delete(tid1); thread_delete(tid2); thread_delete(tid3); FAILED(); return; } } thread_delete(tid1); thread_delete(tid2); thread_delete(tid3); PASSED(); }