/* * start C code running in another cog * returns -1 on failure, otherwise the * id of the new cog * "func" is the function to start running * "arg" is the argument * "stacktop" is the top of the new process' stack * NOTE: this is a raw low-level function; the * pthreads functions may be more useful */ int _start_cog_thread(void *stacktop, void (*func)(void *), void *arg, _thread_state_t *tls) { void *tmp = __builtin_alloca(1984); unsigned int *sp = stacktop; int r; #if defined(__PROPELLER_USE_XMM__) /* the space for the cache is taken from the top of the stack space */ unsigned int cachebase; sp -= (CACHE_EXTRA_SPACE/sizeof(*sp)); cachebase = ~0xf & (15 + (unsigned int)sp); /* align to 16 byte boundary */ #endif /* copy the kernel into temporary (HUB) memory */ _clone_cog(tmp); /* push the pointer to thread local storage */ *--sp = (unsigned int)tls; /* push the parameter to the function */ *--sp = (unsigned int)arg; /* push the code address */ *--sp = (unsigned int)func; #if defined(__PROPELLER_USE_XMM__) { unsigned int cogid = __builtin_propeller_cogid(); // push the cache geometry *--sp = CACHE_GEOMETRY; // push the cache line storage address *--sp = cachebase; // push the cache tag storage address *--sp = cachebase + CACHE_SIZE; // push the base of the hub mailbox array *--sp = ((unsigned int)_hub_mailbox) - (cogid<<3); } #endif /* now start the kernel */ r = cognew(tmp, sp); return r; }
static int32_t Coginit__(int cogid, void *stacktop, void *func, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4) { void *tmp = __builtin_alloca(1984); unsigned int *sp = (unsigned int *)stacktop; static int32_t cogargs__[5]; int r; cogargs__[0] = (int32_t) func; cogargs__[1] = arg1; cogargs__[2] = arg2; cogargs__[3] = arg3; cogargs__[4] = arg4; _clone_cog(tmp); *--sp = 0; *--sp = (unsigned int)cogargs__; *--sp = (unsigned int)Cogstub__; r = coginit(cogid, tmp, sp); return r; }