Ticket #1: runtime.diff

File runtime.diff, 63.8 KB (added by Valery V. Sedletski, 9 years ago)

Runtime

  • \src\VBox\Runtime/Makefile.kmk

    diff -urN vbox-clean-bk\src\VBox\Runtime/Makefile.kmk vbox-clean\src\VBox\Runtime/Makefile.kmk
    old new  
    894894        generic/RTProcIsRunningByName-generic.cpp \
    895895        generic/RTThreadGetNativeState-generic.cpp \
    896896        os2/RTErrConvertFromOS2.cpp \
     897        r3/os2/fileaio-os2.cpp \
    897898        r3/generic/allocex-r3-generic.cpp \
    898899        r3/os2/filelock-os2.cpp \
    899900        r3/os2/mp-os2.cpp \
     
    21082109        generic/RTAssertShouldPanic-generic.cpp \
    21092110        generic/RTLogWriteDebugger-generic.cpp \
    21102111        generic/RTLogWriteStdOut-stub-generic.cpp \
    2111         generic/RTMpCpuId-generic.cpp \
    2112         generic/RTMpCpuIdFromSetIndex-generic.cpp \
    2113         generic/RTMpCpuIdToSetIndex-generic.cpp \
    2114         generic/RTMpIsCpuPossible-generic.cpp \
    2115         generic/RTMpGetCount-generic.cpp \
    2116         generic/RTMpGetMaxCpuId-generic.cpp \
    2117         generic/RTMpGetOnlineCount-generic.cpp \
    2118         generic/RTMpGetOnlineSet-generic.cpp \
    2119         generic/RTMpGetSet-generic.cpp \
    2120         generic/RTMpIsCpuOnline-generic.cpp \
    21212112        generic/RTTimerCreate-generic.cpp \
    21222113        generic/mppresent-generic.cpp \
     2114        generic/RTMpOnPair-generic.cpp \
    21232115        os2/RTErrConvertFromOS2.cpp \
    21242116        os2/rtSemWaitOs2ConvertTimeout.cpp \
    21252117        os2/sys0.asm \
     2118        win/amd64/ASMGetCS.asm \
     2119        win/amd64/ASMGetDS.asm \
     2120        win/amd64/ASMGetES.asm \
     2121        win/amd64/ASMGetFS.asm \
     2122        win/amd64/ASMGetGS.asm \
     2123        win/amd64/ASMGetSS.asm \
    21262124        r0drv/generic/RTMpIsCpuWorkPending-r0drv-generic.cpp \
    2127         r0drv/generic/RTMpOn-r0drv-generic.cpp \
    21282125        r0drv/generic/mpnotification-r0drv-generic.cpp \
    21292126        r0drv/generic/threadctxhooks-r0drv-generic.cpp \
    21302127        r0drv/memobj-r0drv.cpp \
    21312128        r0drv/powernotification-r0drv.c \
     2129        r0drv/os2/mp-r0drv-os2.cpp \
    21322130        r0drv/os2/alloc-r0drv-os2.cpp \
    21332131        r0drv/os2/assert-r0drv-os2.cpp \
    21342132        r0drv/os2/assertA-r0drv-os2.asm \
     
    21432141        r0drv/os2/semevent-r0drv-os2.cpp \
    21442142        r0drv/os2/semeventmulti-r0drv-os2.cpp \
    21452143        r0drv/os2/semfastmutex-r0drv-os2.cpp \
     2144        r0drv/os2/semmutex-r0drv-os2.cpp \
    21462145        r0drv/os2/spinlock-r0drv-os2.cpp \
    21472146        r0drv/os2/thread-r0drv-os2.cpp \
    21482147        r0drv/os2/thread2-r0drv-os2.cpp \
  • \src\VBox\Runtime/os2/asm-os2.cpp

    diff -urN vbox-clean-bk\src\VBox\Runtime/os2/asm-os2.cpp vbox-clean\src\VBox\Runtime/os2/asm-os2.cpp
    old new  
     1/* $Id: asm-os2.cpp 3 2015-07-31 15:39:00Z dmik $ */
     2/*******************************************************************************
     3*   Header Files                                                               *
     4*******************************************************************************/
     5//#include <iprt/asm.h>
     6#include "internal/iprt.h"
     7
     8#include <iprt/string.h>
     9#include <iprt/param.h>
     10
     11#if 1
     12
     13RTDECL(uint8_t) ASMAtomicXchgU8(volatile uint8_t *pu8, uint8_t u8)
     14{
     15    uint8_t u8Ret = *pu8;
     16    *pu8 = u8;
     17    return u8Ret;
     18}
     19
     20#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     21RTDECL(void) ASMNopPause(void)
     22{
     23}
     24#endif
     25
     26RTDECL(int) ASMBitFirstSet(const volatile void *pvBitmap, uint32_t cBits)
     27{
     28    uint32_t           iBit = 0;
     29    uint8_t volatile *pu8 = (uint8_t volatile *)pvBitmap;
     30    while (iBit < cBits)
     31    {
     32        uint8_t u8 = *pu8;
     33        if (u8 != 0)
     34        {
     35            while (!(u8 & 1))
     36            {
     37                u8 >>= 1;
     38                iBit++;
     39            }
     40            if (iBit >= cBits)
     41                return -1;
     42            return iBit;
     43        }
     44
     45        iBit += 8;
     46        pu8++;
     47    }
     48    return -1;
     49}
     50
     51#endif
  • \src\VBox\Runtime/r0drv/os2/memobj-r0drv-os2.cpp

    diff -urN vbox-clean-bk\src\VBox\Runtime/r0drv/os2/memobj-r0drv-os2.cpp vbox-clean\src\VBox\Runtime/r0drv/os2/memobj-r0drv-os2.cpp
    old new  
    514514        case RTR0MEMOBJTYPE_PHYS:
    515515            return pMemOs2->Core.u.Phys.PhysBase + (iPage << PAGE_SHIFT);
    516516
    517         case RTR0MEMOBJTYPE_RES_VIRT:
    518517        case RTR0MEMOBJTYPE_MAPPING:
     518            return rtR0MemObjNativeGetPagePhysAddr(pMemOs2->Core.uRel.Child.pParent, iPage);
     519
     520        case RTR0MEMOBJTYPE_RES_VIRT:
    519521        default:
    520522            return NIL_RTHCPHYS;
    521523    }
  • \src\VBox\Runtime/r0drv/os2/mp-r0drv-os2.cpp

    diff -urN vbox-clean-bk\src\VBox\Runtime/r0drv/os2/mp-r0drv-os2.cpp vbox-clean\src\VBox\Runtime/r0drv/os2/mp-r0drv-os2.cpp
    old new  
     1/* $Id: mp-r0drv-freebsd.c 56290 2015-06-09 14:01:31Z vboxsync $ */
     2/** @file
     3 * IPRT - Multiprocessor, Ring-0 Driver, OS/2.
     4 */
     5
     6/*
     7 * Copyright (C) 2008-2015 Oracle Corporation
     8 *
     9 * This file is part of VirtualBox Open Source Edition (OSE), as
     10 * available from http://www.virtualbox.org. This file is free software;
     11 * you can redistribute it and/or modify it under the terms of the GNU
     12 * General Public License (GPL) as published by the Free Software
     13 * Foundation, in version 2 as it comes in the "COPYING" file of the
     14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
     15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
     16 *
     17 * The contents of this file may alternatively be used under the terms
     18 * of the Common Development and Distribution License Version 1.0
     19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
     20 * VirtualBox OSE distribution, in which case the provisions of the
     21 * CDDL are applicable instead of those of the GPL.
     22 *
     23 * You may elect to license modified versions of this file under the
     24 * terms and conditions of either the GPL or the CDDL or both.
     25 */
     26
     27
     28/*******************************************************************************
     29*   Header Files                                                               *
     30*******************************************************************************/
     31#include "the-os2-kernel.h"
     32
     33#include <iprt/mp.h>
     34#include <iprt/err.h>
     35#include <iprt/asm.h>
     36#include <iprt/cpuset.h>
     37#include "r0drv/mp-r0drv.h"
     38
     39
     40RTDECL(RTCPUID) RTMpCpuId(void)
     41{
     42    return 0; // curcpu;
     43}
     44
     45
     46RTDECL(int) RTMpCurSetIndex(void)
     47{
     48    return 0; // curcpu;
     49}
     50
     51
     52RTDECL(int) RTMpCurSetIndexAndId(PRTCPUID pidCpu)
     53{
     54    return *pidCpu = 0; //curcpu;
     55}
     56
     57
     58RTDECL(int) RTMpCpuIdToSetIndex(RTCPUID idCpu)
     59{
     60    return idCpu < RTCPUSET_MAX_CPUS ? (int)idCpu : -1;
     61}
     62
     63
     64RTDECL(RTCPUID) RTMpCpuIdFromSetIndex(int iCpu)
     65{
     66    return (unsigned)iCpu < RTCPUSET_MAX_CPUS ? iCpu : NIL_RTCPUID;
     67}
     68
     69
     70RTDECL(RTCPUID) RTMpGetMaxCpuId(void)
     71{
     72    return 0; //mp_maxid;
     73}
     74
     75
     76RTDECL(bool) RTMpIsCpuPossible(RTCPUID idCpu)
     77{
     78    return idCpu <= 1; // mp_maxid;
     79}
     80
     81
     82RTDECL(PRTCPUSET) RTMpGetSet(PRTCPUSET pSet)
     83{
     84    RTCPUID idCpu;
     85
     86    RTCpuSetEmpty(pSet);
     87    idCpu = RTMpGetMaxCpuId();
     88    do
     89    {
     90        if (RTMpIsCpuPossible(idCpu))
     91            RTCpuSetAdd(pSet, idCpu);
     92    } while (idCpu-- > 0);
     93    return pSet;
     94}
     95
     96
     97RTDECL(RTCPUID) RTMpGetCount(void)
     98{
     99    return 1; //mp_maxid + 1;
     100}
     101
     102
     103RTDECL(RTCPUID) RTMpGetCoreCount(void)
     104{
     105    return 1; //mp_maxid + 1;
     106}
     107
     108RTDECL(bool) RTMpIsCpuOnline(RTCPUID idCpu)
     109{
     110    //return idCpu <= mp_maxid
     111    //    && !CPU_ABSENT(idCpu);
     112    return idCpu == 0;
     113}
     114
     115
     116RTDECL(PRTCPUSET) RTMpGetOnlineSet(PRTCPUSET pSet)
     117{
     118    RTCPUID idCpu;
     119
     120    RTCpuSetEmpty(pSet);
     121    idCpu = RTMpGetMaxCpuId();
     122    do
     123    {
     124        if (RTMpIsCpuOnline(idCpu))
     125            RTCpuSetAdd(pSet, idCpu);
     126    } while (idCpu-- > 0);
     127
     128    return pSet;
     129}
     130
     131
     132RTDECL(RTCPUID) RTMpGetOnlineCount(void)
     133{
     134    return 1; // mp_ncpus;
     135}
     136
     137
     138/**
     139 * Wrapper between the native FreeBSD per-cpu callback and PFNRTWORKER
     140 * for the RTMpOnAll API.
     141 *
     142 * @param   pvArg   Pointer to the RTMPARGS package.
     143 */
     144RTDECL(void) rtmpOnAllOS2Wrapper(void *pvArg)
     145{
     146    PRTMPARGS pArgs = (PRTMPARGS)pvArg;
     147    pArgs->pfnWorker(0, pArgs->pvUser1, pArgs->pvUser2);
     148}
     149
     150
     151RTDECL(int) RTMpOnAll(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
     152{
     153    RTMPARGS Args;
     154    Args.pfnWorker = pfnWorker;
     155    Args.pvUser1 = pvUser1;
     156    Args.pvUser2 = pvUser2;
     157    Args.idCpu = NIL_RTCPUID;
     158    Args.cHits = 0;
     159    // smp_rendezvous(NULL, rtmpOnAllOS2Wrapper, smp_no_rendevous_barrier, &Args);
     160    rtmpOnAllOS2Wrapper(&Args);
     161    return VINF_SUCCESS;
     162}
     163
     164
     165/**
     166 * Wrapper between the native FreeBSD per-cpu callback and PFNRTWORKER
     167 * for the RTMpOnOthers API.
     168 *
     169 * @param   pvArg   Pointer to the RTMPARGS package.
     170 */
     171RTDECL(void) rtmpOnOthersOS2Wrapper(void *pvArg)
     172{
     173    PRTMPARGS pArgs = (PRTMPARGS)pvArg;
     174    RTCPUID idCpu = 0; // curcpu;
     175    if (pArgs->idCpu != idCpu)
     176        pArgs->pfnWorker(idCpu, pArgs->pvUser1, pArgs->pvUser2);
     177}
     178
     179
     180RTDECL(int) RTMpOnOthers(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
     181{
     182    /* Will panic if no rendezvousing cpus, so check up front. */
     183    if (RTMpGetOnlineCount() > 1)
     184    {
     185#if 0
     186#if __FreeBSD_version >= 900000
     187        cpuset_t    Mask;
     188#elif  __FreeBSD_version >= 700000
     189        cpumask_t   Mask;
     190#endif
     191        RTMPARGS    Args;
     192
     193        Args.pfnWorker = pfnWorker;
     194        Args.pvUser1 = pvUser1;
     195        Args.pvUser2 = pvUser2;
     196        Args.idCpu = RTMpCpuId();
     197        Args.cHits = 0;
     198#if __FreeBSD_version >= 700000
     199# if __FreeBSD_version >= 900000
     200    Mask = all_cpus;
     201    CPU_CLR(curcpu, &Mask);
     202# else
     203    Mask = ~(cpumask_t)curcpu;
     204# endif
     205        smp_rendezvous_cpus(Mask, NULL, rtmpOnOthersFreeBSDWrapper, smp_no_rendevous_barrier, &Args);
     206#else
     207        smp_rendezvous(NULL, rtmpOnOthersFreeBSDWrapper, NULL, &Args);
     208#endif
     209#endif
     210        return VERR_CPU_NOT_FOUND;
     211    }
     212    return VINF_SUCCESS;
     213}
     214
     215
     216/**
     217 * Wrapper between the native FreeBSD per-cpu callback and PFNRTWORKER
     218 * for the RTMpOnSpecific API.
     219 *
     220 * @param   pvArg   Pointer to the RTMPARGS package.
     221 */
     222RTDECL(void) rtmpOnSpecificOS2Wrapper(void *pvArg)
     223{
     224    PRTMPARGS   pArgs = (PRTMPARGS)pvArg;
     225    RTCPUID     idCpu = 0; // curcpu;
     226    if (pArgs->idCpu == idCpu)
     227    {
     228        pArgs->pfnWorker(idCpu, pArgs->pvUser1, pArgs->pvUser2);
     229        ASMAtomicIncU32(&pArgs->cHits);
     230    }
     231}
     232
     233
     234RTDECL(int) RTMpOnSpecific(RTCPUID idCpu, PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
     235{
     236#if 0
     237#if __FreeBSD_version >= 900000
     238    cpuset_t    Mask;
     239#elif  __FreeBSD_version >= 700000
     240    cpumask_t   Mask;
     241#endif
     242#endif
     243    RTMPARGS    Args;
     244
     245    /* Will panic if no rendezvousing cpus, so make sure the cpu is online. */
     246    if (!RTMpIsCpuOnline(idCpu))
     247        return VERR_CPU_NOT_FOUND;
     248
     249    Args.pfnWorker = pfnWorker;
     250    Args.pvUser1 = pvUser1;
     251    Args.pvUser2 = pvUser2;
     252    Args.idCpu = idCpu;
     253    Args.cHits = 0;
     254#if 0
     255#if __FreeBSD_version >= 700000
     256# if __FreeBSD_version >= 900000
     257    CPU_SETOF(idCpu, &Mask);
     258# else
     259    Mask = (cpumask_t)1 << idCpu;
     260# endif
     261    smp_rendezvous_cpus(Mask, NULL, rtmpOnSpecificFreeBSDWrapper, smp_no_rendevous_barrier, &Args);
     262#else
     263    smp_rendezvous(NULL, rtmpOnSpecificFreeBSDWrapper, NULL, &Args);
     264#endif
     265#endif
     266    rtmpOnSpecificOS2Wrapper(&Args);
     267    return Args.cHits == 1
     268         ? VINF_SUCCESS
     269         : VERR_CPU_NOT_FOUND;
     270}
     271
     272
     273/**
     274 * Dummy callback for RTMpPokeCpu.
     275 * @param   pvArg   Ignored
     276 */
     277RTDECL(void) rtmpOS2PokeCallback(void *pvArg)
     278{
     279    NOREF(pvArg);
     280}
     281
     282
     283RTDECL(int) RTMpPokeCpu(RTCPUID idCpu)
     284{
     285#if 0
     286#if __FreeBSD_version >= 900000
     287    cpuset_t    Mask;
     288#elif  __FreeBSD_version >= 700000
     289    cpumask_t   Mask;
     290#endif
     291#endif
     292    /* Will panic if no rendezvousing cpus, so make sure the cpu is online. */
     293    if (!RTMpIsCpuOnline(idCpu))
     294        return VERR_CPU_NOT_FOUND;
     295#if 0
     296# if __FreeBSD_version >= 900000
     297    CPU_SETOF(idCpu, &Mask);
     298# else
     299    Mask = (cpumask_t)1 << idCpu;
     300# endif
     301    smp_rendezvous_cpus(Mask, NULL, rtmpFreeBSDPokeCallback, smp_no_rendevous_barrier, NULL);
     302#endif
     303    rtmpOS2PokeCallback(NULL);
     304
     305    return VINF_SUCCESS;
     306}
     307
     308
     309RTDECL(bool) RTMpOnAllIsConcurrentSafe(void)
     310{
     311    return false; // true
     312}
  • \src\VBox\Runtime/r0drv/os2/semmutex-r0drv-os2.cpp

    diff -urN vbox-clean-bk\src\VBox\Runtime/r0drv/os2/semmutex-r0drv-os2.cpp vbox-clean\src\VBox\Runtime/r0drv/os2/semmutex-r0drv-os2.cpp
    old new  
     1/* $Id: semmutex-r0drv-nt.cpp 56290 2015-06-09 14:01:31Z vboxsync $ */
     2/** @file
     3 * IPRT - Mutex Semaphores, Ring-0 Driver, NT.
     4 */
     5
     6/*
     7 * Copyright (C) 2006-2015 Oracle Corporation
     8 *
     9 * This file is part of VirtualBox Open Source Edition (OSE), as
     10 * available from http://www.virtualbox.org. This file is free software;
     11 * you can redistribute it and/or modify it under the terms of the GNU
     12 * General Public License (GPL) as published by the Free Software
     13 * Foundation, in version 2 as it comes in the "COPYING" file of the
     14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
     15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
     16 *
     17 * The contents of this file may alternatively be used under the terms
     18 * of the Common Development and Distribution License Version 1.0
     19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
     20 * VirtualBox OSE distribution, in which case the provisions of the
     21 * CDDL are applicable instead of those of the GPL.
     22 *
     23 * You may elect to license modified versions of this file under the
     24 * terms and conditions of either the GPL or the CDDL or both.
     25 */
     26
     27
     28
     29/*******************************************************************************
     30*   Header Files                                                               *
     31*******************************************************************************/
     32#define RTSEMMUTEX_WITHOUT_REMAPPING
     33#include "the-os2-kernel.h"
     34
     35#include "internal/iprt.h"
     36#include <iprt/semaphore.h>
     37#include <iprt/alloc.h>
     38#include <iprt/assert.h>
     39#include <iprt/asm.h>
     40#include <iprt/err.h>
     41#include <iprt/mem.h>
     42#include <iprt/lockvalidator.h>
     43
     44#include "internal/magics.h"
     45
     46
     47/*******************************************************************************
     48*   Structures and Typedefs                                                    *
     49*******************************************************************************/
     50/**
     51 * NT mutex semaphore.
     52 */
     53typedef struct RTSEMMUTEXINTERNAL
     54{
     55    /** Magic value (RTSEMMUTEX_MAGIC). */
     56    uint32_t volatile   u32Magic;
     57    /* Owner                     */
     58    uint32_t            fOwned;
     59    /* KEE Mutex Semaphore       */
     60    MutexLock_t         Mutex;
     61//#ifdef RT_USE_FAST_MUTEX
     62//    /** The fast mutex object. */
     63//    FAST_MUTEX          Mutex;
     64//#else
     65//    /** The NT Mutex object.   */
     66//    KMUTEX              Mutex;
     67//#endif
     68} RTSEMMUTEXINTERNAL, *PRTSEMMUTEXINTERNAL;
     69
     70
     71
     72RTDECL(int)  RTSemMutexCreate(PRTSEMMUTEX phMutexSem)
     73{
     74    return RTSemMutexCreateEx(phMutexSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL);
     75}
     76
     77
     78RTDECL(int) RTSemMutexCreateEx(PRTSEMMUTEX phMutexSem, uint32_t fFlags,
     79                               RTLOCKVALCLASS hClass, uint32_t uSubClass, const char *pszNameFmt, ...)
     80{
     81    AssertReturn(!(fFlags & ~RTSEMMUTEX_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER);
     82
     83    AssertCompile(sizeof(RTSEMMUTEXINTERNAL) > sizeof(void *));
     84    PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)RTMemAlloc(sizeof(*pThis));
     85
     86    if (!pThis)
     87        return VERR_NO_MEMORY;
     88
     89    pThis->u32Magic = RTSEMMUTEX_MAGIC;
     90    KernAllocMutexLock(&pThis->Mutex);
     91    /* Owned by someone flag */
     92    pThis->fOwned = 0;
     93//#ifdef RT_USE_FAST_MUTEX
     94//    ExInitializeFastMutex(&pThis->Mutex);
     95//#else
     96//    KeInitializeMutex(&pThis->Mutex, 0);
     97//#endif
     98
     99    *phMutexSem = pThis;
     100    return VINF_SUCCESS;
     101}
     102
     103
     104RTDECL(int) RTSemMutexDestroy(RTSEMMUTEX hMutexSem)
     105{
     106    /*
     107     * Validate input.
     108     */
     109    PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)hMutexSem;
     110    if (pThis == NIL_RTSEMMUTEX)
     111        return VINF_SUCCESS;
     112    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     113    AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
     114
     115    /*
     116     * Invalidate it and signal the object just in case.
     117     */
     118    AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, RTSEMMUTEX_MAGIC_DEAD, RTSEMMUTEX_MAGIC), VERR_INVALID_HANDLE);
     119    KernFreeMutexLock(&pThis->Mutex); // ???
     120    pThis->fOwned = 0;
     121    RTMemFree(pThis);
     122    return VINF_SUCCESS;
     123}
     124
     125
     126/**
     127 * Internal worker for RTSemMutexRequest and RTSemMutexRequestNoResume
     128 *
     129 * @returns IPRT status code.
     130 * @param   hMutexSem            The mutex handle.
     131 * @param   cMillies            The timeout.
     132 * @param   fInterruptible      Whether it's interruptible
     133 *                              (RTSemMutexRequestNoResume) or not
     134 *                              (RTSemMutexRequest).
     135 */
     136static int rtR0SemMutexRequest(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies, BOOL fInterruptible)
     137{
     138    PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)hMutexSem;
     139
     140    /*
     141     * Validate and convert input.
     142     */
     143    if (!pThis)
     144        return VERR_INVALID_HANDLE;
     145
     146    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     147    AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
     148
     149    /*
     150     * Get the mutex.
     151     */
     152    int       rc;
     153    ULONGLONG Timeout = 0;
     154    ULONG     fBlock  = BLOCK_EXCLUSIVE_MUTEX;
     155
     156    if (! fInterruptible)
     157        fBlock |= BLOCK_UNINTERRUPTABLE;
     158
     159    if (cMillies == RT_INDEFINITE_WAIT)
     160        //rcNt = KeWaitForSingleObject(&pThis->Mutex, Executive, KernelMode, fInterruptible, NULL);
     161        cMillies = SEM_INDEFINITE_WAIT;
     162    else
     163    {
     164        Timeout = (ULONG)cMillies;
     165        //Timeout.QuadPart = -(int64_t)cMillies * 10000;
     166        //rcNt = KeWaitForSingleObject(&pThis->Mutex, Executive, KernelMode, fInterruptible, &Timeout);
     167    }
     168
     169    ULONG ulData = (ULONG)VERR_INTERNAL_ERROR;
     170
     171    rc = KernBlock((ULONG)pThis, (ULONG)Timeout, fBlock,
     172                       &pThis->Mutex,
     173                       &ulData);
     174    switch (rc)
     175    {
     176        case NO_ERROR:
     177            rc = (int)ulData;
     178            Assert(rc == VINF_SUCCESS || rc == VERR_SEM_DESTROYED);
     179
     180        if (pThis->u32Magic == RTSEMMUTEX_MAGIC)
     181            {
     182                pThis->fOwned = 1;
     183                rc = VINF_SUCCESS;
     184            }
     185
     186            rc = VERR_SEM_DESTROYED;
     187            break;
     188
     189        case ERROR_TIMEOUT:
     190            Assert(Timeout != SEM_INDEFINITE_WAIT);
     191            //ASMAtomicDecU32(&pThis->cWaiters); // !!!
     192            rc = VERR_TIMEOUT;
     193            break;
     194
     195        case ERROR_INTERRUPT:
     196            Assert(fInterruptible == RTSEMWAIT_FLAGS_INTERRUPTIBLE);
     197            //ASMAtomicDecU32(&pThis->cWaiters); // !!!
     198            rc = VERR_INTERRUPTED;
     199            break;
     200
     201        default:
     202            AssertMsgFailed(("rc=%d\n", rc));
     203            rc = VERR_GENERAL_FAILURE;
     204            break;
     205    }
     206    return rc;
     207}
     208
     209
     210RTDECL(int) RTSemMutexRequest(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies)
     211{
     212    return rtR0SemMutexRequest(hMutexSem, cMillies, FALSE /*fInterruptible*/);
     213}
     214
     215
     216RTDECL(int) RTSemMutexRequestDebug(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
     217{
     218    return RTSemMutexRequest(hMutexSem, cMillies);
     219}
     220
     221
     222RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies)
     223{
     224    return rtR0SemMutexRequest(hMutexSem, cMillies, TRUE /*fInterruptible*/);
     225}
     226
     227
     228RTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
     229{
     230    return RTSemMutexRequestNoResume(hMutexSem, cMillies);
     231}
     232
     233
     234RTDECL(int) RTSemMutexRelease(RTSEMMUTEX hMutexSem)
     235{
     236    /*
     237     * Validate input.
     238     */
     239    PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)hMutexSem;
     240    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     241    AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
     242
     243    /*
     244     * Release the mutex.
     245     */
     246//#ifdef RT_USE_FAST_MUTEX
     247//    ExReleaseFastMutex(&pThis->Mutex);
     248//#else
     249//    KeReleaseMutex(&pThis->Mutex, FALSE /*Wait*/);
     250//#endif
     251    KernReleaseExclusiveMutex(&pThis->Mutex);
     252    /* Owned by someone flag */
     253    pThis->fOwned = 0;
     254
     255    return VINF_SUCCESS;
     256}
     257
     258
     259RTDECL(bool) RTSemMutexIsOwned(RTSEMMUTEX hMutexSem)
     260{
     261    /*
     262     * Validate.
     263     */
     264    PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)hMutexSem;
     265    AssertPtrReturn(pThis, false);
     266    AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, false);
     267
     268//#ifdef RT_USE_FAST_MUTEX
     269//    return pThis->Mutex && pThis->Mutex->Owner != NULL;
     270//#else
     271//    return KeReadStateMutex(&pThis->Mutex) == 1;
     272//#endif
     273    return pThis && (pThis->fOwned != 0);
     274}
     275
  • \src\VBox\Runtime/r0drv/os2/thread-r0drv-os2.cpp

    diff -urN vbox-clean-bk\src\VBox\Runtime/r0drv/os2/thread-r0drv-os2.cpp vbox-clean\src\VBox\Runtime/r0drv/os2/thread-r0drv-os2.cpp
    old new  
    7676            AssertMsgFailed(("%d\n", rc));
    7777            return VERR_NO_TRANSLATION;
    7878    }
     79   return VINF_SUCCESS;
    7980}
    8081
    8182
  • \src\VBox\Runtime/r3/os2/fileaio-os2.cpp

    diff -urN vbox-clean-bk\src\VBox\Runtime/r3/os2/fileaio-os2.cpp vbox-clean\src\VBox\Runtime/r3/os2/fileaio-os2.cpp
    old new  
     1/* $Id: fileaio-os2.cpp 56290 2015-06-09 14:01:31Z dmik $ */
     2/** @file
     3 * IPRT - File async I/O, native implementation for the Windows host platform.
     4 */
     5
     6/*
     7 * Copyright (C) 2006-2015 Oracle Corporation
     8 *
     9 * This file is part of VirtualBox Open Source Edition (OSE), as
     10 * available from http://www.virtualbox.org. This file is free software;
     11 * you can redistribute it and/or modify it under the terms of the GNU
     12 * General Public License (GPL) as published by the Free Software
     13 * Foundation, in version 2 as it comes in the "COPYING" file of the
     14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
     15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
     16 *
     17 * The contents of this file may alternatively be used under the terms
     18 * of the Common Development and Distribution License Version 1.0
     19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
     20 * VirtualBox OSE distribution, in which case the provisions of the
     21 * CDDL are applicable instead of those of the GPL.
     22 *
     23 * You may elect to license modified versions of this file under the
     24 * terms and conditions of either the GPL or the CDDL or both.
     25 */
     26
     27
     28/*******************************************************************************
     29*   Header Files                                                               *
     30*******************************************************************************/
     31#define LOG_GROUP RTLOGGROUP_DIR
     32
     33#include <iprt/asm.h>
     34#include <iprt/file.h>
     35#include <iprt/mem.h>
     36#include <iprt/assert.h>
     37#include <iprt/string.h>
     38#include <iprt/err.h>
     39#include <iprt/log.h>
     40#include "internal/fileaio.h"
     41
     42#define  INCL_DOSERRORS
     43#define  INCL_DOSFILEMGR
     44#include <os2.h>
     45
     46
     47/*******************************************************************************
     48*   Structures and Typedefs                                                    *
     49*******************************************************************************/
     50
     51/**
     52 * Transfer direction.
     53 */
     54typedef enum TRANSFERDIRECTION
     55{
     56    TRANSFERDIRECTION_INVALID = 0,
     57    /** Read. */
     58    TRANSFERDIRECTION_READ,
     59    /** Write. */
     60    TRANSFERDIRECTION_WRITE,
     61    /** The usual 32-bit hack. */
     62    TRANSFERDIRECTION_32BIT_HACK = 0x7fffffff
     63} TRANSFERDIRECTION;
     64
     65/**
     66 * Async I/O completion context state.
     67 */
     68typedef struct RTFILEAIOCTXINTERNAL
     69{
     70    /** handle to I/O completion port. */
     71    HFILE             hIoCompletionPort;
     72    /** Current number of requests pending. */
     73    volatile int32_t  cRequests;
     74    /** Flag whether the thread was woken up. */
     75    volatile bool     fWokenUp;
     76    /** Flag whether the thread is currently waiting. */
     77    volatile bool     fWaiting;
     78    /** Flags given during creation. */
     79    uint32_t          fFlags;
     80    /** Magic value (RTFILEAIOCTX_MAGIC). */
     81    uint32_t          u32Magic;
     82} RTFILEAIOCTXINTERNAL;
     83/** Pointer to an internal context structure. */
     84typedef RTFILEAIOCTXINTERNAL *PRTFILEAIOCTXINTERNAL;
     85
     86/**
     87 * Async I/O request state.
     88 */
     89typedef struct RTFILEAIOREQINTERNAL
     90{
     91    /** Overlapped structure. */
     92    // -- OVERLAPPED            Overlapped;
     93    LONGLONG              llOff;
     94    /** Current state the request is in. */
     95    RTFILEAIOREQSTATE     enmState;
     96    /** The file handle. */
     97    HFILE                 hFile;
     98    /** Kind of transfer Read/Write. */
     99    TRANSFERDIRECTION     enmTransferDirection;
     100    /** Number of bytes to transfer. */
     101    size_t                cbTransfer;
     102    /** Pointer to the buffer. */
     103    void                 *pvBuf;
     104    /** Opaque user data. */
     105    void                 *pvUser;
     106    /** Flag whether the request completed. */
     107    bool                  fCompleted;
     108    /** Number of bytes transferred successfully. */
     109    size_t                cbTransfered;
     110    /** Error code of the completed request. */
     111    int                   Rc;
     112    /** Completion context we are assigned to. */
     113    PRTFILEAIOCTXINTERNAL pCtxInt;
     114    /** Magic value  (RTFILEAIOREQ_MAGIC). */
     115    uint32_t              u32Magic;
     116} RTFILEAIOREQINTERNAL;
     117/** Pointer to an internal request structure. */
     118typedef RTFILEAIOREQINTERNAL *PRTFILEAIOREQINTERNAL;
     119
     120/*******************************************************************************
     121*   Defined Constants And Macros                                               *
     122*******************************************************************************/
     123/** Id for the wakeup event. */
     124#define AIO_CONTEXT_WAKEUP_EVENT 1
     125/** Converts a pointer to an OVERLAPPED structure to a internal request. */
     126#define OVERLAPPED_2_RTFILEAIOREQINTERNAL(pOverlapped) ( (PRTFILEAIOREQINTERNAL)((uintptr_t)(pOverlapped) - RT_OFFSETOF(RTFILEAIOREQINTERNAL, Overlapped)) )
     127
     128RTR3DECL(int) RTFileAioGetLimits(PRTFILEAIOLIMITS pAioLimits)
     129{
     130    int rcBSD = 0;
     131    AssertPtrReturn(pAioLimits, VERR_INVALID_POINTER);
     132
     133    /* No limits known. */
     134    pAioLimits->cReqsOutstandingMax = RTFILEAIO_UNLIMITED_REQS;
     135    pAioLimits->cbBufferAlignment   = 0;
     136
     137    //return VINF_SUCCESS;
     138    return VERR_NOT_IMPLEMENTED;
     139}
     140
     141RTR3DECL(int) RTFileAioReqCreate(PRTFILEAIOREQ phReq)
     142{
     143    AssertPtrReturn(phReq, VERR_INVALID_POINTER);
     144
     145    PRTFILEAIOREQINTERNAL pReqInt = (PRTFILEAIOREQINTERNAL)RTMemAllocZ(sizeof(RTFILEAIOREQINTERNAL));
     146
     147    if (RT_UNLIKELY(!pReqInt))
     148        return VERR_NO_MEMORY;
     149
     150    pReqInt->pCtxInt    = NULL;
     151    pReqInt->fCompleted = false;
     152    pReqInt->u32Magic   = RTFILEAIOREQ_MAGIC;
     153    RTFILEAIOREQ_SET_STATE(pReqInt, COMPLETED);
     154
     155    *phReq = (RTFILEAIOREQ)pReqInt;
     156
     157    return VINF_SUCCESS;
     158}
     159
     160RTDECL(int) RTFileAioReqDestroy(RTFILEAIOREQ hReq)
     161{
     162    /*
     163     * Validate the handle and ignore nil.
     164     */
     165    if (hReq == NIL_RTFILEAIOREQ)
     166        return VINF_SUCCESS;
     167
     168    PRTFILEAIOREQINTERNAL pReqInt = hReq;
     169    RTFILEAIOREQ_VALID_RETURN(pReqInt);
     170    RTFILEAIOREQ_NOT_STATE_RETURN_RC(pReqInt, SUBMITTED, VERR_FILE_AIO_IN_PROGRESS);
     171
     172    /*
     173     * Trash the magic and free it.
     174     */
     175    ASMAtomicUoWriteU32(&pReqInt->u32Magic, ~RTFILEAIOREQ_MAGIC);
     176    RTMemFree(pReqInt);
     177
     178    return VINF_SUCCESS;
     179}
     180
     181/**
     182 * Worker setting up the request.
     183 */
     184DECLINLINE(int) rtFileAioReqPrepareTransfer(RTFILEAIOREQ hReq, RTFILE hFile,
     185                                            TRANSFERDIRECTION enmTransferDirection,
     186                                            RTFOFF off, void *pvBuf, size_t cbTransfer,
     187                                            void *pvUser)
     188{
     189    /*
     190     * Validate the input.
     191     */
     192    PRTFILEAIOREQINTERNAL pReqInt = hReq;
     193    RTFILEAIOREQ_VALID_RETURN(pReqInt);
     194    RTFILEAIOREQ_NOT_STATE_RETURN_RC(pReqInt, SUBMITTED, VERR_FILE_AIO_IN_PROGRESS);
     195    Assert(hFile != NIL_RTFILE);
     196    AssertPtr(pvBuf);
     197    Assert(off >= 0);
     198    Assert(cbTransfer > 0);
     199
     200    pReqInt->enmTransferDirection  = enmTransferDirection;
     201    pReqInt->hFile                 = (HFILE)RTFileToNative(hFile);
     202    // pReqInt->Overlapped.Offset     = (ULONG)(off & 0xffffffff);
     203    // pReqInt->Overlapped.OffsetHigh = (ULONG)(off >> 32);
     204    pReqInt->llOff                 = off;
     205    pReqInt->cbTransfer            = cbTransfer;
     206    pReqInt->pvBuf                 = pvBuf;
     207    pReqInt->pvUser                = pvUser;
     208    pReqInt->fCompleted            = false;
     209
     210    return VINF_SUCCESS;
     211}
     212
     213RTDECL(int) RTFileAioReqPrepareRead(RTFILEAIOREQ hReq, RTFILE hFile, RTFOFF off,
     214                                    void *pvBuf, size_t cbRead, void *pvUser)
     215{
     216    return rtFileAioReqPrepareTransfer(hReq, hFile, TRANSFERDIRECTION_READ,
     217                                       off, pvBuf, cbRead, pvUser);
     218}
     219
     220RTDECL(int) RTFileAioReqPrepareWrite(RTFILEAIOREQ hReq, RTFILE hFile, RTFOFF off,
     221                                     void const *pvBuf, size_t cbWrite, void *pvUser)
     222{
     223    return rtFileAioReqPrepareTransfer(hReq, hFile, TRANSFERDIRECTION_WRITE,
     224                                        off, (void *)pvBuf, cbWrite, pvUser);
     225}
     226
     227RTDECL(int) RTFileAioReqPrepareFlush(RTFILEAIOREQ hReq, RTFILE hFile, void *pvUser)
     228{
     229    PRTFILEAIOREQINTERNAL pReqInt = hReq;
     230    RTFILEAIOREQ_VALID_RETURN(pReqInt);
     231    RTFILEAIOREQ_NOT_STATE_RETURN_RC(pReqInt, SUBMITTED, VERR_FILE_AIO_IN_PROGRESS);
     232    AssertReturn(hFile != NIL_RTFILE, VERR_INVALID_HANDLE);
     233
     234    return VERR_NOT_SUPPORTED;
     235}
     236
     237RTDECL(void *) RTFileAioReqGetUser(RTFILEAIOREQ hReq)
     238{
     239    PRTFILEAIOREQINTERNAL pReqInt = hReq;
     240    RTFILEAIOREQ_VALID_RETURN_RC(pReqInt, NULL);
     241
     242    return pReqInt->pvUser;
     243}
     244
     245RTDECL(int) RTFileAioReqCancel(RTFILEAIOREQ hReq)
     246{
     247    PRTFILEAIOREQINTERNAL pReqInt = hReq;
     248    RTFILEAIOREQ_VALID_RETURN(pReqInt);
     249    RTFILEAIOREQ_STATE_RETURN_RC(pReqInt, SUBMITTED, VERR_FILE_AIO_NOT_SUBMITTED);
     250
     251    /**
     252     * @todo r=aeichner It is not possible to cancel specific
     253     * requests on Windows before Vista.
     254     * CancelIo cancels all requests for a file issued by the
     255     * calling thread and CancelIoEx which does what we need
     256     * is only available from Vista and up.
     257     * The solution is to return VERR_FILE_AIO_IN_PROGRESS
     258     * if the request didn't completed yet (checked above).
     259     * Shouldn't be a big issue because a request is normally
     260     * only canceled if it exceeds a timeout which is quite huge.
     261     */
     262    return VERR_FILE_AIO_COMPLETED;
     263}
     264
     265RTDECL(int) RTFileAioReqGetRC(RTFILEAIOREQ hReq, size_t *pcbTransfered)
     266{
     267    int rc = VINF_SUCCESS;
     268    PRTFILEAIOREQINTERNAL pReqInt = hReq;
     269    RTFILEAIOREQ_VALID_RETURN(pReqInt);
     270    RTFILEAIOREQ_NOT_STATE_RETURN_RC(pReqInt, SUBMITTED, VERR_FILE_AIO_IN_PROGRESS);
     271    RTFILEAIOREQ_NOT_STATE_RETURN_RC(pReqInt, PREPARED, VERR_FILE_AIO_NOT_SUBMITTED);
     272
     273    rc = pReqInt->Rc;
     274    if (pcbTransfered && RT_SUCCESS(rc))
     275        *pcbTransfered = pReqInt->cbTransfered;
     276
     277    return rc;
     278}
     279
     280RTDECL(int) RTFileAioCtxCreate(PRTFILEAIOCTX phAioCtx, uint32_t cAioReqsMax,
     281                               uint32_t fFlags)
     282{
     283    PRTFILEAIOCTXINTERNAL pCtxInt;
     284    AssertPtrReturn(phAioCtx, VERR_INVALID_POINTER);
     285    AssertReturn(!(fFlags & ~RTFILEAIOCTX_FLAGS_VALID_MASK), VERR_INVALID_PARAMETER);
     286
     287    pCtxInt = (PRTFILEAIOCTXINTERNAL)RTMemAllocZ(sizeof(RTFILEAIOCTXINTERNAL));
     288
     289    if (RT_UNLIKELY(!pCtxInt))
     290        return VERR_NO_MEMORY;
     291
     292    //pCtxInt->hIoCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,
     293    //                                                    NULL,
     294    //                                                    0,
     295    //                                                    0);
     296    //if (RT_UNLIKELY(!pCtxInt->hIoCompletionPort))
     297    //{
     298    //    RTMemFree(pCtxInt);
     299    //    //fprintf(stderr, "%s: exit\n", __FUNCTION__);
     300    //    return VERR_NO_MEMORY;
     301    //}
     302
     303    pCtxInt->fFlags   = fFlags;
     304    pCtxInt->u32Magic = RTFILEAIOCTX_MAGIC;
     305
     306    *phAioCtx = (RTFILEAIOCTX)pCtxInt;
     307
     308    return VINF_SUCCESS;
     309}
     310
     311RTDECL(int) RTFileAioCtxDestroy(RTFILEAIOCTX hAioCtx)
     312{
     313    /* Validate the handle and ignore nil. */
     314    if (hAioCtx == NIL_RTFILEAIOCTX)
     315        return VINF_SUCCESS;
     316
     317    PRTFILEAIOCTXINTERNAL pCtxInt = hAioCtx;
     318    RTFILEAIOCTX_VALID_RETURN(pCtxInt);
     319
     320    /* Cannot destroy a busy context. */
     321    if (RT_UNLIKELY(pCtxInt->cRequests))
     322        return VERR_FILE_AIO_BUSY;
     323
     324    // CloseHandle(pCtxInt->hIoCompletionPort);
     325
     326    if (pCtxInt && pCtxInt->hIoCompletionPort)
     327        DosClose(pCtxInt->hIoCompletionPort);
     328
     329    ASMAtomicUoWriteU32(&pCtxInt->u32Magic, RTFILEAIOCTX_MAGIC_DEAD);
     330
     331    if (pCtxInt)
     332        RTMemFree(pCtxInt);
     333
     334    return VINF_SUCCESS;
     335}
     336
     337RTDECL(int) RTFileAioCtxAssociateWithFile(RTFILEAIOCTX hAioCtx, RTFILE hFile)
     338{
     339    int rc = VINF_SUCCESS;
     340    PRTFILEAIOCTXINTERNAL pCtxInt = hAioCtx;
     341    RTFILEAIOCTX_VALID_RETURN(pCtxInt);
     342
     343    // HFILE hTemp = CreateIoCompletionPort((HFILE)RTFileToNative(hFile), pCtxInt->hIoCompletionPort, 0, 1);
     344    //if (hTemp != pCtxInt->hIoCompletionPort)
     345    //    rc = RTErrConvertFromWin32(GetLastError());
     346    ////    rc = RTErrConvertFromOs2(rc);
     347
     348    return rc;
     349}
     350
     351RTDECL(uint32_t) RTFileAioCtxGetMaxReqCount(RTFILEAIOCTX hAioCtx)
     352{
     353    return RTFILEAIO_UNLIMITED_REQS;
     354}
     355
     356RTDECL(int) RTFileAioCtxSubmit(RTFILEAIOCTX hAioCtx, PRTFILEAIOREQ pahReqs, size_t cReqs)
     357{
     358    /*
     359     * Parameter validation.
     360     */
     361    int rc = VINF_SUCCESS;
     362    PRTFILEAIOCTXINTERNAL pCtxInt = hAioCtx;
     363    RTFILEAIOCTX_VALID_RETURN(pCtxInt);
     364    AssertReturn(cReqs > 0,  VERR_INVALID_PARAMETER);
     365    Assert(cReqs <= INT32_MAX);
     366    AssertPtrReturn(pahReqs, VERR_INVALID_POINTER);
     367    size_t i;
     368
     369    for (i = 0; i < cReqs; i++)
     370    {
     371        PRTFILEAIOREQINTERNAL pReqInt = pahReqs[i];
     372        ULONG cbActual;
     373        //BOOL fSucceeded;
     374
     375        Assert(pReqInt->cbTransfer == (ULONG)pReqInt->cbTransfer);
     376        if (pReqInt->enmTransferDirection == TRANSFERDIRECTION_READ)
     377        {
     378            //fSucceeded = ReadFile(pReqInt->hFile, pReqInt->pvBuf,
     379            //                      (ULONG)pReqInt->cbTransfer, NULL,
     380            //                      &pReqInt->Overlapped);
     381            rc = DosRead(pReqInt->hFile, pReqInt->pvBuf,
     382                         (ULONG)pReqInt->cbTransfer, &cbActual);
     383        }
     384        else if (pReqInt->enmTransferDirection == TRANSFERDIRECTION_WRITE)
     385        {
     386            //fSucceeded = WriteFile(pReqInt->hFile, pReqInt->pvBuf,
     387            //                       (ULONG)pReqInt->cbTransfer, NULL,
     388            //                       &pReqInt->Overlapped);
     389            rc = DosWrite(pReqInt->hFile, pReqInt->pvBuf,
     390                         (ULONG)pReqInt->cbTransfer, &cbActual);
     391        }
     392        else
     393        {
     394            //fSucceeded = false;
     395                rc = VERR_INVALID_PARAMETER;
     396            AssertMsgFailed(("Invalid transfer direction\n"));
     397        }
     398
     399        if (rc == NO_ERROR)
     400            rc = DosSetFilePtrL(pReqInt->hFile, cbActual,
     401                                FILE_BEGIN, &pReqInt->llOff);
     402
     403        if (RT_UNLIKELY(rc))
     404        {
     405            RTFILEAIOREQ_SET_STATE(pReqInt, COMPLETED);
     406            //rc = RTErrConvertFromWin32(GetLastError());
     407            ////rc = RTErrConvertFromOS2(rc);
     408            ////pReqInt->Rc = rc;
     409            break;
     410        }
     411        RTFILEAIOREQ_SET_STATE(pReqInt, SUBMITTED);
     412    }
     413
     414    ASMAtomicAddS32(&pCtxInt->cRequests, (int32_t)i);
     415
     416    return rc;
     417}
     418
     419RTDECL(int) RTFileAioCtxWait(RTFILEAIOCTX hAioCtx, size_t cMinReqs, RTMSINTERVAL cMillies,
     420                             PRTFILEAIOREQ pahReqs, size_t cReqs, uint32_t *pcReqs)
     421{
     422    /*
     423     * Validate the parameters, making sure to always set pcReqs.
     424     */
     425    AssertPtrReturn(pcReqs, VERR_INVALID_POINTER);
     426    *pcReqs = 0; /* always set */
     427    PRTFILEAIOCTXINTERNAL pCtxInt = hAioCtx;
     428    RTFILEAIOCTX_VALID_RETURN(pCtxInt);
     429    AssertPtrReturn(pahReqs, VERR_INVALID_POINTER);
     430    AssertReturn(cReqs != 0, VERR_INVALID_PARAMETER);
     431    AssertReturn(cReqs >= cMinReqs, VERR_OUT_OF_RANGE);
     432
     433    /*
     434     * Can't wait if there are no requests around.
     435     */
     436    if (   RT_UNLIKELY(ASMAtomicUoReadS32(&pCtxInt->cRequests) == 0)
     437        && !(pCtxInt->fFlags & RTFILEAIOCTX_FLAGS_WAIT_WITHOUT_PENDING_REQUESTS))
     438        return VERR_FILE_AIO_NO_REQUEST;
     439
     440    /* Wait for at least one. */
     441    if (!cMinReqs)
     442        cMinReqs = 1;
     443
     444    /*
     445     * Loop until we're woken up, hit an error (incl timeout), or
     446     * have collected the desired number of requests.
     447     */
     448    int rc = VINF_SUCCESS;
     449    int cRequestsCompleted = 0;
     450    while (   !pCtxInt->fWokenUp
     451           && cMinReqs > 0)
     452    {
     453        uint64_t     StartNanoTS = 0;
     454        ULONG        dwTimeout = cMillies; // == RT_INDEFINITE_WAIT ? INFINITE : cMillies;
     455        //cMillies == RT_INDEFINITE_WAIT ? SEM_INDEFINITE_WAIT : cMillies
     456        ULONG        cbTransfered;
     457        //LPOVERLAPPED pOverlapped;
     458        //ULONG       lCompletionKey;
     459        BOOL         fSucceeded = TRUE;
     460
     461        if (cMillies != RT_INDEFINITE_WAIT)
     462            StartNanoTS = RTTimeNanoTS();
     463
     464        ASMAtomicXchgBool(&pCtxInt->fWaiting, true);
     465        //fSucceeded = GetQueuedCompletionStatus(pCtxInt->hIoCompletionPort,
     466        //                                       &cbTransfered,
     467        //                                       &lCompletionKey,
     468        //                                       &pOverlapped,
     469        //                                       dwTimeout);
     470        ASMAtomicXchgBool(&pCtxInt->fWaiting, false);
     471        if (   !fSucceeded )
     472           // && !pOverlapped)
     473        {
     474            /* The call failed to dequeue a completion packet, includes VERR_TIMEOUT */
     475            // RTErrConvertFromWin32(GetLastError());
     476            rc = NO_ERROR; //// RTErrConvertFromOs2(rc);
     477            break;
     478        }
     479
     480        /* Check if we got woken up. */
     481        //if (lCompletionKey == AIO_CONTEXT_WAKEUP_EVENT)
     482        //{
     483            //Assert(fSucceeded && !pOverlapped);
     484            //break;
     485        //}
     486
     487        /* A request completed. */
     488        //PRTFILEAIOREQINTERNAL pReqInt = OVERLAPPED_2_RTFILEAIOREQINTERNAL(pOverlapped);
     489        //AssertPtr(pReqInt);
     490        //Assert(pReqInt->u32Magic == RTFILEAIOREQ_MAGIC);
     491
     492        /* Mark the request as finished. */
     493        //RTFILEAIOREQ_SET_STATE(pReqInt, COMPLETED);
     494
     495        //pReqInt->cbTransfered = cbTransfered;
     496        if  (! fSucceeded) // (fSucceeded)
     497        //    pReqInt->Rc = VINF_SUCCESS;
     498        //else
     499        {
     500            //ULONG errCode = GetLastError();
     501            //pReqInt->Rc = RTErrConvertFromWin32(errCode);
     502            ////pReqInt->Rc = RTErrConvertFromOs2(rc);
     503            //if (pReqInt->Rc == VERR_UNRESOLVED_ERROR)
     504            //    LogRel(("AIO/win: Request %#p returned rc=%Rrc (native %u\n)", pReqInt, pReqInt->Rc, errCode));
     505        }
     506
     507        //pahReqs[cRequestsCompleted++] = (RTFILEAIOREQ)pReqInt;
     508
     509        /* Update counter. */
     510        cMinReqs--;
     511
     512        if (cMillies != RT_INDEFINITE_WAIT)
     513        {
     514            /* Recalculate timeout. */
     515            uint64_t NanoTS = RTTimeNanoTS();
     516            uint64_t cMilliesElapsed = (NanoTS - StartNanoTS) / 1000000;
     517            if (cMilliesElapsed < cMillies)
     518                cMillies -= cMilliesElapsed;
     519            else
     520                cMillies = 0;
     521        }
     522    }
     523
     524    /*
     525     * Update the context state and set the return value.
     526     */
     527    //*pcReqs = cRequestsCompleted;
     528    //ASMAtomicSubS32(&pCtxInt->cRequests, cRequestsCompleted);
     529
     530    /*
     531     * Clear the wakeup flag and set rc.
     532     */
     533    //bool fWokenUp = ASMAtomicXchgBool(&pCtxInt->fWokenUp, false);
     534
     535    //if (    fWokenUp
     536    //    &&  RT_SUCCESS(rc))
     537    //    rc = VERR_INTERRUPTED;
     538
     539    return rc;
     540}
     541
     542RTDECL(int) RTFileAioCtxWakeup(RTFILEAIOCTX hAioCtx)
     543{
     544    int rc = VINF_SUCCESS;
     545    PRTFILEAIOCTXINTERNAL pCtxInt = hAioCtx;
     546    RTFILEAIOCTX_VALID_RETURN(pCtxInt);
     547
     548    bool fWokenUp = ASMAtomicXchgBool(&pCtxInt->fWokenUp, true);
     549    bool fWaiting = ASMAtomicReadBool(&pCtxInt->fWaiting);
     550
     551    if (   !fWokenUp
     552        && fWaiting)
     553    {
     554        //BOOL fSucceeded = PostQueuedCompletionStatus(pCtxInt->hIoCompletionPort,
     555        //                                             0, AIO_CONTEXT_WAKEUP_EVENT,
     556        //                                             NULL);
     557        //
     558        //if (!fSucceeded)
     559        //    rc = RTErrConvertFromWin32(GetLastError());
     560        ////  rc = RTErrConvertFromOs2(rc);
     561    }
     562
     563    return rc;
     564}
  • \src\VBox\Runtime/r3/os2/sems-os2.cpp

    diff -urN vbox-clean-bk\src\VBox\Runtime/r3/os2/sems-os2.cpp vbox-clean\src\VBox\Runtime/r3/os2/sems-os2.cpp
    old new  
    3333#include <os2.h>
    3434#undef RT_MAX
    3535
     36#include <iprt/time.h>
     37#include <iprt/mem.h>
     38#include <iprt/thread.h>
    3639#include <iprt/semaphore.h>
     40#include <iprt/lockvalidator.h>
    3741#include <iprt/assert.h>
    3842#include <iprt/err.h>
    3943
     44#include "internal/magics.h"
    4045
    4146/** Converts semaphore to OS/2 handle. */
    4247#define SEM2HND(Sem) ((LHANDLE)(uintptr_t)Sem)
    4348
    4449
     50/*******************************************************************************
     51*   Defined Constants And Macros                                               *
     52*******************************************************************************/
     53struct RTSEMEVENTMULTIINTERNAL
     54{
     55    /** Magic value (RTSEMEVENTMULTI_MAGIC). */
     56    uint32_t            u32Magic;
     57    /** The event handle. */
     58    HEV                 hev;
     59#ifdef RTSEMEVENT_STRICT
     60    /** Signallers. */
     61    RTLOCKVALRECSHRD    Signallers;
     62    /** Indicates that lock validation should be performed. */
     63    bool volatile       fEverHadSignallers;
     64#endif
     65};
     66
     67typedef R3R0PTRTYPE(struct RTSEMEVENTMULTIINTERNAL) RTSEMEVENTMULTIINTERNAL;
     68typedef R3R0PTRTYPE(struct RTSEMEVENTMULTIINTERNAL *) PRTSEMEVENTMULTIINTERNAL;
     69
     70/*  */
     71struct RTSEMEVENTINTERNAL
     72{
     73    /** Magic value (RTSEMEVENT_MAGIC). */
     74    uint32_t            u32Magic;
     75    /** The event handle. */
     76    HEV                 hev;
     77#ifdef RTSEMEVENT_STRICT
     78    /** Signallers. */
     79    RTLOCKVALRECSHRD    Signallers;
     80    /** Indicates that lock validation should be performed. */
     81    bool volatile       fEverHadSignallers;
     82#endif
     83    /** The creation flags. */
     84    uint32_t            fFlags;
     85};
     86
     87typedef R3R0PTRTYPE(struct RTSEMEVENTINTERNAL) RTSEMEVENTINTERNAL;
     88typedef R3R0PTRTYPE(struct RTSEMEVENTINTERNAL *) PRTSEMEVENTINTERNAL;
     89
     90/** Posix internal representation of a Mutex semaphore. */
     91struct RTSEMMUTEXINTERNAL
     92{
     93    /** Magic value (RTSEMMUTEX_MAGIC). */
     94    uint32_t                u32Magic;
     95    /** Recursion count. */
     96    uint32_t volatile       cRecursions;
     97    /** The owner thread. */
     98    RTNATIVETHREAD volatile hNativeOwner;
     99    /** The mutex handle. */
     100    HMTX                    hMtx;
     101#ifdef RTSEMMUTEX_STRICT
     102    /** Lock validator record associated with this mutex. */
     103    RTLOCKVALRECEXCL        ValidatorRec;
     104#endif
     105};
     106
     107typedef R3R0PTRTYPE(struct RTSEMMUTEXINTERNAL) RTSEMMUTEXINTERNAL;
     108typedef R3R0PTRTYPE(struct RTSEMMUTEXINTERNAL *) PRTSEMMUTEXINTERNAL;
     109
     110RTDECL(int)  RTErrConvertFromOS2(unsigned uNativeCode);
    45111
    46112RTDECL(int)  RTSemEventCreate(PRTSEMEVENT phEventSem)
    47113{
     
    58124     * Create the semaphore.
    59125     * (Auto reset, not signaled, private event object.)
    60126     */
    61     HEV hev;
     127    HEV hev = NULLHANDLE;
     128    PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)RTMemAlloc(sizeof(*pThis));
     129
     130    if (! pThis)
     131        return VERR_NO_MEMORY;
     132
    62133    int rc = DosCreateEventSem(NULL, &hev, DCE_AUTORESET | DCE_POSTONE, 0);
    63     if (!rc)
     134    if (! rc)
    64135    {
    65         *phEventSem = (RTSEMEVENT)(void *)hev;
     136        *phEventSem = (RTSEMEVENT)pThis;
     137        pThis->hev = hev;
     138        pThis->u32Magic = RTSEMEVENT_MAGIC;
    66139        return VINF_SUCCESS;
    67140    }
    68141    return RTErrConvertFromOS2(rc);
     
    77150    /*
    78151     * Close semaphore handle.
    79152     */
    80     int rc = DosCloseEventSem(SEM2HND(hEventSem));
    81     if (!rc)
     153    PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)hEventSem;
     154
     155    int rc = DosCloseEventSem(pThis->hev);
     156
     157    if (! rc)
     158    {
     159        RTMemFree(pThis);
    82160        return VINF_SUCCESS;
     161    }
     162
    83163    AssertMsgFailed(("Destroy hEventSem %p failed, rc=%d\n", hEventSem, rc));
    84164    return RTErrConvertFromOS2(rc);
    85165}
     
    90170    /*
    91171     * Wait for condition.
    92172     */
    93     int rc = DosWaitEventSem(SEM2HND(hEventSem), cMillies == RT_INDEFINITE_WAIT ? SEM_INDEFINITE_WAIT : cMillies);
     173    PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)hEventSem;
     174
     175    int rc = DosWaitEventSem(pThis->hev, cMillies == RT_INDEFINITE_WAIT ? SEM_INDEFINITE_WAIT : cMillies);
    94176    switch (rc)
    95177    {
    96178        case NO_ERROR:              return VINF_SUCCESS;
     
    111193    /*
    112194     * Signal the object.
    113195     */
    114     int rc = DosPostEventSem(SEM2HND(hEventSem));
     196    PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)hEventSem;
     197
     198    int rc = DosPostEventSem(pThis->hev);
     199
    115200    switch (rc)
    116201    {
    117202        case NO_ERROR:
     
    141226
    142227}
    143228
     229#if 1
     230
     231RTDECL(int)  RTSemEventMultiCreate(PRTSEMEVENTMULTI phEventMultiSem)
     232{
     233    return RTSemEventMultiCreateEx(phEventMultiSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, NULL);
     234}
     235
     236RTDECL(int)  RTSemEventMultiCreateEx(PRTSEMEVENTMULTI phEventMultiSem, uint32_t fFlags, RTLOCKVALCLASS hClass,
     237                                     const char *pszNameFmt, ...)
     238{
     239    AssertReturn(!(fFlags & ~RTSEMEVENTMULTI_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER);
     240
     241    /*
     242     * Create the semaphore.
     243     * (Manual reset, not signaled, private event object.)
     244     */
     245    HEV hev = NULLHANDLE;
     246    PRTSEMEVENTMULTIINTERNAL pThis = NULL;
     247
     248    int rc = DosCreateEventSem(NULL, &hev, 0, FALSE);
     249
     250    if (!rc)
     251    {
     252        pThis = (PRTSEMEVENTMULTIINTERNAL)RTMemAlloc(sizeof(*pThis));
     253       
     254        if (! pThis)
     255            return VERR_NO_MEMORY;
     256
     257        pThis->hev = hev;
     258        pThis->u32Magic = RTSEMEVENTMULTI_MAGIC;
     259        *phEventMultiSem  = (RTSEMEVENTMULTI)pThis;
     260        return VINF_SUCCESS;
     261    }
     262
     263    return RTErrConvertFromOS2(rc);
     264}
     265
     266
     267RTDECL(int)  RTSemEventMultiDestroy(RTSEMEVENTMULTI hEventMultiSem)
     268{
     269    if (hEventMultiSem == NIL_RTSEMEVENTMULTI)
     270        return VINF_SUCCESS;
     271
     272    /*
     273     * Close semaphore handle.
     274     */
     275    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
     276
     277    int rc = DosCloseEventSem(pThis->hev);
     278
     279    if (!rc)
     280    {
     281        RTMemFree(pThis);
     282        return VINF_SUCCESS;
     283    }
     284
     285    AssertMsgFailed(("Destroy hEventMultiSem %p failed, rc=%d\n", hEventMultiSem, rc));
     286    return RTErrConvertFromOS2(rc);
     287}
     288
     289
     290RTDECL(int)  RTSemEventMultiSignal(RTSEMEVENTMULTI hEventMultiSem)
     291{
     292    /*
     293     * Signal the object.
     294     */
     295    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
     296
     297    int rc = DosPostEventSem(pThis->hev);
     298
     299    switch (rc)
     300    {
     301        case NO_ERROR:
     302        case ERROR_ALREADY_POSTED:
     303        case ERROR_TOO_MANY_POSTS:
     304            return VINF_SUCCESS;
     305        default:
     306            return RTErrConvertFromOS2(rc);
     307    }
     308}
     309
     310
     311RTDECL(int)  RTSemEventMultiReset(RTSEMEVENTMULTI hEventMultiSem)
     312{
     313    /*
     314     * Reset the object.
     315     */
     316    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
     317    ULONG ulIgnore = 0;
     318    int rc = DosResetEventSem(pThis->hev, &ulIgnore);
     319    switch (rc)
     320    {
     321        case NO_ERROR:
     322        case ERROR_ALREADY_RESET:
     323            return VINF_SUCCESS;
     324        default:
     325            return RTErrConvertFromOS2(rc);
     326    }
     327}
     328
     329
     330RTDECL(int)  RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies)
     331{
     332    /*
     333     * Wait for condition.
     334     */
     335    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
     336
     337    int rc = DosWaitEventSem(pThis->hev, cMillies == RT_INDEFINITE_WAIT ? SEM_INDEFINITE_WAIT : cMillies);
     338
     339    switch (rc)
     340    {
     341        case NO_ERROR:              return VINF_SUCCESS;
     342        case ERROR_SEM_TIMEOUT:
     343        case ERROR_TIMEOUT:         return VERR_TIMEOUT;
     344        case ERROR_INTERRUPT:       return VERR_INTERRUPTED;
     345        default:
     346        {
     347            AssertMsgFailed(("Wait on hEventMultiSem %p failed, rc=%d\n", hEventMultiSem, rc));
     348            rc = RTErrConvertFromOS2(rc);
     349            return rc;
     350        }
     351    }
     352}
     353
     354RTDECL(int) rtSemEventMultiOs2Wait(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout,
     355                                       PCRTLOCKVALSRCPOS pSrcPos)
     356{
     357    /*
     358     * Validate input.
     359     */
     360    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
     361
     362    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     363    AssertReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, VERR_INVALID_HANDLE);
     364    AssertReturn(RTSEMWAIT_FLAGS_ARE_VALID(fFlags), VERR_INVALID_PARAMETER);
     365
     366    /*
     367     * Convert the timeout to a millisecond count.
     368     */
     369    uint64_t    uAbsDeadline;
     370    LONG        dwMsTimeout;
     371
     372    if (fFlags & RTSEMWAIT_FLAGS_INDEFINITE)
     373    {
     374        dwMsTimeout  = -1; // INFINITE;
     375        uAbsDeadline = UINT64_MAX;
     376    }
     377    else
     378    {
     379        if (fFlags & RTSEMWAIT_FLAGS_NANOSECS)
     380            uTimeout = uTimeout < UINT64_MAX - UINT32_C(1000000) / 2
     381                     ? (uTimeout + UINT32_C(1000000) / 2) / UINT32_C(1000000)
     382                     : UINT64_MAX / UINT32_C(1000000);
     383        if (fFlags & RTSEMWAIT_FLAGS_ABSOLUTE)
     384        {
     385            uAbsDeadline = uTimeout;
     386            uint64_t u64Now = RTTimeSystemMilliTS();
     387            if (u64Now < uTimeout)
     388                uTimeout -= u64Now;
     389            else
     390                uTimeout = 0;
     391        }
     392        else if (fFlags & RTSEMWAIT_FLAGS_RESUME)
     393            uAbsDeadline = RTTimeSystemMilliTS() + uTimeout;
     394        else
     395            uAbsDeadline = UINT64_MAX;
     396
     397        dwMsTimeout = (uTimeout < UINT32_MAX)
     398                    ? (LONG)uTimeout
     399                    : (LONG)-1;
     400    }
     401
     402    /*
     403     * Do the wait.
     404     */
     405    int rc;
     406#ifdef RTSEMEVENT_STRICT
     407    RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
     408
     409    if ((PRTSEMEVENTMULTIINTERNAL)pThis->fEverHadSignallers)
     410    {
     411        do
     412            // rc = WaitForSingleObjectEx(pThis->hev, 0 /*Timeout*/, TRUE /*fAlertable*/);
     413            rc = RTErrConvertFromOS2(DosWaitEventSem(pThis->hev, 0 /*Timeout*/));
     414        while (rc == VERR_INTERRUPTED && (fFlags & RTSEMWAIT_FLAGS_RESUME));
     415
     416        if ((rc != VERR_INTERRUPTED && rc != VERR_TIMEOUT) || dwMsTimeout == 0)
     417        {
     418            //return rtSemEventWaitHandleStatus(pThis, fFlags, rc);
     419            rc = RTErrConvertFromOS2(rc);
     420            return rc;
     421        }
     422
     423        int rc9 = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
     424                                                        dwMsTimeout, RTTHREADSTATE_EVENT_MULTI, true);
     425        if (RT_FAILURE(rc9))
     426            return rc9;
     427    }
     428#else
     429    RTTHREAD hThreadSelf = RTThreadSelf();
     430#endif
     431    RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT_MULTI, true);
     432
     433    //rc = WaitForSingleObjectEx(pThis->hev, dwMsTimeout, TRUE /*fAlertable*/);
     434    rc = RTErrConvertFromOS2(DosWaitEventSem(pThis->hev, dwMsTimeout));
     435
     436    if ((rc == VERR_INTERRUPTED || rc == VERR_TIMEOUT) && (fFlags & RTSEMWAIT_FLAGS_RESUME))
     437    {
     438        while ( (rc == VERR_INTERRUPTED || rc == VERR_TIMEOUT)
     439               && RTTimeSystemMilliTS() < uAbsDeadline)
     440            //rc = WaitForSingleObjectEx(pThis->hev, dwMsTimeout, TRUE /*fAlertable*/);
     441            rc = RTErrConvertFromOS2(DosWaitEventSem(pThis->hev, dwMsTimeout));
     442    }
     443
     444    RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT_MULTI);
     445
     446    // return rtSemEventWaitHandleStatus(pThis, fFlags, rc);
     447    return rc;
     448}
     449
     450
     451RTDECL(int)  RTSemEventMultiWaitEx(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout)
     452{
     453#ifndef RTSEMEVENT_STRICT
     454    return rtSemEventMultiOs2Wait(hEventMultiSem, fFlags, uTimeout, NULL);
     455#else
     456    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API();
     457    return rtSemEventMultiOs2Wait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
     458#endif
     459}
    144460
    145461
     462RTDECL(int)  RTSemEventMultiWaitExDebug(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout,
     463                                        RTHCUINTPTR uId, RT_SRC_POS_DECL)
     464{
     465    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API();
     466    return rtSemEventMultiOs2Wait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
     467}
     468
     469#else
    146470
    147471RTDECL(int)  RTSemEventMultiCreate(PRTSEMEVENTMULTI phEventMultiSem)
    148472{
     
    242566    }
    243567}
    244568
     569#endif
    245570
    246571RTDECL(void) RTSemEventMultiSetSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread)
    247572{
     
    259584}
    260585
    261586
    262 
    263 #undef RTSemMutexCreate
    264587RTDECL(int)  RTSemMutexCreate(PRTSEMMUTEX phMutexSem)
    265588{
    266589    return RTSemMutexCreateEx(phMutexSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL);
     
    276599     * Create the semaphore.
    277600     */
    278601    HMTX hmtx;
     602    PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)RTMemAlloc(sizeof(*pThis));
     603
     604    if (! pThis)
     605        return VERR_NO_MEMORY;
     606
    279607    int rc = DosCreateMutexSem(NULL, &hmtx, 0, FALSE);
    280     if (!rc)
     608
     609    if (! rc)
    281610    {
    282611        /** @todo implement lock validation of OS/2 mutex semaphores. */
    283         *phMutexSem = (RTSEMMUTEX)(void *)hmtx;
     612        *phMutexSem = (RTSEMMUTEX)pThis;
     613        pThis->hMtx = hmtx;
     614        pThis->u32Magic = RTSEMMUTEX_MAGIC;
    284615        return VINF_SUCCESS;
    285616    }
    286617
     
    296627    /*
    297628     * Close semaphore handle.
    298629     */
    299     int rc = DosCloseMutexSem(SEM2HND(hMutexSem));
    300     if (!rc)
     630    PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)hMutexSem;
     631
     632    int rc = DosCloseMutexSem(pThis->hMtx);
     633
     634    if (! rc)
     635    {
     636        RTMemFree(pThis);
    301637        return VINF_SUCCESS;
     638    }
     639
    302640    AssertMsgFailed(("Destroy hMutexSem %p failed, rc=%d\n", hMutexSem, rc));
    303641    return RTErrConvertFromOS2(rc);
    304642}
     
    311649    /*
    312650     * Validate.
    313651     */
    314     RTSEMMUTEXINTERNAL *pThis = hMutexSem;
     652    RTSEMMUTEXINTERNAL *pThis = (RTSEMMUTEXINTERNAL *)hMutexSem;
    315653    AssertPtrReturn(pThis, RTLOCKVAL_SUB_CLASS_INVALID);
    316654    AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, RTLOCKVAL_SUB_CLASS_INVALID);
    317655
    318     return RTLockValidatorRecExclSetSubClass(&pThis->ValidatorRec, uSubClass);
     656    return RTLockValidatorRecExclSetSubClass(pThis->ValidatorRec, uSubClass);
    319657#else
    320658    return RTLOCKVAL_SUB_CLASS_INVALID;
    321659#endif
    322660}
    323661
    324 
    325 #undef RTSemMutexRequestNoResume
    326662RTDECL(int)  RTSemMutexRequestNoResume(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies)
    327663{
    328664    /*
    329665     * Lock mutex semaphore.
    330666     */
    331     int rc = DosRequestMutexSem(SEM2HND(hMutexSem), cMillies == RT_INDEFINITE_WAIT ? SEM_INDEFINITE_WAIT : cMillies);
     667    PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)hMutexSem;
     668
     669    int rc = DosRequestMutexSem(pThis->hMtx, cMillies == RT_INDEFINITE_WAIT ? SEM_INDEFINITE_WAIT : cMillies);
     670
    332671    switch (rc)
    333672    {
    334673        case NO_ERROR:              return VINF_SUCCESS;
     
    357696    /*
    358697     * Unlock mutex semaphore.
    359698     */
    360     int rc = DosReleaseMutexSem(SEM2HND(hMutexSem));
     699    PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)hMutexSem;
     700
     701    int rc = DosReleaseMutexSem(pThis->hMtx);
     702
    361703    if (!rc)
    362704        return VINF_SUCCESS;
     705
    363706    AssertMsgFailed(("Release hMutexSem %p failed, rc=%d\n", hMutexSem, rc));
    364707    return RTErrConvertFromOS2(rc);
    365708}
     
    373716    PID     pid;
    374717    TID     tid;
    375718    ULONG   cRecursions;
    376     int rc = DosQueryMutexSem(SEM2HND(hMutexSem), &pid, &tid, &cRecursions);
     719
     720    PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)hMutexSem;
     721
     722    int rc = DosQueryMutexSem(pThis->hMtx, &pid, &tid, &cRecursions);
     723
    377724    if (!rc)
    378725        return cRecursions != 0;
     726
    379727    AssertMsgFailed(("DosQueryMutexSem %p failed, rc=%d\n", hMutexSem, rc));
    380728    return rc == ERROR_SEM_OWNER_DIED;
    381729}
  • \src\VBox\Runtime/r3/os2/thread-os2.cpp

    diff -urN vbox-clean-bk\src\VBox\Runtime/r3/os2/thread-os2.cpp vbox-clean\src\VBox\Runtime/r3/os2/thread-os2.cpp
    old new  
    3030*******************************************************************************/
    3131#define LOG_GROUP RTLOGGROUP_THREAD
    3232#define INCL_BASE
     33#define INCL_PROCESS
    3334#include <os2.h>
    3435#undef RT_MAX
    3536
     
    5556*   Global Variables                                                           *
    5657*******************************************************************************/
    5758/** Pointer to thread local memory which points to the current thread. */
    58 static PRTTHREADINT *g_ppCurThread;
     59static PRTTHREADINT *g_ppCurThread = NULL;
    5960
    6061
    6162/*******************************************************************************
    6263*   Internal Functions                                                         *
    6364*******************************************************************************/
    6465static void rtThreadNativeMain(void *pvArgs);
     66static int rtOs2GetThreadOrdinal(void);
    6567
    6668
    6769DECLHIDDEN(int) rtThreadNativeInit(void)
     
    6971    /*
    7072     * Allocate thread local memory.
    7173     */
    72     PULONG pul;
     74    PULONG pul = NULL;
    7375    int rc = DosAllocThreadLocalMemory(1, &pul);
    7476    if (rc)
    7577        return VERR_NO_TLS_FOR_SELF;
     
    101103DECLHIDDEN(int) rtThreadNativeAdopt(PRTTHREADINT pThread)
    102104{
    103105
     106    if (pThread == NULL)
     107        return VERR_FAILED_TO_SET_SELF_TLS;
     108
    104109    *g_ppCurThread = pThread;
    105110    return VINF_SUCCESS;
    106111}
     
    118123 */
    119124static void rtThreadNativeMain(void *pvArgs)
    120125{
     126    int   rc;
    121127    rtThreadOs2BlockSigAlarm();
    122128
    123129    /*
    124130     * Call common main.
    125131     */
     132    RTNATIVETHREAD pNativeThread = RTThreadNativeSelf();
    126133    PRTTHREADINT  pThread = (PRTTHREADINT)pvArgs;
     134
     135    Assert(pThread == NULL);
    127136    *g_ppCurThread = pThread;
    128137
     138#if 0
    129139#ifdef fibGetTidPid
    130     rtThreadMain(pThread, fibGetTidPid(), &pThread->szName[0]);
     140    rc = rtThreadMain(pThread, fibGetTidPid(), &pThread->szName[0]);
    131141#else
    132     rtThreadMain(pThread, _gettid(), &pThread->szName[0]);
     142    rc = rtThreadMain(pThread, (unsigned short)_gettid(), &pThread->szName[0]);
     143#endif
    133144#endif
     145    rc = rtThreadMain(pThread, pNativeThread, &pThread->szName[0]);
    134146
    135147    *g_ppCurThread = NULL;
    136     _endthread();
     148    DosExit(EXIT_THREAD, rc);
    137149}
    138150
    139151
    140152DECLHIDDEN(int) rtThreadNativeCreate(PRTTHREADINT pThread, PRTNATIVETHREAD pNativeThread)
    141153{
     154    AssertReturn(pThread->cbStack < ~(unsigned)0, VERR_INVALID_PARAMETER);
     155
    142156    /*
    143157     * Default stack size.
    144158     */
     
    148162    /*
    149163     * Create the thread.
    150164     */
    151     int iThreadId = _beginthread(rtThreadNativeMain, NULL, pThread->cbStack, pThread);
    152     if (iThreadId > 0)
     165    TID    tid = NULL;
     166    APIRET rc;
     167    rc = DosCreateThread(&tid, (PFNTHREAD)rtThreadNativeMain, (ULONG)pThread,
     168                         CREATE_READY | STACK_SPARSE, pThread->cbStack);
     169    if (! rc)
    153170    {
    154171#ifdef fibGetTidPid
    155         *pNativeThread = iThreadId | (fibGetPid() << 16);
     172        tid |= (fibGetPid() << 16);
     173        *pNativeThread = tid;
    156174#else
    157         *pNativeThread = iThreadId;
     175        *pNativeThread = (unsigned short)tid;
    158176#endif
    159177        return VINF_SUCCESS;
    160178    }
     
    165183RTDECL(RTTHREAD) RTThreadSelf(void)
    166184{
    167185    PRTTHREADINT pThread = *g_ppCurThread;
     186    Assert(pThread == NULL);
     187
    168188    if (pThread)
    169189        return (RTTHREAD)pThread;
    170190    /** @todo import alien threads? */
    171     return NULL;
     191    return (RTTHREAD)NULL;
    172192}
    173193
    174194
     
    318338{
    319339    return VERR_NOT_IMPLEMENTED;
    320340}
     341
     342DECLHIDDEN(int) rtOs2GetThreadOrdinal(void)
     343{
     344   PPIB ppib;
     345   PTIB ptib;
     346
     347   DosGetInfoBlocks(&ptib, &ppib);
     348
     349   return (int)( ptib->tib_ordinal );
     350}
  • \src\VBox\Runtime/r3/os2/time-os2.cpp

    diff -urN vbox-clean-bk\src\VBox\Runtime/r3/os2/time-os2.cpp vbox-clean\src\VBox\Runtime/r3/os2/time-os2.cpp
    old new  
    11/* $Id: time-os2.cpp 3 2015-07-31 15:39:00Z dmik $ */
    22/** @file
    3  * IPRT - Time, POSIX.
     3 * IPRT - Time, OS/2.
    44 */
    55
    66/*
     
    3535#define LOG_GROUP RTLOGGROUP_TIME
    3636#include <InnoTekLIBC/FastInfoBlocks.h>
    3737
     38#define  INCL_DOSPROFILE
     39#include <os2.h>
     40
    3841#include <iprt/time.h>
    3942#include "internal/time.h"
    4043
     
    4245
    4346RTDECL(uint64_t) RTTimeSystemNanoTS(void)
    4447{
    45     return fibGetMsCount() * UINT64_C(10000000);
     48    uint64_t t;
     49    static ULONG freq = 0;
     50    ULONGLONG time;
     51#if 1
     52    t = fibGetMsCount() * UINT64_C(1000000);
     53#else
     54    if (! freq)
     55        DosTmrQueryFreq(&freq);
     56
     57    DosTmrQueryTime((QWORD *)&time);
     58    t = (uint64_t)(time * 1000000000) / freq;
     59#endif
     60
     61    return t;
    4662}
    4763
    4864
    4965RTDECL(uint64_t) RTTimeSystemMilliTS(void)
    5066{
    51     return fibGetMsCount();
     67    uint64_t t;
     68#if 1
     69    t = fibGetMsCount();
     70#else
     71    t = RTTimeSystemNanoTS() / 1000000;
     72#endif
     73    return t;
    5274}
    5375
  • \src\VBox\Runtime/testcase/Makefile.kmk

    diff -urN vbox-clean-bk\src\VBox\Runtime/testcase/Makefile.kmk vbox-clean\src\VBox\Runtime/testcase/Makefile.kmk
    old new  
    125125        tstRTTemp \
    126126        tstRTDirCreateUniqueNumbered \
    127127        tstTermCallbacks \
    128         tstThread-1 \
    129         tstRTThreadPoke \
     128        tstThread-1
     129
     130ifdef RTTHREAD_POSIX_WITH_POKE
     131PROGRAMS += \
     132        tstRTThreadPoke
     133endif
     134PROGRAMS += \
    130135        tstRTThreadExecutionTime \
    131136        tstRTTime \
    132137        tstTime-2 \
  • \src\VBox\Runtime/testcase/tstLdrDisasmTest.cpp

    diff -urN vbox-clean-bk\src\VBox\Runtime/testcase/tstLdrDisasmTest.cpp vbox-clean\src\VBox\Runtime/testcase/tstLdrDisasmTest.cpp
    old new  
    3838#include <VBox/disopcode.h>
    3939#include <iprt/string.h>
    4040
    41 #if defined(IN_RING0) && !defined(RT_OS_WINDOWS) /* Too lazy to make import libs. */
     41#if defined(IN_RING0) && !defined(RT_OS_WINDOWS) && !defined(RT_OS_OS2) /* Too lazy to make import libs. */
    4242extern "C" DECLIMPORT(int) MyPrintf(const char *pszFormat, ...);
    4343# define MY_PRINTF(a) MyPrintf a
    4444#else