📄 l4thread.c
字号:
l4_thread_ex_regs(l4_myself(), (l4_umword_t)-1, (l4_umword_t)-1, &preempter, &pager, &dummy, &dummy, &dummy); #endif return athread;}/** * All new Threads run this function on start. * It prevents the VM to call jthread_current() and other functions, * before jthread_create() has queued the new thread. */static void start_kaffe_l4thread(void *data UNUSED){ jthread_t current; l4semaphore_down(&leaflet.threadLock); // prevent the VM to call jthread_current(), when creating a new thread l4semaphore_up(&leaflet.threadLock); /* register thread for handling ArithmeticException and Null Object accesses */ drops_registerForExceptions(); current = jthread_current(); /* call start function provided by the JVM */ current->func(current->data.jlThread);}/* * Create an jthread context to go with the initial thread in the system. * (The initial thread is created in jthread_init, above). */jthread_tjthread_createfirst(size_t mainThreadStackSize UNUSED, unsigned int prio, void* jlThread){ volatile jthread_t current = jthread_current(); current->data.jlThread = jlThread; //set priority assert(l4thread_set_prio(current->l4thread, (signed)prio + leaflet.startPrio)==0); return current;}/* * set a function to be run when all non-daemon threads have exited */voidjthread_atexit(void (*f)(void)){ leaflet.runatexit = f;}/* * create a new thread */jthread_tjthread_create(unsigned int pri, void (*func)(void *), int isDaemon, void *jlThread, size_t threadStackSize UNUSED){ volatile jthread_t next; volatile jthread_t athread = KGC_malloc((Collector *)leaflet.threadCollector, sizeof (*athread), KGC_ALLOC_THREADCTX); KGC_addRef((Collector *)leaflet.threadCollector, athread); athread->next = 0; athread->data.jlThread = jlThread; athread->daemon = isDaemon; athread->func = func; athread->interrupting = 0; #ifdef REALTIME_EXTENSION athread->status = 0; athread->threadtype = THREADTYPE_NORMAL; // normal thread #endif l4semaphore_down(&leaflet.threadLock); athread->l4thread = l4thread_create_long(L4THREAD_INVALID_ID, start_kaffe_l4thread, 0, L4THREAD_INVALID_SP, L4THREAD_DEFAULT_SIZE, //threadStackSize, leaflet.startPrio+(signed)pri, 0, L4THREAD_CREATE_ASYNC); if (isDaemon) leaflet.daemonCount ++; else leaflet.threadCount ++; next = live; while (next->next) next = next->next; athread->prev = next; next->next = athread; if (l4thread_data_set(athread->l4thread,leaflet.datakey,athread) < 0) assert(!"l4thread_data_set_current failed"); l4semaphore_up(&leaflet.threadLock);// LOG("start thread "l4util_idfmt" %p", l4util_idstr(l4thread_l4_id(athread->l4thread)),&athread->data.sem); return athread;}#ifdef REALTIME_EXTENSION/* * create a new realtime thread */jthread_tjthread_createRT(unsigned int pri, void (*func)(void *), int isDaemon, void *jlThread, size_t threadStackSize UNUSED, int threadtype){ l4_threadid_t pager = L4_INVALID_ID; l4_threadid_t preempter; l4_umword_t dummy; volatile jthread_t next; volatile jthread_t athread = KGC_malloc((Collector *)leaflet.threadCollector, sizeof (*athread), KGC_ALLOC_THREADCTX); KGC_addRef((Collector *)leaflet.threadCollector, athread); athread->next = 0; athread->data.jlThread = jlThread; athread->daemon = isDaemon; athread->func = func; athread->threadtype = threadtype; athread->status = 0; athread->interrupting = 0; l4semaphore_down(&leaflet.threadLock); athread->l4thread = l4thread_create_long(L4THREAD_INVALID_ID, start_kaffe_l4thread, 0, L4THREAD_INVALID_SP, L4THREAD_DEFAULT_SIZE, //threadStackSize, leaflet.startPrio+(signed)pri, 0, L4THREAD_CREATE_ASYNC); assert(!(athread->threadtype == THREADTYPE_NOHEAPREAL && isDaemon)); if (athread->threadtype == THREADTYPE_NOHEAPREAL) leaflet.noheapthreadCount ++; else if (isDaemon) leaflet.daemonCount ++; else leaflet.threadCount ++; next = live; while (next->next) next = next->next; athread->prev = next; next->next = athread; if (l4thread_data_set(athread->l4thread,leaflet.datakey,athread) < 0) assert(!"l4thread_data_set_current failed"); /* set the preempter for the current thread */ preempter = leaflet.preempter; l4_thread_ex_regs_flags(l4thread_l4_id(athread->l4thread), (l4_umword_t)-1, (l4_umword_t)-1, &preempter, &pager, &dummy, &dummy, &dummy, L4_THREAD_EX_REGS_NO_CANCEL); l4semaphore_up(&leaflet.threadLock); return athread;}#endif/* * Java thread exit. */voidjthread_exit(void){ int last = 0; jthread_t current = jthread_current(); if (leaflet.onthreadexit) (*leaflet.onthreadexit)(current->data.jlThread); l4semaphore_down(&leaflet.threadLock); #ifdef REALTIME_EXTENSION if (current->threadtype == THREADTYPE_NOHEAPREAL) leaflet.noheapthreadCount --; else #endif if (current->daemon) leaflet.daemonCount --; else leaflet.threadCount --; if (leaflet.threadCount == 0 #ifdef REALTIME_EXTENSION && leaflet.noheapthreadCount == 0 #endif && !current->daemon) //only daemon threads left, shut down the VM last = 1; if (current->prev == 0){ assert(live == current); if (current->next == 0) live = 0; //May or can it ever happen ? else { live = current->next; live->prev = 0; } }else{ current->prev->next = current->next; if (current->next){ current->next->prev = current->prev; } } l4semaphore_up(&leaflet.threadLock); #ifdef REALTIME_EXTENSION if (current->status & L4KAFFE_PERIODIC) jthread_stopPeriodic(); #endif if (last){ //only daemon threads left, shut down the VM leaflet.runatexit(); exit(0); } // LOG("start thread "l4util_idfmt, l4util_idstr(l4thread_l4_id(current->l4thread))); l4thread_sleep_forever();// l4thread_exit(); while (1) assert(!"This better not return");}#ifdef REALTIME_EXTENSIONvoid * jthread_reservearea(l4_size_t size){ l4_addr_t addr = 0; int err; err = l4rm_area_reserve(size, L4RM_LOG2_ALIGNED, &addr, &area ); assert( err == 0); return (void *)addr;}void * jthread_createarea(l4_size_t size){ l4dm_dataspace_t ds = L4DM_INVALID_DATASPACE_INITIALIZER; int err; void *addr1 = 0; err = l4dm_mem_open(L4DM_DEFAULT_DSM, size, 0, //alignment 0, //flags "test1", &ds); assert( err == 0); err = l4rm_area_attach (&ds, area, size, 0, L4DM_RW + L4RM_MAP, &addr1); assert( err == 0); return addr1;}#endif/* * Check whether a thread is alive. */intjthread_alive(jthread_t tid UNUSED){ printf("jthread_alive todo\n"); return 0;}/* * Stop a thread */voidjthread_stop(jthread_t jtid UNUSED){ printf("jthread_stop todo\n");}/* * sleep for time milliseconds */ voidjthread_sleep(jlong jtime UNUSED){ printf("jthread_sleep todo\n");}/* * Print info about a given jthread to stderr */void jthread_dumpthreadinfo(jthread_t tid UNUSED){ printf("jthread_dumpthreadinfo todo\n");}intjthread_frames(jthread_t thrd UNUSED){ printf("jthread_frames\n"); return 0;}void jthread_set_blocking (int fd UNUSED, int blocking UNUSED){ printf("todo -jthread_set_blocking \n");}#ifdef REALTIME_EXTENSIONjint jthread_startPeriodic(jlong start_ms, jint start_ns, jlong period_ms, jint period_ns, jlong wcet_ms, jint wcet_ns){ // basis us - transform ms and ns values int timeslice; // = wcet_ms * 1000;// + wcet_ns / 1000; l4_kernel_clock_t task_period;// = period_ms * 1000;// + period_ns / 1000; l4_uint64_t current; l4_threadid_t dest = l4_myself(); int prio = l4thread_get_prio(l4thread_myself()); jthread_t thread = jthread_current(); l4_kernel_info_t * kip; // basis us - transform ms and ns values timeslice = wcet_ms * 1000 + wcet_ns / 1000; task_period = period_ms * 1000 + period_ns / 1000; thread->status = thread->status | L4KAFFE_PERIODIC; LOG("s: %lld %ld p: %lld %ld wcet: %lld %ld", (long long)start_ms, (long)start_ns, (long long)period_ms, (long)period_ns, (long long)wcet_ms, (long)wcet_ns); if (!l4_rt_add_timeslice(dest, prio, timeslice)) { l4_rt_set_period(dest, task_period); kip = l4util_kip_map(); assert(kip != NULL); current = kip->clock + start_ms * 1000 + start_ns / 1000; if (l4_rt_begin_strictly_periodic(dest, current)) return 1; //error if (!l4_rt_next_period()) return 0; //ok } return 1; //error}void jthread_stopPeriodic(){ jthread_t thread = jthread_current(); l4_threadid_t dest = l4_myself(); l4_rt_end_periodic(dest); thread->status = thread->status & ~L4KAFFE_PERIODIC;}void jthread_nextPeriod(){ assert(l4_rt_next_period() == 0);}#endif //REALTIME_EXTENSION
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -