Commit f0cd82b8 authored by Martin Karsten's avatar Martin Karsten

- expose owner lock (recursive lock) to C interface

parent 2b8ecbb8
Pipeline #40475 passed with stage
in 6 minutes and 38 seconds
......@@ -9,21 +9,45 @@
#define CurrCluster Context::CurrCluster
typedef Fibre shim_thread_t;
typedef FibreMutex shim_mutex_t;
typedef FibreCondition shim_cond_t;
typedef FibreBarrier shim_barrier_t;
#if TESTING_LOCK_RECURSION
typedef OwnerMutex<FibreMutex> shim_mutex_t;
#else
typedef FibreMutex shim_mutex_t;
#endif
static inline shim_thread_t* shim_thread_create(void (*start_routine)(void *), void* arg, bool bg = false) {
return new Fibre(start_routine, arg, bg);
}
static inline void shim_thread_destroy(shim_thread_t* tid) { delete tid; }
static inline void shim_yield() { Fibre::yield(); }
#if TESTING_LOCK_RECURSION
#undef HASTRYLOCK
static inline void shim_mutex_init(shim_mutex_t* mtx) {
new (mtx) shim_mutex_t;
mtx->enableRecursion();
}
static inline void shim_mutex_lock(shim_mutex_t* mtx) {
size_t x;
x = mtx->acquire(); RASSERT0(x == 1);
x = mtx->acquire(); RASSERT0(x == 2);
}
static inline void shim_mutex_unlock(shim_mutex_t* mtx) {
size_t x;
x = mtx->release(); RASSERT0(x == 1);
x = mtx->release(); RASSERT0(x == 0);
}
#else
static inline void shim_mutex_init(shim_mutex_t* mtx) { new (mtx) shim_mutex_t; }
static inline void shim_mutex_destroy(shim_mutex_t* mtx) {}
static inline void shim_mutex_lock(shim_mutex_t* mtx) { mtx->acquire(); }
static inline bool shim_mutex_trylock(shim_mutex_t* mtx) { return mtx->tryAcquire(); }
static inline void shim_mutex_unlock(shim_mutex_t* mtx) { mtx->release(); }
#endif
static inline void shim_mutex_destroy(shim_mutex_t* mtx) {}
static inline void shim_cond_init(shim_cond_t* cond) { new (cond) shim_cond_t; }
static inline void shim_cond_destroy(shim_cond_t* cond) {}
......
......@@ -181,6 +181,22 @@ extern "C" int cfibre_sem_getvalue(cfibre_sem_t *sem, int *sval) {
return fibre_sem_getvalue(*sem, sval);
}
extern "C" int cfibre_mutexattr_init(cfibre_mutexattr_t *attr) {
*attr = new _cfibre_mutexattr_t;
return fibre_mutexattr_init(*attr);
}
extern "C" int cfibre_mutexattr_destroy(cfibre_mutexattr_t *attr) {
int ret = fibre_mutexattr_destroy(*attr);
delete *attr;
*attr = nullptr;
return ret;
}
extern "C" int cfibre_mutexattr_settype(cfibre_mutexattr_t *attr, int type) {
return fibre_mutexattr_settype(*attr, type);
}
extern "C" int cfibre_mutex_init(cfibre_mutex_t *restrict mutex, const cfibre_mutexattr_t *restrict attr) {
*mutex = (cfibre_mutex_t)new fibre_mutex_t;
return fibre_mutex_init(*mutex, (fibre_mutexattr_t*)attr);
......@@ -293,6 +309,22 @@ extern "C" int cfibre_barrier_wait(cfibre_barrier_t *barrier) {
return fibre_barrier_wait(*barrier);
}
extern "C" int cfibre_fastmutexattr_init(cfibre_fastmutexattr_t *attr) {
*attr = new _cfibre_fastmutexattr_t;
return fibre_fastmutexattr_init(*attr);
}
extern "C" int cfibre_fastmutexattr_destroy(cfibre_fastmutexattr_t *attr) {
int ret = fibre_fastmutexattr_destroy(*attr);
delete *attr;
*attr = nullptr;
return ret;
}
extern "C" int cfibre_fastmutexattr_settype(cfibre_fastmutexattr_t *attr, int type) {
return fibre_fastmutexattr_settype(*attr, type);
}
extern "C" int cfibre_fastmutex_init(cfibre_fastmutex_t *restrict mutex, const cfibre_fastmutexattr_t *restrict attr) {
*mutex = (cfibre_fastmutex_t)new fibre_fastmutex_t;
return fibre_fastmutex_init(*mutex, (fibre_fastmutexattr_t*)attr);
......
......@@ -99,6 +99,10 @@ int cfibre_sem_timedwait(cfibre_sem_t *sem, const struct timespec *abs_timeout);
int cfibre_sem_post(cfibre_sem_t *sem);
int cfibre_sem_getvalue(cfibre_sem_t *sem, int *sval);
int cfibre_mutexattr_init(cfibre_mutexattr_t *attr);
int cfibre_mutexattr_destroy(cfibre_mutexattr_t *attr);
int cfibre_mutexattr_settype(cfibre_mutexattr_t *attr, int type);
int cfibre_mutex_init(cfibre_mutex_t *restrict mutex, const cfibre_mutexattr_t *restrict attr);
int cfibre_mutex_destroy(cfibre_mutex_t *mutex);
int cfibre_mutex_lock(cfibre_mutex_t *mutex);
......@@ -127,6 +131,10 @@ int cfibre_barrier_init(cfibre_barrier_t *restrict barrier, const cfibre_barrier
int cfibre_barrier_destroy(cfibre_barrier_t *barrier);
int cfibre_barrier_wait(cfibre_barrier_t *barrier);
int cfibre_fastmutexattr_init(cfibre_fastmutexattr_t *attr);
int cfibre_fastmutexattr_destroy(cfibre_fastmutexattr_t *attr);
int cfibre_fastmutexattr_settype(cfibre_fastmutexattr_t *attr, int type);
int cfibre_fastmutex_init(cfibre_fastmutex_t *restrict mutex, const cfibre_fastmutexattr_t *restrict attr);
int cfibre_fastmutex_destroy(cfibre_fastmutex_t *mutex);
int cfibre_fastmutex_lock(cfibre_fastmutex_t *mutex);
......
......@@ -39,13 +39,18 @@ typedef LockRW<WorkerLock> FibreLockRW;
typedef Barrier<WorkerLock> FibreBarrier;
typedef Fibre* fibre_t;
typedef FibreMutex fibre_mutex_t;
typedef FibreCondition fibre_cond_t;
typedef FibreSemaphore fibre_sem_t;
typedef FibreLockRW fibre_rwlock_t;
typedef FibreBarrier fibre_barrier_t;
#if TESTING_LOCK_RECURSION
typedef OwnerMutex<FibreMutex> fibre_mutex_t;
typedef OwnerMutex<FastMutex> fibre_fastmutex_t;
#else
typedef FibreMutex fibre_mutex_t;
typedef FastMutex fibre_fastmutex_t;
#endif
struct fibre_attr_t {
size_t stackSize;
......@@ -60,12 +65,23 @@ struct fibre_attr_t {
}
};
struct fibre_mutexattr_t {};
enum {
FIBRE_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE,
FIBRE_MUTEX_DEFAULT = PTHREAD_MUTEX_DEFAULT
};
struct fibre_mutexattr_t {
int type;
fibre_mutexattr_t() : type(FIBRE_MUTEX_DEFAULT) {}
};
struct fibre_condattr_t {};
struct fibre_rwlockattr_t {};
struct fibre_barrierattr_t {};
struct fibre_fastmutexattr_t {};
struct fibre_fastmutexattr_t {
int type;
fibre_fastmutexattr_t() : type(FIBRE_MUTEX_DEFAULT) {}
};
#ifdef __GNUC__
#define restrict __restrict__
......@@ -214,9 +230,29 @@ inline int fibre_sem_getvalue(fibre_sem_t *sem, int *sval) {
return 0;
}
/** @brief Initialize the mutex attributes object. (`pthread_mutexattr_init`) */
inline int fibre_mutexattr_init(fibre_mutexattr_t *attr) {
return 0;
}
/** @brief Destroy the mutex attributes object. (`pthread_mutexattr_destroy`) */
inline int fibre_mutexattr_destroy(fibre_mutexattr_t *attr) {
return 0;
}
/** @brief Set the mutex type attribute. (`pthread_mutexattr_settype`) */
inline int fibre_mutexattr_settype(fibre_mutexattr_t *attr, int type) {
attr->type = type;
return 0;
}
/** @brief Initialize mutex lock. (`pthread_mutex_init`) */
inline int fibre_mutex_init(fibre_mutex_t *restrict mutex, const fibre_mutexattr_t *restrict attr) {
RASSERT0(attr == nullptr);
#if TESTING_LOCK_RECURSION
if (attr && attr->type == PTHREAD_MUTEX_RECURSIVE) mutex->enableRecursion();
#else
if (attr && attr->type == PTHREAD_MUTEX_RECURSIVE) return -1;
#endif
return 0;
}
......@@ -350,9 +386,29 @@ inline int fibre_barrier_wait(fibre_barrier_t *barrier) {
return barrier->wait() ? PTHREAD_BARRIER_SERIAL_THREAD : 0;
}
/** @brief Initialize the fastmutex attributes object. (`pthread_mutexattr_init`) */
inline int fibre_fastmutexattr_init(fibre_fastmutexattr_t *attr) {
return 0;
}
/** @brief Destroy the fastmutex attributes object. (`pthread_mutexattr_destroy`) */
inline int fibre_fastmutexattr_destroy(fibre_fastmutexattr_t *attr) {
return 0;
}
/** @brief Set the fastmutex type attribute. (`pthread_mutexattr_settype`) */
inline int fibre_fastmutexattr_settype(fibre_fastmutexattr_t *attr, int type) {
attr->type = type;
return 0;
}
/** @brief Initialize mutex lock. (`pthread_mutex_init`) */
inline int fibre_fastmutex_init(fibre_fastmutex_t *restrict mutex, const fibre_fastmutexattr_t *restrict attr) {
RASSERT0(attr == nullptr);
#if TESTING_LOCK_RECURSION
if (attr && attr->type == PTHREAD_MUTEX_RECURSIVE) mutex->enableRecursion();
#else
if (attr && attr->type == PTHREAD_MUTEX_RECURSIVE) return -1;
#endif
return 0;
}
......
......@@ -7,6 +7,7 @@
// **** libfibre options - system threading
//#define TESTING_LOCK_SPIN 1024 // spin before blocking on system lock
//#define TESTING_LOCK_RECURSION 1 // enable mutex recursion in C interface
/******************************** sanity checks ********************************/
......
......@@ -493,13 +493,18 @@ public:
template<typename BaseMutex>
class OwnerMutex : private BaseMutex {
size_t counter;
bool recursion;
public:
OwnerMutex() : counter(0) {}
OwnerMutex() : counter(0), recursion(false) {}
void enableRecursion() { recursion = true; }
template<typename... Args>
size_t acquire(const Args&... args) {
if (BaseMutex::template internalAcquire<true>(args...)) return ++counter; else return 0;
bool success = recursion
? BaseMutex::template internalAcquire<true>(args...)
: BaseMutex::template internalAcquire<false>(args...);
if (success) return ++counter; else return 0;
}
size_t tryAcquire() { return acquire(false); }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment