VirtualBox

Changeset 21536 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Jul 13, 2009 2:49:39 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
50009
Message:

iprt/thread.h: Redefined RTThreadPreemptIsEnabled for systems without preemption (we keep count ourselves). Added RTThreadPreemptIsPossible and RTThreadIsInInterrupt. Fixed RTThreadPreemptIsEnabled on FreeBSD and Solaris/vbi.

Location:
trunk/src/VBox/Runtime/r0drv
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/darwin/threadpreempt-r0drv-darwin.cpp

    r20124 r21536  
    2929 */
    3030
     31
    3132/*******************************************************************************
    3233*   Header Files                                                               *
     
    3536#include <iprt/thread.h>
    3637
     38#include <iprt/asm.h>
    3739#include <iprt/assert.h>
    3840#include <iprt/err.h>
    3941#include <iprt/mp.h>
    40 #include <iprt/asm.h>
    4142
    4243
     
    5253} RTDARWINPREEMPTHACK;
    5354typedef RTDARWINPREEMPTHACK *PRTDARWINPREEMPTHACK;
    54 
    5555
    5656
     
    130130
    131131
     132RTDECL(bool) RTThreadPreemptIsPossible(void)
     133{
     134    /* yes, kernel preemption is possible. */
     135    return true;
     136}
     137
     138
    132139RTDECL(void) RTThreadPreemptDisable(PRTTHREADPREEMPTSTATE pState)
    133140{
     
    181188
    182189
     190RTDECL(bool) RTThreadIsInInterrupt(RTTHREAD hThread)
     191{
     192    Assert(hThread == NIL_RTTHREAD); NOREF(hThread);
     193    /** @todo Solaris: Implement RTThreadIsInInterrupt. Required for guest
     194     *        additions! */
     195    return !ASMIntAreEnabled();
     196}
     197
  • trunk/src/VBox/Runtime/r0drv/freebsd/thread-r0drv-freebsd.c

    r20554 r21536  
    3535
    3636#include <iprt/thread.h>
     37#include <iprt/asm.h>
     38#include <iprt/assert.h>
    3739#include <iprt/err.h>
    38 #include <iprt/assert.h>
    3940
    4041#include "internal/thread.h"
     
    112113    Assert(hThread == NIL_RTTHREAD);
    113114
    114     return curthread->td_critnest == 0;
     115    return curthread->td_critnest == 0
     116        && ASMIntAreEnabled(); /** @todo is there a native freebsd function/macro for this? */
    115117}
    116118
     
    127129{
    128130    /* yes, RTThreadPreemptIsPending is reliable. */
     131    return true;
     132}
     133
     134
     135RTDECL(bool) RTThreadPreemptIsPossible(void)
     136{
     137    /* yes, kernel preemption is possible. */
    129138    return true;
    130139}
     
    150159}
    151160
     161
     162RTDECL(bool) RTThreadIsInInterrupt(RTTHREAD hThread)
     163{
     164    Assert(hThread == NIL_RTTHREAD); NOREF(hThread);
     165    /** @todo FreeBSD: Implement RTThreadIsInInterrupt. Required for guest
     166     *        additions! */
     167    return !ASMIntAreEnabled();
     168}
     169
  • trunk/src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c

    r21337 r21536  
    3737
    3838#include <iprt/thread.h>
     39#include <iprt/asm.h>
     40#include <iprt/assert.h>
    3941#include <iprt/err.h>
    40 #include <iprt/assert.h>
     42
     43
     44/*******************************************************************************
     45*   Global Variables                                                           *
     46*******************************************************************************/
     47#ifndef CONFIG_PREEMPT
     48/** Per-cpu preemption counters. */
     49static int32_t volatile g_acPreemptDisabled[NR_CPUS];
     50#endif
    4151
    4252
     
    7686RTDECL(bool) RTThreadPreemptIsEnabled(RTTHREAD hThread)
    7787{
     88#ifdef CONFIG_PREEMPT
    7889    Assert(hThread == NIL_RTTHREAD);
    79 #ifdef CONFIG_PREEMPT
    8090# ifdef preemptible
    8191    return preemptible();
     
    8494# endif
    8595#else
    86     return false;
     96    int32_t c;
     97
     98    Assert(hThread == NIL_RTTHREAD);
     99    c = g_acPreemptDisabled[smp_processor_id()];
     100    AssertMsg(c >= 0 && c < 32, ("%d\n", c));
     101    return c == 0 && !in_atomic() && !irqs_disabled();
    87102#endif
    88103}
     
    117132
    118133
     134RTDECL(bool) RTThreadPreemptIsPossible(void)
     135{
     136#ifdef CONFIG_PREEMPT
     137    return true;    /* yes, kernel preemption is possible. */
     138#else
     139    return false;   /* no kernel preemption */
     140#endif
     141}
     142RT_EXPORT_SYMBOL(RTThreadPreemptIsPossible);
     143
     144
    119145RTDECL(void) RTThreadPreemptDisable(PRTTHREADPREEMPTSTATE pState)
    120146{
     147#ifdef CONFIG_PREEMPT
    121148    AssertPtr(pState);
    122149    Assert(pState->uchDummy != 42);
    123150    pState->uchDummy = 42;
     151    preempt_disable();
    124152
    125     /*
    126      * Note: This call is a NOP if CONFIG_PREEMPT is not enabled in the Linux kernel
    127      * configuration. In that case, schedule() is only called need_resched() is set
    128      * which is tested just before we return to R3 (not when returning from R0 to R0).
    129      */
    130     preempt_disable();
     153#else /* !CONFIG_PREEMPT */
     154    int32_t c;
     155    AssertPtr(pState);
     156
     157    /* Do our own accounting. */
     158    c = ASMAtomicIncS32(&g_acPreemptDisabled[smp_processor_id()]);
     159    AssertMsg(c > 0 && c < 32, ("%d\n", c));
     160    pState->uchDummy = (unsigned char )c;
     161#endif
    131162}
    132163RT_EXPORT_SYMBOL(RTThreadPreemptDisable);
     
    135166RTDECL(void) RTThreadPreemptRestore(PRTTHREADPREEMPTSTATE pState)
    136167{
     168#ifdef CONFIG_PREEMPT
    137169    AssertPtr(pState);
    138170    Assert(pState->uchDummy == 42);
    139171    pState->uchDummy = 0;
     172    preempt_enable();
    140173
    141     preempt_enable();
     174#else
     175    int32_t volatile *pc;
     176    AssertPtr(pState);
     177    AssertMsg(pState->uchDummy > 0 && pState->uchDummy < 32, ("%d\n", pState->uchDummy));
     178
     179    /* Do our own accounting. */
     180    pc = &g_acPreemptDisabled[smp_processor_id()];
     181    AssertMsg(pState->uchDummy == (uint32_t)*pc, ("uchDummy=%d *pc=%d \n", pState->uchDummy, *pc));
     182    ASMAtomicUoWriteS32(pc, pState->uchDummy - 1);
     183#endif
    142184}
    143185RT_EXPORT_SYMBOL(RTThreadPreemptRestore);
    144186
     187
     188RTDECL(bool) RTThreadIsInInterrupt(RTTHREAD hThread)
     189{
     190    Assert(hThread == NIL_RTTHREAD); NOREF(hThread);
     191
     192    return in_interrupt() != 0;
     193}
     194RT_EXPORT_SYMBOL(RTThreadIsInInterrupt);
     195
  • trunk/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp

    r20374 r21536  
    8282    if (Irql > APC_LEVEL)
    8383        return false;
    84 #if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
    85     if (!(ASMGetFlags() & 0x00000200 /* X86_EFL_IF */))
     84    if (!ASMIntAreEnabled())
    8685        return false;
    87 #endif
    8886    return true;
    8987}
     
    157155
    158156
     157RTDECL(bool) RTThreadPreemptIsPossible(void)
     158{
     159    /* yes, kernel preemption is possible. */
     160    return true;
     161}
     162
     163
    159164RTDECL(void) RTThreadPreemptDisable(PRTTHREADPREEMPTSTATE pState)
    160165{
     
    175180}
    176181
     182
     183RTDECL(bool) RTThreadIsInInterrupt(RTTHREAD hThread)
     184{
     185    Assert(hThread == NIL_RTTHREAD); NOREF(hThread);
     186
     187    KIRQL CurIrql = KeGetCurrentIrql();
     188    return CurIrql > PASSIVE_LEVEL; /** @todo Is there a more correct way? */
     189}
     190
  • trunk/src/VBox/Runtime/r0drv/os2/thread-r0drv-os2.cpp

    r20124 r21536  
    3535
    3636#include <iprt/thread.h>
     37#include <iprt/asm.h>
     38#include <iprt/assert.h>
    3739#include <iprt/err.h>
    38 #include <iprt/assert.h>
    3940#include "internal/thread.h"
     41
     42
     43/*******************************************************************************
     44*   Global Variables                                                           *
     45*******************************************************************************/
     46/** Per-cpu preemption counters. */
     47static int32_t volatile g_acPreemptDisabled[256];
     48
    4049
    4150
     
    7887{
    7988    Assert(hThread == NIL_RTTHREAD);
    80     return false;
    81 }
    82 
    83 
    84 RTDECL(bool) RTThreadPreemptIsPendingTrusty(void)
    85 {
    86     /* yes, RTThreadPreemptIsPending is reliable. */
    87     return true;
     89    int32_t c = g_acPreemptDisabled[ASMGetApicId()];
     90    AssertMsg(c >= 0 && c < 32, ("%d\n", c));
     91    return c == 0
     92        && ASMIntAreEnabled();
    8893}
    8994
     
    112117
    113118
     119RTDECL(bool) RTThreadPreemptIsPendingTrusty(void)
     120{
     121    /* yes, RTThreadPreemptIsPending is reliable. */
     122    return true;
     123}
     124
     125
     126RTDECL(bool) RTThreadPreemptIsPossible(void)
     127{
     128    /* no kernel preemption on OS/2. */
     129    return false;
     130}
     131
     132
    114133RTDECL(void) RTThreadPreemptDisable(PRTTHREADPREEMPTSTATE pState)
    115134{
    116135    AssertPtr(pState);
    117     Assert(pState->uchDummy != 42);
    118     pState->uchDummy = 42;
    119     /* Nothing to do here as OS/2 doesn't preempt kernel threads. */
     136
     137    /* No preemption on OS/2, so do our own accounting. */
     138    int32_t c = ASMAtomicIncS32(&g_acPreemptDisabled[ASMGetApicId()]);
     139    AssertMsg(c > 0 && c < 32, ("%d\n", c));
     140    pState->uchDummy = (unsigned char)c;
    120141}
    121142
     
    124145{
    125146    AssertPtr(pState);
    126     Assert(pState->uchDummy == 42);
     147    AssertMsg(pState->uchDummy > 0 && pState->uchDummy < 32, ("%d\n", pState->uchDummy));
     148
     149    /* No preemption on OS/2, so do our own accounting. */
     150    int32_t volatile *pc = &g_acPreemptDisabled[ASMGetApicId()];
     151    AssertMsg(pState->uchDummy == (uint32_t)*pc, ("uchDummy=%d *pc=%d \n", pState->uchDummy, *pc));
     152    ASMAtomicUoWriteS32(pc, pState->uchDummy - 1);
    127153    pState->uchDummy = 0;
    128154}
    129155
     156
     157RTDECL(bool) RTThreadIsInInterrupt(RTTHREAD hThread)
     158{
     159    Assert(hThread == NIL_RTTHREAD); NOREF(hThread);
     160
     161    union
     162    {
     163        RTFAR16 fp;
     164        uint8_t cInterruptLevel;
     165    } u;
     166    /** @todo OS/2: verify the usage of DHGETDOSV_INTERRUPTLEV. */
     167    int rc = RTR0Os2DHQueryDOSVar(DHGETDOSV_INTERRUPTLEV, 0, &u.fp);
     168    AssertReturn(rc == 0, true);
     169
     170    return cInterruptLevel > 0;
     171}
     172
  • trunk/src/VBox/Runtime/r0drv/solaris/thread-r0drv-solaris.c

    r20124 r21536  
    2929 */
    3030
     31
    3132/*******************************************************************************
    3233*   Header Files                                                               *
     
    3536
    3637#include <iprt/thread.h>
    37 #include <iprt/err.h>
    3838#include <iprt/asm.h>
    3939#include <iprt/assert.h>
     40#include <iprt/err.h>
    4041
    4142
     
    105106    if (curthread->t_preempt != 0)
    106107        return false;
    107 #if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
    108     if (!(ASMGetFlags() & 0x00000200 /* X86_EFL_IF */))
     108    if (!ASMIntAreEnabled())
    109109        return false;
    110 #endif
    111110    return true;
    112111}
     
    125124{
    126125    /* yes, RTThreadPreemptIsPending is reliable. */
     126    return true;
     127}
     128
     129
     130RTDECL(bool) RTThreadPreemptIsPossible(void)
     131{
     132    /* yes, kernel preemption is possible. */
    127133    return true;
    128134}
     
    148154}
    149155
     156
     157RTDECL(bool) RTThreadIsInInterrupt(RTTHREAD hThread)
     158{
     159    Assert(hThread == NIL_RTTHREAD); NOREF(hThread);
     160    /** @todo Solaris: Implement RTThreadIsInInterrupt. Required for guest
     161     *        additions! */
     162    return !ASMIntAreEnabled();
     163}
     164
  • trunk/src/VBox/Runtime/r0drv/solaris/vbi/thread-r0drv-solaris.c

    r21452 r21536  
    2929 */
    3030
     31
    3132/*******************************************************************************
    3233*   Header Files                                                               *
     
    3536
    3637#include <iprt/thread.h>
     38#include <iprt/asm.h>
     39#include <iprt/assert.h>
    3740#include <iprt/err.h>
    38 #include <iprt/assert.h>
     41
    3942
    4043RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
     
    100103{
    101104    Assert(hThread == NIL_RTTHREAD);
    102     return vbi_is_preempt_enabled() != 0;
     105    if (    vbi_is_preempt_enabled()
     106        &&  ASMIntAreEnabled())
     107        return true;
     108    return false;
    103109}
    104110
     
    107113{
    108114    Assert(hThread == NIL_RTTHREAD);
    109     /** @todo Review this! */
    110115    return !!vbi_is_preempt_pending();
    111116}
     
    115120{
    116121    /* yes, RTThreadPreemptIsPending is reliable. */
     122    return true;
     123}
     124
     125
     126RTDECL(bool) RTThreadPreemptIsPossible(void)
     127{
     128    /* yes, kernel preemption is possible. */
    117129    return true;
    118130}
     
    136148}
    137149
     150
     151RTDECL(bool) RTThreadIsInInterrupt(RTTHREAD hThread)
     152{
     153    Assert(hThread == NIL_RTTHREAD); NOREF(hThread);
     154    /** @todo Solaris: Implement RTThreadIsInInterrupt. Required for guest
     155     *        additions! */
     156    return !ASMIntAreEnabled();
     157}
     158
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette