/* * 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; } }
static void mutex0403_worker_thread(void) { int i; for (i = 0; i < 100; i++) { L4_Lock(m); mutex0403_lock_holder = L4_Myself(); L4_Yield(); fail_unless(mutex0403_lock_holder.raw == L4_Myself().raw, "Protected counter changed while we held the lock."); L4_Unlock(m); L4_Yield(); } L4_Send(main_thread); L4_WaitForever(); }
/* * The lowest priority thread acquires a mutex at initialisation time, releases * it the next it is run in scenario 1. It increments a counter on success. * It sends IPC to medium thread in scenario 2. It increments a counter on success. */ void mixed_pi_low(int argc, char **argv) { L4_ThreadId_t tid; L4_MsgTag_t tag; int counter = 10000; while (!libs_ready) ; while (L4_IsNilThread(medium3_prio_thread)) ; tid = medium3_prio_thread; //printf("Low thread %lx/%lx starts PI test\n", me, pi_main.raw); while (1) { // Initalisation if (scenario1) { //printf("Low thread %lx/%lx acquires mutex for resource\n", me, pi_main.raw); okl4_libmutex_count_lock(resource_mutex); cnt_l++; } //printf("(Initialisation) Low thread %lx/%lx blocks sending to Medium thread\n", me, pi_main.raw); L4_LoadMR(0, 0); L4_Send(tid); //printf("(Initialisation) Low thread %lx/%lx sent to Medium thread\n", me, pi_main.raw); L4_Yield(); /*** Start test ***/ while (stop_spinning) ; wait_a_bit(counter); if (!flag1 && (counter < LIMIT)) { counter *= 2; } if (scenario1) { okl4_libmutex_count_unlock(resource_mutex); } else if (scenario2) { cnt_l++; //printf("Low thread %lx/%lx blocks sending to Medium thread\n", me, pi_main.raw); L4_LoadMR(0, 0); tag = L4_Send(medium2_prio_thread); if (L4_IpcFailed(tag)) cnt_l--; } L4_Yield(); tid = medium2_prio_thread; } }
/* Read data from the shared zone. */ static void zone0140_thread1_routine(void) { okl4_word_t i; okl4_word_t *p; okl4_init_thread(); for (i = 0, p = (okl4_word_t *)zone0140_shared_zone_addr.base; i < zone0140_shared_zone_addr.size / sizeof(okl4_word_t); i++, p++) { while (*p != 0xdeadbee) { L4_Yield(); } } zone0140_child_b_done = 1; while (1) { L4_Yield(); } }
void okl4_libmutex_unlock(okl4_libmutex_t mutex) { assert(okl4_libmutex_am_holder(mutex)); assert(mutex->count == 0); okl4_libmutex_init_holder(mutex); if (mutex->needed) { mutex->needed = 0; L4_Yield(); } }
static void w_thread(void) { static char data[20], res[20] = "Welcome to my lwL4!"; for (;;) L4_Yield(); again: //printstr("w waiting...\n"); L4_Wait(5, data); //printstr("w got data="); //printnstr(data, sizeof(data)); //printstr("\n"); //printstr("w replying...\n"); L4_ReplyWait(5, res, data); goto again; }
static void zone0105_thread_routine(void) { okl4_word_t *p; okl4_init_thread(); p = (okl4_word_t *)zone0105_memsec_addr.base; *p = 0xdeadbee; zone0105_child_done = 1; while (1) { L4_Yield(); } }
thread_ref_t create_thread(pd_ref_t pd, void (*start)(void), int priority, int wait) { uintptr_t stack_base; int r; memsection_ref_t stack; thread_ref_t thread; L4_ThreadId_t tid; thread = pd_create_thread_with_priority(pd, priority, &tid); if (thread == 0 || thread == -1) { printf("Failed to create thread.\n"); return -1; } stack = pd_create_memsection(pd, SIZE, &stack_base); if (stack == 0 || stack == -1) { printf("Failed to create stack.\n"); return -1; } r = pd_attach(pd, stack, L4_ReadWriteOnly); if (r != 0) { printf("Failed to attach stack.\n"); return -1; } thread_start(thread, (uintptr_t)start, stack_base + SIZE); /* * Block on the mutex if waiting. The other thread will unlock just * before faulting. */ if (wait) { L4_Receive(thread_l4tid(thread)); okl4_libmutex_lock(serialise_mutex); okl4_libmutex_unlock(serialise_mutex); /* * Wait a little longer for iguana server to print out the * page fault details. */ for (r = 0; r < 1000; r++) L4_Yield(); } return thread; }
static void worker_a(void *ignore) { ARCH_THREAD_INIT memsection_ref_t m; uintptr_t base; int i; L4_KDB_SetThreadName(thread_l4tid(thread_myself()), "worker_a"); L4_Yield(); for (i = 0; i < 10000; i++) { m = pd_create_memsection(pd_myself(), 1UL << 31, &base); assert(m == 0); } worker_a_done = 1; L4_WaitForever(); }
/* * Intermediate thread 1 has priority in between highest and medium thread. * Intermediate thread 2 has priority in between medium and lowest thread. * They set their flag each time they run during the PI test. */ void mixed_pi_intermediate(int argc, char **argv) { int num = 0; L4_ThreadId_t any_thread; L4_MsgTag_t tag = L4_Niltag; while (!libs_ready) ; if (argc) { num = atoi(argv[0]); } else { printf("(%s Intermediate Thread) Error: Argument(s) missing!\n", test_name); L4_Set_Label(&tag, 0xdead); L4_Set_MsgTag(tag); L4_Call(pi_main); } // Initialisation if (num == 1) { L4_Wait(&any_thread); L4_LoadMR(0, 0); L4_Send(pi_main); } else if (num == 2) { L4_Wait(&any_thread); while (L4_IsNilThread(medium2_prio_thread)) ; L4_LoadMR(0, 0); L4_Send(medium2_prio_thread); } L4_Yield(); // Thread is now ready to set the flag the next time it is run. while(1) { if (num == 1) { flag1 = 1; } else if (num == 2) { flag3 = 1; } L4_LoadMR(0, 0); L4_Send(high_prio_thread); } }
static void utimer(void) { L4_KDB_SetThreadName(sos_my_tid(), "utimer"); L4_Accept(L4_UntypedWordsAcceptor); List *entryq; entryq = list_empty(); for (;;) { L4_Yield(); // Walk the timer list L4_Word_t now = L4_KDB_GetTick(); list_delete(entryq, processExpired, &now); // Wait for a new packet either blocking or non-blocking L4_MsgTag_t tag = L4_Niltag; if (list_null(entryq)) L4_Set_ReceiveBlock(&tag); else L4_Clear_ReceiveBlock(&tag); L4_ThreadId_t wait_tid = L4_nilthread; tag = L4_Ipc(L4_nilthread, L4_anythread, tag, &wait_tid); if (!L4_IpcFailed(tag)) { // Received a time out request queue it L4_Msg_t msg; L4_MsgStore(tag, &msg); // Get the message utimer_entry_t *entry = (utimer_entry_t *) L4_MsgWord(&msg, 0); entry->fTid = wait_tid; list_shift(entryq, entry); } else if (3 == L4_ErrorCode()) // Receive error # 1 continue; // no-partner - non-blocking else assert(!"Unhandled IPC error"); } }
static void worker_b(void *ignore) { ARCH_THREAD_INIT memsection_ref_t m; uintptr_t base; int i; char *p; L4_KDB_SetThreadName(thread_l4tid(thread_myself()), "worker_b"); L4_Yield(); for (i = 0; i < 1000; i++) { m = pd_create_memsection(pd_myself(), MEM_SIZE, &base); assert(m != 0); p = (char *)base; memset(p, '%', 0x10); memsection_delete(m); } worker_b_done = 1; L4_WaitForever(); }