mirror of
https://github.com/opnsense/src.git
synced 2026-02-15 08:38:13 -05:00
Its latest version merged from: ^/vendor/processor-trace/892e12c5a27bda5806d1e63269986bb4171b5a8b Sponsored by: DARPA, AFRL
239 lines
4.6 KiB
C
239 lines
4.6 KiB
C
/*
|
|
* Copyright (c) 2014-2019, Intel Corporation
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
* * Neither the name of Intel Corporation nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*
|
|
* It looks like there is still no support for C11's threads.h.
|
|
*
|
|
* We implement the few features we actually need hoping that this file will
|
|
* soon go away.
|
|
*/
|
|
|
|
#ifndef THREADS_H
|
|
#define THREADS_H
|
|
|
|
#include "windows.h"
|
|
|
|
|
|
enum {
|
|
thrd_success = 1,
|
|
thrd_error
|
|
};
|
|
|
|
|
|
struct pt_thread {
|
|
HANDLE handle;
|
|
};
|
|
typedef struct pt_thread thrd_t;
|
|
|
|
typedef int (*thrd_start_t)(void *);
|
|
|
|
|
|
struct thrd_args {
|
|
thrd_start_t fun;
|
|
void *arg;
|
|
};
|
|
|
|
static DWORD WINAPI thrd_routine(void *arg)
|
|
{
|
|
struct thrd_args *args;
|
|
int result;
|
|
|
|
args = (struct thrd_args *) arg;
|
|
if (!args)
|
|
return (DWORD) -1;
|
|
|
|
result = -1;
|
|
if (args->fun)
|
|
result = args->fun(args->arg);
|
|
|
|
free(args);
|
|
|
|
return (DWORD) result;
|
|
}
|
|
|
|
static inline int thrd_create(thrd_t *thrd, thrd_start_t fun, void *arg)
|
|
{
|
|
struct thrd_args *args;
|
|
HANDLE handle;
|
|
|
|
if (!thrd || !fun)
|
|
return thrd_error;
|
|
|
|
args = malloc(sizeof(*args));
|
|
if (!args)
|
|
return thrd_error;
|
|
|
|
args->fun = fun;
|
|
args->arg = arg;
|
|
|
|
handle = CreateThread(NULL, 0, thrd_routine, args, 0, NULL);
|
|
if (!handle) {
|
|
free(args);
|
|
return thrd_error;
|
|
}
|
|
|
|
thrd->handle = handle;
|
|
return thrd_success;
|
|
}
|
|
|
|
static inline int thrd_join(thrd_t *thrd, int *res)
|
|
{
|
|
DWORD status;
|
|
BOOL success;
|
|
|
|
if (!thrd)
|
|
return thrd_error;
|
|
|
|
status = WaitForSingleObject(thrd->handle, INFINITE);
|
|
if (status)
|
|
return thrd_error;
|
|
|
|
if (res) {
|
|
DWORD result;
|
|
|
|
success = GetExitCodeThread(thrd->handle, &result);
|
|
if (!success) {
|
|
(void) CloseHandle(thrd->handle);
|
|
return thrd_error;
|
|
}
|
|
|
|
*res = (int) result;
|
|
}
|
|
|
|
success = CloseHandle(thrd->handle);
|
|
if (!success)
|
|
return thrd_error;
|
|
|
|
return thrd_success;
|
|
}
|
|
|
|
struct pt_mutex {
|
|
CRITICAL_SECTION cs;
|
|
};
|
|
typedef struct pt_mutex mtx_t;
|
|
|
|
enum {
|
|
mtx_plain
|
|
};
|
|
|
|
static inline int mtx_init(mtx_t *mtx, int type)
|
|
{
|
|
if (!mtx || type != mtx_plain)
|
|
return thrd_error;
|
|
|
|
InitializeCriticalSection(&mtx->cs);
|
|
|
|
return thrd_success;
|
|
}
|
|
|
|
static inline void mtx_destroy(mtx_t *mtx)
|
|
{
|
|
if (mtx)
|
|
DeleteCriticalSection(&mtx->cs);
|
|
}
|
|
|
|
static inline int mtx_lock(mtx_t *mtx)
|
|
{
|
|
if (!mtx)
|
|
return thrd_error;
|
|
|
|
EnterCriticalSection(&mtx->cs);
|
|
|
|
return thrd_success;
|
|
}
|
|
|
|
static inline int mtx_unlock(mtx_t *mtx)
|
|
{
|
|
if (!mtx)
|
|
return thrd_error;
|
|
|
|
LeaveCriticalSection(&mtx->cs);
|
|
|
|
return thrd_success;
|
|
}
|
|
|
|
|
|
struct pt_cond {
|
|
CONDITION_VARIABLE cond;
|
|
};
|
|
typedef struct pt_cond cnd_t;
|
|
|
|
static inline int cnd_init(cnd_t *cnd)
|
|
{
|
|
if (!cnd)
|
|
return thrd_error;
|
|
|
|
InitializeConditionVariable(&cnd->cond);
|
|
|
|
return thrd_success;
|
|
}
|
|
|
|
static inline int cnd_destroy(cnd_t *cnd)
|
|
{
|
|
if (!cnd)
|
|
return thrd_error;
|
|
|
|
/* Nothing to do. */
|
|
|
|
return thrd_success;
|
|
}
|
|
|
|
static inline int cnd_signal(cnd_t *cnd)
|
|
{
|
|
if (!cnd)
|
|
return thrd_error;
|
|
|
|
WakeConditionVariable(&cnd->cond);
|
|
|
|
return thrd_success;
|
|
}
|
|
|
|
static inline int cnd_broadcast(cnd_t *cnd)
|
|
{
|
|
if (!cnd)
|
|
return thrd_error;
|
|
|
|
WakeAllConditionVariable(&cnd->cond);
|
|
|
|
return thrd_success;
|
|
}
|
|
|
|
static inline int cnd_wait(cnd_t *cnd, mtx_t *mtx)
|
|
{
|
|
BOOL success;
|
|
|
|
if (!cnd || !mtx)
|
|
return thrd_error;
|
|
|
|
success = SleepConditionVariableCS(&cnd->cond, &mtx->cs, INFINITE);
|
|
if (!success)
|
|
return thrd_error;
|
|
|
|
return thrd_success;
|
|
}
|
|
|
|
#endif /* THREADS_H */
|