Exemplo n.º 1
0
Thread threadGetCurrent(void)
{
	ThreadVars* tv = getThreadVars();
	if (tv->magic != THREADVARS_MAGIC)
		__panic();
	return tv->thread_ptr;
}
Exemplo n.º 2
0
void __system_initSyscalls(void)
{
	// Register newlib syscalls
	__syscalls.exit     = __ctru_exit;
	__syscalls.gettod_r = __libctru_gtod;
	__syscalls.getreent = __ctru_get_reent;
	__syscalls.nanosleep = __libctru_nanosleep;

	// Register locking syscalls
	__syscalls.lock_init                  = LightLock_Init;
	__syscalls.lock_acquire               = LightLock_Lock;
	__syscalls.lock_try_acquire           = LightLock_TryLock;
	__syscalls.lock_release               = LightLock_Unlock;
	__syscalls.lock_init_recursive        = RecursiveLock_Init;
	__syscalls.lock_acquire_recursive     = RecursiveLock_Lock;
	__syscalls.lock_try_acquire_recursive = RecursiveLock_TryLock;
	__syscalls.lock_release_recursive     = RecursiveLock_Unlock;

	// Initialize thread vars for the main thread
	ThreadVars* tv = getThreadVars();
	tv->magic = THREADVARS_MAGIC;
	tv->reent = _impure_ptr;
	tv->thread_ptr = NULL;
	tv->tls_tp = __tls_start-8; // ARM ELF TLS ABI mandates an 8-byte header
	tv->srv_blocking_policy = false;

	u32 tls_size = __tdata_lma_end - __tdata_lma;
	if (tls_size)
		memcpy(__tls_start, __tdata_lma, tls_size);
}
Exemplo n.º 3
0
boolean isErrAbortInProgress() 
/* Flag to indicate that an error abort is in progress.
 * Needed so that a warn handler can tell if it's really
 * being called because of a warning or an error. */
{
struct perThreadAbortVars *ptav = getThreadVars();
return ptav->errAbortInProgress;
}
Exemplo n.º 4
0
void noWarnAbort()
/* Abort without message. */
{
struct perThreadAbortVars *ptav = getThreadVars();
ptav->abortArray[ptav->abortIx]();
exit(-1);               /* This is just to make compiler happy.
                         * We have already exited or longjmped by now. */
}
Exemplo n.º 5
0
static struct _reent* __ctru_get_reent()
{
	ThreadVars* tv = getThreadVars();
	if (tv->magic != THREADVARS_MAGIC)
	{
		svcBreak(USERBREAK_PANIC);
		for (;;);
	}
	return tv->reent;
}
Exemplo n.º 6
0
static void _thread_begin(void* arg)
{
	Thread t = (Thread)arg;
	ThreadVars* tv = getThreadVars();
	tv->magic = THREADVARS_MAGIC;
	tv->reent = &t->reent;
	tv->thread_ptr = t;
	tv->tls_tp = (u8*)t->stacktop-8; // ARM ELF TLS ABI mandates an 8-byte header
	t->ep(t->arg);
	threadExit(0);
}
Exemplo n.º 7
0
void popAbortHandler()
/* Revert to old abort handler. */
{
struct perThreadAbortVars *ptav = getThreadVars();
if (ptav->abortIx <= 0)
    {
    if (ptav->debugPushPopErr)
        dumpStack("popAbortHandler underflow");
    errAbort("Too many popAbortHandlers\n");
    }
--ptav->abortIx;
}
Exemplo n.º 8
0
void pushAbortHandler(AbortHandler handler)
/* Set abort handler */
{
struct perThreadAbortVars *ptav = getThreadVars();
if (ptav->abortIx >= maxAbortHandlers-1)
    {
    if (ptav->debugPushPopErr)
        dumpStack("pushAbortHandler overflow");
    errAbort("Too many pushAbortHandlers, can only handle %d", maxAbortHandlers-1);
    }
ptav->abortArray[++ptav->abortIx] = handler;
}
Exemplo n.º 9
0
void popWarnHandler()
/* Revert to old warn handler. */
{
struct perThreadAbortVars *ptav = getThreadVars();
if (ptav->warnIx <= 0)
    {
    if (ptav->debugPushPopErr)
        dumpStack("popWarnHandler underflow");
    errAbort("Too few popWarnHandlers");
    }
--ptav->warnIx;
}
Exemplo n.º 10
0
void vaErrAbort(char *format, va_list args)
/* Abort function, with optional (vprintf formatted) error message. */
{
/* flag is needed because both errAbort and warn generate message
 * using the warn handler, however sometimes one needed to know
 * (like when logging), if it's an error or a warning.  This is far from
 * perfect, as this isn't cleared if the error handler continues,
 * as with an exception mechanism. */
struct perThreadAbortVars *ptav = getThreadVars();
ptav->errAbortInProgress = TRUE;
vaWarn(format, args);
noWarnAbort();
}
Exemplo n.º 11
0
Thread threadCreate(ThreadFunc entrypoint, void* arg, size_t stack_size, int prio, int affinity, bool detached)
{
	size_t stackoffset = (sizeof(struct Thread_tag)+7)&~7;
	size_t allocsize   = stackoffset + ((stack_size+7)&~7);
	size_t tlssize = __tls_end-__tls_start;
	size_t tlsloadsize = __tdata_lma_end-__tdata_lma;
	size_t tbsssize = tlssize-tlsloadsize;

	// Guard against overflow
	if (allocsize < stackoffset) return NULL;
	if ((allocsize-stackoffset) < stack_size) return NULL;
	if ((allocsize+tlssize) < allocsize) return NULL;

	Thread t = (Thread)memalign(8,allocsize+tlssize);
	if (!t) return NULL;

	t->ep       = entrypoint;
	t->arg      = arg;
	t->detached = detached;
	t->finished = false;
	t->stacktop = (u8*)t + allocsize;

	if (tlsloadsize)
		memcpy(t->stacktop, __tdata_lma, tlsloadsize);
	if (tbsssize)
		memset((u8*)t->stacktop+tlsloadsize, 0, tbsssize);

	// Set up child thread's reent struct, inheriting standard file handles
	_REENT_INIT_PTR(&t->reent);
	struct _reent* cur = getThreadVars()->reent;
	t->reent._stdin  = cur->_stdin;
	t->reent._stdout = cur->_stdout;
	t->reent._stderr = cur->_stderr;

	Result rc;
	rc = svcCreateThread(&t->handle, _thread_begin, (u32)t, (u32*)t->stacktop, prio, affinity);
	if (R_FAILED(rc))
	{
		free(t);
		return NULL;
	}

	return t;
}
Exemplo n.º 12
0
void vaWarn(char *format, va_list args)
/* Call top of warning stack to issue warning. */
{
struct perThreadAbortVars *ptav = getThreadVars();
ptav->warnArray[ptav->warnIx](format, args);
}
Exemplo n.º 13
0
void errAbortDebugnPushPopErr()
/*  generate stack dump if there is a error in the push/pop functions */
{
struct perThreadAbortVars *ptav = getThreadVars();
ptav->debugPushPopErr = TRUE;
}