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

📄 thread.c

📁 Nucleus_2_kvm_Hello 是kvm移植到Nucleus系统的源代码。。。好东西啊
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (c) 1998-2002 Sun Microsystems, Inc. All Rights Reserved. * * This software is the confidential and proprietary information of Sun * Microsystems, Inc. ("Confidential Information").  You shall not * disclose such Confidential Information and shall use it only in * accordance with the terms of the license agreement you entered into * with Sun. * * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING * THIS SOFTWARE OR ITS DERIVATIVES. * * Use is subject to license terms. *//*========================================================================= * SYSTEM:    KVM * SUBSYSTEM: Thread (concurrency) management * FILE:      thread.c * OVERVIEW:  This file defines the structures and operations *            that are needed for Java-style multithreading. * AUTHOR:    Antero Taivalsaari, Sun Labs *            Edited by Doug Simon 11/1998 *            Edited by Nik Shaylor 09/1999 to allow asynchronous I/O *            Frank Yellin (new monitors), Bill Pittore (debugging) *=======================================================================*//*========================================================================= * COMMENTS: * Read the description of thread and monitor structures in thread.h *=======================================================================*//*========================================================================= * Local include files *=======================================================================*/#include "global.h"#include "execute.h"/*========================================================================= * Global variables needed for multitasking *=======================================================================*/THREAD CurrentThread;   /* Current thread pointer */THREAD MainThread;      /* Global so debugger code can create a name */THREAD AllThreads;      /* List of all threads */THREAD RunnableThreads;  /* Runnable thread list *//* NOTE: * RunnableThreads is a circular queue of threads.  RunnableThreads * is either NULL or points to the >>last<< element of the list. * This makes it easier to add to either end of the list * */int AliveThreadCount;   /* Number of alive threads in AllThreads.  This count                         * does >>not<< include threads that haven't yet been                         * started */int Timeslice;          /* Time slice counter for multitasking *//*========================================================================= * Static declarations needed for this file *=======================================================================*/#define QUEUE_ADDED TRUE#define QUEUE_REMOVED FALSE#if INCLUDEDEBUGCODEstatic voidTraceMonitor(THREAD thread, MONITOR monitor, THREAD *queue, bool_t added);static void TraceThread(THREAD thread, char *what);#endif/* Internal monitor operations */static void addMonitorWait(MONITOR monitor, THREAD thread);static void addCondvarWait(MONITOR monitor, THREAD thread);static void removeMonitorWait(MONITOR monitor);static void removeCondvarWait(MONITOR monitor, bool_t notifyAll);static void removePendingAlarm(THREAD thread);/* Internal queue manipulation operations */typedef enum { AT_START, AT_END } queueWhere;static void   addThreadToQueue(THREAD *queue, THREAD, queueWhere where);static THREAD removeQueueStart(THREAD *queue);static bool_t removeFromQueue(THREAD *queue, THREAD waiter);static int    queueLength(THREAD queue);static void   monitorWaitAlarm(THREAD thread);/*========================================================================= * Global multitasking operations *=======================================================================*//*========================================================================= * FUNCTION:      storeExecutionEnvironment() *                loadExecutionEnvironment() * TYPE:          private operations * OVERVIEW:      These functions are used for storing and restoring *                virtual machine registers upon task switching. * INTERFACE: *   parameters:  thread pointer *   returns:     <nothing> *=======================================================================*/void storeExecutionEnvironment(THREAD thisThread){    /* Save the current thread execution environment     * (virtual machine registers) to the thread structure.     */    thisThread->fpStore = getFP();    thisThread->spStore = getSP();    thisThread->ipStore = getIP();}void loadExecutionEnvironment(THREAD thisThread){    /*  Restore the thread execution environment */    /*  (VM registers) from the thread structure */    setFP(thisThread->fpStore);    setLP(FRAMELOCALS(getFP()));    setCP(getFP()->thisMethod->ofClass->constPool);    setSP(thisThread->spStore);    setIP(thisThread->ipStore);}/*========================================================================= * FUNCTION:      SwitchThread() * TYPE:          public global operations * OVERVIEW:      Fundamental task switching operation: *                switches to the next thread to be executed. * INTERFACE: *   parameters:  <none> *   returns:     Boolean showing if there is now a current thread * * NOTE: * * On entry to this routine there are three states the current thread * pointer can be in: * * CurrentThread == NIL * *     There is no current thread because suspendThread() was called. * * CurrentThread != NIL && CurrentThread->state == THREAD_ACTIVE * *     This is the normal case when the current thread's timeslice has *     run out. * * CurrentThread != NIL && CurrentThread->state != THREAD_ACTIVE * *     This is an atypical condition when suspendThread() was called *     while we were in supervisor mode. In this case the routine *     must spin until CurrentThread->state == THREAD_ACTIVE. * *=======================================================================*/bool_t SwitchThread(void){    THREAD threadToAdd = NIL;    if (CurrentThread != NIL) {#if ASYNCHRONOUS_NATIVE_FUNCTIONS        if (CurrentThread->pendingException != NIL) {            fatalError(KVM_MSG_BAD_PENDING_EXCEPTION);        }#endif        if (CurrentThread->state == THREAD_ACTIVE) {            /* If there is only one thread, or we can't switch threads then               just return */            if (RunnableThreads == NULL) {                /* Nothing else to run */                Timeslice = CurrentThread->timeslice;                return TRUE;            } else {                /* Save the VM registers.  Indicate that this thread is to */                /* to be added to the dormant thread queue */                storeExecutionEnvironment(CurrentThread);                threadToAdd = CurrentThread;                CurrentThread = NIL;            }        } else {            fatalError(KVM_MSG_ATTEMPTING_TO_SWITCH_TO_INACTIVE_THREAD);        }    }    /*  Try and find a thread */    CurrentThread = removeQueueStart(&RunnableThreads);    /* If there was a thread to add then do so */    if (threadToAdd != NIL) {        addThreadToQueue(&RunnableThreads, threadToAdd, AT_END);    }    /* If nothing can run then return FALSE */    if (CurrentThread == NIL) {        return FALSE;    }#if ENABLEPROFILING    ThreadSwitchCounter++;#endif    /*  Load the VM registers of the new thread */    loadExecutionEnvironment(CurrentThread);#if INCLUDEDEBUGCODE    if (tracethreading) {        /* Diagnostics */        TraceThread(CurrentThread, "Switching to this thread");    }#endif    /*  Load new time slice */    Timeslice = CurrentThread->timeslice;#if ASYNCHRONOUS_NATIVE_FUNCTIONS    if (CurrentThread->pendingException != NIL) {        char *pending = CurrentThread->pendingException;        CurrentThread->pendingException = NIL;        raiseException(pending);    }#endif    return TRUE;}/*========================================================================= * Public operations on thread instances *=======================================================================*//*========================================================================= * Constructors and destructors *=======================================================================*//*========================================================================= * FUNCTION:      BuildThread() * TYPE:          public global operation * OVERVIEW:      Build a new VM-level thread by instantiating and *                initializing the necessary structures. * INTERFACE: *   returns:     a new thread instance * NOTE:          The created thread is an internal structure that does *                not map one-to-one with Java class 'Thread.class'. *                One-to-one mapping is implemented by structure *                JAVATHREAD. *=======================================================================*/static THREAD BuildThread(JAVATHREAD_HANDLE javaThreadH){    THREAD newThread;    JAVATHREAD javaThread;    START_TEMPORARY_ROOTS        DECLARE_TEMPORARY_ROOT(THREAD, newThreadX,                               (THREAD)callocObject(SIZEOF_THREAD, GCT_THREAD));        STACK newStack = (STACK)callocObject(sizeof(struct stackStruct)                                                     / CELL, GCT_EXECSTACK);        /* newStack->next = NULL;  Already zero from calloc */        newStack->size = STACKCHUNKSIZE;        newThreadX->stack = newStack;#if INCLUDEDEBUGCODE        if (tracethreading) {            TraceThread(newThreadX, "Created");        }        if (tracestackchunks) {            fprintf(stdout,                "Created a new stack (thread: %lx, first chunk: %lx, chunk size: %ld\n",                (long)newThreadX, (long)newStack, (long)STACKCHUNKSIZE);        }#endif /* INCLUDEDEBUGCODE */        newThread = newThreadX;    END_TEMPORARY_ROOTS    /*  Time slice will be initialized to default value */    newThread->timeslice = BASETIMESLICE;    /* Link the THREAD to the JAVATHREAD */    javaThread = unhand(javaThreadH);    newThread->javaThread = javaThread;    javaThread->VMthread = newThread;    /*  Initialize the state */    newThread->state = THREAD_JUST_BORN;#if ENABLE_JAVA_DEBUGGER    newThread->nextOpcode = NOP;#endif    /* Add to the alive thread list  */    newThread->nextAliveThread = AllThreads;    AllThreads = newThread;    return(newThread);}/*========================================================================= * FUNCTION:      DismantleThread() * TYPE:          public global operation * OVERVIEW:      Free off the thread's resources * INTERFACE: *   parameters:  The thread pointer *   returns:     <none> *=======================================================================*/voidDismantleThread(THREAD thisThread){    START_TEMPORARY_ROOTS        IS_TEMPORARY_ROOT(thisThread, thisThread);#if ENABLE_JAVA_DEBUGGER        if (vmDebugReady) {            CEModPtr cep;            storeExecutionEnvironment(thisThread);            cep = GetCEModifier();            cep->threadID = getObjectID((OBJECT)thisThread->javaThread);            setEvent_ThreadDeath(cep);            FreeCEModifier(cep);        }#endif /* ENABLE_JAVA_DEBUGGER */    /*     * A side effect of setevent is that the state could change, let's     * hammer it home that this thread is DEAD     */    thisThread->state = THREAD_DEAD;    if (AllThreads == thisThread) {        AllThreads = AllThreads->nextAliveThread;    } else {        THREAD prevThread = AllThreads;        /* Remove from alive thread list */        while (prevThread->nextAliveThread != thisThread) {            prevThread = prevThread->nextAliveThread;        }        prevThread->nextAliveThread = thisThread->nextAliveThread;    }    thisThread->nextAliveThread = NULL;    thisThread->stack = NULL;    thisThread->fpStore = NULL;    thisThread->spStore = NULL;    if (inTimerQueue(thisThread)) {        removePendingAlarm(thisThread);    }    END_TEMPORARY_ROOTS}/*========================================================================= * FUNCTION:      InitializeThreading() * TYPE:          public global operation * OVERVIEW:      Create the first low-level system thread and *                initialize it properly.  Initialize VM registers *                accordingly. * INTERFACE: *   parameters:  method: The main(String[]) method to cal *                arguments:  String[] argument *   returns:     <nothing> *=======================================================================*/static voidinitInitialThreadBehaviorFromThread(FRAME_HANDLE);void InitializeThreading(INSTANCE_CLASS mainClass, ARRAY argumentsArg){    START_TEMPORARY_ROOTS        DECLARE_TEMPORARY_ROOT(ARRAY, arguments, argumentsArg);        DECLARE_TEMPORARY_ROOT(JAVATHREAD, javaThread,                               (JAVATHREAD)instantiate(JavaLangThread));        makeGlobalRoot((cell **)&MainThread);        MainThread = NULL;        MonitorCache = NULL;        makeGlobalRoot((cell **)&CurrentThread);        makeGlobalRoot((cell **)&RunnableThreads);        makeGlobalRoot((cell **)&TimerQueue);        /*  Initialize the field of the Java-level thread structure */        javaThread->priority = 5;        MainThread = BuildThread(&javaThread);        /* AllThreads is initialized to NULL by the garbage collector.         *         * Ensure that the thread list is properly initialized         * and set mainThread as the active (CurrentThread) thread

⌨️ 快捷键说明

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