Created
October 27, 2023 13:22
-
-
Save Hamayama/0eb5234311054d6dbbe8e75727040aef to your computer and use it in GitHub Desktop.
Windows で spin lock と mutex lock のテスト (MSYS2/MinGW-w64)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@set PATH=C:\msys64\mingw32\bin;C:\msys64\usr\local\bin;C:\msys64\usr\bin;C:\msys64\bin;%PATH% | |
set MSYSTEM=MINGW32 | |
for %%i in ( | |
spinlock mutexlock | |
) do ( | |
gcc -g -O2 -Wall -Wextra -o %%i_32.exe %%i.c | |
) | |
pause |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@set PATH=C:\msys64\mingw64\bin;C:\msys64\usr\local\bin;C:\msys64\usr\bin;C:\msys64\bin;%PATH% | |
set MSYSTEM=MINGW64 | |
for %%i in ( | |
spinlock mutexlock | |
) do ( | |
gcc -g -O2 -Wall -Wextra -o %%i_64.exe %%i.c | |
) | |
pause |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@set PATH=C:\msys64\mingw32\bin;C:\msys64\usr\local\bin;C:\msys64\usr\bin;C:\msys64\bin;%PATH% | |
@set MSYSTEM=MINGW32 | |
@rem gdb spinlock_32.exe | |
C:\msys64\usr\bin\time.exe -p ./spinlock_32.exe | |
C:\msys64\usr\bin\time.exe -p ./mutexlock_32.exe | |
pause |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@set PATH=C:\msys64\mingw64\bin;C:\msys64\usr\local\bin;C:\msys64\usr\bin;C:\msys64\bin;%PATH% | |
@set MSYSTEM=MINGW64 | |
@rem gdb spinlock_64.exe | |
C:\msys64\usr\bin\time.exe -p ./spinlock_64.exe | |
C:\msys64\usr\bin\time.exe -p ./mutexlock_64.exe | |
pause |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <windows.h> | |
#include <stdio.h> | |
#include <process.h> | |
#include <stdatomic.h> | |
/* Mutex lock function */ | |
#define SCM_INTERNAL_MUTEX_INIT(mutex) ((mutex) = Scm__WinCreateMutex()) | |
#define SCM_INTERNAL_MUTEX_LOCK(mutex) Scm__WinMutexLock(mutex) | |
#define SCM_INTERNAL_MUTEX_UNLOCK(mutex) ReleaseMutex(mutex) | |
#define SCM_INTERNAL_MUTEX_DESTROY(mutex) CloseHandle(mutex) | |
#define SCM_INTERNAL_MUTEX_INITIALIZER INVALID_HANDLE_VALUE | |
typedef HANDLE ScmInternalMutex; | |
HANDLE Scm__WinCreateMutex() | |
{ | |
HANDLE m = CreateMutex(NULL, FALSE, NULL); | |
//if (m == NULL) Scm_SysError("couldn't create a mutex"); | |
return m; | |
} | |
int Scm__WinMutexLock(HANDLE mutex) | |
{ | |
DWORD r = WaitForSingleObject(mutex, INFINITE); | |
if (r == WAIT_OBJECT_0) return 0; | |
else return 1; /* TODO: proper error handling */ | |
} | |
/* Multithreading test */ | |
#define THREAD_NUM 100 | |
#define COUNT_NUM 1000000 | |
double count = 0; | |
ScmInternalMutex mutex = SCM_INTERNAL_MUTEX_INITIALIZER; | |
//unsigned __stdcall countup(void *args) { | |
// (void)args; | |
DWORD WINAPI countup(LPVOID lpParameter) { | |
(void)lpParameter; | |
for (int i = 0; i < COUNT_NUM; i++) { | |
SCM_INTERNAL_MUTEX_LOCK(mutex); | |
count++; | |
SCM_INTERNAL_MUTEX_UNLOCK(mutex); | |
} | |
return 0; | |
} | |
int main(void) { | |
HANDLE hThread[THREAD_NUM]; | |
SCM_INTERNAL_MUTEX_INIT(mutex); | |
for (int i = 0; i < THREAD_NUM; i++) { | |
//hThread[i] = (HANDLE)_beginthreadex(NULL, 0, countup, NULL, CREATE_SUSPENDED, NULL); | |
hThread[i] = CreateThread(NULL, 0, countup, NULL, CREATE_SUSPENDED, NULL); | |
} | |
for (int i = 0; i < THREAD_NUM; i++) { | |
ResumeThread(hThread[i]); | |
} | |
//Sleep(10000); | |
// The maximum number of waiting objects is 64 . | |
//WaitForMultipleObjects(THREAD_NUM, hThread, TRUE, INFINITE); | |
for (int i = 0; i < THREAD_NUM; i++) { | |
WaitForSingleObject(hThread[i], INFINITE); | |
} | |
for (int i = 0; i < THREAD_NUM; i++) { | |
CloseHandle(hThread[i]); | |
} | |
SCM_INTERNAL_MUTEX_DESTROY(mutex); | |
printf("count=%f\n", count); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <windows.h> | |
#include <stdio.h> | |
#include <process.h> | |
#include <stdatomic.h> | |
/* Spin lock function */ | |
#define SCM_INTERNAL_FASTLOCK_INIT(spin) Scm__WinFastLockInit(&(spin)) | |
#define SCM_INTERNAL_FASTLOCK_LOCK(spin) Scm__WinFastLockLock(&(spin)) | |
#define SCM_INTERNAL_FASTLOCK_UNLOCK(spin) Scm__WinFastLockUnlock(&(spin)) | |
#define SCM_INTERNAL_FASTLOCK_DESTROY(spin) Scm__WinFastLockDestroy(&(spin)) | |
#define SCM_INTERNAL_FASTLOCK_FINALIZATION_NOT_REQUIRED | |
typedef volatile struct { | |
atomic_int lock_state; | |
int dummy; /* padding */ | |
} win_spinlock_t; | |
typedef win_spinlock_t ScmInternalFastlock; | |
int Scm__WinFastLockInit(ScmInternalFastlock *spin) | |
{ | |
(spin->lock_state) = ATOMIC_VAR_INIT(0); | |
return 0; | |
} | |
int Scm__WinFastLockLock(ScmInternalFastlock *spin) | |
{ | |
while (atomic_exchange_explicit(&(spin->lock_state), 1, memory_order_acquire)) { | |
while (atomic_load_explicit(&(spin->lock_state), memory_order_relaxed)) { | |
/* it might be slow */ | |
Sleep(0); | |
} | |
} | |
return 0; | |
} | |
int Scm__WinFastLockUnlock(ScmInternalFastlock *spin) | |
{ | |
atomic_store_explicit(&(spin->lock_state), 0, memory_order_release); | |
return 0; | |
} | |
int Scm__WinFastLockDestroy(ScmInternalFastlock *spin) | |
{ | |
(void)spin; /* suppress unused var warning */ | |
return 0; | |
} | |
/* Multithreading test */ | |
#define THREAD_NUM 100 | |
#define COUNT_NUM 1000000 | |
double count = 0; | |
ScmInternalFastlock spin; | |
//unsigned __stdcall countup(void *args) { | |
// (void)args; | |
DWORD WINAPI countup(LPVOID lpParameter) { | |
(void)lpParameter; | |
for (int i = 0; i < COUNT_NUM; i++) { | |
SCM_INTERNAL_FASTLOCK_LOCK(spin); | |
count++; | |
SCM_INTERNAL_FASTLOCK_UNLOCK(spin); | |
} | |
return 0; | |
} | |
int main(void) { | |
HANDLE hThread[THREAD_NUM]; | |
SCM_INTERNAL_FASTLOCK_INIT(spin); | |
for (int i = 0; i < THREAD_NUM; i++) { | |
//hThread[i] = (HANDLE)_beginthreadex(NULL, 0, countup, NULL, CREATE_SUSPENDED, NULL); | |
hThread[i] = CreateThread(NULL, 0, countup, NULL, CREATE_SUSPENDED, NULL); | |
} | |
for (int i = 0; i < THREAD_NUM; i++) { | |
ResumeThread(hThread[i]); | |
} | |
//Sleep(10000); | |
// The maximum number of waiting objects is 64 . | |
//WaitForMultipleObjects(THREAD_NUM, hThread, TRUE, INFINITE); | |
for (int i = 0; i < THREAD_NUM; i++) { | |
WaitForSingleObject(hThread[i], INFINITE); | |
} | |
for (int i = 0; i < THREAD_NUM; i++) { | |
CloseHandle(hThread[i]); | |
} | |
SCM_INTERNAL_FASTLOCK_DESTROY(spin); | |
printf("count=%f\n", count); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
> C:\msys64\usr\bin\time.exe -p ./spinlock_32.exe | |
count=100000000.000000 | |
real 2.65 | |
user 0.01 | |
sys 0.01 | |
> C:\msys64\usr\bin\time.exe -p ./mutexlock_32.exe | |
count=100000000.000000 | |
real 376.80 | |
user 0.01 | |
sys 0.00 | |
> C:\msys64\usr\bin\time.exe -p ./spinlock_64.exe | |
count=100000000.000000 | |
real 2.98 | |
user 0.00 | |
sys 0.01 | |
> C:\msys64\usr\bin\time.exe -p ./mutexlock_64.exe | |
count=100000000.000000 | |
real 364.81 | |
user 0.00 | |
sys 0.01 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment