various flavors of condition variables/mutexes -- not all are complete -- for experimentation only
This commit was SVN r816.
Этот коммит содержится в:
родитель
2493a6c3ea
Коммит
366b325f24
@ -10,14 +10,25 @@ noinst_LTLIBRARIES = libthreads.la
|
||||
# Source code files
|
||||
|
||||
headers = \
|
||||
condition.h \
|
||||
condition_pthread.h \
|
||||
condition_spinlock.h \
|
||||
condition_spinwait.h \
|
||||
mutex.h \
|
||||
mutex_pthread.h \
|
||||
mutex_spinlock.h \
|
||||
mutex_spinwait.h \
|
||||
thread.h
|
||||
|
||||
libthreads_la_SOURCES = \
|
||||
$(headers) \
|
||||
mutex.c \
|
||||
condition_pthread.c \
|
||||
condition_spinlock.c \
|
||||
condition_spinwait.c \
|
||||
mutex.c \
|
||||
mutex_pthread.c \
|
||||
mutex_spinlock.c \
|
||||
mutex_spinwait.c \
|
||||
thread.c
|
||||
|
||||
# Conditionally install the header files
|
||||
|
20
src/lam/threads/condition.h
Обычный файл
20
src/lam/threads/condition.h
Обычный файл
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
#ifndef LAM_CONDITION_H
|
||||
#define LAM_CONDITION_H
|
||||
|
||||
#include "lam_config.h"
|
||||
#include "lam/threads/mutex.h"
|
||||
|
||||
#if defined(LAM_USE_SPINLOCK)
|
||||
#include "condition_spinlock.h"
|
||||
#elif defined(LAM_USE_SPINWAIT)
|
||||
#include "condition_spinwait.h"
|
||||
#elif defined(LAM_USE_PTHREADS)
|
||||
#include "condition_pthread.h"
|
||||
#else
|
||||
#error "concurrency model not configured"
|
||||
#endif
|
||||
|
||||
#endif
|
27
src/lam/threads/condition_pthread.c
Обычный файл
27
src/lam/threads/condition_pthread.c
Обычный файл
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "mutex.h"
|
||||
#include "condition.h"
|
||||
#if defined(LAM_USE_PTHREADS)
|
||||
|
||||
static void lam_condition_construct(lam_condition_t* c)
|
||||
{
|
||||
pthread_cond_init(&c->c_cond, NULL);
|
||||
}
|
||||
|
||||
static void lam_condition_destruct(lam_condition_t* c)
|
||||
{
|
||||
pthread_cond_destroy(&c->c_cond);
|
||||
}
|
||||
|
||||
OBJ_CLASS_INSTANCE(
|
||||
lam_condition_t,
|
||||
lam_object_t,
|
||||
lam_condition_construct,
|
||||
lam_condition_destruct
|
||||
);
|
||||
|
||||
#endif
|
||||
|
41
src/lam/threads/condition_pthread.h
Обычный файл
41
src/lam/threads/condition_pthread.h
Обычный файл
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
#ifndef LAM_CONDITION_PTHREAD_H
|
||||
#define LAM_CONDITION_PTHREAD_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include "lam/threads/mutex.h"
|
||||
|
||||
|
||||
struct lam_condition_t {
|
||||
lam_object_t super;
|
||||
pthread_cond_t c_cond;
|
||||
};
|
||||
typedef struct lam_condition_t lam_condition_t;
|
||||
|
||||
OBJ_CLASS_DECLARATION(lam_condition_t);
|
||||
|
||||
|
||||
static inline int lam_condition_wait(lam_condition_t* c, lam_mutex_t* m)
|
||||
{
|
||||
return pthread_cond_wait(&c->c_cond, &m->m_lock);
|
||||
}
|
||||
|
||||
static inline int lam_condition_timedwait(lam_condition_t* c, lam_mutex_t* m, const struct timespec *abstime)
|
||||
{
|
||||
return pthread_cond_timedwait(&c->c_cond, &m->m_lock, abstime);
|
||||
}
|
||||
|
||||
static inline int lam_condition_signal(lam_condition_t* c)
|
||||
{
|
||||
return pthread_cond_signal(&c->c_cond);
|
||||
}
|
||||
|
||||
static inline int lam_condition_broadcast(lam_condition_t* c)
|
||||
{
|
||||
return pthread_cond_broadcast(&c->c_cond);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
30
src/lam/threads/condition_spinlock.c
Обычный файл
30
src/lam/threads/condition_spinlock.c
Обычный файл
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "mutex.h"
|
||||
#include "condition.h"
|
||||
|
||||
#if defined(LAM_USE_SPINLOCK)
|
||||
|
||||
|
||||
static void lam_condition_construct(lam_condition_t* c)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void lam_condition_destruct(lam_condition_t* c)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
OBJ_CLASS_INSTANCE(
|
||||
lam_condition_t,
|
||||
lam_object_t,
|
||||
lam_condition_construct,
|
||||
lam_condition_destruct
|
||||
);
|
||||
|
||||
|
||||
#endif
|
||||
|
39
src/lam/threads/condition_spinlock.h
Обычный файл
39
src/lam/threads/condition_spinlock.h
Обычный файл
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
#ifndef LAM_CONDITION_SPINLOCK_H
|
||||
#define LAM_CONDITION_SPINLOCK_H
|
||||
|
||||
#include "lam/threads/condition.h"
|
||||
|
||||
|
||||
struct lam_condition_t {
|
||||
volatile int c_waiting;
|
||||
};
|
||||
typedef struct lam_condition_t lam_condition_t;
|
||||
|
||||
OBJ_CLASS_DECLARATION(lam_condition_t);
|
||||
|
||||
|
||||
static inline int lam_condition_wait(lam_condition_t* c, lam_mutex_t* m)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int lam_condition_timedwait(lam_condition_t* c, lam_mutex_t* m, const struct timespec *abstime)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int lam_condition_signal(lam_condition_t* c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int lam_condition_broadcast(lam_condition_t* c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
29
src/lam/threads/condition_spinwait.c
Обычный файл
29
src/lam/threads/condition_spinwait.c
Обычный файл
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "mutex.h"
|
||||
#include "condition.h"
|
||||
|
||||
#if defined(LAM_USE_SPINWAIT)
|
||||
|
||||
|
||||
static void lam_condition_construct(lam_condition_t* c)
|
||||
{
|
||||
pthread_cond_init(&c->c_cond, NULL);
|
||||
}
|
||||
|
||||
static void lam_condition_destruct(lam_condition_t* c)
|
||||
{
|
||||
pthread_cond_destroy(&c->c_cond);
|
||||
}
|
||||
|
||||
OBJ_CLASS_INSTANCE(
|
||||
lam_condition_t,
|
||||
lam_object_t,
|
||||
lam_condition_construct,
|
||||
lam_condition_destruct
|
||||
);
|
||||
|
||||
#endif
|
||||
|
58
src/lam/threads/condition_spinwait.h
Обычный файл
58
src/lam/threads/condition_spinwait.h
Обычный файл
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
#ifndef LAM_CONDITION_SPINWAIT_H
|
||||
#define LAM_CONDITION_SPINWAIT_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include "lam/threads/mutex.h"
|
||||
|
||||
|
||||
struct lam_condition_t {
|
||||
lam_object_t super;
|
||||
pthread_cond_t c_cond;
|
||||
};
|
||||
typedef struct lam_condition_t lam_condition_t;
|
||||
|
||||
OBJ_CLASS_DECLARATION(lam_condition_t);
|
||||
|
||||
|
||||
static inline int lam_condition_wait(lam_condition_t* c, lam_mutex_t* m)
|
||||
{
|
||||
|
||||
int rc;
|
||||
pthread_mutex_lock(&m->m_lock);
|
||||
/* release the spinlock */
|
||||
fetchNset(&m->m_spinlock, 0);
|
||||
if(m->m_waiting)
|
||||
pthread_cond_signal(&m->m_cond);
|
||||
rc = pthread_cond_wait(&c->c_cond, &m->m_lock);
|
||||
fetchNset(&m->m_spinlock, 1);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline int lam_condition_timedwait(lam_condition_t* c, lam_mutex_t* m, const struct timespec *abstime)
|
||||
{
|
||||
int rc;
|
||||
pthread_mutex_lock(&m->m_lock);
|
||||
/* release the spinlock */
|
||||
fetchNset(&m->m_spinlock, 0);
|
||||
if(m->m_waiting)
|
||||
pthread_cond_signal(&m->m_cond);
|
||||
rc = pthread_cond_timedwait(&c->c_cond, &m->m_lock, abstime);
|
||||
fetchNset(&m->m_spinlock, 1);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline int lam_condition_signal(lam_condition_t* c)
|
||||
{
|
||||
return pthread_cond_signal(&c->c_cond);
|
||||
}
|
||||
|
||||
static inline int lam_condition_broadcast(lam_condition_t* c)
|
||||
{
|
||||
return pthread_cond_broadcast(&c->c_cond);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -8,11 +8,17 @@
|
||||
#define LAM_MUTEX_H_
|
||||
|
||||
#include "lam_config.h"
|
||||
#define LAM_USE_PTHREADS
|
||||
|
||||
#if defined(USE_SPINWAIT)
|
||||
#include "lam/threads/mutex_spinwait.h"
|
||||
#else
|
||||
|
||||
#if defined(LAM_USE_SPINLOCK)
|
||||
#include "lam/threads/mutex_spinlock.h"
|
||||
#elif defined(LAM_USE_SPINWAIT)
|
||||
#include "lam/threads/mutex_spinwait.h"
|
||||
#elif defined(LAM_USE_PTHREADS)
|
||||
#include "lam/threads/mutex_pthread.h"
|
||||
#else
|
||||
#error "concurrency model not configured"
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
25
src/lam/threads/mutex_pthread.c
Обычный файл
25
src/lam/threads/mutex_pthread.c
Обычный файл
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
#include "lam/threads/mutex.h"
|
||||
#if defined(LAM_USE_PTHREADS)
|
||||
|
||||
static void lam_mutex_construct(lam_mutex_t* m)
|
||||
{
|
||||
pthread_mutex_init(&m->m_lock, 0);
|
||||
}
|
||||
|
||||
static void lam_mutex_destruct(lam_mutex_t* m)
|
||||
{
|
||||
pthread_mutex_destroy(&m->m_lock);
|
||||
}
|
||||
|
||||
OBJ_CLASS_INSTANCE(
|
||||
lam_mutex_t,
|
||||
lam_object_t,
|
||||
lam_mutex_construct,
|
||||
lam_mutex_destruct
|
||||
);
|
||||
|
||||
#endif
|
||||
|
40
src/lam/threads/mutex_pthread.h
Обычный файл
40
src/lam/threads/mutex_pthread.h
Обычный файл
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#ifndef _LAM_MUTEX_PTHREAD_
|
||||
#define _LAM_MUTEX_PTHREAD_
|
||||
|
||||
#include <pthread.h>
|
||||
#include "lam/lfc/lam_object.h"
|
||||
#include "lam/os/atomic.h"
|
||||
|
||||
|
||||
struct lam_mutex_t {
|
||||
lam_object_t super;
|
||||
pthread_mutex_t m_lock;
|
||||
};
|
||||
typedef struct lam_mutex_t lam_mutex_t;
|
||||
|
||||
OBJ_CLASS_DECLARATION(lam_mutex_t);
|
||||
|
||||
|
||||
|
||||
static inline void lam_mutex_lock(lam_mutex_t* m)
|
||||
{
|
||||
pthread_mutex_lock(&m->m_lock);
|
||||
}
|
||||
|
||||
|
||||
static inline int lam_mutex_trylock(lam_mutex_t* m)
|
||||
{
|
||||
return pthread_mutex_trylock(&m->m_lock);
|
||||
}
|
||||
|
||||
|
||||
static inline void lam_mutex_unlock(lam_mutex_t* m)
|
||||
{
|
||||
pthread_mutex_unlock(&m->m_lock);
|
||||
}
|
||||
|
||||
#endif
|
27
src/lam/threads/mutex_spinlock.c
Обычный файл
27
src/lam/threads/mutex_spinlock.c
Обычный файл
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "mutex.h"
|
||||
#if defined(LAM_USE_SPINLOCK)
|
||||
|
||||
static void lam_mutex_construct(lam_mutex_t* m)
|
||||
{
|
||||
spinunlock(&m->m_lock);
|
||||
}
|
||||
|
||||
|
||||
static void lam_mutex_destruct(lam_mutex_t* m)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
OBJ_CLASS_INSTANCE(
|
||||
lam_mutex_t,
|
||||
lam_object_t,
|
||||
lam_mutex_construct,
|
||||
lam_mutex_destruct
|
||||
);
|
||||
|
||||
#endif
|
||||
|
@ -5,13 +5,34 @@
|
||||
#ifndef LAM_MUTEX_SPINLOCK_
|
||||
#define LAM_MUTEX_SPINLOCK_
|
||||
|
||||
#include "lam/lfc/lam_object.h"
|
||||
#include "lam/os/atomic.h"
|
||||
typedef lam_lock_data_t lam_mutex_t;
|
||||
|
||||
#define lam_mutex_init(m) spinunlock(m)
|
||||
#define lam_mutex_destroy(m)
|
||||
#define lam_mutex_lock(m) spinlock(m)
|
||||
#define lam_mutex_trylock(m) spintrylock(m)
|
||||
#define lam_mutex_unlock(m) spinunlock(m)
|
||||
|
||||
struct lam_mutex_t {
|
||||
lam_object_t super;
|
||||
lam_lock_data_t m_lock;
|
||||
|
||||
};
|
||||
typedef struct lam_mutex_t lam_mutex_t;
|
||||
|
||||
|
||||
OBJ_CLASS_DECLARATION(lam_mutex_t);
|
||||
|
||||
|
||||
static inline void lam_mutex_lock(lam_mutex_t* m)
|
||||
{
|
||||
spinlock(&m->m_lock);
|
||||
}
|
||||
|
||||
static inline int lam_mutex_trylock(lam_mutex_t* m)
|
||||
{
|
||||
return spintrylock(&m->m_lock);
|
||||
}
|
||||
|
||||
static inline void lam_mutex_unlock(lam_mutex_t* m)
|
||||
{
|
||||
spinunlock(&m->m_lock);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
27
src/lam/threads/mutex_spinwait.c
Обычный файл
27
src/lam/threads/mutex_spinwait.c
Обычный файл
@ -0,0 +1,27 @@
|
||||
#include "lam/threads/mutex.h"
|
||||
#if defined(LAM_USE_SPINWAIT)
|
||||
|
||||
|
||||
static void lam_mutex_construct(lam_mutex_t* m)
|
||||
{
|
||||
m->m_spinlock = 0;
|
||||
m->m_waiting = 0;
|
||||
pthread_mutex_init(&m->m_lock, 0);
|
||||
pthread_cond_init(&m->m_cond, 0);
|
||||
}
|
||||
|
||||
static void lam_mutex_destruct(lam_mutex_t* m)
|
||||
{
|
||||
pthread_mutex_destroy(&m->m_lock);
|
||||
pthread_cond_destroy(&m->m_cond);
|
||||
}
|
||||
|
||||
OBJ_CLASS_INSTANCE(
|
||||
lam_mutex_t,
|
||||
lam_object_t,
|
||||
lam_mutex_construct,
|
||||
lam_mutex_destruct
|
||||
);
|
||||
|
||||
#endif
|
||||
|
@ -6,7 +6,8 @@
|
||||
#define LAM_MUTEX_SPINWAIT_
|
||||
|
||||
#include <pthread.h>
|
||||
#include "os/atomic.h"
|
||||
#include "lam/lfc/lam_object.h"
|
||||
#include "lam/os/atomic.h"
|
||||
|
||||
#ifndef MUTEX_SPINWAIT
|
||||
#define MUTEX_SPINWAIT 10000
|
||||
@ -14,58 +15,49 @@
|
||||
|
||||
|
||||
struct lam_mutex_t {
|
||||
volatile int mutex_spinlock;
|
||||
volatile int mutex_waiting;
|
||||
pthread_mutex_t mutex_lock;
|
||||
pthread_cond_t mutex_cond;
|
||||
lam_object_t super;
|
||||
volatile int m_spinlock;
|
||||
volatile int m_waiting;
|
||||
pthread_mutex_t m_lock;
|
||||
pthread_cond_t m_cond;
|
||||
};
|
||||
struct lam_mutex_t lam_mutex_t;
|
||||
typedef struct lam_mutex_t lam_mutex_t;
|
||||
|
||||
OBJ_CLASS_DECLARATION(lam_mutex_t);
|
||||
|
||||
static inline void lam_mutex_init(lam_mutex_t* m)
|
||||
{
|
||||
m->mutex_spinlock = 0;
|
||||
m->mutex_waiting = 0;
|
||||
pthread_mutex_init(&m->mutex_lock, 0);
|
||||
pthread_cond_init(&m->mutex_cond, 0);
|
||||
}
|
||||
|
||||
static inline void lam_mutex_destroy(lam_mutex_t* m)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline void lam_mutex_lock(lam_mutex_t* m)
|
||||
{
|
||||
unsigned long cnt = 0;
|
||||
int locked;
|
||||
|
||||
fetchNadd(&m->mutex_waiting, 1);
|
||||
while( ((locked = fetchNset(&m->mutex_spinlock, 1)) == 1)
|
||||
&& (cnt++ < MUTEX_SPINWAIT) )
|
||||
;
|
||||
if(locked) {
|
||||
pthread_mutex_lock(&m->mutex_lock);
|
||||
while(fetchNset(&m->mutex_spinlock, 1) == 1)
|
||||
pthread_cond_wait(&m->mutex_cond, &m->mutex_lock);
|
||||
pthread_mutex_unlock(&m->mutex_lock);
|
||||
if(fetchNset(&m->m_spinlock, 1) == 1) {
|
||||
unsigned long cnt = 0;
|
||||
int locked;
|
||||
fetchNadd(&m->m_waiting, 1);
|
||||
while( ((locked = fetchNset(&m->m_spinlock, 1)) == 1)
|
||||
&& (cnt++ < MUTEX_SPINWAIT) )
|
||||
;
|
||||
if(locked) {
|
||||
pthread_mutex_lock(&m->m_lock);
|
||||
while(fetchNset(&m->m_spinlock, 1) == 1)
|
||||
pthread_cond_wait(&m->m_cond, &m->m_lock);
|
||||
pthread_mutex_unlock(&m->m_lock);
|
||||
}
|
||||
fetchNadd(&m->m_waiting, -1);
|
||||
}
|
||||
fetchNadd(&m->mutex_waiting, -1);
|
||||
}
|
||||
|
||||
|
||||
static inline int lam_mutex_trylock(lam_mutex_t* m)
|
||||
{
|
||||
return (fetchNset(&m->mutex_spinlock, 1) == 0);
|
||||
return (fetchNset(&m->m_spinlock, 1) == 0);
|
||||
}
|
||||
|
||||
|
||||
static inline void lam_mutex_unlock(lam_mutex_t* m)
|
||||
{
|
||||
fetchNset(&m->mutex_spinlock, 0);
|
||||
if(m->mutex_waiting) {
|
||||
pthread_cond_signal(&m->mutex_cond);
|
||||
fetchNset(&m->m_spinlock, 0);
|
||||
if(m->m_waiting) {
|
||||
pthread_cond_signal(&m->m_cond);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,5 +2,46 @@
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "lam/constants.h"
|
||||
#include "lam/threads/thread.h"
|
||||
|
||||
|
||||
static void lam_thread_construct(lam_thread_t* t)
|
||||
{
|
||||
t->t_run = 0;
|
||||
t->t_handle = -1;
|
||||
}
|
||||
|
||||
|
||||
static void lam_thread_destruct(lam_thread_t* t)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
OBJ_CLASS_INSTANCE(
|
||||
lam_thread_t,
|
||||
lam_object_t,
|
||||
lam_thread_construct,
|
||||
lam_thread_destruct
|
||||
);
|
||||
|
||||
typedef void* (*pthread_start_fn_t)(void*);
|
||||
|
||||
|
||||
int lam_thread_start(lam_thread_t* t)
|
||||
{
|
||||
int rc;
|
||||
#if LAM_ENABLE_DEBUG
|
||||
if(NULL == t->t_run || t->t_handle != -1)
|
||||
return LAM_ERR_BAD_PARAM;
|
||||
#endif
|
||||
rc = pthread_create(&t->t_handle, NULL, (pthread_start_fn_t)t->t_run, t);
|
||||
return (rc == 0) ? LAM_SUCCESS: LAM_ERROR;
|
||||
}
|
||||
|
||||
int lam_thread_join(lam_thread_t* t, void** thr_return)
|
||||
{
|
||||
int rc = pthread_join(t->t_handle, thr_return);
|
||||
return (rc == 0) ? LAM_SUCCESS: LAM_ERROR;
|
||||
}
|
||||
|
||||
|
@ -5,16 +5,25 @@
|
||||
#ifndef LAM_THREAD_H
|
||||
#define LAM_THREAD_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include "lam/lfc/lam_object.h"
|
||||
|
||||
typedef struct lam_thread
|
||||
typedef void* (*lam_thread_fn_t)(lam_object_t*);
|
||||
|
||||
|
||||
struct lam_thread_t
|
||||
{
|
||||
lam_object_t super;
|
||||
void (*thr_run)(lam_object_t*);
|
||||
} lam_thread_t;
|
||||
lam_thread_fn_t t_run;
|
||||
pthread_t t_handle;
|
||||
};
|
||||
typedef struct lam_thread_t lam_thread_t;
|
||||
|
||||
|
||||
void lam_thr_construct(lam_thread_t *a_thread);
|
||||
lam_thread_t *lam_thr_create(lam_object_t *arg);
|
||||
OBJ_CLASS_DECLARATION(lam_thread_t);
|
||||
|
||||
|
||||
int lam_thread_start(lam_thread_t*);
|
||||
int lam_thread_join(lam_thread_t*, void** thread_return);
|
||||
|
||||
#endif /* LAM_THREAD_H */
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user