msvcp110: Add _Mtx_{destroy,getconcrtcs,init,lock,unlock,trylock} implementation.
This commit is contained in:
parent
333fbba681
commit
3fa2bb2dce
|
@ -3819,14 +3819,14 @@
|
|||
@ cdecl _Mbrtowc(ptr ptr long ptr ptr)
|
||||
@ stub _Mtx_clear_owner
|
||||
@ stub _Mtx_current_owns
|
||||
@ stub _Mtx_destroy
|
||||
@ stub _Mtx_getconcrtcs
|
||||
@ stub _Mtx_init
|
||||
@ stub _Mtx_lock
|
||||
@ cdecl _Mtx_destroy(ptr)
|
||||
@ cdecl _Mtx_getconcrtcs(ptr)
|
||||
@ cdecl _Mtx_init(ptr long)
|
||||
@ cdecl _Mtx_lock(ptr)
|
||||
@ stub _Mtx_reset_owner
|
||||
@ stub _Mtx_timedlock
|
||||
@ stub _Mtx_trylock
|
||||
@ stub _Mtx_unlock
|
||||
@ cdecl _Mtx_trylock(ptr)
|
||||
@ cdecl _Mtx_unlock(ptr)
|
||||
@ stub _Mtxdst
|
||||
@ stub _Mtxinit
|
||||
@ stub _Mtxlock
|
||||
|
|
|
@ -374,3 +374,107 @@ unsigned int __cdecl _Random_device(void)
|
|||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if _MSVCP_VER >= 110
|
||||
#if defined(__i386__) && !defined(__arm__)
|
||||
|
||||
#define THISCALL(func) __thiscall_ ## func
|
||||
#define __thiscall __stdcall
|
||||
#define DEFINE_THISCALL_WRAPPER(func,args) \
|
||||
extern void THISCALL(func)(void); \
|
||||
__ASM_GLOBAL_FUNC(__thiscall_ ## func, \
|
||||
"popl %eax\n\t" \
|
||||
"pushl %ecx\n\t" \
|
||||
"pushl %eax\n\t" \
|
||||
"jmp " __ASM_NAME(#func) __ASM_STDCALL(args) )
|
||||
|
||||
extern void *call_thiscall_func;
|
||||
__ASM_GLOBAL_FUNC(call_thiscall_func,
|
||||
"popl %eax\n\t"
|
||||
"popl %edx\n\t"
|
||||
"popl %ecx\n\t"
|
||||
"pushl %eax\n\t"
|
||||
"jmp *%edx\n\t")
|
||||
|
||||
#define call_func1(func,this) ((void* (WINAPI*)(void*,void*))&call_thiscall_func)(func,this)
|
||||
|
||||
#else /* __i386__ */
|
||||
|
||||
#define __thiscall __cdecl
|
||||
#define DEFINE_THISCALL_WRAPPER(func,args) /* nothing */
|
||||
|
||||
#define call_func1(func,this) func(this)
|
||||
|
||||
#endif /* __i386__ */
|
||||
|
||||
#define MTX_MULTI_LOCK 0x100
|
||||
#define MTX_LOCKED 3
|
||||
typedef struct
|
||||
{
|
||||
DWORD flags;
|
||||
critical_section cs;
|
||||
DWORD thread_id;
|
||||
DWORD count;
|
||||
} *_Mtx_t;
|
||||
|
||||
int __cdecl _Mtx_init(_Mtx_t *mtx, int flags)
|
||||
{
|
||||
if(flags & ~MTX_MULTI_LOCK)
|
||||
FIXME("unknown flags ignorred: %x\n", flags);
|
||||
|
||||
*mtx = MSVCRT_operator_new(sizeof(**mtx));
|
||||
(*mtx)->flags = flags;
|
||||
call_func1(critical_section_ctor, &(*mtx)->cs);
|
||||
(*mtx)->thread_id = -1;
|
||||
(*mtx)->count = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __cdecl _Mtx_destroy(_Mtx_t *mtx)
|
||||
{
|
||||
call_func1(critical_section_dtor, &(*mtx)->cs);
|
||||
MSVCRT_operator_delete(*mtx);
|
||||
}
|
||||
|
||||
int __cdecl _Mtx_lock(_Mtx_t *mtx)
|
||||
{
|
||||
if((*mtx)->thread_id != GetCurrentThreadId()) {
|
||||
call_func1(critical_section_lock, &(*mtx)->cs);
|
||||
(*mtx)->thread_id = GetCurrentThreadId();
|
||||
}else if(!((*mtx)->flags & MTX_MULTI_LOCK)) {
|
||||
return MTX_LOCKED;
|
||||
}
|
||||
|
||||
(*mtx)->count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __cdecl _Mtx_unlock(_Mtx_t *mtx)
|
||||
{
|
||||
if(--(*mtx)->count)
|
||||
return 0;
|
||||
|
||||
(*mtx)->thread_id = -1;
|
||||
call_func1(critical_section_unlock, &(*mtx)->cs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __cdecl _Mtx_trylock(_Mtx_t *mtx)
|
||||
{
|
||||
if((*mtx)->thread_id != GetCurrentThreadId()) {
|
||||
if(!call_func1(critical_section_trylock, &(*mtx)->cs))
|
||||
return MTX_LOCKED;
|
||||
(*mtx)->thread_id = GetCurrentThreadId();
|
||||
}else if(!((*mtx)->flags & MTX_MULTI_LOCK)) {
|
||||
return MTX_LOCKED;
|
||||
}
|
||||
|
||||
(*mtx)->count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
critical_section* __cdecl _Mtx_getconcrtcs(_Mtx_t *mtx)
|
||||
{
|
||||
return &(*mtx)->cs;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -45,6 +45,31 @@ extern void* (__cdecl *MSVCRT_operator_new)(MSVCP_size_t);
|
|||
extern void (__cdecl *MSVCRT_operator_delete)(void*);
|
||||
extern void* (__cdecl *MSVCRT_set_new_handler)(void*);
|
||||
|
||||
#if _MSVCP_VER >= 110
|
||||
/* keep in sync with msvcrt/lock.c */
|
||||
typedef struct cs_queue
|
||||
{
|
||||
struct cs_queue *next;
|
||||
BOOL free;
|
||||
int unknown;
|
||||
} cs_queue;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG_PTR unk_thread_id;
|
||||
cs_queue unk_active;
|
||||
void *unknown[2];
|
||||
cs_queue *head;
|
||||
void *tail;
|
||||
} critical_section;
|
||||
|
||||
extern critical_section* (__thiscall *critical_section_ctor)(critical_section*);
|
||||
extern void (__thiscall *critical_section_dtor)(critical_section*);
|
||||
extern void (__thiscall *critical_section_lock)(critical_section*);
|
||||
extern void (__thiscall *critical_section_unlock)(critical_section*);
|
||||
extern MSVCP_bool (__thiscall *critical_section_trylock)(critical_section*);
|
||||
#endif
|
||||
|
||||
/* basic_string<char, char_traits<char>, allocator<char>> */
|
||||
#define BUF_SIZE_CHAR 16
|
||||
typedef struct
|
||||
|
|
|
@ -60,6 +60,14 @@ void* (__cdecl *MSVCRT_operator_new)(MSVCP_size_t);
|
|||
void (__cdecl *MSVCRT_operator_delete)(void*);
|
||||
void* (__cdecl *MSVCRT_set_new_handler)(void*);
|
||||
|
||||
#if _MSVCP_VER >= 110
|
||||
critical_section* (__thiscall *critical_section_ctor)(critical_section*);
|
||||
void (__thiscall *critical_section_dtor)(critical_section*);
|
||||
void (__thiscall *critical_section_lock)(critical_section*);
|
||||
void (__thiscall *critical_section_unlock)(critical_section*);
|
||||
MSVCP_bool (__thiscall *critical_section_trylock)(critical_section*);
|
||||
#endif
|
||||
|
||||
#define VERSION_STRING(ver) #ver
|
||||
#define MSVCRT_NAME(ver) "msvcr" VERSION_STRING(ver) ".dll"
|
||||
|
||||
|
@ -74,12 +82,36 @@ static void init_cxx_funcs(void)
|
|||
MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPEAX_K@Z");
|
||||
MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPEAX@Z");
|
||||
MSVCRT_set_new_handler = (void*)GetProcAddress(hmod, "?_set_new_handler@@YAP6AH_K@ZP6AH0@Z@Z");
|
||||
|
||||
#if _MSVCP_VER >= 110
|
||||
critical_section_ctor = (void*)GetProcAddress(hmod, "??0critical_section@Concurrency@@QEAA@XZ");
|
||||
critical_section_dtor = (void*)GetProcAddress(hmod, "??1critical_section@Concurrency@@QEAA@XZ");
|
||||
critical_section_lock = (void*)GetProcAddress(hmod, "?lock@critical_section@Concurrency@@QEAAXXZ");
|
||||
critical_section_unlock = (void*)GetProcAddress(hmod, "?unlock@critical_section@Concurrency@@QEAAXXZ");
|
||||
critical_section_trylock = (void*)GetProcAddress(hmod, "?try_lock@critical_section@Concurrency@@QEAA_NXZ");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPAXI@Z");
|
||||
MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPAX@Z");
|
||||
MSVCRT_set_new_handler = (void*)GetProcAddress(hmod, "?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z");
|
||||
|
||||
#if _MSVCP_VER >= 110
|
||||
#ifdef __arm__
|
||||
critical_section_ctor = (void*)GetProcAddress(hmod, "??0critical_section@Concurrency@@QAA@XZ");
|
||||
critical_section_dtor = (void*)GetProcAddress(hmod, "??1critical_section@Concurrency@@QAA@XZ");
|
||||
critical_section_lock = (void*)GetProcAddress(hmod, "?lock@critical_section@Concurrency@@QAAXXZ");
|
||||
critical_section_unlock = (void*)GetProcAddress(hmod, "?unlock@critical_section@Concurrency@@QAAXXZ");
|
||||
critical_section_trylock = (void*)GetProcAddress(hmod, "?try_lock@critical_section@Concurrency@@QAA_NXZ");
|
||||
#else
|
||||
critical_section_ctor = (void*)GetProcAddress(hmod, "??0critical_section@Concurrency@@QAE@XZ");
|
||||
critical_section_dtor = (void*)GetProcAddress(hmod, "??1critical_section@Concurrency@@QAE@XZ");
|
||||
critical_section_lock = (void*)GetProcAddress(hmod, "?lock@critical_section@Concurrency@@QAEXXZ");
|
||||
critical_section_unlock = (void*)GetProcAddress(hmod, "?unlock@critical_section@Concurrency@@QAEXXZ");
|
||||
critical_section_trylock = (void*)GetProcAddress(hmod, "?try_lock@critical_section@Concurrency@@QAE_NXZ");
|
||||
#endif
|
||||
#endif /* _MSVCP_VER >= 110 */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -287,6 +287,7 @@ MSVCRT_bool __thiscall SpinWait__SpinOnce(SpinWait *this)
|
|||
|
||||
static HANDLE keyed_event;
|
||||
|
||||
/* keep in sync with msvcp90/msvcp90.h */
|
||||
typedef struct cs_queue
|
||||
{
|
||||
struct cs_queue *next;
|
||||
|
|
Loading…
Reference in New Issue