Reintegrated timerSleep() (now threadSleep() because I'm not bloating things further). initmain.c fully restored!

This commit is contained in:
Pietro Gagliardi 2020-01-21 15:13:24 -05:00
parent b722922428
commit b1b60f6077
4 changed files with 81 additions and 8 deletions

View File

@ -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);
} }

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;
}