Add comments on description.
This commit is contained in:
1 parent
c488d979cf
commit
8be06cadb3
3 files changed
+82
No files matched your search
@@ -1635,8 +1635,10 @@ M_PARSE_DEFAULT_TYPE_DEF(m_core_parse_ldouble, long double, strtold, )
|
|||||||
NOTE: C definition is safer than the C++ one.
|
NOTE: C definition is safer than the C++ one.
|
||||||
*/
|
*/
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
|
/* Cast the object n into type only if it is C assignable */
|
||||||
# define M_ASSIGN_CAST(type, n) ((type) { 0 } = (n))
|
# define M_ASSIGN_CAST(type, n) ((type) { 0 } = (n))
|
||||||
#else
|
#else
|
||||||
|
/* Cast the object n into type using a static_cast */
|
||||||
# define M_ASSIGN_CAST(type, n) static_cast<type>(n)
|
# define M_ASSIGN_CAST(type, n) static_cast<type>(n)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -35,63 +35,84 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "m-core.h"
|
#include "m-core.h"
|
||||||
|
|
||||||
|
/* Define a mutex type based on C11 definition */
|
||||||
typedef mtx_t m_mutex_t[1];
|
typedef mtx_t m_mutex_t[1];
|
||||||
|
|
||||||
|
/* Define a condition variable type based on C11 definition */
|
||||||
typedef cnd_t m_cond_t[1];
|
typedef cnd_t m_cond_t[1];
|
||||||
|
|
||||||
|
/* Define a thread type based on C11 definition */
|
||||||
typedef thrd_t m_thread_t[1];
|
typedef thrd_t m_thread_t[1];
|
||||||
|
|
||||||
|
/* Initialize the mutex (constructor) */
|
||||||
static inline void m_mutex_init(m_mutex_t m)
|
static inline void m_mutex_init(m_mutex_t m)
|
||||||
{
|
{
|
||||||
int rc = mtx_init(m, mtx_plain);
|
int rc = mtx_init(m, mtx_plain);
|
||||||
|
// Abort program in case of initialization failure
|
||||||
|
// There is really nothing else to do if a mutex cannot be constructed
|
||||||
M_ASSERT_INIT (rc == 0, "mutex");
|
M_ASSERT_INIT (rc == 0, "mutex");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear the mutex (destructor) */
|
||||||
static inline void m_mutex_clear(m_mutex_t m)
|
static inline void m_mutex_clear(m_mutex_t m)
|
||||||
{
|
{
|
||||||
mtx_destroy(m);
|
mtx_destroy(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Lock the mutex */
|
||||||
static inline void m_mutex_lock(m_mutex_t m)
|
static inline void m_mutex_lock(m_mutex_t m)
|
||||||
{
|
{
|
||||||
mtx_lock(m);
|
mtx_lock(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Unlock the mutex */
|
||||||
static inline void m_mutex_unlock(m_mutex_t m)
|
static inline void m_mutex_unlock(m_mutex_t m)
|
||||||
{
|
{
|
||||||
mtx_unlock(m);
|
mtx_unlock(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize the condition variable (constructor) */
|
||||||
static inline void m_cond_init(m_cond_t c)
|
static inline void m_cond_init(m_cond_t c)
|
||||||
{
|
{
|
||||||
int rc = cnd_init(c);
|
int rc = cnd_init(c);
|
||||||
|
// Abort program in case of initialization failure
|
||||||
|
// There is really nothing else to do if the object cannot be constructed
|
||||||
M_ASSERT_INIT (rc == 0, "conditional variable");
|
M_ASSERT_INIT (rc == 0, "conditional variable");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear the condition variable (destructor) */
|
||||||
static inline void m_cond_clear(m_cond_t c)
|
static inline void m_cond_clear(m_cond_t c)
|
||||||
{
|
{
|
||||||
cnd_destroy(c);
|
cnd_destroy(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Signal the condition variable to at least one waiting thread */
|
||||||
static inline void m_cond_signal(m_cond_t c)
|
static inline void m_cond_signal(m_cond_t c)
|
||||||
{
|
{
|
||||||
cnd_signal(c);
|
cnd_signal(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Signal the condition variable to all waiting threads */
|
||||||
static inline void m_cond_broadcast(m_cond_t c)
|
static inline void m_cond_broadcast(m_cond_t c)
|
||||||
{
|
{
|
||||||
cnd_broadcast(c);
|
cnd_broadcast(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Wait for signaling the condition variable by another thread */
|
||||||
static inline void m_cond_wait(m_cond_t c, m_mutex_t m)
|
static inline void m_cond_wait(m_cond_t c, m_mutex_t m)
|
||||||
{
|
{
|
||||||
cnd_wait(c, m);
|
cnd_wait(c, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create the thread (constructor) and start it */
|
||||||
static inline void m_thread_create(m_thread_t t, void (*func)(void*), void* arg)
|
static inline void m_thread_create(m_thread_t t, void (*func)(void*), void* arg)
|
||||||
{
|
{
|
||||||
int rc = thrd_create(t, (int(*)(void*))(void(*)(void))func, arg);
|
int rc = thrd_create(t, (int(*)(void*))(void(*)(void))func, arg);
|
||||||
|
// Abort program in case of initialization failure
|
||||||
M_ASSERT_INIT (rc == thrd_success, "thread");
|
M_ASSERT_INIT (rc == thrd_success, "thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Wait for the thread to terminate and destroy it (destructor) */
|
||||||
static inline void m_thread_join(m_thread_t t)
|
static inline void m_thread_join(m_thread_t t)
|
||||||
{
|
{
|
||||||
int rc = thrd_join(*t, NULL);
|
int rc = thrd_join(*t, NULL);
|
||||||
@@ -100,11 +121,15 @@ static inline void m_thread_join(m_thread_t t)
|
|||||||
(void) rc;
|
(void) rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The thread has nothing meaningfull to do.
|
||||||
|
Inform the OS to let other threads be scheduled */
|
||||||
static inline void m_thread_yield(void)
|
static inline void m_thread_yield(void)
|
||||||
{
|
{
|
||||||
thrd_yield();
|
thrd_yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sleep the thread for at least usec microseconds.
|
||||||
|
Return true if the sleep was successful */
|
||||||
static inline bool m_thread_sleep(unsigned long long usec)
|
static inline bool m_thread_sleep(unsigned long long usec)
|
||||||
{
|
{
|
||||||
struct timespec tv;
|
struct timespec tv;
|
||||||
@@ -116,12 +141,17 @@ static inline bool m_thread_sleep(unsigned long long usec)
|
|||||||
|
|
||||||
// Internal type, not exported.
|
// Internal type, not exported.
|
||||||
typedef once_flag m_oncei_t[1];
|
typedef once_flag m_oncei_t[1];
|
||||||
|
|
||||||
|
// Initial value for m_oncei_t
|
||||||
#define M_ONCEI_INIT_VALUE { ONCE_FLAG_INIT }
|
#define M_ONCEI_INIT_VALUE { ONCE_FLAG_INIT }
|
||||||
|
|
||||||
|
// Call the function exactly once
|
||||||
static inline void m_oncei_call(m_oncei_t o, void (*func)(void))
|
static inline void m_oncei_call(m_oncei_t o, void (*func)(void))
|
||||||
{
|
{
|
||||||
call_once(o,func);
|
call_once(o,func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attribute to use to allocate a global variable to a thread.
|
||||||
#define M_THREAD_ATTR _Thread_local
|
#define M_THREAD_ATTR _Thread_local
|
||||||
|
|
||||||
|
|
||||||
@@ -142,61 +172,77 @@ static inline void m_oncei_call(m_oncei_t o, void (*func)(void))
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "m-core.h"
|
#include "m-core.h"
|
||||||
|
|
||||||
|
/* Define a thread type based on WINDOWS definition */
|
||||||
typedef HANDLE m_thread_t[1];
|
typedef HANDLE m_thread_t[1];
|
||||||
|
|
||||||
|
/* Define a mutex type based on WINDOWS definition */
|
||||||
typedef CRITICAL_SECTION m_mutex_t[1];
|
typedef CRITICAL_SECTION m_mutex_t[1];
|
||||||
|
|
||||||
|
/* Define a condition variable type based on WINDOWS definition */
|
||||||
typedef CONDITION_VARIABLE m_cond_t[1];
|
typedef CONDITION_VARIABLE m_cond_t[1];
|
||||||
|
|
||||||
|
/* Initialize a mutex (Constructor)*/
|
||||||
static inline void m_mutex_init(m_mutex_t m)
|
static inline void m_mutex_init(m_mutex_t m)
|
||||||
{
|
{
|
||||||
InitializeCriticalSection(m);
|
InitializeCriticalSection(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear a mutex (destructor) */
|
||||||
static inline void m_mutex_clear(m_mutex_t m)
|
static inline void m_mutex_clear(m_mutex_t m)
|
||||||
{
|
{
|
||||||
DeleteCriticalSection(m);
|
DeleteCriticalSection(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Lock a mutex */
|
||||||
static inline void m_mutex_lock(m_mutex_t m)
|
static inline void m_mutex_lock(m_mutex_t m)
|
||||||
{
|
{
|
||||||
EnterCriticalSection(m);
|
EnterCriticalSection(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Unlock a mutex */
|
||||||
static inline void m_mutex_unlock(m_mutex_t m)
|
static inline void m_mutex_unlock(m_mutex_t m)
|
||||||
{
|
{
|
||||||
LeaveCriticalSection(m);
|
LeaveCriticalSection(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize a condition variable (constructor) */
|
||||||
static inline void m_cond_init(m_cond_t c)
|
static inline void m_cond_init(m_cond_t c)
|
||||||
{
|
{
|
||||||
InitializeConditionVariable(c);
|
InitializeConditionVariable(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear a condition variable (destructor) */
|
||||||
static inline void m_cond_clear(m_cond_t c)
|
static inline void m_cond_clear(m_cond_t c)
|
||||||
{
|
{
|
||||||
(void) c; // There is no destructor for this object.
|
(void) c; // There is no destructor for this object.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Signal a condition variable to at least one waiting thread */
|
||||||
static inline void m_cond_signal(m_cond_t c)
|
static inline void m_cond_signal(m_cond_t c)
|
||||||
{
|
{
|
||||||
WakeConditionVariable(c);
|
WakeConditionVariable(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Signal a condition variable to all waiting threads */
|
||||||
static inline void m_cond_broadcast(m_cond_t c)
|
static inline void m_cond_broadcast(m_cond_t c)
|
||||||
{
|
{
|
||||||
WakeAllConditionVariable(c);
|
WakeAllConditionVariable(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Wait for a condition variable */
|
||||||
static inline void m_cond_wait(m_cond_t c, m_mutex_t m)
|
static inline void m_cond_wait(m_cond_t c, m_mutex_t m)
|
||||||
{
|
{
|
||||||
SleepConditionVariableCS(c, m, INFINITE);
|
SleepConditionVariableCS(c, m, INFINITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create a thread (constructor) and start it */
|
||||||
static inline void m_thread_create(m_thread_t t, void (*func)(void*), void *arg)
|
static inline void m_thread_create(m_thread_t t, void (*func)(void*), void *arg)
|
||||||
{
|
{
|
||||||
*t = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) (uintptr_t) func, arg, 0, NULL);
|
*t = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) (uintptr_t) func, arg, 0, NULL);
|
||||||
M_ASSERT_INIT (*t != NULL, "thread");
|
M_ASSERT_INIT (*t != NULL, "thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Wait for the thread to terminate and destroy it (destructor) */
|
||||||
static inline void m_thread_join(m_thread_t t)
|
static inline void m_thread_join(m_thread_t t)
|
||||||
{
|
{
|
||||||
DWORD dwWaitResult = WaitForSingleObject(*t, INFINITE);
|
DWORD dwWaitResult = WaitForSingleObject(*t, INFINITE);
|
||||||
@@ -205,11 +251,15 @@ static inline void m_thread_join(m_thread_t t)
|
|||||||
CloseHandle(*t);
|
CloseHandle(*t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The thread has nothing meaningfull to do.
|
||||||
|
Inform the OS to let other threads be scheduled */
|
||||||
static inline void m_thread_yield(void)
|
static inline void m_thread_yield(void)
|
||||||
{
|
{
|
||||||
Sleep(0);
|
Sleep(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sleep the thread for at least usec microseconds
|
||||||
|
Return true if the sleep was successful */
|
||||||
static inline bool m_thread_sleep(unsigned long long usec)
|
static inline bool m_thread_sleep(unsigned long long usec)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER ft;
|
LARGE_INTEGER ft;
|
||||||
@@ -241,8 +291,10 @@ static inline void m_oncei_call(m_oncei_t o, void (*func)(void))
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
// Attribute to use to allocate a global variable to a thread (MSVC def).
|
||||||
# define M_THREAD_ATTR __declspec( thread )
|
# define M_THREAD_ATTR __declspec( thread )
|
||||||
#else
|
#else
|
||||||
|
// Attribute to use to allocate a global variable to a thread (GCC def).
|
||||||
# define M_THREAD_ATTR __thread
|
# define M_THREAD_ATTR __thread
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -261,69 +313,92 @@ static inline void m_oncei_call(m_oncei_t o, void (*func)(void))
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "m-core.h"
|
#include "m-core.h"
|
||||||
|
|
||||||
|
/* Define a mutex type based on PTHREAD definition */
|
||||||
typedef pthread_mutex_t m_mutex_t[1];
|
typedef pthread_mutex_t m_mutex_t[1];
|
||||||
|
|
||||||
|
/* Define a condition variable type based on PTHREAD definition */
|
||||||
typedef pthread_cond_t m_cond_t[1];
|
typedef pthread_cond_t m_cond_t[1];
|
||||||
|
|
||||||
|
/* Define a thread type based on PTHREAD definition */
|
||||||
typedef pthread_t m_thread_t[1];
|
typedef pthread_t m_thread_t[1];
|
||||||
|
|
||||||
|
/* Initialize the mutex (constructor) */
|
||||||
static inline void m_mutex_init(m_mutex_t m)
|
static inline void m_mutex_init(m_mutex_t m)
|
||||||
{
|
{
|
||||||
int _rc = pthread_mutex_init(m, NULL);
|
int _rc = pthread_mutex_init(m, NULL);
|
||||||
|
// Abort program in case of initialization failure
|
||||||
|
// There is really nothing else to do if a mutex cannot be constructed
|
||||||
M_ASSERT_INIT (_rc == 0, "mutex");
|
M_ASSERT_INIT (_rc == 0, "mutex");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear the mutex (destructor) */
|
||||||
static inline void m_mutex_clear(m_mutex_t m)
|
static inline void m_mutex_clear(m_mutex_t m)
|
||||||
{
|
{
|
||||||
pthread_mutex_destroy(m);
|
pthread_mutex_destroy(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Lock the mutex */
|
||||||
static inline void m_mutex_lock(m_mutex_t m)
|
static inline void m_mutex_lock(m_mutex_t m)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(m);
|
pthread_mutex_lock(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Unlock the mutex */
|
||||||
static inline void m_mutex_unlock(m_mutex_t m)
|
static inline void m_mutex_unlock(m_mutex_t m)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(m);
|
pthread_mutex_unlock(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Lazy lock initialization */
|
||||||
#define M_MUTEXI_INIT_VALUE { PTHREAD_MUTEX_INITIALIZER }
|
#define M_MUTEXI_INIT_VALUE { PTHREAD_MUTEX_INITIALIZER }
|
||||||
|
|
||||||
|
/* Internal function compatible with lazy lock */
|
||||||
static inline void m_mutexi_lazy_lock(m_mutex_t m)
|
static inline void m_mutexi_lazy_lock(m_mutex_t m)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(m);
|
pthread_mutex_lock(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize the condition variable (constructor) */
|
||||||
static inline void m_cond_init(m_cond_t c)
|
static inline void m_cond_init(m_cond_t c)
|
||||||
{
|
{
|
||||||
int _rc = pthread_cond_init(c, NULL);
|
int _rc = pthread_cond_init(c, NULL);
|
||||||
|
// Abort program in case of initialization failure
|
||||||
|
// There is really nothing else to do if a mutex cannot be constructed
|
||||||
M_ASSERT_INIT (_rc == 0, "conditional variable");
|
M_ASSERT_INIT (_rc == 0, "conditional variable");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear the condition variable (destructor) */
|
||||||
static inline void m_cond_clear(m_cond_t c)
|
static inline void m_cond_clear(m_cond_t c)
|
||||||
{
|
{
|
||||||
pthread_cond_destroy(c);
|
pthread_cond_destroy(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Signal a condition variable to at least a waiting thread */
|
||||||
static inline void m_cond_signal(m_cond_t c)
|
static inline void m_cond_signal(m_cond_t c)
|
||||||
{
|
{
|
||||||
pthread_cond_signal(c);
|
pthread_cond_signal(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Signal a condition variable to all waiting threads */
|
||||||
static inline void m_cond_broadcast(m_cond_t c)
|
static inline void m_cond_broadcast(m_cond_t c)
|
||||||
{
|
{
|
||||||
pthread_cond_broadcast(c);
|
pthread_cond_broadcast(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Waiting for a condition variable */
|
||||||
static inline void m_cond_wait(m_cond_t c, m_mutex_t m)
|
static inline void m_cond_wait(m_cond_t c, m_mutex_t m)
|
||||||
{
|
{
|
||||||
pthread_cond_wait(c, m);
|
pthread_cond_wait(c, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create a thread (constructor) and start it */
|
||||||
static inline void m_thread_create(m_thread_t t, void (*func)(void*), void *arg)
|
static inline void m_thread_create(m_thread_t t, void (*func)(void*), void *arg)
|
||||||
{
|
{
|
||||||
int _rc = pthread_create(t, NULL, (void*(*)(void*))(void(*)(void))func, arg);
|
int _rc = pthread_create(t, NULL, (void*(*)(void*))(void(*)(void))func, arg);
|
||||||
M_ASSERT_INIT (_rc == 0, "thread");
|
M_ASSERT_INIT (_rc == 0, "thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Wait for the thread to terminate and destroy it (destructor) */
|
||||||
static inline void m_thread_join(m_thread_t t)
|
static inline void m_thread_join(m_thread_t t)
|
||||||
{
|
{
|
||||||
int _rc = pthread_join(*t, NULL);
|
int _rc = pthread_join(*t, NULL);
|
||||||
@@ -331,6 +406,8 @@ static inline void m_thread_join(m_thread_t t)
|
|||||||
assert (_rc == 0);
|
assert (_rc == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The thread has nothing meaningfull to do.
|
||||||
|
Inform the OS to let other threads be scheduled */
|
||||||
static inline void m_thread_yield(void)
|
static inline void m_thread_yield(void)
|
||||||
{
|
{
|
||||||
#ifdef _POSIX_PRIORITY_SCHEDULING
|
#ifdef _POSIX_PRIORITY_SCHEDULING
|
||||||
@@ -338,6 +415,8 @@ static inline void m_thread_yield(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sleep for at least usec microseconds
|
||||||
|
Return true if the sleep was successful */
|
||||||
static inline bool m_thread_sleep(unsigned long long usec)
|
static inline bool m_thread_sleep(unsigned long long usec)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|||||||
@@ -1562,6 +1562,7 @@ string_utf8_p(string_t str)
|
|||||||
C++ definition.
|
C++ definition.
|
||||||
*/
|
*/
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
|
/* Initialize a constant string with the given C string */
|
||||||
# define STRING_CTE(s) \
|
# define STRING_CTE(s) \
|
||||||
((const string_t){{.u.heap = { .size = sizeof(s)-1, .alloc = sizeof(s) } , \
|
((const string_t){{.u.heap = { .size = sizeof(s)-1, .alloc = sizeof(s) } , \
|
||||||
.ptr = ((struct { long long _n; char _d[sizeof (s)]; }){ 0, s })._d }})
|
.ptr = ((struct { long long _n; char _d[sizeof (s)]; }){ 0, s })._d }})
|
||||||
|
|||||||
Reference in new issue
Block a user