mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-22 00:17: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
|
|
@ -162,6 +162,13 @@ SOURCES += [
|
|||
'xiph.c'
|
||||
]
|
||||
|
||||
# dummy_funcs.c intentionally provides tentative definitions for FFmpeg
|
||||
# objects that are disabled by the generated configuration. Clang's default
|
||||
# -fno-common turns those placeholders into duplicate definitions when an
|
||||
# enabled codec supplies the real object.
|
||||
if CONFIG['CLANG_CL']:
|
||||
SOURCES['dummy_funcs.c'].flags += ['-fcommon']
|
||||
|
||||
SYMBOLS_FILE = 'avcodec.symbols'
|
||||
NO_VISIBILITY_FLAGS = True
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ static inline void atomic_int_set_win32(volatile int *ptr, int val)
|
|||
#define avpriv_atomic_int_add_and_fetch atomic_int_add_and_fetch_win32
|
||||
static inline int atomic_int_add_and_fetch_win32(volatile int *ptr, int inc)
|
||||
{
|
||||
return inc + InterlockedExchangeAdd(ptr, inc);
|
||||
/* Windows int and LONG are both 32-bit, but have distinct C types. */
|
||||
return inc + InterlockedExchangeAdd((volatile LONG *)ptr, inc);
|
||||
}
|
||||
|
||||
#define avpriv_atomic_ptr_cas atomic_ptr_cas_win32
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@ if CONFIG['CC_TYPE'] == 'gcc':
|
|||
OS_LIBS += ['gomp']
|
||||
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
OS_LIBS += ['dl']
|
||||
elif CONFIG['CLANG_CL']:
|
||||
# clang-cl lowers OpenMP pragmas to the LLVM OpenMP runtime.
|
||||
CXXFLAGS += ['-fopenmp']
|
||||
|
||||
DEFINES['BUILDING_SOUNDTOUCH'] = 1
|
||||
|
||||
|
|
|
|||
|
|
@ -39,11 +39,12 @@ if CONFIG['OS_TARGET'] != 'Android':
|
|||
DEFINES['FAKE_LOG_DEVICE'] = True
|
||||
SOURCES += [
|
||||
'system/core/liblog/fake_log_device.c',
|
||||
# io.h conflicts with the access stub in logd_write.c on Windows.
|
||||
'system/core/liblog/logprint.c',
|
||||
]
|
||||
UNIFIED_SOURCES += [
|
||||
'system/core/libcutils/strdup16to8.c',
|
||||
'system/core/liblog/logd_write.c',
|
||||
'system/core/liblog/logprint.c',
|
||||
]
|
||||
|
||||
EXPORTS.mp4_demuxer += [
|
||||
|
|
|
|||
|
|
@ -26,6 +26,12 @@
|
|||
#include <assert.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <log/logd.h>
|
||||
#include <log/logprint.h>
|
||||
|
||||
|
|
@ -945,7 +951,11 @@ int android_log_printLogLine(
|
|||
return -1;
|
||||
|
||||
do {
|
||||
#ifdef _WIN32
|
||||
ret = _write(fd, outBuffer, totalLen);
|
||||
#else
|
||||
ret = write(fd, outBuffer, totalLen);
|
||||
#endif
|
||||
} while (ret < 0 && errno == EINTR);
|
||||
|
||||
if (ret < 0) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue