diff --git a/trunk/research/st/stk.c b/trunk/research/st/stk.c index 34769697f..ced5717bb 100644 --- a/trunk/research/st/stk.c +++ b/trunk/research/st/stk.c @@ -46,7 +46,6 @@ #include #include "common.h" - /* How much space to leave between the stacks, at each end */ #define REDZONE _ST_PAGE_SIZE @@ -58,116 +57,118 @@ static char *_st_new_stk_segment(int size); _st_stack_t *_st_stack_new(int stack_size) { - _st_clist_t *qp; - _st_stack_t *ts; - int extra; - - for (qp = _st_free_stacks.next; qp != &_st_free_stacks; qp = qp->next) { - ts = _ST_THREAD_STACK_PTR(qp); - if (ts->stk_size >= stack_size) { - /* Found a stack that is big enough */ - ST_REMOVE_LINK(&ts->links); - _st_num_free_stacks--; - ts->links.next = NULL; - ts->links.prev = NULL; - return ts; + _st_clist_t *qp; + _st_stack_t *ts; + int extra; + + for (qp = _st_free_stacks.next; qp != &_st_free_stacks; qp = qp->next) { + ts = _ST_THREAD_STACK_PTR(qp); + if (ts->stk_size >= stack_size) { + /* Found a stack that is big enough */ + ST_REMOVE_LINK(&ts->links); + _st_num_free_stacks--; + ts->links.next = NULL; + ts->links.prev = NULL; + return ts; + } } - } - - /* Make a new thread stack object. */ - if ((ts = (_st_stack_t *)calloc(1, sizeof(_st_stack_t))) == NULL) - return NULL; - extra = _st_randomize_stacks ? _ST_PAGE_SIZE : 0; - ts->vaddr_size = stack_size + 2*REDZONE + extra; - ts->vaddr = _st_new_stk_segment(ts->vaddr_size); - if (!ts->vaddr) { - free(ts); - return NULL; - } - ts->stk_size = stack_size; - ts->stk_bottom = ts->vaddr + REDZONE; - ts->stk_top = ts->stk_bottom + stack_size; - + + /* Make a new thread stack object. */ + if ((ts = (_st_stack_t *)calloc(1, sizeof(_st_stack_t))) == NULL) { + return NULL; + } + extra = _st_randomize_stacks ? _ST_PAGE_SIZE : 0; + ts->vaddr_size = stack_size + 2*REDZONE + extra; + ts->vaddr = _st_new_stk_segment(ts->vaddr_size); + if (!ts->vaddr) { + free(ts); + return NULL; + } + ts->stk_size = stack_size; + ts->stk_bottom = ts->vaddr + REDZONE; + ts->stk_top = ts->stk_bottom + stack_size; + #ifdef DEBUG - mprotect(ts->vaddr, REDZONE, PROT_NONE); - mprotect(ts->stk_top + extra, REDZONE, PROT_NONE); + mprotect(ts->vaddr, REDZONE, PROT_NONE); + mprotect(ts->stk_top + extra, REDZONE, PROT_NONE); #endif - - if (extra) { - long offset = (random() % extra) & ~0xf; - - ts->stk_bottom += offset; - ts->stk_top += offset; - } - - return ts; + + if (extra) { + long offset = (random() % extra) & ~0xf; + + ts->stk_bottom += offset; + ts->stk_top += offset; + } + + return ts; } - /* * Free the stack for the current thread */ void _st_stack_free(_st_stack_t *ts) { - if (!ts) - return; - - /* Put the stack on the free list */ - ST_APPEND_LINK(&ts->links, _st_free_stacks.prev); - _st_num_free_stacks++; + if (!ts) { + return; + } + + /* Put the stack on the free list */ + ST_APPEND_LINK(&ts->links, _st_free_stacks.prev); + _st_num_free_stacks++; } - static char *_st_new_stk_segment(int size) { #ifdef MALLOC_STACK - void *vaddr = malloc(size); -#else - static int zero_fd = -1; - int mmap_flags = MAP_PRIVATE; - void *vaddr; - -#if defined (MD_USE_SYSV_ANON_MMAP) - if (zero_fd < 0) { - if ((zero_fd = open("/dev/zero", O_RDWR, 0)) < 0) - return NULL; - fcntl(zero_fd, F_SETFD, FD_CLOEXEC); - } -#elif defined (MD_USE_BSD_ANON_MMAP) - mmap_flags |= MAP_ANON; + void *vaddr = malloc(size); #else -#error Unknown OS + static int zero_fd = -1; + int mmap_flags = MAP_PRIVATE; + void *vaddr; + + #if defined (MD_USE_SYSV_ANON_MMAP) + if (zero_fd < 0) { + if ((zero_fd = open("/dev/zero", O_RDWR, 0)) < 0) { + return NULL; + } + fcntl(zero_fd, F_SETFD, FD_CLOEXEC); + } + #elif defined (MD_USE_BSD_ANON_MMAP) + mmap_flags |= MAP_ANON; + #else + #error Unknown OS + #endif + + vaddr = mmap(NULL, size, PROT_READ | PROT_WRITE, mmap_flags, zero_fd, 0); + if (vaddr == (void *)MAP_FAILED) { + return NULL; + } + #endif - - vaddr = mmap(NULL, size, PROT_READ | PROT_WRITE, mmap_flags, zero_fd, 0); - if (vaddr == (void *)MAP_FAILED) - return NULL; - -#endif /* MALLOC_STACK */ - - return (char *)vaddr; + + return (char *)vaddr; } - /* Not used */ #if 0 void _st_delete_stk_segment(char *vaddr, int size) { #ifdef MALLOC_STACK - free(vaddr); + free(vaddr); #else - (void) munmap(vaddr, size); + (void) munmap(vaddr, size); #endif } #endif int st_randomize_stacks(int on) { - int wason = _st_randomize_stacks; - - _st_randomize_stacks = on; - if (on) - srandom((unsigned int) st_utime()); - - return wason; + int wason = _st_randomize_stacks; + + _st_randomize_stacks = on; + if (on) { + srandom((unsigned int) st_utime()); + } + + return wason; } diff --git a/trunk/research/st/sync.c b/trunk/research/st/sync.c index 49bceb3e3..3e5324084 100644 --- a/trunk/research/st/sync.c +++ b/trunk/research/st/sync.c @@ -44,326 +44,309 @@ #include #include "common.h" - extern time_t _st_curr_time; extern st_utime_t _st_last_tset; extern int _st_active_count; static st_utime_t (*_st_utime)(void) = NULL; - /***************************************** * Time functions */ st_utime_t st_utime(void) { - if (_st_utime == NULL) { + if (_st_utime == NULL) { #ifdef MD_GET_UTIME - MD_GET_UTIME(); + MD_GET_UTIME(); #else -#error Unknown OS + #error Unknown OS #endif - } - - return (*_st_utime)(); + } + + return (*_st_utime)(); } - int st_set_utime_function(st_utime_t (*func)(void)) { - if (_st_active_count) { - errno = EINVAL; - return -1; - } - - _st_utime = func; - - return 0; + if (_st_active_count) { + errno = EINVAL; + return -1; + } + + _st_utime = func; + + return 0; } - st_utime_t st_utime_last_clock(void) { - return _ST_LAST_CLOCK; + return _ST_LAST_CLOCK; } - int st_timecache_set(int on) { - int wason = (_st_curr_time) ? 1 : 0; - - if (on) { - _st_curr_time = time(NULL); - _st_last_tset = st_utime(); - } else - _st_curr_time = 0; - - return wason; + int wason = (_st_curr_time) ? 1 : 0; + + if (on) { + _st_curr_time = time(NULL); + _st_last_tset = st_utime(); + } else { + _st_curr_time = 0; + } + + return wason; } - time_t st_time(void) { - if (_st_curr_time) - return _st_curr_time; - - return time(NULL); + if (_st_curr_time) { + return _st_curr_time; + } + + return time(NULL); } - int st_usleep(st_utime_t usecs) { - _st_thread_t *me = _ST_CURRENT_THREAD(); - - if (me->flags & _ST_FL_INTERRUPT) { - me->flags &= ~_ST_FL_INTERRUPT; - errno = EINTR; - return -1; - } - - if (usecs != ST_UTIME_NO_TIMEOUT) { - me->state = _ST_ST_SLEEPING; - _ST_ADD_SLEEPQ(me, usecs); - } else - me->state = _ST_ST_SUSPENDED; - - _ST_SWITCH_CONTEXT(me); - - if (me->flags & _ST_FL_INTERRUPT) { - me->flags &= ~_ST_FL_INTERRUPT; - errno = EINTR; - return -1; - } - - return 0; + _st_thread_t *me = _ST_CURRENT_THREAD(); + + if (me->flags & _ST_FL_INTERRUPT) { + me->flags &= ~_ST_FL_INTERRUPT; + errno = EINTR; + return -1; + } + + if (usecs != ST_UTIME_NO_TIMEOUT) { + me->state = _ST_ST_SLEEPING; + _ST_ADD_SLEEPQ(me, usecs); + } else { + me->state = _ST_ST_SUSPENDED; + } + + _ST_SWITCH_CONTEXT(me); + + if (me->flags & _ST_FL_INTERRUPT) { + me->flags &= ~_ST_FL_INTERRUPT; + errno = EINTR; + return -1; + } + + return 0; } - int st_sleep(int secs) { - return st_usleep((secs >= 0) ? secs * (st_utime_t) 1000000LL : - ST_UTIME_NO_TIMEOUT); + return st_usleep((secs >= 0) ? secs * (st_utime_t) 1000000LL : ST_UTIME_NO_TIMEOUT); } - /***************************************** * Condition variable functions */ - _st_cond_t *st_cond_new(void) { - _st_cond_t *cvar; - - cvar = (_st_cond_t *) calloc(1, sizeof(_st_cond_t)); - if (cvar) { - ST_INIT_CLIST(&cvar->wait_q); - } - - return cvar; + _st_cond_t *cvar; + + cvar = (_st_cond_t *) calloc(1, sizeof(_st_cond_t)); + if (cvar) { + ST_INIT_CLIST(&cvar->wait_q); + } + + return cvar; } - int st_cond_destroy(_st_cond_t *cvar) { - if (cvar->wait_q.next != &cvar->wait_q) { - errno = EBUSY; - return -1; - } - - free(cvar); - - return 0; + if (cvar->wait_q.next != &cvar->wait_q) { + errno = EBUSY; + return -1; + } + + free(cvar); + + return 0; } - int st_cond_timedwait(_st_cond_t *cvar, st_utime_t timeout) { - _st_thread_t *me = _ST_CURRENT_THREAD(); - int rv; - - if (me->flags & _ST_FL_INTERRUPT) { - me->flags &= ~_ST_FL_INTERRUPT; - errno = EINTR; - return -1; - } - - /* Put caller thread on the condition variable's wait queue */ - me->state = _ST_ST_COND_WAIT; - ST_APPEND_LINK(&me->wait_links, &cvar->wait_q); - - if (timeout != ST_UTIME_NO_TIMEOUT) - _ST_ADD_SLEEPQ(me, timeout); - - _ST_SWITCH_CONTEXT(me); - - ST_REMOVE_LINK(&me->wait_links); - rv = 0; - - if (me->flags & _ST_FL_TIMEDOUT) { - me->flags &= ~_ST_FL_TIMEDOUT; - errno = ETIME; - rv = -1; - } - if (me->flags & _ST_FL_INTERRUPT) { - me->flags &= ~_ST_FL_INTERRUPT; - errno = EINTR; - rv = -1; - } - - return rv; + _st_thread_t *me = _ST_CURRENT_THREAD(); + int rv; + + if (me->flags & _ST_FL_INTERRUPT) { + me->flags &= ~_ST_FL_INTERRUPT; + errno = EINTR; + return -1; + } + + /* Put caller thread on the condition variable's wait queue */ + me->state = _ST_ST_COND_WAIT; + ST_APPEND_LINK(&me->wait_links, &cvar->wait_q); + + if (timeout != ST_UTIME_NO_TIMEOUT) { + _ST_ADD_SLEEPQ(me, timeout); + } + + _ST_SWITCH_CONTEXT(me); + + ST_REMOVE_LINK(&me->wait_links); + rv = 0; + + if (me->flags & _ST_FL_TIMEDOUT) { + me->flags &= ~_ST_FL_TIMEDOUT; + errno = ETIME; + rv = -1; + } + if (me->flags & _ST_FL_INTERRUPT) { + me->flags &= ~_ST_FL_INTERRUPT; + errno = EINTR; + rv = -1; + } + + return rv; } - int st_cond_wait(_st_cond_t *cvar) { - return st_cond_timedwait(cvar, ST_UTIME_NO_TIMEOUT); + return st_cond_timedwait(cvar, ST_UTIME_NO_TIMEOUT); } - static int _st_cond_signal(_st_cond_t *cvar, int broadcast) { - _st_thread_t *thread; - _st_clist_t *q; - - for (q = cvar->wait_q.next; q != &cvar->wait_q; q = q->next) { - thread = _ST_THREAD_WAITQ_PTR(q); - if (thread->state == _ST_ST_COND_WAIT) { - if (thread->flags & _ST_FL_ON_SLEEPQ) - _ST_DEL_SLEEPQ(thread); - - /* Make thread runnable */ - thread->state = _ST_ST_RUNNABLE; - _ST_ADD_RUNQ(thread); - if (!broadcast) - break; + _st_thread_t *thread; + _st_clist_t *q; + + for (q = cvar->wait_q.next; q != &cvar->wait_q; q = q->next) { + thread = _ST_THREAD_WAITQ_PTR(q); + if (thread->state == _ST_ST_COND_WAIT) { + if (thread->flags & _ST_FL_ON_SLEEPQ) { + _ST_DEL_SLEEPQ(thread); + } + + /* Make thread runnable */ + thread->state = _ST_ST_RUNNABLE; + _ST_ADD_RUNQ(thread); + if (!broadcast) { + break; + } + } } - } - - return 0; + + return 0; } - int st_cond_signal(_st_cond_t *cvar) { - return _st_cond_signal(cvar, 0); + return _st_cond_signal(cvar, 0); } - int st_cond_broadcast(_st_cond_t *cvar) { - return _st_cond_signal(cvar, 1); + return _st_cond_signal(cvar, 1); } - /***************************************** * Mutex functions */ - _st_mutex_t *st_mutex_new(void) { - _st_mutex_t *lock; - - lock = (_st_mutex_t *) calloc(1, sizeof(_st_mutex_t)); - if (lock) { - ST_INIT_CLIST(&lock->wait_q); - lock->owner = NULL; - } - - return lock; + _st_mutex_t *lock; + + lock = (_st_mutex_t *) calloc(1, sizeof(_st_mutex_t)); + if (lock) { + ST_INIT_CLIST(&lock->wait_q); + lock->owner = NULL; + } + + return lock; } - int st_mutex_destroy(_st_mutex_t *lock) { - if (lock->owner != NULL || lock->wait_q.next != &lock->wait_q) { - errno = EBUSY; - return -1; - } - - free(lock); - - return 0; + if (lock->owner != NULL || lock->wait_q.next != &lock->wait_q) { + errno = EBUSY; + return -1; + } + + free(lock); + + return 0; } - int st_mutex_lock(_st_mutex_t *lock) { - _st_thread_t *me = _ST_CURRENT_THREAD(); - - if (me->flags & _ST_FL_INTERRUPT) { - me->flags &= ~_ST_FL_INTERRUPT; - errno = EINTR; - return -1; - } - - if (lock->owner == NULL) { - /* Got the mutex */ - lock->owner = me; + _st_thread_t *me = _ST_CURRENT_THREAD(); + + if (me->flags & _ST_FL_INTERRUPT) { + me->flags &= ~_ST_FL_INTERRUPT; + errno = EINTR; + return -1; + } + + if (lock->owner == NULL) { + /* Got the mutex */ + lock->owner = me; + return 0; + } + + if (lock->owner == me) { + errno = EDEADLK; + return -1; + } + + /* Put caller thread on the mutex's wait queue */ + me->state = _ST_ST_LOCK_WAIT; + ST_APPEND_LINK(&me->wait_links, &lock->wait_q); + + _ST_SWITCH_CONTEXT(me); + + ST_REMOVE_LINK(&me->wait_links); + + if ((me->flags & _ST_FL_INTERRUPT) && lock->owner != me) { + me->flags &= ~_ST_FL_INTERRUPT; + errno = EINTR; + return -1; + } + return 0; - } - - if (lock->owner == me) { - errno = EDEADLK; - return -1; - } - - /* Put caller thread on the mutex's wait queue */ - me->state = _ST_ST_LOCK_WAIT; - ST_APPEND_LINK(&me->wait_links, &lock->wait_q); - - _ST_SWITCH_CONTEXT(me); - - ST_REMOVE_LINK(&me->wait_links); - - if ((me->flags & _ST_FL_INTERRUPT) && lock->owner != me) { - me->flags &= ~_ST_FL_INTERRUPT; - errno = EINTR; - return -1; - } - - return 0; } - int st_mutex_unlock(_st_mutex_t *lock) { - _st_thread_t *thread; - _st_clist_t *q; - - if (lock->owner != _ST_CURRENT_THREAD()) { - errno = EPERM; - return -1; - } - - for (q = lock->wait_q.next; q != &lock->wait_q; q = q->next) { - thread = _ST_THREAD_WAITQ_PTR(q); - if (thread->state == _ST_ST_LOCK_WAIT) { - lock->owner = thread; - /* Make thread runnable */ - thread->state = _ST_ST_RUNNABLE; - _ST_ADD_RUNQ(thread); - return 0; + _st_thread_t *thread; + _st_clist_t *q; + + if (lock->owner != _ST_CURRENT_THREAD()) { + errno = EPERM; + return -1; } - } - - /* No threads waiting on this mutex */ - lock->owner = NULL; - - return 0; + + for (q = lock->wait_q.next; q != &lock->wait_q; q = q->next) { + thread = _ST_THREAD_WAITQ_PTR(q); + if (thread->state == _ST_ST_LOCK_WAIT) { + lock->owner = thread; + /* Make thread runnable */ + thread->state = _ST_ST_RUNNABLE; + _ST_ADD_RUNQ(thread); + return 0; + } + } + + /* No threads waiting on this mutex */ + lock->owner = NULL; + + return 0; } - int st_mutex_trylock(_st_mutex_t *lock) { - if (lock->owner != NULL) { - errno = EBUSY; - return -1; - } - - /* Got the mutex */ - lock->owner = _ST_CURRENT_THREAD(); - - return 0; + if (lock->owner != NULL) { + errno = EBUSY; + return -1; + } + + /* Got the mutex */ + lock->owner = _ST_CURRENT_THREAD(); + + return 0; }