You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
205 lines
4.0 KiB
205 lines
4.0 KiB
|
|
#ifdef _MSC_VER
|
|
#define EXPORT _declspec(dllexport)
|
|
#include <Windows.h>
|
|
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 <dispatch/dispatch.h>
|
|
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 <semaphore.h>
|
|
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 <mutex>
|
|
#include <chrono>
|
|
#include <thread>
|
|
#include <condition_variable>
|
|
#include <semaphore>
|
|
|
|
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<mutex> 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<mutex> 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 <atomic>
|
|
std::atomic<bool> 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);
|
|
}
|