int __pthread_mutex_unlock(pthread_mutex_t *m)
{
	pthread_t self;
	int waiters = m->_m_waiters;
	int cont;
	int type = m->_m_type & 15;
	int priv = (m->_m_type & 128) ^ 128;

	if (type != PTHREAD_MUTEX_NORMAL) {
		self = __pthread_self();
		if ((m->_m_lock&0x7fffffff) != self->tid)
			return EPERM;
		if ((type&3) == PTHREAD_MUTEX_RECURSIVE && m->_m_count)
			return m->_m_count--, 0;
		if (!priv) {
			self->robust_list.pending = &m->_m_next;
			__vm_lock_impl(+1);
		}
		volatile void *prev = m->_m_prev;
		volatile void *next = m->_m_next;
		*(volatile void *volatile *)prev = next;
		if (next != &self->robust_list.head) *(volatile void *volatile *)
			((char *)next - sizeof(void *)) = prev;
	}
	cont = a_swap(&m->_m_lock, (type & 8) ? 0x40000000 : 0);
	if (type != PTHREAD_MUTEX_NORMAL && !priv) {
		self->robust_list.pending = 0;
		__vm_unlock_impl();
	}
	if (waiters || cont<0)
		__wake(&m->_m_lock, 1, priv);
	return 0;
}
int pthread_mutex_unlock(pthread_mutex_t *m)
{
	pthread_t self;
	int waiters = m->_m_waiters;
	int cont;
	int robust = 0;

	if (m->_m_type != PTHREAD_MUTEX_NORMAL) {
		if (!m->_m_lock)
			return EPERM;
		self = __pthread_self();
		if ((m->_m_lock&0x1fffffff) != self->tid)
			return EPERM;
		if ((m->_m_type&3) == PTHREAD_MUTEX_RECURSIVE && m->_m_count)
			return m->_m_count--, 0;
		if (m->_m_type >= 4) {
			robust = 1;
			self->robust_list.pending = &m->_m_next;
			*(void **)m->_m_prev = m->_m_next;
			if (m->_m_next) ((void **)m->_m_next)[-1] = m->_m_prev;
			__vm_lock_impl(+1);
		}
	}
	cont = a_swap(&m->_m_lock, 0);
	if (robust) {
		self->robust_list.pending = 0;
		__vm_unlock_impl();
	}
	if (waiters || cont<0)
		__wake(&m->_m_lock, 1, 0);
	return 0;
}
Example #3
0
void __testcancel()
{
	if (!libc.has_thread_pointer) return;
	pthread_t self = __pthread_self();
	if (self->cancel && !self->canceldisable)
		__cancel();
}
Example #4
0
void __cancel()
{
	pthread_t self = __pthread_self();
	self->canceldisable = 1;
	self->cancelasync = 0;
	pthread_exit(PTHREAD_CANCELED);
}
Example #5
0
void __unlist_locked_file(FILE *f)
{
	if (f->lockcount) {
		if (f->next_locked) f->next_locked->prev_locked = f->prev_locked;
		if (f->prev_locked) f->prev_locked->next_locked = f->next_locked;
		else __pthread_self()->stdio_locks = f->next_locked;
	}
}
Example #6
0
void __init_ssp(void *entropy)
{
	if (entropy) memcpy(&__stack_chk_guard, entropy, sizeof(uintptr_t));
	else __stack_chk_guard = (uintptr_t)&__stack_chk_guard * 1103515245;

	if (libc.has_thread_pointer)
		__pthread_self()->canary = __stack_chk_guard;
}
Example #7
0
int __lockfile(FILE *f)
{
	int owner, tid = __pthread_self()->tid;
	if (f->lock == tid)
		return 0;
	while ((owner = a_cas(&f->lock, 0, tid)))
		__wait(&f->lock, &f->waiters, owner, 1);
	return 1;
}
Example #8
0
int pthread_setspecific(pthread_key_t k, const void* x) {
    struct pthread* self = __pthread_self();
    /* Avoid unnecessary COW */
    if (self->tsd[k] != x) {
        self->tsd[k] = (void*)x;
        self->tsd_used = 1;
    }
    return 0;
}
Example #9
0
void *__tls_get_addr(size_t *v)
{
	pthread_t self = __pthread_self();
#ifdef SHARED
	if (v[0]<=(size_t)self->dtv[0])
		return (char *)self->dtv[v[0]]+v[1];
	return __tls_get_new(v);
#else
	return (char *)self->dtv[1]+v[1];
#endif
}
Example #10
0
pthread_t __pthread_self_def()
{
    static int init=0, failed=0;
	if (!init) {
		if (failed) return 0;
		if (init_main_thread() < 0) failed = 1;
		if (failed) return 0;
		init = 1;
	}
	return __pthread_self();
}
void __reset_tls()
{
	pthread_t self = __pthread_self();
	struct tls_module *p;
	size_t i, n = (size_t)self->dtv[0];
	if (n) for (p=libc.tls_head, i=1; i<=n; i++, p=p->next) {
		if (!self->dtv[i]) continue;
		memcpy(self->dtv[i], p->image, p->len);
		memset((char *)self->dtv[i]+p->len, 0,
			p->size - p->len);
	}
}
Example #12
0
pid_t fork(void)
{
	pid_t ret;
	if (libc.fork_handler) libc.fork_handler(-1);
	ret = syscall(SYS_fork);
	if (libc.lock && !ret) {
		pthread_t self = __pthread_self();
		self->tid = self->pid = syscall(SYS_getpid);
		libc.threads_minus_1 = 0;
	}
	if (libc.fork_handler) libc.fork_handler(!ret);
	return ret;
}
Example #13
0
int __pthread_mutex_trylock_owner(pthread_mutex_t* m) {
  int old, own;
  int type = m->_m_type & 15;
  pthread_t self = __pthread_self();
  int tid = self->tid;

  old = m->_m_lock;
  own = old & 0x7fffffff;
  if (own == tid && (type & 3) == PTHREAD_MUTEX_RECURSIVE) {
    if ((unsigned)m->_m_count >= INT_MAX)
      return EAGAIN;
    m->_m_count++;
    return 0;
  }
  if (own == 0x40000000)
    return ENOTRECOVERABLE;

  if (m->_m_type & 128) {
    if (!self->robust_list.off) {
      self->robust_list.off = (char*)&m->_m_lock - (char*)&m->_m_next;
      __syscall(SYS_set_robust_list, &self->robust_list, 3 * sizeof(long));
    }
    if (m->_m_waiters)
      tid |= 0x80000000;
    self->robust_list.pending = &m->_m_next;
  }

  if ((own && (!(own & 0x40000000) || !(type & 4))) ||
      a_cas(&m->_m_lock, old, tid) != old) {
    self->robust_list.pending = 0;
    return EBUSY;
  }

  volatile void* next = self->robust_list.head;
  m->_m_next = next;
  m->_m_prev = &self->robust_list.head;
  if (next != &self->robust_list.head)
    *(volatile void* volatile*)((char*)next - sizeof(void*)) = &m->_m_next;
  self->robust_list.head = &m->_m_next;
  self->robust_list.pending = 0;

  if (own) {
    m->_m_count = 0;
    m->_m_type |= 8;
    return EOWNERDEAD;
  }

  return 0;
}
Example #14
0
long (__syscall_cp)(syscall_arg_t nr,
                    syscall_arg_t u, syscall_arg_t v, syscall_arg_t w,
                    syscall_arg_t x, syscall_arg_t y, syscall_arg_t z)
{
	pthread_t self;
	long r;

	if (!libc.has_thread_pointer || (self = __pthread_self())->canceldisable)
		return __syscall(nr, u, v, w, x, y, z);

	r = __syscall_cp_asm(&self->cancel, nr, u, v, w, x, y, z);
	if (r==-EINTR && nr!=SYS_close && self->cancel && !self->canceldisable)
		__cancel();
	return r;
}
Example #15
0
void fiber_io_check(void)
{
	if (__thread_fiber != NULL) {
		if (__thread_fiber->ev_fiber == NULL) {
			__thread_fiber->ev_fiber  = acl_fiber_create(
				fiber_io_loop, __thread_fiber->event,
				STACK_SIZE);
			__thread_fiber->io_count  = 0;
			__thread_fiber->nsleeping = 0;
			__thread_fiber->io_stop   = 0;
			ring_init(&__thread_fiber->ev_timer);
		}
		return;
	}

	if (pthread_once(&__once_control, thread_init) != 0) {
		msg_fatal("%s(%d), %s: pthread_once error %s",
			__FILE__, __LINE__, __FUNCTION__, last_serror());
	}

	var_maxfd = open_limit(0);
	if (var_maxfd <= 0) {
		var_maxfd = MAXFD;
	}

	__thread_fiber = (FIBER_TLS *) malloc(sizeof(FIBER_TLS));
	__thread_fiber->event = event_create(var_maxfd);
	__thread_fiber->ev_fiber  = acl_fiber_create(fiber_io_loop,
			__thread_fiber->event, STACK_SIZE);
	__thread_fiber->io_count  = 0;
	__thread_fiber->nsleeping = 0;
	__thread_fiber->io_stop   = 0;
	ring_init(&__thread_fiber->ev_timer);

#ifdef SYS_WIN
	__thread_fiber->events = htable_create(var_maxfd);
#else
	__thread_fiber->events = (FILE_EVENT **)
		calloc(var_maxfd, sizeof(FILE_EVENT*));
#endif

	if (__pthread_self() == main_thread_self()) {
		__main_fiber = __thread_fiber;
		atexit(fiber_io_main_free);
	} else if (pthread_setspecific(__fiber_key, __thread_fiber) != 0) {
		msg_fatal("pthread_setspecific error!");
	}
}
Example #16
0
void __pthread_tsd_run_dtors()
{
	pthread_t self = __pthread_self();
	int i, j, not_finished = self->tsd_used;
	for (j=0; not_finished && j<PTHREAD_DESTRUCTOR_ITERATIONS; j++) {
		not_finished = 0;
		for (i=0; i<PTHREAD_KEYS_MAX; i++) {
			if (self->tsd[i] && keys[i]) {
				void *tmp = self->tsd[i];
				self->tsd[i] = 0;
				keys[i](tmp);
				not_finished = 1;
			}
		}
	}
}
Example #17
0
int ftrylockfile(FILE *f)
{
	pthread_t self = __pthread_self();
	int tid = self->tid;
	int owner = f->lock;
	if ((owner & ~MAYBE_WAITERS) == tid) {
		if (f->lockcount == LONG_MAX)
			return -1;
		f->lockcount++;
		return 0;
	}
	if (owner < 0) f->lock = owner = 0;
	if (owner || a_cas(&f->lock, 0, tid))
		return -1;
	__register_locked_file(f, self);
	return 0;
}
Example #18
0
int __pthread_key_create(pthread_key_t *k, void (*dtor)(void *))
{
	unsigned i = (uintptr_t)&k / 16 % PTHREAD_KEYS_MAX;
	unsigned j = i;
	pthread_t self = __pthread_self();

	/* This can only happen in the main thread before
	 * pthread_create has been called. */
	if (!self->tsd) self->tsd = __pthread_tsd_main;

	if (!dtor) dtor = nodtor;
	do {
		if (!a_cas_p(keys+j, 0, (void *)dtor)) {
			*k = j;
			return 0;
		}
	} while ((j=(j+1)%PTHREAD_KEYS_MAX) != i);
	return EAGAIN;
}
Example #19
0
static void cancel_handler(int sig, siginfo_t *si, void *ctx)
{
	pthread_t self = __pthread_self();
	ucontext_t *uc = ctx;
	const char *ip = ((char **)&uc->uc_mcontext)[CANCEL_REG_IP];
	extern const char __cp_begin[1], __cp_end[1];

	if (!self->cancel || self->canceldisable) return;

	_sigaddset(&uc->uc_sigmask, SIGCANCEL);

	if (self->cancelasync || ip >= __cp_begin && ip < __cp_end) {
		self->canceldisable = 1;
		pthread_sigmask(SIG_SETMASK, &uc->uc_sigmask, 0);
		__cancel();
	}

	__syscall(SYS_tgkill, self->pid, self->tid, SIGCANCEL);
}
Example #20
0
static void cancel_handler(int sig, siginfo_t *si, void *ctx)
{
    pthread_t self = __pthread_self();
    ucontext_t *uc = ctx;
    uintptr_t sp = ((uintptr_t *)&uc->uc_mcontext)[CANCEL_REG_SP];
    uintptr_t ip = ((uintptr_t *)&uc->uc_mcontext)[CANCEL_REG_IP];

    if (!self->cancel || self->canceldisable) return;

    _sigaddset(&uc->uc_sigmask, SIGCANCEL);

    if (self->cancelasync || sp == self->cp_sp && ip <= self->cp_ip) {
        self->canceldisable = 1;
        pthread_sigmask(SIG_SETMASK, &uc->uc_sigmask, 0);
        __cancel();
    }

    if (self->cp_sp)
        __syscall(SYS_tgkill, self->pid, self->tid, SIGCANCEL);
}
Example #21
0
long (__syscall_cp)(long nr, long u, long v, long w, long x, long y, long z)
{
    pthread_t self;
    uintptr_t old_sp, old_ip;
    long r;

    if (!libc.main_thread || (self = __pthread_self())->canceldisable)
        return __syscall(nr, u, v, w, x, y, z);

    old_sp = self->cp_sp;
    old_ip = self->cp_ip;
    self->cp_sp = 0;
    self->cp_ip = 0;
    r = __syscall_cp_asm(&self->cp_sp, nr, u, v, w, x, y, z);
    self->cp_ip = old_ip;
    self->cp_sp = old_sp;
    if (r==-EINTR && nr!=SYS_close && self->cancel && !self->canceldisable)
        __cancel();
    return r;
}
Example #22
0
const char *last_serror(void)
{
	char *buf;
	int   error = acl_fiber_last_error();
	static size_t __buf_size = 4096;

	if (pthread_once(&once_control, thread_buf_init) != 0) {
		abort();
	}

	buf = (char*) pthread_getspecific(__errbuf_key);
	if (buf == NULL) {
		buf = (char*) malloc(__buf_size);
		assert(pthread_setspecific(__errbuf_key, buf) == 0);
		if (__pthread_self() == main_thread_self()) {
			__main_buf = buf;
			atexit(main_free_buf);
		}
	}
	return acl_fiber_strerror(error, buf, __buf_size);
}
Example #23
0
pid_t fork(void)
{
	pid_t ret;
	sigset_t set;
	__fork_handler(-1);
	__block_all_sigs(&set);
#ifdef SYS_fork
	ret = syscall(SYS_fork);
#else
	ret = syscall(SYS_clone, SIGCHLD, 0);
#endif
	if (libc.has_thread_pointer && !ret) {
		pthread_t self = __pthread_self();
		self->tid = self->pid = __syscall(SYS_getpid);
		memset(&self->robust_list, 0, sizeof self->robust_list);
		libc.threads_minus_1 = 0;
	}
	__restore_sigs(&set);
	__fork_handler(!ret);
	return ret;
}
pid_t fork(void)
{
	pid_t ret;
	sigset_t set;
	__fork_handler(-1);
	__block_all_sigs(&set);
#ifdef SYS_fork
	ret = syscall(SYS_fork);
#else
	ret = syscall(SYS_clone, SIGCHLD, 0);
#endif
	if (!ret) {
		pthread_t self = __pthread_self();
		self->tid = __syscall(SYS_gettid);
		self->robust_list.off = 0;
		self->robust_list.pending = 0;
		libc.threads_minus_1 = 0;
	}
	__restore_sigs(&set);
	__fork_handler(!ret);
	return ret;
}
Example #25
0
#include "pthread_impl.h"

int pthread_setcanceltype(int new, int* old) {
  struct pthread* self = __pthread_self();
  if (new > 1U)
    return EINVAL;
  if (old)
    *old = self->cancelasync;
  self->cancelasync = new;
  if (new)
    pthread_testcancel();
  return 0;
}
Example #26
0
#include <limits.h>
#include "pthread_impl.h"

static void dummy(void)
{
}

weak_alias(dummy, __aio_wake);

static void notify_signal(struct sigevent *sev)
{
	siginfo_t si = {
		.si_signo = sev->sigev_signo,
		.si_value = sev->sigev_value,
		.si_code = SI_ASYNCIO,
		.si_pid = __pthread_self()->pid,
		.si_uid = getuid()
	};
	__syscall(SYS_rt_sigqueueinfo, si.si_pid, si.si_signo, &si);
}

static void *io_thread(void *p)
{
	struct aiocb *cb = p;
	int fd = cb->aio_fildes;
	void *buf = (void *)cb->aio_buf;
	size_t len = cb->aio_nbytes;
	off_t off = cb->aio_offset;
	int op = cb->aio_lio_opcode;
	struct sigevent sev = cb->aio_sigevent;
	ssize_t ret;
Example #27
0
int *__errno_location(void)
{
	static int e;
	return &e;
	return &__pthread_self()->errno_val;
}
Example #28
0
int *__errno_location(void)
{
	static int e;
	if (libc.has_thread_pointer) return &__pthread_self()->errno_val;
	return &e;
}
Example #29
0
void *pthread_getspecific(pthread_key_t k)
{
	struct pthread *self = __pthread_self();
	return self->tsd[k];
}
Example #30
0
void __do_orphaned_stdio_locks()
{
	FILE *f;
	for (f=__pthread_self()->stdio_locks; f; f=f->next_locked)
		a_store(&f->lock, 0x40000000);
}