In this project, you will implement a small threads library for Solaris. Your library will include some of the the basic functionality of pthreads, but will include some additional features to make your life more "interesting." To implement your library, you will utilize a variety of low-level Solaris system calls related to lightweight processes (LWPs) and you will need to worry about issues such as signal handling, thread scheduling, and synchronization. Your library will not use any existing threads library (i.e., you may not use Solaris threads or POSIX threads in your implementation). You may, however, use low-level Solaris system calls.
For development, you will be using a 4 processor Sun Enterprise 420R server (schlitz.cs.uchicago.edu). You may use C or C++ to implement your library.
int mthread_init(void)
Initialize the threads library. User programs execute this prior to creating any threads.
int mthread_create(mthread_t *thr, void (*func)(void *), void *arg, int flags, size_t stacksize)
Creates a new thread. The newly created thread id is placed in thr. func is the function that will start executing when the thread begins. arg is the argument passed to func. flags is the bitwise-or of the following values:stacksize is the number of bytes to use for the thread stack. If set to 0, then the default stack size is used (typically 1 Mbyte). Returns 0 on success, and a negative value for an error.MTHREAD_NEW_LWP - Create a new LWP MTHREAD_DETACH - Detached thread MTHREAD_BOUND - Bind thread to a new LWP. MTHREAD_SUSPEND - Thread is started in a suspended state. MTHREAD_MONDO - Mondo thread
int mthread_join(mthread_t thr, void **status)
Waits for thread thr to call mthread_exit() or mthread_detach(). The return value of the specified thread is placed in status. status is set to NULL when a thread detaches. Returns 0 on success.
int mthread_detach(mthread_t thr)
The specified thread is detached. When a detached thread terminates, its resources are automatically recovered. Note: It is not possible to join a detached thread.
void mthread_exit(void *status)
The current thread is terminated. status is an optional pointer to data that will be passed to a matching mthread_join() call. This data may not be placed on the thread's stack (which is reclaimed upon termination).
mthread_t mthread_self(void)
Returns the thread id of the calling thread.
int mthread_equal(mthread_t t1, mthread_t t2)
Returns true if thread t1 and t2 are the same thread.
int mthread_yield()
The calling thread yields. If other threads can run, the calling thread is simply placed on a ready queue and rescheduled. If no other threads are available to run, the calling thread continues to execute.
int mthread_suspend(mthread_t thr)
Suspends the execution of thread thr. If thread is already suspended, does nothing.
int mthread_resume(mthread_t thr)
Resumes execution of thread thr. If the thread is already running, this function has no effect.
int mthread_mutex_init(mutex_t *mtx)
Initialize a mutex lock. Locks are initialized in the unlocked state.
int mthread_mutex_lock(mutex_t *mtx)
Lock a mutex. If already locked, a thread blocks until the lock is released.
int mthread_mutex_unlock(mutex_t *mtx)
Unlock a mutex. If any other threads are waiting on the lock, one of them is awakened and given the lock.
int mthread_sema_init(sema_t *s, unsigned int val)
Initialize a semaphore with initial value val.
int mthread_sema_post(sema_t *s)
Increase semaphore value. If any threads are waiting on the signal, one is awakened.
int mthread_sema_wait(sema_t *s)
If semaphore value is 0, go to sleep. If non-zero, decrement semaphore value and continue.
int mthread_cond_init(cond_t *cv)
Initialize the condition variable cv.
int mthread_cond_wait(cond_t *cv,mutex_t *lck, void (*cont)(void *), void *arg)
The calling thread goes to sleep on the condition variable cv. lck is a mutex lock which must be locked prior to calling mthread_cond_wait(). When the calling thread goes to sleep, the lock is released. The cont and arg functions define an optional continuation function. If NULL, execution resumes with the next statement. If cont is supplied, the thread gives up its stack and context when it goes to sleep and resumes execution in a new thread starting with the function cont when it resumes.
int mthread_cond_signal(cond_t *cv)
Signal the condition variable cv. One of the threads waiting on cv is awakened.Proper use of condition variables requires special attention to locking. Here is an example:
mutex_t m; cond_t cv; ... mthread_mutex_init(&m); mthread_cond_init(&cv); ... void foo() { mthread_mutex_lock(&m); mthread_cond_wait(&cv,&m, NULL, NULL); /* Sleep until signalled */ mthread_mutex_unlock(&m); } void bar() { mthread_mutex_lock(&m); mthread_cond_signal(&cv); mthread_mutex_unlock(&m); }
#include "thread.h" #include <stdio.h> void howdy(void *arg) { int n = *((int *)arg); int i; for (i = 0; i < n; i++) { printf("Howdy %d\n", i); } mthread_exit(NULL); } int main() { mthread_t tid1; int n1 = 10; void *status; /* Start the thread */ mthread_init(&tid1, howdy, &n1, MTHREAD_NEW_LWP, 0); /* Wait for the thread */ mthread_join(tid1, &status); exit(0); }
I will also be implementing the library and will share notes as necessary._lwp_create _lwp_makecontext _lwp_exit _lwp_setprivate _lwp_wait _lwp_suspend _lwp_continue _lwp_cond_wait _lwp_timed_wait _lwp_cond_broadcast _lwp_cond_signal _lwp_kill _lwp_mutex_lock _lwp_mutex_unlock _signotifywait _lwp_sigredirect