mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-25 09:57:32 +09:00
clang on windows support
This commit is contained in:
parent
b08f544172
commit
1d44f05fba
22 changed files with 208 additions and 65 deletions
|
|
@ -85,10 +85,24 @@ COLD int dav1d_num_logical_processors(Dav1dContext *const c) {
|
|||
#ifdef _WIN32
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
GROUP_AFFINITY affinity;
|
||||
if (GetThreadGroupAffinity(GetCurrentThread(), &affinity)) {
|
||||
int num_processors = 1;
|
||||
while (affinity.Mask &= affinity.Mask - 1)
|
||||
DWORD_PTR mask = 0, system_mask;
|
||||
HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll");
|
||||
typedef BOOL (WINAPI *get_thread_group_affinity_fn)(HANDLE, PGROUP_AFFINITY);
|
||||
get_thread_group_affinity_fn get_thread_group_affinity = kernel32 ?
|
||||
(get_thread_group_affinity_fn)GetProcAddress(kernel32, "GetThreadGroupAffinity") : NULL;
|
||||
|
||||
/* Processor groups are only available on Windows 7 and later. */
|
||||
if (get_thread_group_affinity &&
|
||||
get_thread_group_affinity(GetCurrentThread(), &affinity))
|
||||
mask = affinity.Mask;
|
||||
else if (!GetProcessAffinityMask(GetCurrentProcess(), &mask, &system_mask))
|
||||
mask = 0;
|
||||
|
||||
if (mask) {
|
||||
int num_processors = 0;
|
||||
do {
|
||||
num_processors++;
|
||||
} while (mask &= mask - 1);
|
||||
return num_processors;
|
||||
}
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@
|
|||
#include <limits.h>
|
||||
#include <windows.h>
|
||||
|
||||
#define PTHREAD_MUTEX_INITIALIZER SRWLOCK_INIT
|
||||
#define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT
|
||||
#define PTHREAD_MUTEX_INITIALIZER { 0 }
|
||||
#define PTHREAD_ONCE_INIT 0
|
||||
|
||||
typedef struct {
|
||||
HANDLE h;
|
||||
|
|
@ -46,9 +46,16 @@ typedef struct {
|
|||
unsigned stack_size;
|
||||
} pthread_attr_t;
|
||||
|
||||
typedef SRWLOCK pthread_mutex_t;
|
||||
typedef CONDITION_VARIABLE pthread_cond_t;
|
||||
typedef INIT_ONCE pthread_once_t;
|
||||
typedef struct {
|
||||
volatile LONG state;
|
||||
CRITICAL_SECTION cs;
|
||||
} pthread_mutex_t;
|
||||
struct dav1d_cond_waiter;
|
||||
typedef struct {
|
||||
CRITICAL_SECTION cs;
|
||||
struct dav1d_cond_waiter *head;
|
||||
} pthread_cond_t;
|
||||
typedef volatile LONG pthread_once_t;
|
||||
|
||||
void dav1d_init_thread(void);
|
||||
void dav1d_set_thread_name(const wchar_t *name);
|
||||
|
|
@ -84,50 +91,51 @@ static inline int pthread_attr_setstacksize(pthread_attr_t *const attr,
|
|||
static inline int pthread_mutex_init(pthread_mutex_t *const mutex,
|
||||
const void *const attr)
|
||||
{
|
||||
InitializeSRWLock(mutex);
|
||||
mutex->state = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_mutex_destroy(pthread_mutex_t *const mutex) {
|
||||
if (mutex->state == 2) DeleteCriticalSection(&mutex->cs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_mutex_lock(pthread_mutex_t *const mutex) {
|
||||
AcquireSRWLockExclusive(mutex);
|
||||
if (InterlockedCompareExchange(&mutex->state, 1, 0) == 0) {
|
||||
InitializeCriticalSection(&mutex->cs);
|
||||
InterlockedExchange(&mutex->state, 2);
|
||||
} else {
|
||||
while (InterlockedCompareExchange(&mutex->state, 2, 2) != 2)
|
||||
Sleep(1);
|
||||
}
|
||||
EnterCriticalSection(&mutex->cs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_mutex_unlock(pthread_mutex_t *const mutex) {
|
||||
ReleaseSRWLockExclusive(mutex);
|
||||
LeaveCriticalSection(&mutex->cs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_cond_init(pthread_cond_t *const cond,
|
||||
const void *const attr)
|
||||
{
|
||||
InitializeConditionVariable(cond);
|
||||
InitializeCriticalSection(&cond->cs);
|
||||
cond->head = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_cond_destroy(pthread_cond_t *const cond) {
|
||||
DeleteCriticalSection(&cond->cs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_cond_wait(pthread_cond_t *const cond,
|
||||
pthread_mutex_t *const mutex)
|
||||
{
|
||||
return !SleepConditionVariableSRW(cond, mutex, INFINITE, 0);
|
||||
}
|
||||
|
||||
static inline int pthread_cond_signal(pthread_cond_t *const cond) {
|
||||
WakeConditionVariable(cond);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_cond_broadcast(pthread_cond_t *const cond) {
|
||||
WakeAllConditionVariable(cond);
|
||||
return 0;
|
||||
}
|
||||
#define pthread_cond_wait dav1d_pthread_cond_wait
|
||||
#define pthread_cond_signal dav1d_pthread_cond_signal
|
||||
#define pthread_cond_broadcast dav1d_pthread_cond_broadcast
|
||||
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
|
||||
int pthread_cond_signal(pthread_cond_t *cond);
|
||||
int pthread_cond_broadcast(pthread_cond_t *cond);
|
||||
|
||||
#else
|
||||
|
||||
|
|
|
|||
|
|
@ -85,15 +85,73 @@ COLD int dav1d_pthread_join(pthread_t *const thread, void **const res) {
|
|||
COLD int dav1d_pthread_once(pthread_once_t *const once_control,
|
||||
void (*const init_routine)(void))
|
||||
{
|
||||
BOOL pending = FALSE;
|
||||
|
||||
if (InitOnceBeginInitialize(once_control, 0, &pending, NULL) != TRUE)
|
||||
return 1;
|
||||
|
||||
if (pending == TRUE)
|
||||
if (InterlockedCompareExchange(once_control, 1, 0) == 0) {
|
||||
init_routine();
|
||||
InterlockedExchange(once_control, 2);
|
||||
} else {
|
||||
while (InterlockedCompareExchange(once_control, 2, 2) != 2)
|
||||
Sleep(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return !InitOnceComplete(once_control, 0, NULL);
|
||||
/* Each waiter owns an event. Queue operations and signalling share a lock,
|
||||
* so a new waiter cannot consume an earlier waiter's notification. */
|
||||
struct dav1d_cond_waiter {
|
||||
HANDLE event;
|
||||
struct dav1d_cond_waiter *next;
|
||||
};
|
||||
|
||||
int dav1d_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) {
|
||||
struct dav1d_cond_waiter waiter, **link;
|
||||
DWORD result;
|
||||
waiter.event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
if (!waiter.event) return 1;
|
||||
EnterCriticalSection(&cond->cs);
|
||||
waiter.next = NULL;
|
||||
for (link = &cond->head; *link; link = &(*link)->next) {}
|
||||
*link = &waiter;
|
||||
pthread_mutex_unlock(mutex);
|
||||
LeaveCriticalSection(&cond->cs);
|
||||
|
||||
result = WaitForSingleObject(waiter.event, INFINITE);
|
||||
EnterCriticalSection(&cond->cs);
|
||||
/* Also unlink on wait failure before the stack record goes away. */
|
||||
for (link = &cond->head; *link; link = &(*link)->next) {
|
||||
if (*link == &waiter) {
|
||||
*link = waiter.next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CloseHandle(waiter.event);
|
||||
LeaveCriticalSection(&cond->cs);
|
||||
pthread_mutex_lock(mutex);
|
||||
return result != WAIT_OBJECT_0;
|
||||
}
|
||||
|
||||
int dav1d_pthread_cond_signal(pthread_cond_t *cond) {
|
||||
int result = 0;
|
||||
EnterCriticalSection(&cond->cs);
|
||||
if (cond->head) {
|
||||
if (SetEvent(cond->head->event)) cond->head = cond->head->next;
|
||||
else result = 1;
|
||||
}
|
||||
LeaveCriticalSection(&cond->cs);
|
||||
return result;
|
||||
}
|
||||
|
||||
int dav1d_pthread_cond_broadcast(pthread_cond_t *cond) {
|
||||
int result = 0;
|
||||
EnterCriticalSection(&cond->cs);
|
||||
while (cond->head) {
|
||||
if (!SetEvent(cond->head->event)) {
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
cond->head = cond->head->next;
|
||||
}
|
||||
LeaveCriticalSection(&cond->cs);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue