VirtualBox

Changeset 13254

Show
Ignore:
Timestamp:
10/14/08 14:35:50 (3 months ago)
Author:
vboxsync
Message:

IPRT: Added RTThreadPreemptIsEnabled, RTThreadPreemptDisable and RTThreadPreemptRestore. Made the logger check that preemption is enabled before trying to take the semaphore on Solaris and Windows.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/include/iprt/err.h

    r11725 r13254  
    479479#define VWRN_INVALID_STATE                  79 
    480480/** Generic out of resources error. */ 
    481 #define VERR_OUT_OF_RESOURCES              (-80) 
     481#define VERR_OUT_OF_RESOURCES              (-80) 
    482482/** Generic out of resources warning. */ 
    483483#define VWRN_OUT_OF_RESOURCES               80 
    484484/** No more handles available, too many open handles. */ 
    485 #define VERR_NO_MORE_HANDLES               (-81) 
     485#define VERR_NO_MORE_HANDLES                (-81) 
     486/** Preemption is disabled. 
     487 * The requested operation can only be performed when preemption is enabled. */ 
     488#define VERR_PREEMPT_DISABLED               (-82) 
    486489/** @} */ 
    487490 
  • trunk/include/iprt/thread.h

    r11596 r13254  
    217217 
    218218/** 
    219  * Create a new thread.  
    220  *   
     219 * Create a new thread. 
     220 * 
    221221 * Same as RTThreadCreate except the name is given in the RTStrPrintfV form. 
    222222 * 
     
    235235 
    236236/** 
    237  * Create a new thread.  
    238  *   
     237 * Create a new thread. 
     238 * 
    239239 * Same as RTThreadCreate except the name is given in the RTStrPrintf form. 
    240240 * 
     
    372372RTDECL(int) RTThreadUserReset(RTTHREAD Thread); 
    373373 
     374#ifdef IN_RING0 
     375 
     376/** 
     377 * Check if preemption is currently enabled or not for the current thread. 
     378 * 
     379 * @returns true if preemtion is enabled, false if preemetion is disabled. 
     380 * @param       hThread         Must be NIL_RTTHREAD for now. 
     381 */ 
     382RTDECL(bool) RTThreadPreemptIsEnabled(RTTHREAD hThread); 
     383 
     384/** 
     385 * Preemption state saved by RTThreadPreemptDisable and used by 
     386 * RTThreadPreemptRestore to restore the previous state. 
     387 */ 
     388typedef struct RTTHREADPREEMPTSTATE 
     389{ 
     390#ifdef RT_OS_WINDOWS 
     391    /** The old IRQL. Don't touch. */ 
     392    unsigned char uchOldIrql; 
     393# define RTTHREADPREEMPTSTATE_INITIALIZER { 255 } 
     394#else 
     395    /** Dummy unused placeholder. */ 
     396    unsigned char uchDummy; 
     397# define RTTHREADPREEMPTSTATE_INITIALIZER { 0 } 
     398#endif 
     399} RTTHREADPREEMPTSTATE; 
     400/** Pointer to a preemption state. */ 
     401typedef RTTHREADPREEMPTSTATE *PRTTHREADPREEMPTSTATE; 
     402 
     403/** 
     404 * Disable preemption. 
     405 * 
     406 * A call to this function must be matched by exactly one call to 
     407 * RTThreadPreemptRestore(). 
     408 * 
     409 * @param   pState              Where to store the preemption state. 
     410 */ 
     411RTDECL(void) RTThreadPreemptDisable(PRTTHREADPREEMPTSTATE pState); 
     412 
     413/** 
     414 * Restores the preemption state, undoing a previous call to 
     415 * RTThreadPreemptDisable. 
     416 * 
     417 * A call to this function must be matching a previous call to 
     418 * RTThreadPreemptDisable. 
     419 * 
     420 * @param  pState               The state return by RTThreadPreemptDisable. 
     421 */ 
     422RTDECL(void) RTThreadPreemptRestore(PRTTHREADPREEMPTSTATE pState); 
     423 
     424#endif /* IN_RING0 */ 
     425 
    374426 
    375427#ifdef IN_RING3 
  • trunk/src/VBox/Runtime/Makefile.kmk

    r13248 r13254  
    976976        generic/RTLogWriteStdOut-stub-generic.cpp \ 
    977977        generic/mppresent-generic.cpp \ 
     978        r0drv/generic/RTThreadPreemptIsEnabled-r0drv-generic.cpp \ 
     979        r0drv/generic/RTThreadPreemptDisable-r0drv-generic.cpp \ 
     980        r0drv/generic/RTThreadPreemptRestore-r0drv-generic.cpp \ 
    978981        r0drv/linux/alloc-r0drv-linux.c \ 
    979982        r0drv/linux/initterm-r0drv-linux.c \ 
     
    10101013        r0drv/memobj-r0drv.cpp \ 
    10111014        r0drv/mpnotification-r0drv.c \ 
     1015        r0drv/generic/RTThreadPreemptIsEnabled-r0drv-generic.cpp \ 
     1016        r0drv/generic/RTThreadPreemptDisable-r0drv-generic.cpp \ 
     1017        r0drv/generic/RTThreadPreemptRestore-r0drv-generic.cpp \ 
    10121018        r0drv/nt/alloc-r0drv-nt.cpp \ 
    10131019        r0drv/nt/assert-r0drv-nt.cpp \ 
     
    10541060        generic/timer-generic.cpp \ 
    10551061        r0drv/generic/RTMpOn-r0drv-generic.cpp \ 
     1062        r0drv/generic/RTThreadPreemptIsEnabled-r0drv-generic.cpp \ 
     1063        r0drv/generic/RTThreadPreemptDisable-r0drv-generic.cpp \ 
     1064        r0drv/generic/RTThreadPreemptRestore-r0drv-generic.cpp \ 
    10561065        r0drv/generic/mpnotification-r0drv-generic.cpp \ 
    10571066        r0drv/darwin/alloc-r0drv-darwin.cpp \ 
     
    11031112        r0drv/memobj-r0drv.cpp \ 
    11041113        r0drv/generic/RTMpOn-r0drv-generic.cpp \ 
     1114        r0drv/generic/RTThreadPreemptIsEnabled-r0drv-generic.cpp \ 
     1115        r0drv/generic/RTThreadPreemptDisable-r0drv-generic.cpp \ 
     1116        r0drv/generic/RTThreadPreemptRestore-r0drv-generic.cpp \ 
    11051117        r0drv/generic/mpnotification-r0drv-generic.cpp \ 
    11061118        r0drv/os2/alloc-r0drv-os2.cpp \ 
     
    11491161        generic/mppresent-generic.cpp \ 
    11501162        r0drv/generic/RTMpOn-r0drv-generic.cpp \ 
     1163        r0drv/generic/RTThreadPreemptIsEnabled-r0drv-generic.cpp \ 
     1164        r0drv/generic/RTThreadPreemptDisable-r0drv-generic.cpp \ 
     1165        r0drv/generic/RTThreadPreemptRestore-r0drv-generic.cpp \ 
    11511166        r0drv/generic/mpnotification-r0drv-generic.cpp \ 
    11521167        r0drv/freebsd/alloc-r0drv-freebsd.c \ 
     
    11961211else  # !VBOX_WITH_SOLARIS_VBI 
    11971212 RuntimeR0Drv_SOURCES.solaris += \ 
     1213        r0drv/generic/RTThreadPreemptIsEnabled-r0drv-generic.cpp \ 
     1214        r0drv/generic/RTThreadPreemptDisable-r0drv-generic.cpp \ 
     1215        r0drv/generic/RTThreadPreemptRestore-r0drv-generic.cpp \ 
    11981216        r0drv/solaris/mpnotification-r0drv-solaris.c \ 
    11991217        r0drv/solaris/alloc-r0drv-solaris.c \ 
  • trunk/src/VBox/Runtime/common/log/log.cpp

    r12905 r13254  
    143143    if (pLogger->MutexSem != NIL_RTSEMFASTMUTEX) 
    144144    { 
     145# if defined(IN_RING0) \ 
     146  && (defined(RT_OS_WINDOWS) || defined(RT_OS_SOLARIS)) 
     147        if (!RTThreadPreemptIsEnabled()) 
     148            return VERR_PREEMPT_DISABLED; 
     149# endif 
    145150        int rc = RTSemFastMutexRequest(pLogger->MutexSem); 
    146151        if (RT_FAILURE(rc)) 
  • trunk/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp

    r8245 r13254  
    7272 
    7373 
     74RTDECL(bool) RTThreadPreemptIsEnabled(RTTHREAD hThread) 
     75{ 
     76    Assert(hThread == NIL_RTTHREAD); 
     77    KIRQL Irql = KeGetCurrentIrql(); 
     78    return Irql <= APC_LEVEL; 
     79} 
     80 
     81 
     82RTDECL(void) RTThreadPreemptDisable(PRTTHREADPREEMPTSTATE pState) 
     83{ 
     84    AssertPtr(pState); 
     85    Assert(pState->uchOldIrql == 255); 
     86    Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL); 
     87 
     88    KeRaiseIrql(DISPATCH_LEVEL, &pState->uchOldIrql); 
     89} 
     90 
     91 
     92RTDECL(void) RTThreadPreemptRestore(PRTTHREADPREEMPTSTATE pState) 
     93{ 
     94    AssertPtr(pState); 
     95 
     96    KeLowerIrql(pState->uchOldIrql); 
     97    pState->uchOldIrql = 255; 
     98} 
     99 
  • trunk/src/VBox/Runtime/r0drv/solaris/thread-r0drv-solaris.c

    r8245 r13254  
    4949    clock_t cTicks; 
    5050    unsigned long timeout; 
    51      
     51 
    5252    if (!cMillies) 
    5353    { 
     
    6363#if 0 
    6464    timeout = ddi_get_lbolt(); 
    65     timeout += cTicks;  
    66   
     65    timeout += cTicks; 
     66 
    6767    kcondvar_t cnd; 
    6868    kmutex_t mtx; 
     
    9898} 
    9999 
     100 
     101RTDECL(bool) RTThreadPreemptIsEnabled(RTTHREAD hThread) 
     102{ 
     103    Assert(hThread == NIL_RTTHREAD); 
     104    return curthread->t_preempt == 0; 
     105} 
     106 
     107 
     108RTDECL(void) RTThreadPreemptDisable(PRTTHREADPREEMPTSTATE pState) 
     109{ 
     110    AssertPtr(pState); 
     111    Assert(pState->uchDummy != 42); 
     112    pState->uchDummy = 42; 
     113 
     114    kpreempt_disable(); 
     115} 
     116 
     117 
     118RTDECL(void) RTThreadPreemptRestore(PRTTHREADPREEMPTSTATE pState) 
     119{ 
     120    AssertPtr(pState); 
     121    Assert(pState->uchDummy == 42); 
     122    pState->uchDummy = 0; 
     123 
     124    kpreempt_enable(); 
     125} 
     126 
  • trunk/src/VBox/Runtime/r0drv/solaris/vbi/thread-r0drv-solaris.c

    r9176 r13254  
    6262#if 0 
    6363    timeout = ddi_get_lbolt(); 
    64     timeout += cTicks;  
    65   
     64    timeout += cTicks; 
     65 
    6666    kcondvar_t cnd; 
    6767    kmutex_t mtx; 
     
    9696} 
    9797 
     98 
     99RTDECL(bool) RTThreadPreemptIsEnabled(RTTHREAD hThread) 
     100{ 
     101    Assert(hThread == NIL_RTTHREAD); 
     102    return vbi_is_preempt_enabled() != 0; 
     103} 
     104 
     105 
     106RTDECL(void) RTThreadPreemptDisable(PRTTHREADPREEMPTSTATE pState) 
     107{ 
     108    AssertPtr(pState); 
     109    Assert(pState->uchDummy != 42); 
     110    pState->uchDummy = 42; 
     111    vbi_preempt_disable(); 
     112} 
     113 
     114 
     115RTDECL(void) RTThreadPreemptRestore(PRTTHREADPREEMPTSTATE pState) 
     116{ 
     117    AssertPtr(pState); 
     118    Assert(pState->uchDummy == 42); 
     119    pState->uchDummy = 0; 
     120    vbi_preempt_enable(); 
     121} 
     122 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy