#define _DEFAULT_SOURCE
#include <pthread.h>
#include <stdatomic.h>
#include <stdbool.h>
#define _LOCK_T struct __lock *
struct __lock {
pthread_mutex_t mut;
};
struct __lock __lock___libc_recursive_mutex;
__attribute__((constructor)) static void
libc_lock_init(void)
{
pthread_mutexattr_t mutexattr;
pthread_mutexattr_init(&mutexattr);
pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&__lock___libc_recursive_mutex.mut, &mutexattr);
}
#define MAX_LOCKS 32
static struct __lock locks[MAX_LOCKS];
static _Atomic int in_use[MAX_LOCKS];
void __retarget_lock_init(_LOCK_T *lock);
void
__retarget_lock_init(_LOCK_T *lock)
{
int lock_id = 0;
for (lock_id = 0; lock_id < MAX_LOCKS; lock_id++) {
int expected = 0;
int desired = 1;
if (atomic_compare_exchange_strong(&in_use[lock_id], &expected, desired)) {
pthread_mutexattr_t mutexattr;
pthread_mutexattr_init(&mutexattr);
pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&locks[lock_id].mut, &mutexattr);
*lock = &locks[lock_id];
return;
}
}
}
void __retarget_lock_init_recursive(_LOCK_T *lock);
void
__retarget_lock_init_recursive(_LOCK_T *lock)
{
__retarget_lock_init(lock);
}
void __retarget_lock_close(_LOCK_T lock);
void
__retarget_lock_close(_LOCK_T lock)
{
int lock_id = lock - locks;
int desired = 0;
pthread_mutex_destroy(&locks[lock_id].mut);
atomic_exchange(&in_use[lock_id], desired);
}
void __retarget_lock_close_recursive(_LOCK_T lock);
void
__retarget_lock_close_recursive(_LOCK_T lock)
{
__retarget_lock_close(lock);
}
void __retarget_lock_acquire(_LOCK_T lock);
void
__retarget_lock_acquire(_LOCK_T lock)
{
pthread_mutex_lock(&lock->mut);
}
void __retarget_lock_acquire_recursive(_LOCK_T lock);
void
__retarget_lock_acquire_recursive(_LOCK_T lock)
{
pthread_mutex_lock(&lock->mut);
}
void __retarget_lock_release(_LOCK_T lock);
void
__retarget_lock_release(_LOCK_T lock)
{
pthread_mutex_unlock(&lock->mut);
}
void __retarget_lock_release_recursive(_LOCK_T lock);
void
__retarget_lock_release_recursive(_LOCK_T lock)
{
pthread_mutex_unlock(&lock->mut);
}
static pthread_t thread;
int start_thread(void *(*func)(void *), void *arg);
int
start_thread(void *(*func)(void *), void *arg)
{
return pthread_create(&thread, NULL, func, arg);
}
int stop_thread(void);
int
stop_thread(void)
{
return pthread_join(thread, NULL);
}