#ifdef _MSC_VER #define EXPORT _declspec(dllexport) #include class A_Semaphore { private: HANDLE native_handle; public: A_Semaphore(bool v = false) { native_handle = CreateSemaphore(NULL, v, 1, NULL); } void acquire() { WaitForSingleObject(native_handle, INFINITE); } void release() { ReleaseSemaphore(native_handle, 1, NULL); } ~A_Semaphore() { CloseHandle(native_handle); } }; #else #define EXPORT #ifdef __APPLE__ #include class A_Semaphore { private: dispatch_semaphore_t native_handle; public: A_Semaphore(bool v = false) { native_handle = dispatch_semaphore_create(v); } void acquire() { dispatch_semaphore_wait(&native_handle, DISPATCH_TIME_FOREVER); } void release() { dispatch_semaphore_signal(&native_handle); } ~A_Semaphore() { } }; #else #include class A_Semaphore { private: sem_t native_handle; public: A_Semaphore(bool v = false) { sem_init(&native_handle, v, 1); } void acquire() { sem_wait(&native_handle); } void release() { sem_post(&native_handle); } ~A_Semaphore() { sem_destroy(&native_handle); } }; #endif #endif A_Semaphore pp{ 0 }, cc{ 1 }; #include #include #include #include #include using namespace std; using namespace std::chrono_literals; mutex m; condition_variable cv; binary_semaphore producer{ 0 }, consumer{ 1 }; chrono::high_resolution_clock::time_point now; int idx; bool ready = false; extern "C" EXPORT void acquire() { consumer.acquire(); // work producer.release(); } extern "C" EXPORT void loop_acquire(int n) { int i = n; chrono::nanoseconds sum = 0ns; unsigned long long k = 0; now = chrono::high_resolution_clock::now(); while (i-- > 0) { producer.acquire(); // work // printf("%d ", i); consumer.release(); } sum += chrono::high_resolution_clock::now() - now; printf("std::semaphore: %lld sum: %llu\n", sum.count(), k); } extern "C" EXPORT void aacquire() { cc.acquire(); // work pp.release(); } extern "C" EXPORT void loop_aacquire(int n) { int i = n; chrono::nanoseconds sum = 0ns; unsigned long long k = 0; now = chrono::high_resolution_clock::now(); while (i-- > 0) { pp.acquire(); // work // printf("%d ", i); cc.release(); } sum += chrono::high_resolution_clock::now() - now; printf("native semaphore: %lld sum: %llu\n", sum.count(), k); } extern "C" EXPORT void lock(){ static int n = 0; unique_lock lk(m); cv.wait(lk, [] { return ready; }); ready = false; lk.unlock(); cv.notify_one(); } extern "C" EXPORT void loop_lock(int n){ int i = n; chrono::nanoseconds sum = 0ns; unsigned long long k = 0; now = chrono::high_resolution_clock::now(); while(i-- > 0){ unique_lock lk(m); ready = true; lk.unlock(); cv.notify_one(); lk.lock(); cv.wait(lk, [] {return !ready; }); } sum += chrono::high_resolution_clock::now() - now; printf("lock: %lld sum: %llu\n", sum.count(), k); } volatile bool flag = 0; extern "C" EXPORT void set(){ while (!flag); flag = false; } extern "C" EXPORT void loop_flag(int n){ int i = n; unsigned s = 0; chrono::nanoseconds sum = 0ns; now = chrono::high_resolution_clock::now(); while(i > 0){ if (!flag) { flag = true; --i; } } sum += chrono::high_resolution_clock::now() - now; printf("flag: %lld s: %u\n", sum.count(), s); } #include std::atomic af {0}; extern "C" EXPORT void atomic_set(){ while (!af); af = false; } extern "C" EXPORT void loop_atomic(int n){ int i = n; chrono::nanoseconds sum = 0ns; now = chrono::high_resolution_clock::now(); while(i > 0){ if (!af) { af = true; --i; } } sum += chrono::high_resolution_clock::now() - now; printf("flag: %lld\n", sum.count()); } extern "C" EXPORT void loop_slp(int n, int slp){ int i = n; chrono::nanoseconds sum = 0ns; now = chrono::high_resolution_clock::now(); while(i > 0){ if (!flag) { flag = true; --i; } std::this_thread::sleep_for(std::chrono::nanoseconds(slp)); } sum += chrono::high_resolution_clock::now() - now; printf("flag: %lld slp: %d\n", sum.count(), slp); }