/********************* function asm_switchstackandcall *************************
* *
-* void asm_switchstackandcall (void *stack, void *func); *
+* void asm_switchstackandcall (void *stack, void *func, void **stacktopsave); *
* *
* Switches to a new stack, calls a function and switches back. *
* a0 new stack pointer *
* a1 function pointer *
+* a2 pointer to variable where stack top should be stored *
* *
*******************************************************************************/
.ent asm_switchstackandcall
asm_switchstackandcall:
lda a0,-2*8(a0) /* allocate new stack */
- stq ra,0(a0) /* save return address */
- stq sp,1*8(a0) /* save old stack pointer */
+ stq ra,0(a0) /* save return address on new stack */
+ stq sp,1*8(a0) /* save old stack pointer on new stack */
+ stq sp,0(a2) /* save old stack pointer to variable */
mov a0,sp /* switch to new stack */
mov a1,pv /* load function pointer */
- jmp ra,(pv) /* and call funciton */
+ jmp ra,(pv) /* and call function */
ldq ra,0(sp) /* load return address */
ldq sp,1*8(sp) /* switch to old stack */
void perform_alpha_threadswitch (u1 **from, u1 **to, u1 **stackTop);
u1* initialize_thread_stack (void *func, u1 *stack);
-void asm_switchstackandcall (void *stack, void *func);
+void asm_switchstackandcall (void *stack, void *func, void **stacktopsave);
#define THREADSTACKSIZE (32 * 1024)
******************************************************************************/
-static void markstack () /* schani */
+static void markstack ()
{
void *dummy;
for (aThread = liveThreads; aThread != 0;
aThread = CONTEXT(aThread).nextlive) {
mark((heapblock*)aThread);
- if (aThread == currentThread) {
- void **top_of_stack = &dummy;
-
- if (top_of_stack > (void**)CONTEXT(aThread).stackEnd)
- markreferences((void**)CONTEXT(aThread).stackEnd, top_of_stack);
- else
- markreferences(top_of_stack, (void**)CONTEXT(aThread).stackEnd);
- }
- else {
- if (CONTEXT(aThread).usedStackTop > CONTEXT(aThread).stackEnd)
- markreferences((void**)CONTEXT(aThread).stackEnd,
- (void**)CONTEXT(aThread).usedStackTop);
- else
- markreferences((void**)CONTEXT(aThread).usedStackTop,
- (void**)CONTEXT(aThread).stackEnd);
- }
+ if (CONTEXT(aThread).usedStackTop > CONTEXT(aThread).stackEnd)
+ markreferences((void**)CONTEXT(aThread).stackEnd,
+ (void**)CONTEXT(aThread).usedStackTop);
+ else
+ markreferences((void**)CONTEXT(aThread).usedStackTop,
+ (void**)CONTEXT(aThread).stackEnd);
}
markreferences((void**)&threadQhead[0],
gc_call (void)
{
#ifdef USE_THREADS
+ u1 dummy;
+
assert(blockInts == 0);
intsDisable();
- if (currentThread == NULL || currentThread == mainThread)
+ if (currentThread == NULL || currentThread == mainThread) {
+ CONTEXT(mainThread).usedStackTop = &dummy;
heap_docollect();
+ }
else
- asm_switchstackandcall(CONTEXT(mainThread).usedStackTop, heap_docollect);
+ asm_switchstackandcall(CONTEXT(mainThread).usedStackTop, heap_docollect,
+ (void**)&(CONTEXT(currentThread).usedStackTop));
intsRestore();
#else
heap_docollect();
mainThread = currentThread = the_main_thread;
+ heap_addreference((void**)&mainThread);
+
/* Add thread into runQ */
iresumeThread(mainThread);
mainThread = currentThread = the_main_thread;
+ heap_addreference((void**)&mainThread);
+
/* Add thread into runQ */
iresumeThread(mainThread);