split thread/mutex/sem defs out of wposix to wpthread (reduce default dependencies)
waio: add include guard; include from waio.cpp This was SVN commit r1839.
This commit is contained in:
parent
f3a61e4f69
commit
09985eaa7e
@ -19,6 +19,7 @@
|
|||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
|
|
||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
|
#include "waio.h"
|
||||||
#include "win_internal.h"
|
#include "win_internal.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// POSIX asynchronous I/O for Win32
|
// POSIX asynchronous I/O for Win32
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003 Jan Wassenberg
|
// Copyright (c) 2003-2005 Jan Wassenberg
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -16,16 +16,19 @@
|
|||||||
// Jan.Wassenberg@stud.uni-karlsruhe.de
|
// Jan.Wassenberg@stud.uni-karlsruhe.de
|
||||||
// http://www.stud.uni-karlsruhe.de/~urkt/
|
// http://www.stud.uni-karlsruhe.de/~urkt/
|
||||||
|
|
||||||
// included by lib.h
|
// included by wposix.h and waio.cpp
|
||||||
|
|
||||||
// Note: for maximum efficiency, transfer buffers, offsets, and lengths
|
|
||||||
// should be sector aligned (otherwise, buffer is copied).
|
|
||||||
|
|
||||||
|
#ifndef WAIO_H__
|
||||||
|
#define WAIO_H__
|
||||||
|
|
||||||
#include "lib/types.h"
|
#include "lib/types.h"
|
||||||
#include "wposix_types.h"
|
#include "wposix_types.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Note: for maximum efficiency, transfer buffers, offsets, and lengths
|
||||||
|
// should be sector aligned (otherwise, buffer is copied).
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// <signal.h>
|
// <signal.h>
|
||||||
//
|
//
|
||||||
@ -91,3 +94,5 @@ extern int aio_reopen(int fd, const char* fn, int oflag, ...);
|
|||||||
|
|
||||||
// allocate and return a file descriptor
|
// allocate and return a file descriptor
|
||||||
extern int aio_assign_handle(uintptr_t handle);
|
extern int aio_assign_handle(uintptr_t handle);
|
||||||
|
|
||||||
|
#endif // #ifndef WAIO_H__
|
||||||
|
@ -23,8 +23,6 @@
|
|||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
#include "win_internal.h"
|
#include "win_internal.h"
|
||||||
|
|
||||||
#include <process.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -32,7 +30,7 @@
|
|||||||
|
|
||||||
// cast intptr_t to HANDLE; centralized for easier changing, e.g. avoiding
|
// cast intptr_t to HANDLE; centralized for easier changing, e.g. avoiding
|
||||||
// warnings. i = -1 converts to INVALID_HANDLE_VALUE (same value).
|
// warnings. i = -1 converts to INVALID_HANDLE_VALUE (same value).
|
||||||
static inline HANDLE cast_to_HANDLE(intptr_t i)
|
static HANDLE cast_to_HANDLE(intptr_t i)
|
||||||
{
|
{
|
||||||
return (HANDLE)((char*)0 + i);
|
return (HANDLE)((char*)0 + i);
|
||||||
}
|
}
|
||||||
@ -421,209 +419,6 @@ int poll(struct pollfd /* fds */[], int /* nfds */, int /* timeout */)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// thread
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
__declspec(naked) pthread_t pthread_self(void)
|
|
||||||
{ __asm jmp dword ptr [GetCurrentThread] }
|
|
||||||
|
|
||||||
|
|
||||||
int pthread_getschedparam(pthread_t thread, int* policy, struct sched_param* param)
|
|
||||||
{
|
|
||||||
if(policy)
|
|
||||||
{
|
|
||||||
DWORD pc = GetPriorityClass(GetCurrentProcess());
|
|
||||||
*policy = (pc >= HIGH_PRIORITY_CLASS)? SCHED_FIFO : SCHED_RR;
|
|
||||||
}
|
|
||||||
if(param)
|
|
||||||
{
|
|
||||||
const HANDLE hThread = cast_to_HANDLE((intptr_t)thread);
|
|
||||||
param->sched_priority = GetThreadPriority(hThread);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param* param)
|
|
||||||
{
|
|
||||||
const int pri = param->sched_priority;
|
|
||||||
|
|
||||||
// additional boost for policy == SCHED_FIFO
|
|
||||||
DWORD pri_class = NORMAL_PRIORITY_CLASS;
|
|
||||||
if(policy == SCHED_FIFO)
|
|
||||||
{
|
|
||||||
pri_class = HIGH_PRIORITY_CLASS;
|
|
||||||
if(pri == 2)
|
|
||||||
pri_class = REALTIME_PRIORITY_CLASS;
|
|
||||||
}
|
|
||||||
SetPriorityClass(GetCurrentProcess(), pri_class);
|
|
||||||
|
|
||||||
// choose fixed Windows values from pri
|
|
||||||
const HANDLE hThread = cast_to_HANDLE((intptr_t)thread);
|
|
||||||
SetThreadPriority(hThread, pri);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct ThreadParam
|
|
||||||
{
|
|
||||||
void*(*func)(void*);
|
|
||||||
void* user_arg;
|
|
||||||
ThreadParam(void*(*_func)(void*), void* _user_arg)
|
|
||||||
: func(_func), user_arg(_user_arg) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// trampoline to switch calling convention.
|
|
||||||
// param points to a heap-allocated ThreadParam (see pthread_create).
|
|
||||||
static unsigned __stdcall thread_start(void* param)
|
|
||||||
{
|
|
||||||
ThreadParam* f = (ThreadParam*)param;
|
|
||||||
void*(*func)(void*) = f->func;
|
|
||||||
void* user_arg = f->user_arg;
|
|
||||||
delete f;
|
|
||||||
|
|
||||||
// workaround for stupid "void* -> unsigned cast" warning
|
|
||||||
union { void* p; unsigned u; } v;
|
|
||||||
v.p = func(user_arg);
|
|
||||||
return v.u;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int pthread_create(pthread_t* thread, const void* attr, void*(*func)(void*), void* user_arg)
|
|
||||||
{
|
|
||||||
UNUSED(attr);
|
|
||||||
|
|
||||||
// notes:
|
|
||||||
// - don't call via asm: _beginthreadex might be a func ptr (if DLL CRT).
|
|
||||||
// - don't stack-allocate param: thread_start might not be called
|
|
||||||
// in the new thread before we exit this stack frame.
|
|
||||||
ThreadParam* param = new ThreadParam(func, user_arg);
|
|
||||||
*thread = (pthread_t)_beginthreadex(0, 0, thread_start, (void*)param, 0, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void pthread_cancel(pthread_t thread)
|
|
||||||
{
|
|
||||||
HANDLE hThread = cast_to_HANDLE((intptr_t)thread);
|
|
||||||
TerminateThread(hThread, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void pthread_join(pthread_t thread, void** value_ptr)
|
|
||||||
{
|
|
||||||
HANDLE hThread = cast_to_HANDLE((intptr_t)thread);
|
|
||||||
|
|
||||||
// clean exit
|
|
||||||
if(WaitForSingleObject(hThread, 100) == WAIT_OBJECT_0)
|
|
||||||
{
|
|
||||||
if(value_ptr)
|
|
||||||
GetExitCodeThread(hThread, (LPDWORD)value_ptr);
|
|
||||||
}
|
|
||||||
// force close
|
|
||||||
else
|
|
||||||
TerminateThread(hThread, 0);
|
|
||||||
if(value_ptr)
|
|
||||||
*value_ptr = (void*)-1;
|
|
||||||
CloseHandle(hThread);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// DeleteCriticalSection currently doesn't complain if we double-free
|
|
||||||
// (e.g. user calls destroy() and static initializer atexit runs),
|
|
||||||
// and dox are ambiguous.
|
|
||||||
|
|
||||||
// note: pthread_mutex_t must not be an opaque struct, because the
|
|
||||||
// initializer returns pthread_mutex_t directly and CRITICAL_SECTIONS
|
|
||||||
// shouldn't be copied.
|
|
||||||
//
|
|
||||||
// note: must not use new/malloc to allocate the critical section
|
|
||||||
// because mmgr.cpp uses a mutex and must not be called to allocate
|
|
||||||
// anything before it is initialized.
|
|
||||||
|
|
||||||
pthread_mutex_t pthread_mutex_initializer()
|
|
||||||
{
|
|
||||||
CRITICAL_SECTION* cs = (CRITICAL_SECTION*)HeapAlloc(GetProcessHeap(), 0, sizeof(CRITICAL_SECTION));
|
|
||||||
InitializeCriticalSection(cs);
|
|
||||||
return (pthread_mutex_t)cs;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pthread_mutex_destroy(pthread_mutex_t* m)
|
|
||||||
{
|
|
||||||
CRITICAL_SECTION* cs = (CRITICAL_SECTION*)(*m);
|
|
||||||
DeleteCriticalSection(cs);
|
|
||||||
HeapFree(GetProcessHeap(), 0, cs);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pthread_mutex_init(pthread_mutex_t* m, const pthread_mutexattr_t*)
|
|
||||||
{
|
|
||||||
*m = pthread_mutex_initializer();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pthread_mutex_lock(pthread_mutex_t* m)
|
|
||||||
{
|
|
||||||
CRITICAL_SECTION* cs = (CRITICAL_SECTION*)(*m);
|
|
||||||
EnterCriticalSection(cs);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pthread_mutex_trylock(pthread_mutex_t* m)
|
|
||||||
{
|
|
||||||
CRITICAL_SECTION* cs = (CRITICAL_SECTION*)(*m);
|
|
||||||
BOOL got_it = TryEnterCriticalSection(cs);
|
|
||||||
return got_it? 0 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pthread_mutex_unlock(pthread_mutex_t* m)
|
|
||||||
{
|
|
||||||
CRITICAL_SECTION* cs = (CRITICAL_SECTION*)(*m);
|
|
||||||
LeaveCriticalSection(cs);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pthread_mutex_timedlock(pthread_mutex_t* m, const struct timespec* abs_timeout)
|
|
||||||
{
|
|
||||||
UNUSED(m);
|
|
||||||
UNUSED(abs_timeout);
|
|
||||||
return -ENOSYS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int sem_init(sem_t* sem, int pshared, unsigned value)
|
|
||||||
{
|
|
||||||
UNUSED(pshared);
|
|
||||||
*sem = (uintptr_t)CreateSemaphore(0, (LONG)value, 0x7fffffff, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sem_post(sem_t* sem)
|
|
||||||
{
|
|
||||||
ReleaseSemaphore((HANDLE)*sem, 1, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sem_wait(sem_t* sem)
|
|
||||||
{
|
|
||||||
WaitForSingleObject((HANDLE)*sem, INFINITE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sem_destroy(sem_t* sem)
|
|
||||||
{
|
|
||||||
CloseHandle((HANDLE)*sem);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// memory mapping
|
// memory mapping
|
||||||
|
@ -29,10 +29,10 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
// split out of this module.
|
// split out of this module.
|
||||||
// (actually included later, because they depend on some of our defs
|
|
||||||
#include "waio.h"
|
#include "waio.h"
|
||||||
#include "wsock.h"
|
#include "wsock.h"
|
||||||
#include "wtime.h"
|
#include "wtime.h"
|
||||||
|
#include "wpthread.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -290,68 +290,6 @@ extern int tcgetattr(int fd, struct termios* termios_p);
|
|||||||
extern int tcsetattr(int fd, int optional_actions, const struct termios* termios_p);
|
extern int tcsetattr(int fd, int optional_actions, const struct termios* termios_p);
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// <sched.h>
|
|
||||||
//
|
|
||||||
|
|
||||||
struct sched_param
|
|
||||||
{
|
|
||||||
int sched_priority;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
SCHED_RR,
|
|
||||||
SCHED_FIFO,
|
|
||||||
SCHED_OTHER
|
|
||||||
};
|
|
||||||
|
|
||||||
#define sched_get_priority_max(policy) +2
|
|
||||||
#define sched_get_priority_min(policy) -2
|
|
||||||
// changing will break pthread_setschedparam
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// <pthread.h>
|
|
||||||
//
|
|
||||||
|
|
||||||
typedef unsigned int pthread_t;
|
|
||||||
|
|
||||||
extern pthread_t pthread_self(void);
|
|
||||||
extern int pthread_getschedparam(pthread_t thread, int* policy, struct sched_param* param);
|
|
||||||
extern int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param* param);
|
|
||||||
|
|
||||||
extern int pthread_create(pthread_t* thread, const void* attr, void*(*func)(void*), void* arg);
|
|
||||||
extern void pthread_cancel(pthread_t thread);
|
|
||||||
extern void pthread_join(pthread_t thread, void** value_ptr);
|
|
||||||
|
|
||||||
typedef void* pthread_mutex_t; // pointer to critical section
|
|
||||||
typedef void pthread_mutexattr_t;
|
|
||||||
|
|
||||||
extern pthread_mutex_t pthread_mutex_initializer(void);
|
|
||||||
#define PTHREAD_MUTEX_INITIALIZER pthread_mutex_initializer()
|
|
||||||
|
|
||||||
extern int pthread_mutex_init(pthread_mutex_t*, const pthread_mutexattr_t*);
|
|
||||||
extern int pthread_mutex_destroy(pthread_mutex_t*);
|
|
||||||
|
|
||||||
extern int pthread_mutex_lock(pthread_mutex_t*);
|
|
||||||
extern int pthread_mutex_trylock(pthread_mutex_t*);
|
|
||||||
extern int pthread_mutex_unlock(pthread_mutex_t*);
|
|
||||||
extern int pthread_mutex_timedlock(pthread_mutex_t*, const struct timespec*);
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// <semaphore.h>
|
|
||||||
//
|
|
||||||
|
|
||||||
typedef uintptr_t sem_t;
|
|
||||||
|
|
||||||
extern int sem_init(sem_t*, int pshared, unsigned value);
|
|
||||||
extern int sem_post(sem_t*);
|
|
||||||
extern int sem_wait(sem_t*);
|
|
||||||
extern int sem_destroy(sem_t*);
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// <poll.h>
|
// <poll.h>
|
||||||
//
|
//
|
||||||
|
217
source/lib/sysdep/win/wpthread.cpp
Normal file
217
source/lib/sysdep/win/wpthread.cpp
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#include <process.h>
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
|
#include "win_internal.h"
|
||||||
|
#include "wpthread.h"
|
||||||
|
|
||||||
|
static HANDLE pthread_t_to_HANDLE(pthread_t p)
|
||||||
|
{
|
||||||
|
return (HANDLE)((char*)0 + p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static pthread_t HANDLE_to_pthread_t(HANDLE h)
|
||||||
|
{
|
||||||
|
return (pthread_t)(uintptr_t)h;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pthread_t pthread_self(void)
|
||||||
|
{
|
||||||
|
return HANDLE_to_pthread_t(GetCurrentThread());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int pthread_getschedparam(pthread_t thread, int* policy, struct sched_param* param)
|
||||||
|
{
|
||||||
|
if(policy)
|
||||||
|
{
|
||||||
|
DWORD pc = GetPriorityClass(GetCurrentProcess());
|
||||||
|
*policy = (pc >= HIGH_PRIORITY_CLASS)? SCHED_FIFO : SCHED_RR;
|
||||||
|
}
|
||||||
|
if(param)
|
||||||
|
{
|
||||||
|
const HANDLE hThread = pthread_t_to_HANDLE(thread);
|
||||||
|
param->sched_priority = GetThreadPriority(hThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param* param)
|
||||||
|
{
|
||||||
|
const int pri = param->sched_priority;
|
||||||
|
|
||||||
|
// additional boost for policy == SCHED_FIFO
|
||||||
|
DWORD pri_class = NORMAL_PRIORITY_CLASS;
|
||||||
|
if(policy == SCHED_FIFO)
|
||||||
|
{
|
||||||
|
pri_class = HIGH_PRIORITY_CLASS;
|
||||||
|
if(pri == 2)
|
||||||
|
pri_class = REALTIME_PRIORITY_CLASS;
|
||||||
|
}
|
||||||
|
SetPriorityClass(GetCurrentProcess(), pri_class);
|
||||||
|
|
||||||
|
// choose fixed Windows values from pri
|
||||||
|
const HANDLE hThread = pthread_t_to_HANDLE(thread);
|
||||||
|
SetThreadPriority(hThread, pri);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct ThreadParam
|
||||||
|
{
|
||||||
|
void*(*func)(void*);
|
||||||
|
void* user_arg;
|
||||||
|
ThreadParam(void*(*_func)(void*), void* _user_arg)
|
||||||
|
: func(_func), user_arg(_user_arg) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// trampoline to switch calling convention.
|
||||||
|
// param points to a heap-allocated ThreadParam (see pthread_create).
|
||||||
|
static unsigned __stdcall thread_start(void* param)
|
||||||
|
{
|
||||||
|
ThreadParam* f = (ThreadParam*)param;
|
||||||
|
void*(*func)(void*) = f->func;
|
||||||
|
void* user_arg = f->user_arg;
|
||||||
|
delete f;
|
||||||
|
|
||||||
|
// workaround for stupid "void* -> unsigned cast" warning
|
||||||
|
union { void* p; unsigned u; } v;
|
||||||
|
v.p = func(user_arg);
|
||||||
|
return v.u;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int pthread_create(pthread_t* thread, const void* attr, void*(*func)(void*), void* user_arg)
|
||||||
|
{
|
||||||
|
UNUSED(attr);
|
||||||
|
|
||||||
|
// notes:
|
||||||
|
// - don't call via asm: _beginthreadex might be a func ptr (if DLL CRT).
|
||||||
|
// - don't stack-allocate param: thread_start might not be called
|
||||||
|
// in the new thread before we exit this stack frame.
|
||||||
|
ThreadParam* param = new ThreadParam(func, user_arg);
|
||||||
|
*thread = (pthread_t)_beginthreadex(0, 0, thread_start, (void*)param, 0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void pthread_cancel(pthread_t thread)
|
||||||
|
{
|
||||||
|
HANDLE hThread = pthread_t_to_HANDLE(thread);
|
||||||
|
TerminateThread(hThread, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void pthread_join(pthread_t thread, void** value_ptr)
|
||||||
|
{
|
||||||
|
HANDLE hThread = pthread_t_to_HANDLE(thread);
|
||||||
|
|
||||||
|
// clean exit
|
||||||
|
if(WaitForSingleObject(hThread, 100) == WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
if(value_ptr)
|
||||||
|
GetExitCodeThread(hThread, (LPDWORD)value_ptr);
|
||||||
|
}
|
||||||
|
// force close
|
||||||
|
else
|
||||||
|
TerminateThread(hThread, 0);
|
||||||
|
if(value_ptr)
|
||||||
|
*value_ptr = (void*)-1;
|
||||||
|
CloseHandle(hThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// DeleteCriticalSection currently doesn't complain if we double-free
|
||||||
|
// (e.g. user calls destroy() and static initializer atexit runs),
|
||||||
|
// and dox are ambiguous.
|
||||||
|
|
||||||
|
// note: pthread_mutex_t must not be an opaque struct, because the
|
||||||
|
// initializer returns pthread_mutex_t directly and CRITICAL_SECTIONS
|
||||||
|
// shouldn't be copied.
|
||||||
|
//
|
||||||
|
// note: must not use new/malloc to allocate the critical section
|
||||||
|
// because mmgr.cpp uses a mutex and must not be called to allocate
|
||||||
|
// anything before it is initialized.
|
||||||
|
|
||||||
|
pthread_mutex_t pthread_mutex_initializer()
|
||||||
|
{
|
||||||
|
CRITICAL_SECTION* cs = (CRITICAL_SECTION*)HeapAlloc(GetProcessHeap(), 0, sizeof(CRITICAL_SECTION));
|
||||||
|
InitializeCriticalSection(cs);
|
||||||
|
return (pthread_mutex_t)cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pthread_mutex_destroy(pthread_mutex_t* m)
|
||||||
|
{
|
||||||
|
CRITICAL_SECTION* cs = (CRITICAL_SECTION*)(*m);
|
||||||
|
DeleteCriticalSection(cs);
|
||||||
|
HeapFree(GetProcessHeap(), 0, cs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pthread_mutex_init(pthread_mutex_t* m, const pthread_mutexattr_t*)
|
||||||
|
{
|
||||||
|
*m = pthread_mutex_initializer();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pthread_mutex_lock(pthread_mutex_t* m)
|
||||||
|
{
|
||||||
|
CRITICAL_SECTION* cs = (CRITICAL_SECTION*)(*m);
|
||||||
|
EnterCriticalSection(cs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pthread_mutex_trylock(pthread_mutex_t* m)
|
||||||
|
{
|
||||||
|
CRITICAL_SECTION* cs = (CRITICAL_SECTION*)(*m);
|
||||||
|
BOOL got_it = TryEnterCriticalSection(cs);
|
||||||
|
return got_it? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pthread_mutex_unlock(pthread_mutex_t* m)
|
||||||
|
{
|
||||||
|
CRITICAL_SECTION* cs = (CRITICAL_SECTION*)(*m);
|
||||||
|
LeaveCriticalSection(cs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pthread_mutex_timedlock(pthread_mutex_t* m, const struct timespec* abs_timeout)
|
||||||
|
{
|
||||||
|
UNUSED(m);
|
||||||
|
UNUSED(abs_timeout);
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int sem_init(sem_t* sem, int pshared, unsigned value)
|
||||||
|
{
|
||||||
|
UNUSED(pshared);
|
||||||
|
*sem = (uintptr_t)CreateSemaphore(0, (LONG)value, 0x7fffffff, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sem_post(sem_t* sem)
|
||||||
|
{
|
||||||
|
ReleaseSemaphore((HANDLE)*sem, 1, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sem_wait(sem_t* sem)
|
||||||
|
{
|
||||||
|
WaitForSingleObject((HANDLE)*sem, INFINITE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sem_destroy(sem_t* sem)
|
||||||
|
{
|
||||||
|
CloseHandle((HANDLE)*sem);
|
||||||
|
return 0;
|
||||||
|
}
|
86
source/lib/sysdep/win/wpthread.h
Normal file
86
source/lib/sysdep/win/wpthread.h
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// POSIX asynchronous I/O for Win32
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2005 Jan Wassenberg
|
||||||
|
//
|
||||||
|
// 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; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// Contact info:
|
||||||
|
// Jan.Wassenberg@stud.uni-karlsruhe.de
|
||||||
|
// http://www.stud.uni-karlsruhe.de/~urkt/
|
||||||
|
|
||||||
|
// included by wposix.h and wpthread.cpp
|
||||||
|
|
||||||
|
#ifndef WPTHREAD_H__
|
||||||
|
#define WPTHREAD_H__
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// <sched.h>
|
||||||
|
//
|
||||||
|
|
||||||
|
struct sched_param
|
||||||
|
{
|
||||||
|
int sched_priority;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SCHED_RR,
|
||||||
|
SCHED_FIFO,
|
||||||
|
SCHED_OTHER
|
||||||
|
};
|
||||||
|
|
||||||
|
#define sched_get_priority_max(policy) +2
|
||||||
|
#define sched_get_priority_min(policy) -2
|
||||||
|
// changing will break pthread_setschedparam
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// <pthread.h>
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef unsigned int pthread_t;
|
||||||
|
|
||||||
|
extern pthread_t pthread_self(void);
|
||||||
|
extern int pthread_getschedparam(pthread_t thread, int* policy, struct sched_param* param);
|
||||||
|
extern int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param* param);
|
||||||
|
|
||||||
|
extern int pthread_create(pthread_t* thread, const void* attr, void*(*func)(void*), void* arg);
|
||||||
|
extern void pthread_cancel(pthread_t thread);
|
||||||
|
extern void pthread_join(pthread_t thread, void** value_ptr);
|
||||||
|
|
||||||
|
typedef void* pthread_mutex_t; // pointer to critical section
|
||||||
|
typedef void pthread_mutexattr_t;
|
||||||
|
|
||||||
|
extern pthread_mutex_t pthread_mutex_initializer(void);
|
||||||
|
#define PTHREAD_MUTEX_INITIALIZER pthread_mutex_initializer()
|
||||||
|
|
||||||
|
extern int pthread_mutex_init(pthread_mutex_t*, const pthread_mutexattr_t*);
|
||||||
|
extern int pthread_mutex_destroy(pthread_mutex_t*);
|
||||||
|
|
||||||
|
extern int pthread_mutex_lock(pthread_mutex_t*);
|
||||||
|
extern int pthread_mutex_trylock(pthread_mutex_t*);
|
||||||
|
extern int pthread_mutex_unlock(pthread_mutex_t*);
|
||||||
|
extern int pthread_mutex_timedlock(pthread_mutex_t*, const struct timespec*);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// <semaphore.h>
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef uintptr_t sem_t;
|
||||||
|
|
||||||
|
extern int sem_init(sem_t*, int pshared, unsigned value);
|
||||||
|
extern int sem_post(sem_t*);
|
||||||
|
extern int sem_wait(sem_t*);
|
||||||
|
extern int sem_destroy(sem_t*);
|
||||||
|
|
||||||
|
#endif // #ifndef WPTHREAD_H__
|
Loading…
Reference in New Issue
Block a user