Changeset 2723


Ignore:
Timestamp:
Jul 17, 2006, 7:10:19 AM (19 years ago)
Author:
bird
Message:

Started porting to NT.

Location:
trunk/libc
Files:
3 added
5 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/libc/Config.kmk

    r2717 r2723  
    5050        IN_INNOTEK_LIBC \
    5151        __IN_INNOTEK_LIBC__
     52DEFS.os2   = __OS2__
     53DEFS.win32 = __NT__
     54DEFS.win64 = __NT__
     55
    5256
    5357#
     
    7377TEMPLATE_libc_TOOL = GCC3
    7478TEMPLATE_libc_INCS = $(PATH_LIBC_INC) $(dir $(LIBC-STD.H))
     79TEMPLATE_libc_INCS.win32 = $(PATH_LIBC_SRC)/w32api/include
     80TEMPLATE_libc_INCS.win64 = $(TEMPLATE_libc_INCS.win32)
    7581TEMPLATE_libc_DEPS = $(LIBC-STD.H)
    7682TEMPLATE_libc_INST = usr/lib/
     
    8086TEMPLATE_libc.logstrict_TOOL = GCC3
    8187TEMPLATE_libc.logstrict_INCS = $(TEMPLATE_libc_INCS)
     88TEMPLATE_libc.logstrict_INCS.win32 = $(TEMPLATE_libc_INCS.win32)
     89TEMPLATE_libc.logstrict_INCS.win64 = $(TEMPLATE_libc_INCS.win64)
    8290TEMPLATE_libc.logstrict_DEFS = $(TEMPLATE_libc_DEFS) __LIBC_STRICT DEBUG_LOGGING
    8391TEMPLATE_libc.logstrict_DEPS = $(TEMPLATE_libc_DEPS)
     
    8896TEMPLATE_libc.profiled_TOOL = GCC3
    8997TEMPLATE_libc.profiled_INCS = $(TEMPLATE_libc_INCS)
     98TEMPLATE_libc.profiled_INCS.win32 = $(TEMPLATE_libc_INCS.win32)
     99TEMPLATE_libc.profiled_INCS.win64 = $(TEMPLATE_libc_INCS.win64)
    90100TEMPLATE_libc.profiled_DEFS = $(TEMPLATE_libc_DEFS) __LIBC_PROFILED
    91101TEMPLATE_libc.profiled_DEPS = $(TEMPLATE_libc_DEPS)
  • trunk/libc/include/386/builtin.h

    r2049 r2723  
    428428
    429429
     430/**
     431 * Atomically compare and exchange a pointer.
     432 *
     433 * @returns 1 if changed, 0 if unchanged (i.e. boolean).
     434 * @param   ppv     Pointer to the value to compare & exchange.
     435 * @param   pvNew   The new value.
     436 * @param   pvCur   The current value. Only update if *pu32 equals this one.
     437 */
     438static inline unsigned __atomic_cmpxchgptr(void * volatile *ppv, void *pvNew,  void *pvOld)
     439{
     440    __asm__ __volatile__("lock; cmpxchgl %2, %1\n\t"
     441                         "setz  %%al\n\t"
     442                         "movzx %%al, %%eax\n\t"
     443                         : "=a" (pvOld),
     444                           "=m" (*ppv)
     445                         : "r"  (pvNew),
     446                           "0" (pvOld));
     447    return (uintptr_t)pvOld;
     448}
     449
    430450#define __ROTATE_FUN(F,I,T) \
    431451  static __inline__ T F (T value, int shift) \
  • trunk/libc/include/sys/fmutex.h

    r2090 r2723  
    4141{
    4242    /** Handle to event semaphore. */
     43#ifdef __OS2__
    4344    unsigned long           hev;
     45#else
     46    void                   *hev;
     47#endif
    4448    /** Semaphore status. */
    4549    volatile signed char    fs;
  • trunk/libc/src/libc/process/Makefile.kmk

    r2719 r2723  
    121121    $(PATH_LIBC_SRC)/libc/process/os2/fmutex-os2.c \
    122122
     123libc_libc_process_SOURCES.win32 = \
     124    $(PATH_LIBC_SRC)/libc/process/nt/fmutex-nt.c \
     125    $(PATH_LIBC_SRC)/libc/process/nt/smutex-nt.c \
     126
     127libc_libc_process_SOURCES.win64 = $(libc_libc_process_SOURCES.win32)
    123128
    124129# configure the variants. */
  • trunk/libc/src/libc/process/nt/fmutex-nt.c

    r2719 r2723  
    22
    33#include "libc-alias.h"
    4 #define INCL_DOSSEMAPHORES
    5 #define INCL_DOSPROCESS
    6 #define INCL_DOSERRORS
    7 #define INCL_DOSEXCEPTIONS
    8 #define INCL_FSMACROS
    9 #define INCL_EXAPIS
    10 #include <os2.h>
     4#include <klibc/nt/nt.h>
    115#include <stdlib.h>
    126#include <string.h>
     
    148#include <sys/fmutex.h>
    159#include <sys/smutex.h>
    16 #include <InnoTekLIBC/FastInfoBlocks.h>
    1710#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_MUTEX
    1811#include <InnoTekLIBC/logstrict.h>
     
    2821
    2922
    30 unsigned _fmutex_create(_fmutex *sem, unsigned flags)
    31 {
    32     LIBCLOG_ENTER("sem=%p flags=%#x\n", (void *)sem, flags);
    33     unsigned rc = _fmutex_create2(sem, flags, NULL);
     23unsigned _fmutex_create(_fmutex *pSem, unsigned flags)
     24{
     25    LIBCLOG_ENTER("pSem=%p flags=%#x\n", (void *)pSem, flags);
     26    unsigned rc = _fmutex_create2(pSem, flags, NULL);
    3427    if (!rc)
    3528        LIBCLOG_RETURN_UINT(rc);
     
    3831
    3932
    40 unsigned _fmutex_create2(_fmutex *sem, unsigned flags, const char *pszDesc)
    41 {
    42     LIBCLOG_ENTER("sem=%p flags=%#x pszDesc=%s\n", (void *)sem, flags, pszDesc);
    43     unsigned rc;
    44 
    45     sem->hev        = 0;
    46     sem->Owner      = 0;
    47     sem->fs         = _FMS_AVAILABLE;
    48     sem->flags      = flags;
    49     sem->padding[0] = 'f';
    50     sem->padding[1] = 'm';
    51     sem->pszDesc    = pszDesc;
    52     rc = DosCreateEventSemEx(NULL, (PHEV)&sem->hev,
    53                              (flags & _FMC_SHARED) ? DC_SEM_SHARED : 0,
    54                              FALSE);
    55     if (!rc)
     33unsigned _fmutex_create2(_fmutex *pSem, unsigned flags, const char *pszDesc)
     34{
     35    LIBCLOG_ENTER("pSem=%p flags=%#x pszDesc=%s\n", (void *)pSem, flags, pszDesc);
     36    if (flags & _FMC_SHARED)
     37        __libc_Back_panic(0, NULL, "_fmutex_create2: _FMC_SHARED isn't supported on NT. sorry.\n");
     38
     39    pSem->hev        = 0;
     40    pSem->Owner      = 0;
     41    pSem->fs         = _FMS_AVAILABLE;
     42    pSem->flags      = flags;
     43    pSem->padding[0] = 'f';
     44    pSem->padding[1] = 'm';
     45    pSem->pszDesc    = pszDesc;
     46    NTSTATUS rc = NtCreateEvent(&pSem->hev, EVENT_ALL_ACCESS, NULL, FALSE, FALSE);
     47    if (NT_SUCCESS(rc))
    5648        LIBCLOG_RETURN_UINT(rc);
    5749    LIBCLOG_ERROR_RETURN_UINT(rc);
     
    5951
    6052
    61 unsigned _fmutex_open(_fmutex *sem)
    62 {
    63     LIBCLOG_ENTER("sem=%p{.pszDesc=%s}\n", (void *)sem, sem->pszDesc);
    64     unsigned rc = DosOpenEventSemEx(NULL, (PHEV)&sem->hev);
    65     if (!rc)
     53unsigned _fmutex_open(_fmutex *pSem)
     54{
     55    LIBCLOG_ENTER("pSem=%p{.pszDesc=%s}\n", (void *)pSem, pSem->pszDesc);
     56    __libc_Back_panic(0, NULL, "_fmutex_open: _FMC_SHARED isn't supported on NT. sorry.\n");
     57}
     58
     59
     60unsigned _fmutex_close(_fmutex *pSem)
     61{
     62    LIBCLOG_ENTER("pSem=%p{.pszDesc=%s}\n", (void *)pSem, pSem->pszDesc);
     63    NTSTATUS rc = NtClose(pSem->hev);
     64    if (NT_SUCCESS(rc))
    6665        LIBCLOG_RETURN_UINT(rc);
    6766    LIBCLOG_ERROR_RETURN_UINT(rc);
     
    6968
    7069
    71 unsigned _fmutex_close(_fmutex *sem)
    72 {
    73     LIBCLOG_ENTER("sem=%p{.pszDesc=%s}\n", (void *)sem, sem->pszDesc);
    74     unsigned rc = DosCloseEventSemEx(sem->hev);
    75     if (!rc)
    76         LIBCLOG_RETURN_UINT(rc);
    77     LIBCLOG_ERROR_RETURN_UINT(rc);
    78 }
    79 
    80 
    81 unsigned __fmutex_request_internal(_fmutex *sem, unsigned flags, signed char fs)
    82 {
    83     LIBCLOG_ENTER("sem=%p{.pszDesc=%s} flags=%#x fs=%#x\n", (void *)sem, sem->pszDesc, flags, (int)fs);
     70unsigned __fmutex_request_internal(_fmutex *pSem, unsigned flags, signed char fs)
     71{
     72    LIBCLOG_ENTER("pSem=%p{.pszDesc=%s} flags=%#x fs=%#x\n", (void *)pSem, pSem->pszDesc, flags, (int)fs);
    8473    int     rc;
    8574
     
    9079    }
    9180
    92     if (fs == _FMS_AUTO_INITIALIZE || !sem->hev)
    93     {
    94         HEV hev;
    95         rc = DosCreateEventSemEx(NULL, &hev, sem->flags & _FMC_SHARED ? DC_SEM_SHARED : 0, FALSE);
    96         if (rc)
    97         {
    98             LIBC_ASSERTM_FAILED("Failed to create event semaphore for fmutex '%s', rc=%d. flags=%#x\n", sem->pszDesc, rc, sem->flags);
    99             LIBCLOG_RETURN_UINT(ERROR_INVALID_HANDLE);
    100         }
    101         if (__atomic_cmpxchg32((volatile uint32_t *)&sem->hev, hev, 0))
    102         {
    103             LIBCLOG_MSG("auto initialized fmutex %p '%s'\n", (void *)sem, sem->pszDesc);
    104             __atomic_xchg(&sem->Owner, fibGetTidPid());
     81    if (fs == _FMS_AUTO_INITIALIZE || !pSem->hev)
     82    {
     83        if (pSem->flags & _FMC_SHARED)
     84            __libc_Back_panic(0, NULL, "_fmutex_request_internal: _FMC_SHARED isn't supported on NT. sorry.\n");
     85
     86        HANDLE hev;
     87        NTSTATUS rc = NtCreateEvent(&hev, EVENT_ALL_ACCESS, NULL, FALSE, FALSE);
     88        if (!NT_SUCCESS(rc))
     89        {
     90            LIBC_ASSERTM_FAILED("Failed to create event semaphore for fmutex '%s', rc=%d. flags=%#x\n", pSem->pszDesc, rc, pSem->flags);
     91            LIBCLOG_RETURN_UINT(rc);
     92        }
     93        if (__atomic_cmpxchgptr(&pSem->hev, hev, 0))
     94        {
     95            LIBCLOG_MSG("auto initialized fmutex %p '%s'\n", (void *)pSem, pSem->pszDesc);
     96            __atomic_xchg(&pSem->Owner, fibGetTidPid());
    10597            LIBCLOG_RETURN_UINT(NO_ERROR);
    10698        }
    107         LIBCLOG_MSG("lost auto initialization race for fmutex %p '%s'\n", (void *)sem, sem->pszDesc);
    108         DosCloseEventSemEx(hev);
     99        LIBCLOG_MSG("lost auto initialization race for fmutex %p '%s'\n", (void *)pSem, pSem->pszDesc);
     100        NtClose(hev);
    109101        fs = _FMS_OWNED_HARD;
    110102    }
     
    114106        if (fs == _FMS_OWNED_HARD)
    115107        {
    116             if (__cxchg(&sem->fs, _FMS_OWNED_HARD) == _FMS_AVAILABLE)
     108            if (__cxchg(&pSem->fs, _FMS_OWNED_HARD) == _FMS_AVAILABLE)
    117109            {
    118                 __atomic_xchg(&sem->Owner, fibGetTidPid());
     110                __atomic_xchg(&pSem->Owner, fibGetTidPid());
    119111                LIBCLOG_RETURN_UINT(0);
    120112            }
    121113        }
    122         LIBCLOG_RETURN_UINT(ERROR_MUTEX_OWNED);
     114        LIBCLOG_RETURN_UINT(STATUS_TIMEOUT);
    123115    }
    124116
     
    126118    {
    127119        ULONG ulCount;
    128         FS_VAR();
    129         FS_SAVE_LOAD();
    130         rc = DosResetEventSem(sem->hev, &ulCount);
    131         FS_RESTORE();
    132         if (rc != 0 && rc != ERROR_ALREADY_RESET)
    133             LIBCLOG_RETURN_UINT(rc);
    134         if (__cxchg(&sem->fs, _FMS_OWNED_HARD) == _FMS_AVAILABLE)
    135         {
    136             __atomic_xchg(&sem->Owner, fibGetTidPid());
     120        if (__cxchg(&pSem->fs, _FMS_OWNED_HARD) == _FMS_AVAILABLE)
     121        {
     122            __atomic_xchg(&pSem->Owner, fibGetTidPid());
    137123            LIBCLOG_RETURN_UINT(0);
    138124        }
    139         if (sem->Owner == fibGetTidPid())
    140         {
    141             __fmutex_deadlock(sem, "Recursive mutex!");
     125        if (pSem->Owner == fibGetTidPid())
     126        {
     127            __fmutex_deadlock(pSem, "Recursive mutex!");
    142128            LIBCLOG_RETURN_UINT(-1);
    143129        }
    144130
    145         FS_SAVE_LOAD();
    146 
    147131        for (;;)
    148132        {
    149             rc = DosWaitEventSem(sem->hev, sem->flags & _FMC_SHARED ? SEM_INDEFINITE_WAIT : 3000);
    150             if (rc == ERROR_INTERRUPT)
     133            LARGE_INTEGER Interval;
     134            Interval.QuadPart = -30000000; /* 3sec */
     135            rc = NtWaitForSingleObject(pSem->hev, TRUE, &Interval);
     136            if (rc == STATUS_WAIT_0)
     137                break;
     138            if (    rc == STATUS_ALERTED
     139                ||  rc == STATUS_TIMEOUT)
    151140            {
    152                 /*
    153                  * An interrupt occured, this might be a bug in the wait, or
    154                  * more likely someone is killing us. If we're dying/exiting or
    155                  * something along those lines, we return to the caller no matter
    156                  * what flags it specified.
    157                  */
    158                 if (!(flags & _FMR_IGNINT))
    159                     break;
    160                 if (fibIsInExit())
    161                     break;
    162                 rc = ERROR_TIMEOUT;
     141                /** @todo check for process termination and validate owner. */
    163142            }
    164             if (rc != ERROR_TIMEOUT)
     143            else if (NT_SUCCESS(rc))
    165144                break;
    166             /*
    167              * Deadlock detection - check if owner is around.
    168              */
    169             unsigned Owner = sem->Owner;
    170             if (!Owner)
    171                 break;
    172             rc = DosVerifyPidTid(Owner >> 16, Owner & 0xffff);
    173             if (rc)
    174             {
    175                 __fmutex_deadlock(sem, "Owner died!");
    176                 rc = ERROR_SEM_OWNER_DIED;
    177                 break;
    178             }
    179         }
    180         FS_RESTORE();
    181         if (rc != 0)
    182             LIBCLOG_RETURN_UINT(rc);
    183     }
    184 }
    185 
    186 unsigned __fmutex_request_internal_must_complete(_fmutex *sem, unsigned flags)
    187 {
    188     LIBCLOG_ENTER("sem=%p{.pszDesc=%s} flags=%#x\n", (void *)sem, sem->pszDesc, flags);
    189     int     rc;
    190     ULONG   ulNesting = 0;
    191     signed char fs;
    192     FS_VAR();
    193 
    194     if (sem->fs == _FMS_UNINIT)
    195     {
    196         LIBC_ASSERTM_FAILED("Invalid handle, fs == _FMS_UNINIT\n");
    197         LIBCLOG_RETURN_UINT(ERROR_INVALID_HANDLE);
    198     }
    199 
    200     FS_SAVE_LOAD();
    201     DosEnterMustComplete(&ulNesting);
    202     fs = __cxchg(&sem->fs, _FMS_OWNED_SIMPLE);
     145            else
     146                LIBCLOG_ERROR_RETURN_UINT(rc);
     147        }
     148    }
     149}
     150
     151unsigned __fmutex_request_internal_must_complete(_fmutex *pSem, unsigned flags)
     152{
     153    LIBCLOG_ENTER("pSem=%p{.pszDesc=%s} flags=%#x\n", (void *)pSem, pSem->pszDesc, flags);
     154    /** @todo figure out how to do must_complete stuff on NT. */
     155    unsigned rc;
     156    signed char fs = __cxchg(&pSem->fs, _FMS_OWNED_SIMPLE);
    203157    if (fs == _FMS_AVAILABLE)
    204158    {
    205         __atomic_xchg(&sem->Owner, fibGetTidPid());
    206         FS_RESTORE();
    207         LIBCLOG_RETURN_UINT(0);
    208     }
    209 
    210     if (fs == _FMS_AUTO_INITIALIZE || !sem->hev)
    211     {
    212         HEV hev;
    213         rc = DosCreateEventSemEx(NULL, &hev, sem->flags & _FMC_SHARED ? DC_SEM_SHARED : 0, FALSE);
    214         if (rc)
    215         {
    216             LIBC_ASSERTM_FAILED("Failed to create event semaphore for fmutex '%s', rc=%d. flags=%#x\n", sem->pszDesc, rc, sem->flags);
    217             FS_RESTORE();
    218             LIBCLOG_RETURN_UINT(ERROR_INVALID_HANDLE);
    219         }
    220         if (__atomic_cmpxchg32((volatile uint32_t *)&sem->hev, hev, 0))
    221         {
    222             LIBCLOG_MSG("auto initialized fmutex %p '%s'\n", (void *)sem, sem->pszDesc);
    223             __atomic_xchg(&sem->Owner, fibGetTidPid());
    224             FS_RESTORE();
    225             LIBCLOG_RETURN_UINT(NO_ERROR);
    226         }
    227         LIBCLOG_MSG("lost auto initialization race for fmutex %p '%s'\n", (void *)sem, sem->pszDesc);
    228         DosCloseEventSemEx(hev);
    229         fs = _FMS_OWNED_HARD;
    230     }
    231 
    232     if (flags & _FMR_NOWAIT)
    233     {
    234         if (fs == _FMS_OWNED_HARD)
    235         {
    236             if (__cxchg(&sem->fs, _FMS_OWNED_HARD) == _FMS_AVAILABLE)
    237             {
    238                 __atomic_xchg(&sem->Owner, fibGetTidPid());
    239                 FS_RESTORE();
    240                 LIBCLOG_RETURN_UINT(0);
    241             }
    242         }
    243         DosExitMustComplete(&ulNesting);
    244         FS_RESTORE();
    245         LIBCLOG_RETURN_UINT(ERROR_MUTEX_OWNED);
    246     }
    247 
    248     for (;;)
    249     {
    250         ULONG ulCount;
    251         rc = DosResetEventSem(sem->hev, &ulCount);
    252         if (rc != 0 && rc != ERROR_ALREADY_RESET)
    253         {
    254             DosExitMustComplete(&ulNesting);
    255             FS_RESTORE();
    256             LIBCLOG_RETURN_UINT(rc);
    257         }
    258         if (__cxchg(&sem->fs, _FMS_OWNED_HARD) == _FMS_AVAILABLE)
    259         {
    260             __atomic_xchg(&sem->Owner, fibGetTidPid());
    261             FS_RESTORE();
    262             LIBCLOG_RETURN_UINT(0);
    263         }
    264         if (sem->Owner == fibGetTidPid())
    265         {
    266             DosExitMustComplete(&ulNesting);
    267             __fmutex_deadlock(sem, "Recursive mutex!");
    268             FS_RESTORE();
    269             LIBCLOG_RETURN_UINT(-1);
    270         }
    271 
    272         for (;;)
    273         {
    274             DosExitMustComplete(&ulNesting);
    275             rc = DosWaitEventSem(sem->hev, sem->flags & _FMC_SHARED ? SEM_INDEFINITE_WAIT : 3000);
    276             DosEnterMustComplete(&ulNesting);
    277             if (rc == ERROR_INTERRUPT)
    278             {
    279                 /*
    280                  * An interrupt occured, this might be a bug in the wait, or
    281                  * more likely someone is killing us. If we're dying/exiting or
    282                  * something along those lines, we return to the caller no matter
    283                  * what flags it specified.
    284                  */
    285                 if (!(flags & _FMR_IGNINT))
    286                     break;
    287                 if (fibIsInExit())
    288                     break;
    289                 rc = ERROR_TIMEOUT;
    290             }
    291             if (rc != ERROR_TIMEOUT)
    292                 break;
    293             /*
    294              * Deadlock detection - check if owner is around.
    295              */
    296             unsigned Owner = sem->Owner;
    297             if (!Owner)
    298                 break;
    299             rc = DosVerifyPidTid(Owner >> 16, Owner & 0xffff);
    300             if (rc)
    301             {
    302                 DosExitMustComplete(&ulNesting);
    303                 __fmutex_deadlock(sem, "Owner died!");
    304                 rc = ERROR_SEM_OWNER_DIED;
    305                 DosEnterMustComplete(&ulNesting);
    306                 break;
    307             }
    308         }
    309         FS_RESTORE();
    310         if (rc != 0)
    311         {
    312             DosExitMustComplete(&ulNesting);
    313             FS_RESTORE();
    314             LIBCLOG_RETURN_UINT(rc);
    315         }
    316     }
     159        __atomic_xchg(&pSem->Owner, fibGetTidPid());
     160        rc = 0;
     161    }
     162    else
     163        rc = __fmutex_request_internal(pSem, flags, fs);
     164    LIBCLOG_RETURN_UINT(rc);
    317165}
    318166
     
    328176}
    329177
    330 unsigned __fmutex_release_internal_must_complete(_fmutex *sem)
    331 {
    332     LIBCLOG_ENTER("sem=%p{.pszDesc=%s}\n", (void *)sem, sem->pszDesc);
    333     ULONG ulNesting;
    334     __atomic_xchg(&sem->Owner, 0);
    335     signed char fs = __cxchg(&sem->fs, _FMS_AVAILABLE);
     178unsigned __fmutex_release_internal_must_complete(_fmutex *pSem)
     179{
     180    LIBCLOG_ENTER("pSem=%p{.pszDesc=%s}\n", (void *)pSem, pSem->pszDesc);
     181    /** @todo figure out how to do must_complete stuff on NT. */
     182    __atomic_xchg(&pSem->Owner, 0);
     183    signed char fs = __cxchg(&pSem->fs, _FMS_AVAILABLE);
     184    unsigned rc;
    336185    if (fs != _FMS_OWNED_HARD)
    337     {
    338         FS_VAR_SAVE_LOAD();
    339         DosExitMustComplete(&ulNesting);
    340         FS_RESTORE();
    341         LIBCLOG_RETURN_UINT(0);
    342     }
     186        rc = 0;
    343187    else
    344     {
    345         int rc = __fmutex_release_internal (sem);
    346         FS_VAR_SAVE_LOAD();
    347         DosExitMustComplete(&ulNesting);
    348         FS_RESTORE();
    349         LIBCLOG_RETURN_UINT(rc);
    350     }
    351 }
    352 
    353 unsigned __fmutex_release_internal(_fmutex *sem)
    354 {
    355     LIBCLOG_ENTER("sem=%p{.pszDesc=%s}\n", (void *)sem, sem->pszDesc);
    356     unsigned rc;
    357     FS_VAR();
    358 
    359     FS_SAVE_LOAD();
    360     rc = DosPostEventSem(sem->hev);
    361     if (rc != 0 && rc != ERROR_ALREADY_POSTED)
    362     {
    363         FS_RESTORE();
    364         LIBCLOG_RETURN_UINT(rc);
    365     }
     188        rc = __fmutex_release_internal(pSem);
     189    LIBCLOG_RETURN_UINT(rc);
     190}
     191
     192unsigned __fmutex_release_internal(_fmutex *pSem)
     193{
     194    LIBCLOG_ENTER("pSem=%p{.pszDesc=%s}\n", (void *)pSem, pSem->pszDesc);
     195
     196
     197    NTSTATUS rc = NtSetEvent(pSem->hev, NULL);
     198    if (!NT_SUCCESS(rc))
     199        LIBCLOG_ERROR_RETURN_UINT(rc);
    366200
    367201    /* Give up our time slice to give other threads a chance.  Without
     
    370204       _fmutex semaphore from running, forever.
    371205
    372        Why?  Without DosSleep, the thread will keep the CPU for the rest
    373        of the time slice.  It may request (and get) the semaphore again
    374        in the same time slice, perhaps multiple times.  Assume that the
    375        semaphore is still owned at the end of the time slice.  In one of
    376        the next time slices, all the other threads blocking on the
    377        semaphore will wake up for a short while only to see that the
    378        semaphore is owned; they will all go sleeping again.  The thread
    379        which owns the semaphore will get the CPU again.  And may happen
    380        to own the semaphore again at the end of the time slice.  And so
    381        on.  DosSleep reduces that problem a bit.
    382 
    383        Even with DosSleep(0), assignment of time slices to threads
    384        requesting a _fmutex semaphore can be quite unbalanced: The more
    385        frequently a thread requests a _fmutex semaphore, the more CPU
    386        time it will get.  In consequence, a thread which only rarely
    387        needs the resource protected by the _fmutex semaphore will get
    388        much less CPU time than threads competing heavily for the
    389        resource.
    390 
    391        DosSleep(1) would make _fmutex semaphores behave a bit better,
    392        but would also give up way too much CPU time (in the average,
    393        half a time slice (or one and a half?) per call of this
    394        function).
    395 
    396        DosReleaseMutexSem does a better job; it gives the time slice to
    397        the thread which has waited longest on the semaphore (if all the
    398        threads have the same priority).
    399 
    400        Unfortunately, we cannot use an HMTX instead of an HEV because
    401        only the owner (the thread which got assigned ownership by
    402        DosRequestMutexSem) can release the HMTX with DosReleaseMutexSem.
    403        If we could, that would take advantage of the FIFO of blocked
    404        threads maintained by the kernel for each HMTX.
    405 
    406        Using an HMTX would require the first thread requesting an owned
    407        _fmutex semaphore to request the HMTX on behalf of the thread
    408        owning the _fmutex semaphore. */
    409 
    410     DosSleep(0);
    411     FS_RESTORE();
     206      Read the rest of the rant in fmutex-os2.c */
     207    ZwYieldExecution();
    412208    LIBCLOG_RETURN_UINT(0);
    413209}
    414210
    415211
    416 void _fmutex_dummy(_fmutex *sem)
    417 {
    418     LIBCLOG_ENTER("sem=%p\n", (void *)sem);
    419     sem->hev = 0;
    420     sem->fs = _FMS_AVAILABLE;
    421     sem->flags = _FMC_DUMMY;
    422     sem->Owner = 0;
    423     sem->pszDesc = "dummy";
     212void _fmutex_dummy(_fmutex *pSem)
     213{
     214    LIBCLOG_ENTER("pSem=%p\n", (void *)pSem);
     215    pSem->hev = 0;
     216    pSem->fs = _FMS_AVAILABLE;
     217    pSem->flags = _FMC_DUMMY;
     218    pSem->Owner = 0;
     219    pSem->pszDesc = "dummy";
    424220    LIBCLOG_RETURN_VOID();
    425221}
  • trunk/libc/src/libc/process/nt/smutex-nt.c

    r2719 r2723  
    22
    33#include "libc-alias.h"
    4 #define INCL_DOSPROCESS
    5 #define INCL_FSMACROS
    6 #include <os2.h>
     4#include <klibc/nt/nt.h>
    75#include <sys/builtin.h>
    86#include <sys/smutex.h>
    9 #include <InnoTekLIBC/FastInfoBlocks.h>
    107#include <InnoTekLIBC/backend.h>
    118#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_MUTEX
     
    1310
    1411
    15 void __smutex_request_internal(volatile _smutex *sem)
     12void __smutex_request_internal(volatile _smutex *pSem)
    1613{
    17     LIBCLOG_ENTER("sem=%p\n", sem);
    18     FS_VAR();
    19     FS_SAVE_LOAD();
    20     DosSleep(1);
    21     while (__cxchg(sem, 1) != 0)
    22     {
    23         if (fibIsInExit())
    24         {
    25             __libc_Back_panic(0, NULL, "smutex deadlock: %p\n", sem);
    26             break;
    27         }
    28         DosSleep(1);
    29     }
    30     FS_RESTORE();
     14    LIBCLOG_ENTER("pSem=%p\n", pSem);
     15    do
     16        ZwYieldExecution();
     17    while (__cxchg(pSem, 1));
    3118    LIBCLOG_RETURN_VOID();
    3219}
     20
  • trunk/libc/src/libc/process/os2/fmutex-os2.c

    r2719 r2723  
    362362    {
    363363        FS_RESTORE();
    364         LIBCLOG_RETURN_UINT(rc);
     364        LIBCLOG_ERROR_RETURN_UINT(rc);
    365365    }
    366366
Note: See TracChangeset for help on using the changeset viewer.