From 14d5a755717c8fd534faa5fe3af59cf66e0e7cd3 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 12 Oct 2025 18:51:29 +0200 Subject: [PATCH] Add some win compatibility. Signed-off-by: Pol Henarejos --- src/pthread_win32.h | 95 +++++++++++++++++++++++++++++++++++++++++++ src/queue.h | 5 +++ src/semaphore_win32.h | 47 +++++++++++++++++++++ 3 files changed, 147 insertions(+) create mode 100644 src/pthread_win32.h create mode 100644 src/semaphore_win32.h diff --git a/src/pthread_win32.h b/src/pthread_win32.h new file mode 100644 index 0000000..5281633 --- /dev/null +++ b/src/pthread_win32.h @@ -0,0 +1,95 @@ +#ifdef _MSC_VER +#ifndef _PTHREAD_H_ +#define _PTHREAD_H_ +#include +#include + +typedef HANDLE pthread_t; +typedef CRITICAL_SECTION pthread_mutex_t; + +typedef struct { + CONDITION_VARIABLE cond; +} pthread_cond_t; + +// Mutex +static inline int pthread_mutex_init(pthread_mutex_t *m, void *a) { + (void)a; + InitializeCriticalSection(m); + return 0; +} + +static inline int pthread_mutex_lock(pthread_mutex_t *m) { + EnterCriticalSection(m); + return 0; +} + +static inline int pthread_mutex_unlock(pthread_mutex_t *m) { + LeaveCriticalSection(m); + return 0; +} + +static inline int pthread_mutex_destroy(pthread_mutex_t *m) { + DeleteCriticalSection(m); + return 0; +} + +// Thread +static DWORD WINAPI thread_entry(LPVOID param) { + void **args = (void **)param; + void *(*fn)(void *) = (void *(*)(void *))(uintptr_t)args[0]; + void *arg = args[1]; + fn(arg); + free(param); + return 0; +} + +static inline int pthread_create(pthread_t *t, void *a, void *(*fn)(void *), void *arg) { + (void)a; + void **params = malloc(2 * sizeof(void *)); + if (!params) return -1; + params[0] = (void *)(uintptr_t)fn; + params[1] = arg; + *t = CreateThread(NULL, 0, thread_entry, params, 0, NULL); + return *t ? 0 : -1; +} + +static inline int pthread_join(pthread_t t, void **ret) { + WaitForSingleObject(t, INFINITE); + CloseHandle(t); + if (ret) *ret = NULL; + return 0; +} + +// Condition variable +static inline int pthread_cond_init(pthread_cond_t *c, void *a) { + (void)a; + InitializeConditionVariable(&c->cond); + return 0; +} + +static inline int pthread_cond_destroy(pthread_cond_t *c) { + (void)c; + return 0; +} + +static inline int pthread_cond_wait(pthread_cond_t *c, pthread_mutex_t *m) { + SleepConditionVariableCS(&c->cond, m, INFINITE); + return 0; +} + +static inline int pthread_cond_signal(pthread_cond_t *c) { + WakeConditionVariable(&c->cond); + return 0; +} + +static inline int pthread_cond_broadcast(pthread_cond_t *c) { + WakeAllConditionVariable(&c->cond); + return 0; +} + +static inline int pthread_mutex_trylock(pthread_mutex_t *m){ + return TryEnterCriticalSection(m) ? 0 : EBUSY; +} + +#endif // _PTHREAD_H_ +#endif // _MSC_VER diff --git a/src/queue.h b/src/queue.h index 33ce8d5..be5d9a9 100644 --- a/src/queue.h +++ b/src/queue.h @@ -18,8 +18,13 @@ #ifndef QUEUE_H #define QUEUE_H +#ifdef _MSC_VER +#include "pthread_win32.h" +#include "semaphore_win32.h" +#else #include #include +#endif typedef struct { pthread_mutex_t mtx; pthread_cond_t cnd; diff --git a/src/semaphore_win32.h b/src/semaphore_win32.h new file mode 100644 index 0000000..89ce7a5 --- /dev/null +++ b/src/semaphore_win32.h @@ -0,0 +1,47 @@ +/* + * This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk). + * Copyright (c) 2022 Pol Henarejos. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifdef _MSC_VER +#ifndef _SEMAPHORE_H_ +#define _SEMAPHORE_H_ + +#include + +typedef struct { + HANDLE handle; +} sem_t; + +static inline int sem_init(sem_t *sem, int pshared, unsigned int value) { + (void)pshared; + sem->handle = CreateSemaphore(NULL, value, 0x7FFFFFFF, NULL); + return sem->handle ? 0 : -1; +} + +static inline int sem_wait(sem_t *sem) { + return WaitForSingleObject(sem->handle, INFINITE) == WAIT_OBJECT_0 ? 0 : -1; +} + +static inline int sem_post(sem_t *sem) { + return ReleaseSemaphore(sem->handle, 1, NULL) ? 0 : -1; +} + +static inline int sem_destroy(sem_t *sem) { + return CloseHandle(sem->handle) ? 0 : -1; +} + +#endif // _SEMAPHORE_H_ +#endif // _MSC_VER