Esempio n. 1
0
static int
_rthread_init(void)
{
	pthread_t thread = &_initial_thread;
	extern int __isthreaded;

	thread->tid = getthrid();
	thread->donesem.lock = _SPINLOCK_UNLOCKED;
	thread->flags |= THREAD_CANCEL_ENABLE|THREAD_CANCEL_DEFERRED;
	thread->flags_lock = _SPINLOCK_UNLOCKED;
	strlcpy(thread->name, "Main process", sizeof(thread->name));
	LIST_INSERT_HEAD(&_thread_list, thread, threads);
	if (_rthread_open_kqueue())
		return (errno);
	_rthread_debug_init();
	_rthread_debug(1, "rthread init\n");
	_threads_ready = 1;
	__isthreaded = 1;

#if defined(__ELF__) && defined(PIC)
	/*
	 * To avoid recursion problems in ld.so, we need to trigger the
	 * functions once to fully bind them before registering them
	 * for use.
	 */
	_rthread_dl_lock(0);
	_rthread_dl_lock(1);
	_rthread_bind_lock(0);
	_rthread_bind_lock(1);
	dlctl(NULL, DL_SETTHREADLCK, _rthread_dl_lock);
	dlctl(NULL, DL_SETBINDLCK, _rthread_bind_lock);
#endif

	return (0);
}
static void zend_jit_perf_jitdump_register(const char *name, void *start, size_t size)
{
	if (jitdump_fd >= 0) {
		static uint64_t id = 1;
		zend_perf_jitdump_load_record rec;
		size_t len = strlen(name);
		uint32_t thread_id;
#if defined(__linux__)
		thread_id = syscall(SYS_gettid);
#elif defined(__FreeBSD__)
		long tid;
		thr_self(&tid);
		thread_id = (uint32_t)tid;
#elif defined(__OpenBSD__)
		thread_id = getthrid();
#elif defined(__NetBSD__)
		thread_id = _lwp_self();
#endif

		memset(&rec, 0, sizeof(rec));
		rec.hdr.event      = ZEND_PERF_JITDUMP_RECORD_LOAD;
		rec.hdr.size       = sizeof(rec) + len + 1 + size;
		rec.hdr.time_stamp = zend_perf_timestamp();
		rec.process_id     = getpid();
		rec.thread_id      = thread_id;
		rec.vma            = (uint64_t)(uintptr_t)start;
		rec.code_address   = (uint64_t)(uintptr_t)start;
		rec.code_size      = (uint64_t)size;
		rec.code_id        = id++;

		zend_quiet_write(jitdump_fd, &rec, sizeof(rec));
		zend_quiet_write(jitdump_fd, name, len + 1);
		zend_quiet_write(jitdump_fd, start, size);
	}
}
Esempio n. 3
0
static inline void
setup_static_tib(Elf_Phdr *phdr, int phnum)
{
	struct tib *tib;
	char *base;
	int i;

	if (phdr != NULL) {
		for (i = 0; i < phnum; i++) {
			if (phdr[i].p_type != PT_TLS)
				continue;
			if (phdr[i].p_memsz == 0)
				break;
			if (phdr[i].p_memsz < phdr[i].p_filesz)
				break;		/* invalid */
#if TLS_VARIANT == 1
			_static_tls_size = phdr[i].p_memsz;
#elif TLS_VARIANT == 2
			/*
			 * variant 2 places the data before the TIB
			 * so we need to round up to the alignment
			 */
			_static_tls_size = ELF_ROUND(phdr[i].p_memsz,
			    phdr[i].p_align);
#endif
			if (phdr[i].p_vaddr != 0 && phdr[i].p_filesz != 0) {
				static_tls = (void *)phdr[i].p_vaddr;
				static_tls_fsize = phdr[i].p_filesz;
			}
			break;
		}
	}

	/*
	 * We call getpagesize() here instead of using _pagesize because
	 * there's no aux-vector in non-PIE static links, so _pagesize
	 * might not be set yet.  If so getpagesize() will get the value.
	 */
	base = mmap(NULL, ELF_ROUND(_static_tls_size + sizeof *tib,
	    getpagesize()), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
# if TLS_VARIANT == 1
	tib = (struct tib *)base;
# elif TLS_VARIANT == 2
	tib = (struct tib *)(base + _static_tls_size);
# endif

	_static_tls_init(base);
	TIB_INIT(tib, NULL, NULL);
	tib->tib_tid = getthrid();
	TCB_SET(TIB_TO_TCB(tib));
#if ! TCB_HAVE_MD_GET
	_libc_single_tcb = TIB_TO_TCB(tib);
#endif
}
Esempio n. 4
0
static pthread_t
_rthread_findself(void)
{
	pthread_t me;
	pid_t tid = getthrid();

	LIST_FOREACH(me, &_thread_list, threads) 
		if (me->tid == tid)
			break;

	return (me);
}
Esempio n. 5
0
int
pthread_join(pthread_t thread, void **retval)
{
	int e;

	if (thread->tid == getthrid())
		e = EDEADLK;
	else if (thread->flags & THREAD_DETACHED)
		e = EINVAL;
	else {
		_sem_wait(&thread->donesem, 0, 0);
		if (retval)
			*retval = thread->retval;
		e = 0;
		/* We should be the last having a ref to this thread, but
		 * someone stupid or evil might haved detached it;
		 * in that case the thread will cleanup itself */
		if ((thread->flags & THREAD_DETACHED) == 0)
			_rthread_free(thread);
	}

	_rthread_reaper();
	return (e);
}