145 lines · 2.0 KB · C
RawDownload
#include "threadimpl.h"#include "BSD.c" #include <dlfcn.h> struct thread_tag {	struct thread_tag	*next;	spinlock_t		l;	volatile int		key;	void			*data;}; static spinlock_t mlock;static spinlock_t dl_lock;static spinlock_t tag_lock;static struct thread_tag *thread_tag_store = nil;static uint nextkey = 0; void_thread_malloc_lock(void){	_spinlock(&mlock);} void_thread_malloc_unlock(void){	_spinunlock(&mlock);} void_thread_malloc_init(void){} /* * for ld.so */void_thread_dl_lock(int t){	if(t)		_spinunlock(&dl_lock);	else		_spinlock(&dl_lock);} /* * for libc */static void_thread_tag_init(void **tag){	struct thread_tag *t; 	_spinlock(&tag_lock);	if(*tag == nil) {		t = malloc(sizeof (*t));		if(t != nil) {			memset(&t->l, 0, sizeof(t->l));			t->key = nextkey++;			*tag = t;		}	}	_spinunlock(&tag_lock);} void_thread_tag_lock(void **tag){	struct thread_tag *t; 	if(*tag == nil)		_thread_tag_init(tag);	t = *tag;	_spinlock(&t->l);} void_thread_tag_unlock(void **tag){	struct thread_tag *t; 	if(*tag == nil)		_thread_tag_init(tag);	t = *tag;	_spinunlock(&t->l);} static void *_thread_tag_insert(struct thread_tag *t, void *v){	t->data = v;	t->next = thread_tag_store;	thread_tag_store = t;	return t;} static void *_thread_tag_lookup(struct thread_tag *tag, int size){	struct thread_tag *t;	void *p; 	_spinlock(&tag->l);	for(t = thread_tag_store; t != nil; t = t->next)		if(t->key == tag->key)			break;	if(t == nil) {		p = malloc(size);		if(p == nil) {			_spinunlock(&tag->l);			return nil;		}		_thread_tag_insert(tag, p);	}	_spinunlock(&tag->l);	return tag->data;} void *_thread_tag_storage(void **tag, void *storage, size_t n, void *err){	struct thread_tag *t;	void *r; 	if(*tag == nil)		_thread_tag_init(tag);	t = *tag; 	r = _thread_tag_lookup(t, n);	if(r == nil)		r = err;	else		memcpy(r, storage, n);	return r;} void_pthreadinit(void){	__isthreaded = 1;	dlctl(nil, DL_SETTHREADLCK, _thread_dl_lock);	signal(SIGUSR2, sigusr2handler);}