Skip to content

Instantly share code, notes, and snippets.

@CandyMi
Last active October 26, 2023 10:17
Show Gist options
  • Save CandyMi/ed8bb067b6e95b51a2451e1beb5cd913 to your computer and use it in GitHub Desktop.
Save CandyMi/ed8bb067b6e95b51a2451e1beb5cd913 to your computer and use it in GitHub Desktop.
一些API的兼容实现

介绍

一些API的兼容实现

/*
** 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(); }
};
#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;
}
/*
** 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