And implemented 128-bit muldiv on Windows.
This commit is contained in:
parent
288c74b026
commit
ff803bf792
|
@ -147,6 +147,12 @@ static void queueThread(void *data)
|
|||
uiQueueMain(queued, p);
|
||||
}
|
||||
|
||||
/*
|
||||
TODO if I remove the uiQuit() from this test on Windows, I will occasionally get
|
||||
=== RUN TestQueueMain_DifferentThread
|
||||
../test/initmain.c:161: uiMain() timed out (5s)
|
||||
--- FAIL: TestQueueMain_DifferentThread (4.9989539s)
|
||||
*/
|
||||
testingTest(QueueMain_DifferentThread)
|
||||
{
|
||||
threadThread *thread;
|
||||
|
|
|
@ -305,3 +305,48 @@ void timerprivMulDivUint64(uint64_t x, uint64_t y, uint64_t z, timerprivInt128 *
|
|||
int128FromUint64(z, &c);
|
||||
int128MulDiv64(&a, &b, &c, quot);
|
||||
}
|
||||
|
||||
int64_t timerprivInt128ToInt64(const timerprivInt128 *n, int64_t min, int64_t max, int64_t minCap, int64_t maxCap)
|
||||
{
|
||||
if (n->neg) {
|
||||
int64_t ret;
|
||||
|
||||
if (n->high > 0)
|
||||
return minCap;
|
||||
if (n->low > (uint64_t) INT64_MAX) {
|
||||
// we can't safely convert n->low to int64_t
|
||||
#if INT64_MIN == -INT64_MAX
|
||||
// in this case, we can't store -n->low in an int64_t at all!
|
||||
// therefore, it must be out of range
|
||||
return minCap;
|
||||
#else
|
||||
// in this case, INT64_MIN == -INT64_MAX - 1
|
||||
if (n->low > ((uint64_t) INT64_MAX) + 1)
|
||||
// we still can't store -n->low in an int64_t
|
||||
return minCap;
|
||||
// only one option left
|
||||
ret = INT64_MIN;
|
||||
#endif
|
||||
} else {
|
||||
// -n->low can safely be stored in an int64_t, so do so
|
||||
ret = (int64_t) (n->low);
|
||||
ret = -ret;
|
||||
}
|
||||
if (ret < min)
|
||||
return minCap;
|
||||
return ret;
|
||||
}
|
||||
if (n->high > 0)
|
||||
return maxCap;
|
||||
if (n->low > (uint64_t) max)
|
||||
return maxCap;
|
||||
return (int64_t) (n->low);
|
||||
}
|
||||
|
||||
uint64_t timerprivInt128ToUint64(const timerprivInt128 *n, uint64_t max, uint64_t maxCap)
|
||||
{
|
||||
if (n->neg)
|
||||
return 0;
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
typedef int64_t timerDuration;
|
||||
typedef int64_t timerTime;
|
||||
|
||||
#define timerTimeMin ((timerTime) INT64_MIN)
|
||||
#define timerTimeMax ((timerTime) INT64_MAX)
|
||||
|
||||
#define timerNanosecond ((timerDuration) 1)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "timer.h"
|
||||
#include "timerpriv.h"
|
||||
|
||||
static HRESULT lastErrorCodeToHRESULT(DWORD lastError)
|
||||
{
|
||||
|
@ -181,18 +182,13 @@ timerTime timerMonotonicNow(void)
|
|||
timerDuration timerTimeSub(timerTime end, timerTime start)
|
||||
{
|
||||
LARGE_INTEGER qpf;
|
||||
timerDuration qpnsQuot, qpnsRem;
|
||||
timerTime c;
|
||||
timerDuration ret;
|
||||
timerprivInt128 quot;
|
||||
|
||||
QueryPerformanceFrequency(&qpf);
|
||||
qpnsQuot = timerSecond / qpf.QuadPart;
|
||||
qpnsRem = timerSecond % qpf.QuadPart;
|
||||
c = end - start;
|
||||
|
||||
ret = ((timerDuration) c) * qpnsQuot;
|
||||
ret += (c * qpnsRem) / qpf.QuadPart;
|
||||
return ret;
|
||||
timerprivMulDivInt64(end - start, timerSecond, qpf.QuadPart, ");
|
||||
return timerprivInt128ToInt64(",
|
||||
INT64_MIN, INT64_MAX,
|
||||
timerTimeMin, timerTimeMax);
|
||||
}
|
||||
|
||||
// note: the idea for the SetThreadContext() nuttery is from https://www.codeproject.com/Articles/71529/Exception-Injection-Throwing-an-Exception-in-Other
|
||||
|
|
|
@ -10,3 +10,5 @@ struct timerprivInt128 {
|
|||
|
||||
extern void timerprivMulDivInt64(int64_t x, int64_t y, int64_t z, timerprivInt128 *quot);
|
||||
extern void timerprivMulDivUint64(uint64_t x, uint64_t y, uint64_t z, timerprivInt128 *quot);
|
||||
extern int64_t timerprivInt128ToInt64(const timerprivInt128 *n, int64_t min, int64_t max, int64_t minCap, int64_t maxCap);
|
||||
extern uint64_t timerprivInt128ToUint64(const timerprivInt128 *n, uint64_t max, uint64_t maxCap);
|
||||
|
|
Loading…
Reference in New Issue