Workshop o mikrokontrolérech na SKSP 2024.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
2.2 KiB

2 months ago
/*
* The UCW Library -- Threading Helpers
*
* (c) 2006--2010 Martin Mares <mj@ucw.cz>
*
* This software may be freely distributed and used according to the terms
* of the GNU Lesser General Public License.
*/
#include <ucw/lib.h>
#include <ucw/threads.h>
#ifdef CONFIG_UCW_THREADS
#include <pthread.h>
#ifdef CONFIG_LINUX
#include <sys/types.h>
#include <sys/syscall.h>
#include <unistd.h>
#ifdef __NR_gettid
static pid_t
ucw_gettid(void)
{
return syscall(__NR_gettid);
}
#define CONFIG_USE_GETTID
#endif
#endif
/*** Library lock ***/
static pthread_mutex_t ucwlib_master_mutex;
void
ucwlib_lock(void)
{
pthread_mutex_lock(&ucwlib_master_mutex);
}
void
ucwlib_unlock(void)
{
pthread_mutex_unlock(&ucwlib_master_mutex);
}
/*** Thread identifiers ***/
static int
ucwlib_tid(void)
{
static int tid_counter;
int tid;
#ifdef CONFIG_USE_GETTID
tid = ucw_gettid();
if (tid > 0)
return tid;
/* The syscall might be unimplemented */
#endif
ucwlib_lock();
tid = ++tid_counter;
ucwlib_unlock();
return tid;
}
/*** Thread context ***/
static void CONSTRUCTOR_WITH_PRIORITY(10000)
ucwlib_threads_init_master(void)
{
pthread_mutex_init(&ucwlib_master_mutex, NULL);
}
#ifdef CONFIG_UCW_TLS
__thread struct ucwlib_context ucwlib_context;
int
ucwlib_thread_id(struct ucwlib_context *c)
{
if (!c->_thread_id)
c->_thread_id = ucwlib_tid();
return c->_thread_id;
}
#else
static pthread_key_t ucwlib_context_key;
static void
ucwlib_free_thread_context(void *p)
{
xfree(p);
}
static void CONSTRUCTOR_WITH_PRIORITY(10000)
ucwlib_threads_init(void)
{
if (pthread_key_create(&ucwlib_context_key, ucwlib_free_thread_context) < 0)
die("Cannot create pthread_key: %m");
}
struct ucwlib_context *
ucwlib_thread_context(void)
{
struct ucwlib_context *c = pthread_getspecific(ucwlib_context_key);
if (!c)
{
c = xmalloc_zero(sizeof(*c));
c->_thread_id = ucwlib_tid();
pthread_setspecific(ucwlib_context_key, c);
}
return c;
}
#endif /* CONFIG_UCW_TLS */
#else /* !CONFIG_UCW_THREADS */
struct ucwlib_context ucwlib_default_context;
#endif
#ifdef TEST
int main(void)
{
ucwlib_lock();
ucwlib_unlock();
msg(L_INFO, "tid=%d", ucwlib_thread_id(ucwlib_thread_context()));
return 0;
}
#endif