+/* -*- mode: asm; tab-width: 4 -*- */
/****************************** asmpart.c **************************************
* *
* is an assembly language file, but called .c to fake the preprocessor. *
.globl new_builtin_lrem
.globl perform_alpha_threadswitch
.globl initialize_thread_stack
- .globl used_stack_top
+ .globl asm_switchstackandcall
/*************************** imported variables *******************************/
sra $22,48,$22 # isolate offset
addq $22,$28,$22 # compute update address via method pointer
- stq $0,0($22) # save new method address there
+ stq $0,0($22) # save new method address there
- bis $0,$0,pv # load method address into pv
+ bis $0,$0,pv # load method address into pv
jmp zero, (pv) # and call method. The method returns
# directly to the caller (ra).
/******************* function perform_alpha_threadswitch ***********************
* *
+* void perform_alpha_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
* performs a threadswitch *
* *
*******************************************************************************/
stt sf7, 112(sp)
stq ra, 120(sp)
stq sp, 0(a0)
+ stq sp, 0(a2)
ldq sp, 0(a1)
ldq s0, 0(sp)
ldq s1, 8(sp)
.end perform_alpha_threadswitch
-/*********************** function used_stack_top *******************************
+/********************* function asm_switchstackandcall *************************
* *
-* returns $sp *
+* Switches to a new stack, calls a function and switches back. *
+* a0 new stack pointer *
+* a1 function pointer *
* *
*******************************************************************************/
- .ent used_stack_top
-used_stack_top:
- mov sp, v0
- jmp zero,(ra)
- .end used_stack_top
+ .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
+ mov a0,sp # switch to new stack
+
+ mov a1,pv # load function pointer
+ jmp ra,(pv) # and call funciton
+
+ ldq ra,0(sp) # load return address
+ ldq sp,1*8(sp) # switch to old stack
+
+ jmp zero,(ra) # return
+
+ .end asm_switchstackandcall
#include "../threads/thread.h"
-void perform_alpha_threadswitch (u1 **from, u1 **to);
+void perform_alpha_threadswitch (u1 **from, u1 **to, u1 **stackTop);
u1* initialize_thread_stack (void *func, u1 *stack);
-u1* used_stack_top (void);
+void asm_switchstackandcall (void *stack, void *func);
-#define THREADSTACKSIZE (64 * 1024)
+#define THREADSTACKSIZE (32 * 1024)
#define THREADSWITCH(to, from) perform_alpha_threadswitch(&(from)->restorePoint,\
- &(to)->restorePoint)
+ &(to)->restorePoint, &(from)->usedStackTop)
#define THREADINIT(to, func) (to)->restorePoint = \
initialize_thread_stack((u1*)(func), \
(to)->stackEnd)
-#define USEDSTACKTOP(top) (top) = used_stack_top()
-
#define THREADINFO(ee) \
do { \
(ee)->restorePoint = 0; \
void perform_alpha_threadswitch (u1 **from, u1 **to) {}
u1* initialize_thread_stack (void *func, u1 *stack) { return NULL; }
-u1* used_stack_top (void) { return NULL; }
+void asm_switchstackandcall () { }
java_objectheader *native_new_and_init (void *p) { return NULL; }
void perform_alpha_threadswitch (u1 **from, u1 **to) {}
u1* initialize_thread_stack (void *func, u1 *stack) { return NULL; }
-u1* used_stack_top (void) { return NULL; }
+void asm_switchstackandcall () { }
java_objectheader *native_new_and_init (void *p) { return NULL; }
#if defined(USE_INTERNAL_THREADS)
thread* currentThread;
+thread* mainThread;
thread* threadQhead[MAX_THREAD_PRIO + 1];
thread* threadQtail[MAX_THREAD_PRIO + 1];
contexts[i].free = true;
/* Allocate a thread to be the main thread */
- currentThread = (thread*)builtin_new(loader_load(unicode_new_char("java/lang/Thread")));
+ mainThread = currentThread = (thread*)builtin_new(loader_load(unicode_new_char("java/lang/Thread")));
assert(currentThread != 0);
currentThread->PrivateInfo = 1;
iresumeThread(currentThread);
/* Start garbage collection thread */
- gcDaemonThread = startDaemon(gc_thread, "gc", 1024*512);
+ gcDaemonThread = startDaemon(gc_thread, "gc", 16384);
iresumeThread(gcDaemonThread);
heap_addreference((void**)&gcDaemonThread);
if (threadQhead[i] != currentThread)
{
- USEDSTACKTOP((CONTEXT(currentThread).usedStackTop));
+ /* USEDSTACKTOP((CONTEXT(currentThread).usedStackTop)); */
lastThread = currentThread;
currentThread = threadQhead[i];
extern int blockInts;
extern bool needReschedule;
extern thread *currentThread;
+extern thread *mainThread;
extern ctx contexts[];
extern int threadStackSize;
#include "asmpart.h"
#include "callargs.h"
+#include "sysdep/threads.h"
#include "threads/thread.h" /* schani */
#include "threads/locks.h"
static void markstack () /* schani */
{
void *dummy;
- void **top_of_stack = &dummy;
#ifdef USE_THREADS
- thread *aThread;
+ thread *aThread;
- for (aThread = liveThreads; aThread != 0; aThread = CONTEXT(aThread).nextlive) {
+ for (aThread = liveThreads; aThread != 0;
+ aThread = CONTEXT(aThread).nextlive) {
mark((heapblock*)aThread);
if (aThread == currentThread) {
- 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);
+ 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 + 16);
- else
- markreferences ((void**)CONTEXT(aThread).usedStackTop - 16,
- (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],
+ (void**)&threadQhead[MAX_THREAD_PRIO]);
- markreferences((void**)&threadQhead[0], (void**)&threadQhead[MAX_THREAD_PRIO]);
#else
- if (top_of_stack > bottom_of_stack)
- markreferences(bottom_of_stack, top_of_stack);
- else
- markreferences(top_of_stack, bottom_of_stack);
+ void **top_of_stack = &dummy;
+
+ if (top_of_stack > bottom_of_stack)
+ markreferences(bottom_of_stack, top_of_stack);
+ else
+ markreferences(top_of_stack, bottom_of_stack);
#endif
}
wait_cond(&gcThreadMutex, &gcConditionStart, 0);
intsDisable();
- heap_docollect();
+ assert(currentThread != mainThread);
+ asm_switchstackandcall(CONTEXT(mainThread).usedStackTop, heap_docollect);
intsRestore();
signal_cond(&gcConditionDone);
#include "asmpart.h"
#include "callargs.h"
+#include "sysdep/threads.h"
#include "threads/thread.h" /* schani */
#include "threads/locks.h"
static void markstack () /* schani */
{
void *dummy;
- void **top_of_stack = &dummy;
#ifdef USE_THREADS
- thread *aThread;
+ thread *aThread;
- for (aThread = liveThreads; aThread != 0; aThread = CONTEXT(aThread).nextlive) {
+ for (aThread = liveThreads; aThread != 0;
+ aThread = CONTEXT(aThread).nextlive) {
mark((heapblock*)aThread);
if (aThread == currentThread) {
- 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);
+ 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 + 16);
- else
- markreferences ((void**)CONTEXT(aThread).usedStackTop - 16,
- (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],
+ (void**)&threadQhead[MAX_THREAD_PRIO]);
- markreferences((void**)&threadQhead[0], (void**)&threadQhead[MAX_THREAD_PRIO]);
#else
- if (top_of_stack > bottom_of_stack)
- markreferences(bottom_of_stack, top_of_stack);
- else
- markreferences(top_of_stack, bottom_of_stack);
+ void **top_of_stack = &dummy;
+
+ if (top_of_stack > bottom_of_stack)
+ markreferences(bottom_of_stack, top_of_stack);
+ else
+ markreferences(top_of_stack, bottom_of_stack);
#endif
}
wait_cond(&gcThreadMutex, &gcConditionStart, 0);
intsDisable();
- heap_docollect();
+ assert(currentThread != mainThread);
+ asm_switchstackandcall(CONTEXT(mainThread).usedStackTop, heap_docollect);
intsRestore();
signal_cond(&gcConditionDone);
#if defined(USE_INTERNAL_THREADS)
thread* currentThread;
+thread* mainThread;
thread* threadQhead[MAX_THREAD_PRIO + 1];
thread* threadQtail[MAX_THREAD_PRIO + 1];
contexts[i].free = true;
/* Allocate a thread to be the main thread */
- currentThread = (thread*)builtin_new(loader_load(unicode_new_char("java/lang/Thread")));
+ mainThread = currentThread = (thread*)builtin_new(loader_load(unicode_new_char("java/lang/Thread")));
assert(currentThread != 0);
currentThread->PrivateInfo = 1;
iresumeThread(currentThread);
/* Start garbage collection thread */
- gcDaemonThread = startDaemon(gc_thread, "gc", 1024*512);
+ gcDaemonThread = startDaemon(gc_thread, "gc", 16384);
iresumeThread(gcDaemonThread);
heap_addreference((void**)&gcDaemonThread);
if (threadQhead[i] != currentThread)
{
- USEDSTACKTOP((CONTEXT(currentThread).usedStackTop));
+ /* USEDSTACKTOP((CONTEXT(currentThread).usedStackTop)); */
lastThread = currentThread;
currentThread = threadQhead[i];
extern int blockInts;
extern bool needReschedule;
extern thread *currentThread;
+extern thread *mainThread;
extern ctx contexts[];
extern int threadStackSize;