一些API的兼容实现
Last active
October 26, 2023 10:17
-
-
Save CandyMi/ed8bb067b6e95b51a2451e1beb5cd913 to your computer and use it in GitHub Desktop.
一些API的兼容实现
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
/* | |
** LICENSE: BSD | |
** Author: CandyMi[https://github.com/candymi] | |
*/ | |
#pragma once | |
#include <mutex> | |
#include <atomic> | |
#define xrio_thread_local thread_local | |
/* 互斥锁 */ | |
class AtomicMutex | |
{ | |
private: | |
std::atomic_flag _lock = ATOMIC_FLAG_INIT; | |
public: | |
inline void lock() { while (_lock.test_and_set(std::memory_order_acquire)) { } } | |
inline void unlock() { _lock.clear(std::memory_order_release); } | |
}; | |
/* 读写锁 */ | |
class AtomicRWLock | |
{ | |
private: | |
std::atomic<uint32_t> _r; | |
std::atomic<uint32_t> _w; | |
public: | |
explicit AtomicRWLock() { _r.store(0); _w.store(0); } | |
/* unlock */ | |
inline void runlock() { _r.fetch_sub(1, std::memory_order_release); } | |
inline void wunlock() { _w.store(0, std::memory_order_release); } | |
/* lock */ | |
inline void rlock() | |
{ | |
while (1) | |
{ | |
if (_w.load(std::memory_order_relaxed)) | |
continue; | |
_r.fetch_add(1, std::memory_order_relaxed); | |
if (!_w.load(std::memory_order_relaxed)) | |
break; | |
_r.fetch_sub(1, std::memory_order_relaxed); | |
} | |
} | |
inline void wlock() | |
{ | |
while (_w.exchange(1, std::memory_order_acquire)) { }; | |
while (_r.load(std::memory_order_relaxed)) { }; | |
} | |
}; | |
template <typename T = AtomicMutex> | |
class xrio_spinlock_t | |
{ | |
private: | |
T &_mutex; | |
public: | |
explicit xrio_spinlock_t(T &m): _mutex(m) { _mutex.lock(); } | |
~xrio_spinlock_t() { _mutex.unlock(); } | |
}; | |
template <typename T = AtomicRWLock> | |
class xrio_rlock_t | |
{ | |
private: | |
T &_r; | |
public: | |
explicit xrio_rlock_t(T &m): _mutex(m) { _r.rlock(); } | |
~xrio_rlock_t() { _r.runlock(); } | |
}; | |
template <typename T = AtomicRWLock> | |
class xrio_wlock_t | |
{ | |
private: | |
T &_w; | |
public: | |
explicit xrio_wlock_t(T &m): _mutex(m) { _w.wlock(); } | |
~xrio_wlock_t() { _w.wunlock(); } | |
}; |
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 "sem.h" | |
#include <pthread.h> | |
#include <stdlib.h> | |
struct sem_t | |
{ | |
pthread_mutex_t _mutex; | |
pthread_cond_t _cond; | |
}; | |
int sem_init(sem_t *sem, int __pshared, unsigned int __value) | |
{ | |
(void)__pshared; (void)__value; | |
pthread_cond_init(&sem->_cond, NULL); | |
pthread_mutex_init(&sem->_mutex, NULL); | |
return 0; | |
} | |
int sem_post(sem_t *sem) | |
{ | |
pthread_mutex_lock(&sem->_mutex); | |
pthread_cond_signal(&sem->_cond); | |
pthread_mutex_unlock(&sem->_mutex); | |
return 0; | |
} | |
int sem_wait(sem_t *sem) | |
{ | |
return sem_timedwait(sem, NULL); | |
} | |
int sem_timedwait(sem_t *sem, const struct timespec *abs) | |
{ | |
int ret = 0; | |
pthread_mutex_lock(&sem->_mutex); | |
ret = pthread_cond_timedwait(&sem->_cond, &sem->_mutex, abs); | |
pthread_mutex_unlock(&sem->_mutex); | |
return ret; | |
} | |
sem_t *sem_open(const char *name, int oflag, int mode, unsigned int value) | |
{ | |
(void)name; (void)oflag; (void)mode; (void)value; | |
sem_t* sem = (sem_t*)malloc(sizeof(sem_t)); | |
if (!sem) | |
return NULL; | |
sem_init(sem, 0, 0); | |
return sem; | |
} | |
void sem_close(sem_t *sem) | |
{ | |
pthread_cond_destroy(&sem->_cond); | |
pthread_mutex_destroy(&sem->_mutex); | |
free(sem); | |
} | |
int sem_unlink(const char * name) | |
{ | |
(void)name; | |
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
/* | |
** LICENSE: BSD | |
** Author: CandyMi[https://github.com/candymi] | |
*/ | |
#pragma once | |
#ifndef _GNU_SOURCE | |
#define _GNU_SOURCE | |
#endif | |
#include <stdint.h> | |
#ifdef __cplusplus /* 互斥锁 */ | |
#define SEM_EXTERN extern "C" | |
#else | |
#define SEM_EXTERN extern | |
#endif | |
struct timespec; | |
struct sem_t; | |
typedef struct sem_t sem_t; | |
#define SEM_FAILED (sem_t*)0 | |
/* sem wait */ | |
SEM_EXTERN int sem_wait(sem_t *sem); | |
/* sem wait until timeout */ | |
SEM_EXTERN int sem_timedwait(sem_t *sem, const struct timespec *abs); | |
/* sem init */ | |
SEM_EXTERN int sem_init(sem_t *sem, int __pshared, unsigned int __value); | |
/* new sem */ | |
SEM_EXTERN sem_t *sem_open(const char *name, int oflag, int mode, unsigned int value); | |
/* close sem */ | |
SEM_EXTERN void sem_close(sem_t *sem); | |
/* unlink named sem */ | |
SEM_EXTERN int sem_unlink(const char * name); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment