/*********************************************************
- * Copyright (C) 2010-2019 VMware, Inc. All rights reserved.
+ * Copyright (C) 2010-2020 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
#include "windowsu.h"
#endif
-#define MXUSER_A_BILLION (1000 * 1000 * 1000)
+#define MXUSER_A_MILLION (1000 * 1000)
+#define MXUSER_A_BILLION (1000 * MXUSER_A_MILLION)
#if defined(_WIN32)
typedef HANDLE NativeSemaphore;
static int
MXUserTimedDown(NativeSemaphore *sema, // IN:
- uint32 waitTimeMsec, // IN:
+ uint64 waitTimeNS, // IN:
Bool *downOccurred) // OUT:
{
int err;
DWORD status;
+ const uint64 maxWaitTimeMS = (uint64) 0x7FFFFFFF;
+ uint64 waitTimeMS = CEILING(waitTimeNS, (uint64) MXUSER_A_MILLION);
- status = WaitForSingleObject(*sema, waitTimeMsec);
+ if (waitTimeMS > maxWaitTimeMS) {
+ waitTimeMS = maxWaitTimeMS;
+ }
+
+ status = WaitForSingleObject(*sema, (int) waitTimeMS);
switch (status) {
case WAIT_OBJECT_0: // The down (decrement) occurred
static int
MXUserTimedDown(NativeSemaphore *sema, // IN:
- uint32 waitTimeMsec, // IN:
+ uint64 waitTimeNS, // IN:
Bool *downOccurred) // OUT:
{
- int64 nsecWait = 1000000LL * (int64)waitTimeMsec;
- dispatch_time_t deadline = dispatch_time(DISPATCH_TIME_NOW, nsecWait);
+ dispatch_time_t deadline = dispatch_time(DISPATCH_TIME_NOW, waitTimeNS);
*downOccurred = dispatch_semaphore_wait(*sema, deadline) == 0;
+
return 0;
}
static int
MXUserTimedDown(NativeSemaphore *sema, // IN:
- uint32 waitTimeMsec, // IN:
+ uint64 waitTimeNS, // IN:
Bool *downOccurred) // OUT:
{
int err;
gettimeofday(&curTime, NULL);
endNS = ((uint64) curTime.tv_sec * MXUSER_A_BILLION) +
((uint64) curTime.tv_usec * 1000) +
- ((uint64) waitTimeMsec * (1000 * 1000));
+ waitTimeNS;
endTime.tv_sec = (time_t) (endNS / MXUSER_A_BILLION);
endTime.tv_nsec = (long int) (endNS % MXUSER_A_BILLION);
int err;
ASSERT(sema != NULL);
+
MXUserValidateHeader(&sema->header, MXUSER_TYPE_SEMA);
Atomic_Inc(&sema->activeUserCount);
/*
*-----------------------------------------------------------------------------
*
- * MXUser_TimedDownSemaphore --
+ * MXUser_TimedDownSemaphoreNS --
*
* Perform a down (P; probeer te verlagen; "try to reduce") operation
* on a semaphore with a timeout. The wait time will always have elapsed
* before the routine returns.
*
+ * NOT ALL SUPPORTED PLATFORMS CAN NATIVELY HANDLE WAIT TIMES OF LESS
+ * THAN A MILLISECOND. WAIT TIMES WILL BE ROUNDED UP WHEN NECESSARY.
+ *
+ * WAIT TIMES LONGER THAN A SUPPORTED PLATFORM CAN SUPPORT WILL BE
+ * SET TO THE MAXIMUM POSSIBLE.
+ *
* Results:
* TRUE Down operation occurred (count has been decremented)
* FALSE Down operation did not occur (time out occurred)
*/
Bool
-MXUser_TimedDownSemaphore(MXUserSemaphore *sema, // IN/OUT:
- uint32 waitTimeMsec) // IN:
+MXUser_TimedDownSemaphoreNS(MXUserSemaphore *sema, // IN/OUT:
+ uint64 waitTimeNS) // IN:
{
int err;
Bool downOccurred = FALSE;
ASSERT(sema != NULL);
+
MXUserValidateHeader(&sema->header, MXUSER_TYPE_SEMA);
Atomic_Inc(&sema->activeUserCount);
if (tryDownSuccess) {
downOccurred = TRUE;
} else {
- err = MXUserTimedDown(&sema->nativeSemaphore, waitTimeMsec,
+ err = MXUserTimedDown(&sema->nativeSemaphore, waitTimeNS,
&downOccurred);
}
}
}
}
} else {
- err = MXUserTimedDown(&sema->nativeSemaphore, waitTimeMsec,
+ err = MXUserTimedDown(&sema->nativeSemaphore, waitTimeNS,
&downOccurred);
}
}
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_TimedDownSemaphore --
+ *
+ * Perform a down (P; probeer te verlagen; "try to reduce") operation
+ * on a semaphore with a timeout. The wait time will always have elapsed
+ * before the routine returns.
+ *
+ * ALL SUPPORTED PLATFORMS CAN NATIVELY HANDLE MILLISECOND WAITS.
+ *
+ * Results:
+ * TRUE Down operation occurred (count has been decremented)
+ * FALSE Down operation did not occur (time out occurred)
+ *
+ * Side effects:
+ * The caller may sleep.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+MXUser_TimedDownSemaphore(MXUserSemaphore *sema, // IN/OUT:
+ uint32 waitTimeMS) // IN:
+{
+ return MXUser_TimedDownSemaphoreNS(sema,
+ (uint64) MXUSER_A_MILLION * waitTimeMS);
+}
+
+
/*
*-----------------------------------------------------------------------------
*
Bool downOccurred = FALSE;
ASSERT(sema != NULL);
+
MXUserValidateHeader(&sema->header, MXUSER_TYPE_SEMA);
Atomic_Inc(&sema->activeUserCount);
int err;
ASSERT(sema != NULL);
+
MXUserValidateHeader(&sema->header, MXUSER_TYPE_SEMA);
/*