Skip to content

Commit

Permalink
add C11 thread, mutex and condition API (baresip#249)
Browse files Browse the repository at this point in the history
  • Loading branch information
sreimers authored May 11, 2022
1 parent 5986f89 commit 9b1a8b9
Show file tree
Hide file tree
Showing 9 changed files with 666 additions and 1 deletion.
21 changes: 21 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ endif()
#
include(GNUInstallDirs)
include(CheckIncludeFile)
include(CheckFunctionExists)
find_package(Backtrace)
find_package(Threads)
find_package(OpenSSL)
Expand Down Expand Up @@ -86,6 +87,11 @@ else()
set(Backtrace_LIBRARIES)
endif()

check_function_exists(thrd_create HAVE_THREADS)
if(HAVE_THREADS)
add_definitions(-DHAVE_THREADS)
endif()

if(CMAKE_USE_PTHREADS_INIT)
add_definitions(-DHAVE_PTHREAD)
set(HAVE_PTHREAD ON)
Expand Down Expand Up @@ -543,6 +549,21 @@ elseif(HAVE_PTHREAD)
)
endif()

if(HAVE_THREADS)
list(APPEND SRCS
src/thread/thread.c
)
elseif(HAVE_PTHREAD)
list(APPEND SRCS
src/thread/thread.c
src/thread/posix.c
)
elseif(CMAKE_USE_WIN32_THREADS_INIT)
list(APPEND SRCS
src/thread/thread.c
src/thread/win32.c
)
endif()

if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
list(APPEND SRCS
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ MODULES += dns
MODULES += md5 crc32 sha hmac base64
MODULES += udp sa net tcp tls
MODULES += list mbuf hash
MODULES += fmt tmr trace btrace main mem dbg sys lock mqueue
MODULES += fmt tmr trace btrace main mem dbg sys thread lock mqueue
MODULES += mod conf
MODULES += bfcp
MODULES += aes srtp
Expand Down
1 change: 1 addition & 0 deletions include/re.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ extern "C" {
#include "re_sys.h"
#include "re_tcp.h"
#include "re_telev.h"
#include "re_thread.h"
#include "re_tmr.h"
#include "re_trace.h"
#include "re_tls.h"
Expand Down
236 changes: 236 additions & 0 deletions include/re_thread.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
/**
* @file re_thread.h Thread support
*
* Inspired by C11 thread support this provides a cross platform interfaces to
* thread, mutex and condition handling (C11, POSIX and Windows Threads).
*
* Preferred order:
*
* - C11 threads (glibc>=2.28, musl, FreeBSD>=10)
* - POSIX PTHREAD (Linux/UNIX, winpthreads)
* - Windows Thread API
*
* Copyright (C) 2022 Sebastian Reimers
*/

#if defined(HAVE_THREADS)
#include <threads.h>

#else

#if defined(HAVE_PTHREAD)

#include <pthread.h>
#include <time.h>
#define THREAD_ONCE_FLAG_INIT PTHREAD_ONCE_INIT
typedef pthread_once_t thrd_once_flag;
typedef pthread_t thrd_t;
typedef pthread_cond_t cnd_t;
typedef pthread_mutex_t mtx_t;

#elif defined(WIN32)

#include <windows.h>
#define THREAD_ONCE_FLAG_INIT INIT_ONCE_STATIC_INIT
typedef INIT_ONCE thrd_once_flag;
typedef HANDLE thrd_t;
typedef CONDITION_VARIABLE cnd_t;
typedef CRITICAL_SECTION mtx_t;

#endif

enum { mtx_plain = 0, mtx_try = 1, mtx_timed = 2, mtx_recursive = 4 };

/* Exit and error codes. */
enum {
thrd_success = 0,
thrd_busy = 1,
thrd_error = 2,
thrd_nomem = 3,
thrd_timedout = 4
};

typedef int (*thrd_start_t)(void *);


/******************************************************************************
* Thread functions
*****************************************************************************/

/**
* Creates a new thread
*
* @param thr Pointer to new thread
* @param func Function to execute
* @param arg Argument to pass to the function
*
* @return 0 if success, otherwise errorcode
*/
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);


/**
* Checks whether `lhs` and `rhs` refer to the same thread.
*
* @return Non-zero value if lhs and rhs refer to the same value, 0 otherwise.
*/
int thrd_equal(thrd_t lhs, thrd_t rhs);


/**
* Return the identifier of the calling thread.
*/
thrd_t thrd_current(void);


/**
* Detaches the thread identified by `thr` from the current environment.
*
* @return 0 if success, otherwise errorcode
*/
int thrd_detach(thrd_t thr);


/**
* Blocks the current thread until the thread identified by `thr` finishes
* execution
*
* @param thr Thread
* @param res Result code location
*
* @return 0 if success, otherwise errorcode
*/
int thrd_join(thrd_t thr, int *res);


/**
* Calls a function exactly once
*
* @param flag Pointer to object initialized by THREAD_ONCE_FLAG_INIT
* @param func The function to execute only once
*/
void call_once(thrd_once_flag *flag, void (*func)(void));


/**
* Terminates the calling thread
*
* @param res The result value to return
*/
void thrd_exit(int res);


/******************************************************************************
* Condition functions
*****************************************************************************/

/**
* Initializes new condition variable
*
* @param cnd Pointer to a variable to store condition variable
*
* @return 0 if success, otherwise errorcode
*/
int cnd_init(cnd_t *cnd);


/**
* Unblocks one thread blocked on a condition variable
*
* @param cnd Pointer to condition variable
*
* @return 0 if success, otherwise errorcode
*/
int cnd_signal(cnd_t *cnd);


/**
* Unblocks all thrds blocked on a condition variable
*
* @param cnd Pointer to condition variable
*
* @return 0 if success, otherwise errorcode
*/
int cnd_broadcast(cnd_t *cnd);


/**
* Blocks on a condition variable
*
* @param cnd Pointer to condition variable
* @param lock Lock mutex pointer
*
* @return 0 if success, otherwise errorcode
*/
int cnd_wait(cnd_t *cnd, mtx_t *mtx);


/**
* Destroys the condition variable pointed to by cnd.
* If there are thrds waiting on cnd, the behavior is undefined.
*
* @param cnd pointer to the condition variable to destroy
*/
void cnd_destroy(cnd_t *cnd);


/******************************************************************************
* Mutex functions
*****************************************************************************/

/**
* Creates a new mutex object with type. The object pointed to by mutex is set
* to an identifier of the newly created mutex.
*
* @param mtx Pointer to the mutex to initialize
* @param type The type of the mutex
*
* @return thrd_success on success, otherwise thrd_error
*/
int mtx_init(mtx_t *mtx, int type);


/**
* Blocks the current thread until the mutex pointed to by mutex is locked.
* The behavior is undefined if the current thread has already locked the
* mutex and the mutex is not recursive.
*
* @param mtx Pointer to the mutex
*
* @return thrd_success on success, otherwise thrd_error
*/
int mtx_lock(mtx_t *mtx);


/**
* Tries to lock the mutex pointed to by mutex without blocking.
* Returns immediately if the mutex is already locked.
*
* @param mtx Pointer to the mutex
*
* @return thrd_success on success, thrd_busy if alread locked,
* otherwise thrd_error
*/
int mtx_trylock(mtx_t *mtx);


/**
* Unlocks the mutex pointed to by mutex.
*
* @param mtx Pointer to the mutex
*
* @return thrd_success on success, otherwise thrd_error
*/
int mtx_unlock(mtx_t *mtx);


#endif /* C11 threads fallback */


/******************************************************************************
* Extra
*****************************************************************************/
/* int thrd_prio(enum thrd_prio prio) */
/* void thrd_print(struct re_printf *pf, void *unused); */
int thrd_create_name(thrd_t *thr, const char *name, thrd_start_t func,
void *arg);
4 changes: 4 additions & 0 deletions mk/re.mk
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,10 @@ CFLAGS += -DUSE_ZLIB
LIBS += -lz
endif

HAVE_THREADS := $(shell $(call CC_TEST,threads.h))
ifneq ($(HAVE_THREADS),)
CFLAGS += -DHAVE_THREADS
endif

HAVE_PTHREAD := $(shell $(call CC_TEST,pthread.h))
ifneq ($(HAVE_PTHREAD),)
Expand Down
9 changes: 9 additions & 0 deletions src/thread/mod.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ifdef HAVE_THREADS
SRCS += thread/thread.c
else ifdef HAVE_PTHREAD
SRCS += thread/thread.c
SRCS += thread/posix.c
else ifeq ($(OS),win32)
SRCS += thread/thread.c
SRCS += thread/win32.c
endif
Loading

0 comments on commit 9b1a8b9

Please sign in to comment.