Reintegrated timerSleep() (now threadSleep() because I'm not bloating things further). initmain.c fully restored!
This commit is contained in:
parent
b722922428
commit
b1b60f6077
|
@ -44,6 +44,7 @@ Test(InitAfterInitialized)
|
||||||
|
|
||||||
struct testParams {
|
struct testParams {
|
||||||
uint32_t flag;
|
uint32_t flag;
|
||||||
|
threadSysError err;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -148,8 +149,7 @@ static void queueThread(void *data)
|
||||||
{
|
{
|
||||||
struct testParams *p = (struct testParams *) data;
|
struct testParams *p = (struct testParams *) data;
|
||||||
|
|
||||||
// TODO reintegrate the timer somehow
|
p->err = threadSleep(1250 * threadMillisecond);
|
||||||
// p->err = timerSleep(1250 * timerMillisecond);
|
|
||||||
uiQueueMain(queued, p);
|
uiQueueMain(queued, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,8 +168,8 @@ Test(QueueMain_DifferentThread)
|
||||||
err = threadThreadWaitAndFree(thread);
|
err = threadThreadWaitAndFree(thread);
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
TestFatalf("error waiting for thread to finish: " threadSysErrorFmt, threadSysErrorFmtArg(err));
|
TestFatalf("error waiting for thread to finish: " threadSysErrorFmt, threadSysErrorFmtArg(err));
|
||||||
// if (p.err != 0)
|
if (p.err != 0)
|
||||||
// TestErrorf("error sleeping in thread to ensure a high likelihood the uiQueueMain() is run after uiMain() starts: " timerSysErrorFmt, timerSysErrorFmtArg(p.err));
|
TestErrorf("error sleeping in thread to ensure a high likelihood the uiQueueMain() is run after uiMain() starts: " threadSysErrorFmt, threadSysErrorFmtArg(p.err));
|
||||||
if (p.flag != 1)
|
if (p.flag != 1)
|
||||||
TestErrorf("uiQueueMain() didn't set flag properly:" diff("%d"),
|
TestErrorf("uiQueueMain() didn't set flag properly:" diff("%d"),
|
||||||
p.flag, 1);
|
p.flag, 1);
|
||||||
|
@ -179,7 +179,7 @@ static void queueOrderThread(void *data)
|
||||||
{
|
{
|
||||||
struct testParams *p = (struct testParams *) data;
|
struct testParams *p = (struct testParams *) data;
|
||||||
|
|
||||||
// p->err = timerSleep(1250 * timerMillisecond);
|
p->err = threadSleep(1250 * threadMillisecond);
|
||||||
queueOrder(p);
|
queueOrder(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,8 +198,8 @@ Test(QueueMain_DifferentThreadSequence)
|
||||||
err = threadThreadWaitAndFree(thread);
|
err = threadThreadWaitAndFree(thread);
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
TestFatalf("error waiting for thread to finish: " threadSysErrorFmt, threadSysErrorFmtArg(err));
|
TestFatalf("error waiting for thread to finish: " threadSysErrorFmt, threadSysErrorFmtArg(err));
|
||||||
// if (p.err != 0)
|
if (p.err != 0)
|
||||||
// TestErrorf("error sleeping in thread to ensure a high likelihood the uiQueueMain() is run after uiMain() starts: " timerSysErrorFmt, timerSysErrorFmtArg(p.err));
|
TestErrorf("error sleeping in thread to ensure a high likelihood the uiQueueMain() is run after uiMain() starts: " threadSysErrorFmt, threadSysErrorFmtArg(p.err));
|
||||||
checkOrder(p.flag);
|
checkOrder(p.flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,18 @@ typedef uint64_t threadSysError;
|
||||||
extern threadSysError threadNewThread(void (*f)(void *data), void *data, threadThread **t);
|
extern threadSysError threadNewThread(void (*f)(void *data), void *data, threadThread **t);
|
||||||
extern threadSysError threadThreadWaitAndFree(threadThread *t);
|
extern threadSysError threadThreadWaitAndFree(threadThread *t);
|
||||||
|
|
||||||
|
typedef int64_t threadDuration;
|
||||||
|
|
||||||
|
#define threadDurationMin ((threadDuration) INT64_MIN)
|
||||||
|
#define threadDurationMax ((threadDuration) INT64_MAX)
|
||||||
|
|
||||||
|
#define threadNanosecond ((threadDuration) 1)
|
||||||
|
#define threadMicrosecond ((threadDuration) 1000)
|
||||||
|
#define threadMillisecond ((threadDuration) 1000000)
|
||||||
|
#define threadSecond ((threadDuration) 1000000000)
|
||||||
|
|
||||||
|
extern threadSysError threadSleep(threadDuration d);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,8 +4,10 @@
|
||||||
#define _POSIX_C_SOURCE 200112L
|
#define _POSIX_C_SOURCE 200112L
|
||||||
#define _XOPEN_SOURCE 600
|
#define _XOPEN_SOURCE 600
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <time.h>
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
|
||||||
// Do not put any test cases in this file; they will not be run.
|
// Do not put any test cases in this file; they will not be run.
|
||||||
|
@ -63,3 +65,21 @@ threadSysError threadThreadWaitAndFree(threadThread *t)
|
||||||
free(t);
|
free(t);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
threadSysError threadSleep(threadDuration d)
|
||||||
|
{
|
||||||
|
struct timespec duration, remaining;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
duration.tv_sec = d / threadSecond;
|
||||||
|
duration.tv_nsec = d % threadSecond;
|
||||||
|
for (;;) {
|
||||||
|
errno = 0;
|
||||||
|
if (nanosleep(&duration, &remaining) == 0)
|
||||||
|
return 0;
|
||||||
|
err = errno;
|
||||||
|
if (err != EINTR)
|
||||||
|
return (threadSysError) err;
|
||||||
|
duration = remaining;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -52,6 +52,26 @@ static HRESULT WINAPI hrWaitForSingleObject(HANDLE handle, DWORD timeout)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI hrCreateWaitableTimerW(LPSECURITY_ATTRIBUTES attributes, BOOL manualReset, LPCWSTR name, HANDLE *handle)
|
||||||
|
{
|
||||||
|
SetLastError(0);
|
||||||
|
*handle = CreateWaitableTimerW(attributes, manualReset, name);
|
||||||
|
if (*handle == NULL)
|
||||||
|
return lastErrorToHRESULT();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI hrSetWaitableTimer(HANDLE timer, const LARGE_INTEGER *duration, LONG period, PTIMERAPCROUTINE completionRoutine, LPVOID completionData, BOOL resume)
|
||||||
|
{
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
SetLastError(0);
|
||||||
|
ret = SetWaitableTimer(timer, duration, period, completionRoutine, completionData, resume);
|
||||||
|
if (ret == 0)
|
||||||
|
return lastErrorToHRESULT();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
struct threadThread {
|
struct threadThread {
|
||||||
uintptr_t handle;
|
uintptr_t handle;
|
||||||
void (*f)(void *data);
|
void (*f)(void *data);
|
||||||
|
@ -100,3 +120,24 @@ threadSysError threadThreadWaitAndFree(threadThread *t)
|
||||||
free(t);
|
free(t);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
threadSysError timerSleep(threadDuration d)
|
||||||
|
{
|
||||||
|
HANDLE timer;
|
||||||
|
LARGE_INTEGER duration;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
duration.QuadPart = d / 100;
|
||||||
|
duration.QuadPart = -duration.QuadPart;
|
||||||
|
hr = hrCreateWaitableTimerW(NULL, TRUE, NULL, &timer);
|
||||||
|
if (hr != S_OK)
|
||||||
|
return (threadSysError) hr;
|
||||||
|
hr = hrSetWaitableTimer(timer, &duration, 0, NULL, NULL, FALSE);
|
||||||
|
if (hr != S_OK) {
|
||||||
|
CloseHandle(timer);
|
||||||
|
return (threadSysError) hr;
|
||||||
|
}
|
||||||
|
hr = hrWaitForSingleObject(timer, INFINITE);
|
||||||
|
CloseHandle(timer);
|
||||||
|
return (threadSysError) hr;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue