/* * The Philosopher thread tries to take the 2 chopsticks closest to him * (according to its number and the number of each chopstick) in order to eat. */ void philosopher(int argc, char **argv) { int left, right, first, second, mynum = 0; L4_Word_t me = L4_Myself().raw; L4_MsgTag_t tag = L4_Niltag; while (!libs_ready) ; if (argc) { mynum = atoi(argv[0]); } else { printf("(Philosopher 0x%lx) Error: Argument(s) missing!\n", me); L4_Set_MsgTag(L4_Niltag); L4_Send(dp_main); L4_Set_Label(&tag, 0xdead); L4_Set_MsgTag(tag); L4_Call(dp_main); } // Have to take chopsticks according to "my number" left = mynum; if (chopstick[mynum + 1]) { right = mynum + 1; } else { right = 0; } // This should allow to avoid deadlock when trying to grab the chopsticks. first = left < right ? left : right; second = first == left ? right : left; //printf("Philosopher %d: %lx, managed by %lx\n", mynum, me, dp_main.raw); //printf("Philosopher %d: chopsticks %d and %d\n", mynum, left, right); L4_Set_MsgTag(L4_Niltag); L4_Send(dp_main); while (meal_served == 0) ; okl4_libmutex_count_lock(chopstick[first]); //printf("Philosopher %d/%lx holds chopstick %d/%lx\n", mynum, me, first, chopstick[first]); okl4_libmutex_count_lock(chopstick[second]); //printf("Philosopher %d/%lx holds chopstick %d/%lx\n", mynum, me, second, chopstick[second]); //printf("Philosopher %d/%lx is eating\n", mynum, me); okl4_libmutex_count_unlock(chopstick[second]); okl4_libmutex_count_unlock(chopstick[first]); //printf("Philosopher %d: %lx/%lx finished eating\n", mynum, me, dp_main.raw); L4_Set_Label(&tag, 0xfed); L4_Set_MsgTag(tag); L4_Send(dp_main); L4_Send(L4_Myself()); }
static void ping_thread_simulated (void) { volatile L4_Word_t x; /* Wait for pong thread to come up */ L4_Msg_t msg; L4_MsgTag_t tag; for (int i=0; i < num_iterations; i++) { L4_Fpage_t ppage = L4_Fpage((L4_Word_t)&fault_area[i*1024], 4096); L4_Set_Rights(&ppage, L4_FullyAccessible); /* accept fpages */ L4_Accept(L4_UntypedWordsAcceptor); /* send it to our pager */ L4_MsgClear(&msg); L4_MsgAppendWord(&msg, (L4_Word_t) ppage.raw); L4_MsgAppendWord(&msg, (L4_Word_t) 0); L4_Set_Label(&msg.tag, L4_PAGEFAULT); L4_MsgLoad(&msg); /* make the call */ tag = L4_Call(pager_tid); x = fault_area[i*1024]; } /* Tell master that we're finished */ L4_Set_MsgTag (L4_Niltag); L4_Send (master_tid); for (;;) L4_WaitForever(); /* NOTREACHED */ }
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) { } }
void sys$sigma0_map_fpage(L4_Fpage_t virt_page, L4_Fpage_t phys_page, unsigned int priv) { L4_ThreadId_t tid; L4_MsgTag_t tag; L4_Msg_t msg; L4_MapItem_t map; // Find Pager's ID tid = L4_Pager(); L4_Set_Rights(&phys_page, priv); L4_Accept(L4_MapGrantItems(virt_page)); L4_MsgClear(&msg); L4_MsgAppendWord(&msg, (L4_Word_t) phys_page.raw); L4_MsgAppendWord(&msg, (L4_Word_t) 0); L4_Set_Label(&msg.tag, SIGMA0_REQUEST_LABEL); L4_MsgLoad(&msg); tag = L4_Call(tid); PANIC(L4_IpcFailed(tag), notice(IPC_F_FAILED "IPC failed (error %ld: %s)\n", L4_ErrorCode(), L4_ErrorCode_String(L4_ErrorCode()))); L4_MsgStore(tag, &msg); L4_MsgGetMapItem(&msg, 0, &map); if (dbg$virtual_memory == 1) { if (map.X.snd_fpage.raw == L4_Nilpage.raw) { notice(MEM_I_REJMAP "rejecting mapping\n"); notice(MEM_I_REJMAP "virtual $%016lX - $%016lX\n", L4_Address(virt_page), L4_Address(virt_page) + (L4_Size(virt_page) - 1)); notice(MEM_I_REJMAP "physical $%016lX - $%016lX\n", L4_Address(phys_page), L4_Address(phys_page) + (L4_Size(phys_page) - 1)); } else { notice(MEM_I_ACCMAP "accepting mapping\n"); notice(MEM_I_ACCMAP "virtual $%016lX - $%016lX\n", L4_Address(virt_page), L4_Address(virt_page) + (L4_Size(virt_page) - 1)); notice(MEM_I_ACCMAP "physical $%016lX - $%016lX\n", L4_Address(phys_page), L4_Address(phys_page) + (L4_Size(phys_page) - 1)); } } return; }
static void ipc_test(struct bench_test *test, int args[]) { L4_ThreadId_t tid; /* Send "begin" message to notify pager to startup both threads */ L4_MsgTag_t tag = L4_Niltag; L4_Set_Label(&tag, START_LABEL); L4_Set_MsgTag(tag); L4_Send(pager_tid); L4_Wait(&tid); }
END_TEST /* \begin{test}{MUTEX0402} \TestDescription{Verify L4_TryLock on a locked mutex} \TestFunctionalityTested{\Func{L4\_TryLock}} \TestImplementationProcess{ \begin{enumerate} \item Call \Func{L4\_CreateMutex} and check it returns successfully. \item Call \Func{L4\_Lock} and check it returns successfully. \item Create a thread. \item Thread calls L4\_TryLock on the held mutex. \item Check it returns an error. \end{enumerate} } \TestPassStatus{pass} \TestImplementationStatus{Implemented} \TestRegressionStatus{In regression test suite} \end{test} */ START_TEST(MUTEX0402) { L4_ThreadId_t try_lock_thread; L4_MsgTag_t tag; L4_Word_t res; res = okl4_kmutexid_allocany(mutexid_pool, &m); fail_unless(res == OKL4_OK, "Failed to allocate any mutex id."); res = L4_CreateMutex(m); fail_unless(res == 1, "L4_CreateMutex() failed"); res = L4_Lock(m); fail_unless(res == 1, "L4_Lock() failed"); try_lock_thread = createThread(lock_mutex_thread); L4_Set_Label(&tag, 0xb); L4_Set_MsgTag(tag); L4_Call(try_lock_thread); L4_Unlock(m); L4_DeleteMutex(m); okl4_kmutexid_free(mutexid_pool, m); }
/* * 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); } }
END_TEST /* \begin{test}{MUTEX0301} \TestDescription{Verify unprivileged thread can not delete mutex} \TestFunctionalityTested{\Func{L4\_DeleteMutex}} \TestImplementationProcess{ \begin{enumerate} \item Create a mutex. \item Create unprivileged thread. \item Unprivileged thread call \Func{L4\_DeleteMutex} with the created mutex. \item Checks \Func{L4\_DeleteMutex} returns an error. \end{enumerate} } \TestPassStatus{pass} \TestImplementationStatus{Implemented} \TestRegressionStatus{In regression test suite} \end{test} */ START_TEST(MUTEX0301) { L4_ThreadId_t unpriv_thread; L4_MsgTag_t tag; L4_Word_t res; res = okl4_kmutexid_allocany(mutexid_pool, &m); fail_unless(res == OKL4_OK, "Failed to allocate any mutex id."); res = L4_CreateMutex(m); fail_unless(res == 1, "L4_CreateMutex() failed"); unpriv_thread = createThreadInSpace(L4_nilspace, create_delete_mutex_thread); L4_Set_Label(&tag, 0xd); L4_Set_MsgTag(tag); L4_Call(unpriv_thread); res = L4_DeleteMutex(m); fail_unless(res == 1, "L4_DeleteMutex() failed"); okl4_kmutexid_free(mutexid_pool, m); deleteThread(unpriv_thread); }
int l4e_sigma0_map_fpage(L4_Fpage_t virt_page, L4_Fpage_t phys_page) { /* * XXX: These two special cases are workarounds for broken superpage * support in pistachio. On ARM, 1M superpages are disabled by * pistachio to reduce the size of the mapping database, however due to * bugs in the mapping code, any mappings >= 1M get converted into 4K * mappings (rather than 64K). For MIPS, the tlb refill code assumes * only 4K mappings are used, even the the pagetable building code will * use superpages where possible. -- alexw */ #if defined(ARCH_ARM) uintptr_t virt_base = L4_Address(virt_page); uintptr_t phys_base = L4_Address(phys_page); uintptr_t offset = 0; uintptr_t step = L4_Size(virt_page) > 0x10000 ? 0x10000 : L4_Size(virt_page); uintptr_t limit = L4_Size(virt_page) - 1; for (virt_page = L4_Fpage(virt_base + offset, step), phys_page = L4_Fpage(phys_base + offset, step); offset < limit; offset += step, virt_page = L4_Fpage(virt_base + offset, step), phys_page = L4_Fpage(phys_base + offset, step)) #elif defined(ARCH_MIPS64) uintptr_t virt_base = L4_Address(virt_page); uintptr_t phys_base = L4_Address(phys_page); uintptr_t offset = 0; uintptr_t step = 0x1000; uintptr_t limit = L4_Size(virt_page) - 1; for (virt_page = L4_Fpage(virt_base + offset, step), phys_page = L4_Fpage(phys_base + offset, step); offset < limit; offset += step, virt_page = L4_Fpage(virt_base + offset, step), phys_page = L4_Fpage(phys_base + offset, step)) #endif { L4_ThreadId_t tid; L4_MsgTag_t tag; L4_Msg_t msg; L4_MapItem_t map; /* * find our pager's ID */ tid = L4_Pager(); L4_Set_Rights(&phys_page, L4_FullyAccessible); /* accept fpages */ L4_Accept(L4_MapGrantItems(virt_page)); /* send it to our pager */ L4_MsgClear(&msg); L4_MsgAppendWord(&msg, (L4_Word_t) phys_page.raw); L4_MsgAppendWord(&msg, (L4_Word_t) 0); L4_Set_Label(&msg.tag, SIGMA0_REQUEST_LABEL); L4_MsgLoad(&msg); /* make the call */ tag = L4_Call(tid); /* check for an error */ if (L4_IpcFailed(tag)) { return 2; } L4_MsgStore(tag, &msg); L4_MsgGetMapItem(&msg, 0, &map); /* * rejected mapping? */ if (map.X.snd_fpage.raw == L4_Nilpage.raw) { return 1; } } return 0; }