Revamp the mthread library and update test59

Before, the 'main thread' of a process was never taken into account anywhere in
the library, causing mutexes not to work properly (and consequently, neither
did the condition variables). For example, if the 'main thread' (that is, the
thread which is started at the beginning of a process; not a spawned thread by
the library) would lock a mutex, it wasn't actually locked.
This commit is contained in:
Thomas Veerman
2010-09-30 13:44:13 +00:00
parent 3736ce3f55
commit a7072a5e1c
11 changed files with 467 additions and 288 deletions

View File

@@ -17,14 +17,15 @@ typedef int mthread_once_t;
typedef void * mthread_condattr_t;
typedef void * mthread_mutexattr_t;
struct __mthread_tcb;
typedef struct {
mthread_thread_t head;
mthread_thread_t tail;
struct __mthread_tcb *head;
struct __mthread_tcb *tail;
} mthread_queue_t;
struct __mthread_mutex {
mthread_queue_t queue; /* Threads blocked on this mutex */
mthread_thread_t owner; /* Thread that currently owns mutex */
mthread_queue_t queue; /* Queue of threads blocked on this mutex */
mthread_thread_t owner; /* Thread ID that currently owns mutex */
struct __mthread_mutex *prev;
struct __mthread_mutex *next;
};
@@ -37,10 +38,6 @@ struct __mthread_cond {
};
typedef struct __mthread_cond *mthread_cond_t;
typedef enum {
CONDITION, DEAD, EXITING, FALLBACK_EXITING, MUTEX, RUNNABLE
} mthread_state_t;
struct __mthread_attr {
size_t a_stacksize;
char *a_stackaddr;
@@ -50,22 +47,6 @@ struct __mthread_attr {
};
typedef struct __mthread_attr *mthread_attr_t;
typedef struct {
mthread_thread_t m_next; /* Next thread to run */
mthread_state_t m_state; /* Thread state */
struct __mthread_attr m_attr; /* Thread attributes */
struct __mthread_cond *m_cond; /* Condition variable that this thread
* might be blocking on */
void *(*m_proc)(void *); /* Procedure to run */
void *m_arg; /* Argument passed to procedure */
void *m_result; /* Result after procedure returns */
mthread_cond_t m_exited; /* Condition variable signaling this
* thread has ended */
mthread_mutex_t m_exitm; /* Mutex to accompany exit condition */
ucontext_t m_context; /* Thread machine context */
} mthread_tcb_t;
#define NO_THREAD -1
#define MTHREAD_CREATE_JOINABLE 001
#define MTHREAD_CREATE_DETACHED 002
#define MTHREAD_ONCE_INIT 0
@@ -120,23 +101,18 @@ _PROTOTYPE( void mthread_verify_f, (char *f, int l) );
_PROTOTYPE( int mthread_mutex_destroy, (mthread_mutex_t *mutex) );
_PROTOTYPE( int mthread_mutex_init, (mthread_mutex_t *mutex,
mthread_mutexattr_t *mattr) );
#if 0
_PROTOTYPE( int mthread_mutex_lock, (mthread_mutex_t *mutex) );
#endif
_PROTOTYPE( int mthread_mutex_lock_f, (mthread_mutex_t *mutex,
char *file, int line) );
#define mthread_mutex_lock(x) mthread_mutex_lock_f(x, __FILE__, __LINE__)
_PROTOTYPE( int mthread_mutex_trylock, (mthread_mutex_t *mutex) );
_PROTOTYPE( int mthread_mutex_unlock, (mthread_mutex_t *mutex) );
/* schedule.c */
_PROTOTYPE( void mthread_schedule, (void) );
_PROTOTYPE( void mthread_suspend, (mthread_state_t state) );
_PROTOTYPE( void mthread_unsuspend, (mthread_thread_t thread) );
_PROTOTYPE( void mthread_init, (void) );
_PROTOTYPE( int mthread_yield, (void) );
_PROTOTYPE( void mthread_yield_all, (void) );
/* queue.c */
_PROTOTYPE( void mthread_queue_init, (mthread_queue_t *queue) );
_PROTOTYPE( void mthread_queue_add, (mthread_queue_t *queue,
mthread_thread_t thread) );
_PROTOTYPE( mthread_thread_t mthread_queue_remove, (mthread_queue_t *queue));
_PROTOTYPE( int mthread_queue_isempty, (mthread_queue_t *queue) );
#endif