⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 l4thread.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * l4thread.c * Internal threading backend of Kaffe for DROPS *  * Copyright (c) 2004, 2005 *	TU Dresden, Operating System Group.  All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. * * written by Alexander Boettcher <ab764283@os.inf.tu-dresden.de> */#include <l4/sys/rt_sched.h> /* realtime extension */#include <l4/semaphore/semaphore.h>#include <l4/log/l4log.h>#include <l4/util/macros.h> /* l4util_idfmt, l4util_idstr */#include <l4/util/rdtsc.h> /* l4_rdtsc */#include "debug.h"#include "jthread.h"#include "l4thread.h"#include "gc.h"#ifdef REALTIME_EXTENSION#include <l4/dm_generic/types.h>#include <l4/dm_mem/dm_mem.h>#include <l4/dm_phys/dm_phys.h>#include <l4/sys/rt_sched.h>#include <l4/util/kip.h>#include "realtimethread.h"#endif__leaflet leaflet = { 0, 0,                      #ifdef REALTIME_EXTENSION                      0, /* noheapthreadcount */                      #endif	                      -1,                       L4SEMAPHORE_INITIALIZER(1),                      L4SEMAPHORE_INITIALIZER(1),                      L4_INVALID_ID,                       0, 0, 0, 0x05#ifdef REALTIME_EXTENSION                     ,L4_INVALID_ID                     ,NULL //handler to call if overrun situation                     ,0    //cost(wcet) overruns                     ,0    //deadline overruns#endif                    };#ifdef REALTIME_EXTENSIONstatic l4_uint32_t  area;#define L4KAFFE_PERIODIC 0x2U#endifvolatile jthread_t            live        = 0;static volatile unsigned long sleepcount  = 0;void _l4threads_suspendall(void);void _l4threads_resumepoint(void);void _l4threads_suspendall_c(void) NONRETURNING;void _l4threads_suspendall_c(void){  l4_msgdope_t result;  if (sleepcount == leaflet.threadCount)  {    {	  l4_ipc_send(leaflet.gc,              L4_IPC_SHORT_MSG,              0, //l4_umword_t  	  snd_dword0,              0, //l4_umword_t  	  snd_dword1,	      L4_IPC_NEVER,              &result);    } while (L4_IPC_ERROR(result) == L4_IPC_SECANCELED ||             L4_IPC_ERROR(result) == L4_IPC_SEABORTED);  }  while (1) l4thread_sleep_forever();} asm("_l4threads_suspendall:       \n\t"     "pushl $0x0                  \n\t" /*space for return address*/     "pushfl                      \n\t" /*eflags 32 bit*/     "pushal                      \n\t" /*eax,ecx,edx,ebx,esp,ebp,esi,edi*/     "incl sleepcount             \n\t"     "jmp _l4threads_suspendall_c \n\t"     "_l4threads_resumepoint:     \n\t" // resume here, with ex_regs     "popal                       \n\t"     "popfl                       \n\t"     "retl");/* * prevent all other threads from running */void jthread_suspendall(void){ l4_umword_t   old_eflags; l4_umword_t   dummy; l4_msgdope_t  result; l4_threadid_t src; l4_threadid_t preempter  = L4_INVALID_ID; l4_threadid_t pager      = L4_INVALID_ID; jthread_t     current    = live; l4thread_t    myself     = l4thread_myself(); leaflet.gc = l4_myself();// LOG("suspendall"); /*  * ex-regs all threads and save their state  */ while (current)  {    /**     * NoHeapRealtimeThreads will not be stopped     */    if (current->daemon==0 &&        #ifdef REALTIME_EXTENSION        current->threadtype != THREADTYPE_NOHEAPREAL &&        #endif        !l4thread_equal(current->l4thread,myself))    {       l4_thread_ex_regs(l4thread_l4_id(current->l4thread),                        (unsigned long)_l4threads_suspendall,                        (l4_umword_t)-1,                        &preempter,                        &pager,                        &old_eflags,&current->eip,&current->esp);    }    current = current -> next;  } /*  * Waiting for the notification IPC of the last stopped thread  */ {   l4_ipc_wait(&src, L4_IPC_SHORT_MSG, &dummy, &dummy,                           L4_IPC_NEVER,&result); }while(!l4_tasknum_equal(leaflet.gc, src) ||         L4_IPC_ERROR(result) == L4_IPC_RECANCELED ||         L4_IPC_ERROR(result) == L4_IPC_REABORTED);// LOG("suspendall-complete");}/* * restore threads */voidjthread_unsuspendall(void){ volatile unsigned long int * ret_addr; l4_umword_t   old_eflags,dummy; l4_threadid_t preempter = L4_INVALID_ID; l4_threadid_t pager     = L4_INVALID_ID; l4thread_t    myself    = l4thread_myself(); jthread_t     current   = live; while (current) {   /**    * NoHeapRealtimeThreads are never stopped and therefore they are not resumed    */   if (current->daemon==0 &&       #ifdef REALTIME_EXTENSION       current->threadtype != THREADTYPE_NOHEAPREAL &&       #endif       !l4thread_equal(current->l4thread,myself))     {       current->esp -= 0x04;        /* stack address for the return address*/       ret_addr      = (unsigned long int *)current->esp;       /* replace place holder with the eip*/       *ret_addr     = current->eip;       l4_thread_ex_regs(l4thread_l4_id(current->l4thread),                         (unsigned long)_l4threads_resumepoint,                         current->esp-0x24,                         &preempter, &pager,                         &old_eflags, &dummy, &dummy);  }  current = current -> next; } sleepcount = 0;}bool jthread_detach_current_thread (void){ jthread_t current= jthread_current(); printf("detach ....\n"); KGC_rmRef((Collector *)leaflet.threadCollector, current); return true;}int jthread_extract_stack(jthread_t jtid, void **from, unsigned *len){  l4_umword_t esp,eip,eflags;  l4_addr_t low,high;  l4_threadid_t pager     = L4_INVALID_ID;  l4_threadid_t preempter = L4_INVALID_ID;  if (l4thread_get_stack(jtid->l4thread,&low,&high)){    assert(!"l4thread_get_stack() problem!");  } else {    l4_thread_ex_regs_flags(l4thread_l4_id(jtid->l4thread),                            (l4_umword_t)-1, (l4_umword_t)-1,                            &preempter, &pager, &eflags, &eip, &esp,                            L4_THREAD_EX_REGS_NO_CANCEL);    *from = (void *)esp;    *len  = high - esp;  }    return (1);}/* * free a thread context */void    jthread_destroy(jthread_t tid UNUSED){//  leaflet->memCollector.deallocator(tid);}/* * iterate over all live threads */voidjthread_walkLiveThreads (void(*func)(jthread_t,void*), void *priv){  jthread_t next    = live;  while (next)  {     #ifdef REALTIME_EXTENSION    if (next->threadtype != THREADTYPE_NOHEAPREAL)    #endif      func(next,priv);    next = next->next;  }}voidjthread_walkLiveThreads_r(void (*func)(jthread_t, void*), void *priv){  jthread_walkLiveThreads(func, priv);}#ifdef REALTIME_EXTENSION/* * set a function to be run when deadline, period or wcet is missed/overruned */void jthread_misshandler(void (*f)(jthread_t, unsigned), unsigned costoverrun,                         unsigned deadlineoverrun){  leaflet.misshandler  = f;  leaflet.wcetover     = costoverrun;  leaflet.deadover     = deadlineoverrun;}/*  * Handling of preemption IPC and notification of the Kaffe VM */static void jthread_preemption(l4_threadid_t thread, unsigned type){  jthread_t data = (jthread_t)l4thread_data_get(l4thread_id(thread), leaflet.datakey);  if (leaflet.misshandler != NULL && data != NULL)    leaflet.misshandler(data, type);  else    LOG("drop one preemption IPC"); } /** * preempter thread for each Java thread */static void NONRETURNING jthread_preempter(void * obj){  l4_rt_preemption_t dw;  l4_threadid_t src;  l4_msgdope_t result;  int error;  l4_threadid_t self = l4_myself();  l4thread_started(obj);  while (1)  {      /* wait for request */      error = l4_ipc_wait(&src,                          L4_IPC_SHORT_MSG,                          &dw.lh.low,                          &dw.lh.high,                          L4_IPC_NEVER,                          &result);      if (error == 0 && leaflet.misshandler != NULL) {        if (l4_tasknum_equal(self, src)) {          switch(dw.p.type){            case L4_RT_PREEMPT_TIMESLICE://              LOG("TimeSlice "l4util_idfmt"/%d", l4util_idstr(src), dw.p.id);              jthread_preemption(src, leaflet.wcetover);              break;            case L4_RT_PREEMPT_DEADLINE://              LOG("DeadLine "l4util_idfmt, l4util_idstr(src));              jthread_preemption(src, leaflet.deadover);              break;            default:              LOG("unknown preemption");          }        }      }  }}#endif/* * Initialize the threading system. * */jthread_t jthread_init(int pre UNUSED,	int maxpr,  int minpr UNUSED,        Collector *threadCollector,	void (*_onthreadexit)(void*),	void (*_onstop)(void) UNUSED,	void (*_ondeadlock)(void) UNUSED){        volatile jthread_t athread;        #ifdef REALTIME_EXTENSION        l4_threadid_t pager      = L4_INVALID_ID;        l4_threadid_t preempter;        l4_umword_t   dummy;        /* start the preempter thread */        leaflet.preempter = l4thread_l4_id(          l4thread_create_long(L4THREAD_INVALID_ID,	                       jthread_preempter,		               0,			       L4THREAD_INVALID_SP,			       L4THREAD_DEFAULT_SIZE, //threadStackSize,			       leaflet.startPrio + maxpr,			       0,			       L4THREAD_CREATE_SYNC));          #endif        leaflet.threadCollector   = threadCollector;        leaflet.onthreadexit      = _onthreadexit; /* function to call, if a thread dies*/        leaflet.daemonCount       = 0; /* count of all daemon threads */        leaflet.threadCount       = 1; /* count of all threads */        #ifdef REALTIME_EXTENSION        leaflet.noheapthreadCount = 0; /* count of all NoHeapRealtime threads */        #endif        athread = KGC_malloc(threadCollector, sizeof (*athread), KGC_ALLOC_THREADCTX);        KGC_addRef(threadCollector, athread);        athread->l4thread     = l4thread_myself();        athread->prev         = NULL;        athread->next         = NULL;        athread->daemon       = 0; // no daemon thread	athread->interrupting = 0;        #ifdef REALTIME_EXTENSION        athread->status       = 0;        #endif	assert(live == NULL);        live = athread;        /* allocate data key */        leaflet.datakey = l4thread_data_allocate_key();        if (leaflet.datakey < 0) assert(!"l4thread_data_allocate_key failed");        if (l4thread_data_set_current(leaflet.datakey,athread) < 0) assert(!"l4thread_data_set_current failed");        #ifdef REALTIME_EXTENSION        /* set the preempter for the current thread */        preempter = leaflet.preempter;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -