enhanced the gc finalization process a bit more
This commit is contained in:
parent
447012b214
commit
a46113abad
@ -290,10 +290,10 @@ class SemaphoreHeap(Object)
|
|||||||
|
|
||||||
class(#final,#limited) ProcessScheduler(Object)
|
class(#final,#limited) ProcessScheduler(Object)
|
||||||
{
|
{
|
||||||
var(#get) active.
|
var(#get) active, total_count := 0.
|
||||||
var(#get) runnable_count.
|
var(#get) runnable_count := 0.
|
||||||
var runnable_head, runnable_tail.
|
var runnable_head, runnable_tail.
|
||||||
var(#get) suspended_count.
|
var(#get) suspended_count := 0.
|
||||||
var suspended_head, suspended_tail.
|
var suspended_head, suspended_tail.
|
||||||
|
|
||||||
method activeProcess
|
method activeProcess
|
||||||
@ -348,6 +348,12 @@ class(#final,#limited) ProcessScheduler(Object)
|
|||||||
self primitiveFailed.
|
self primitiveFailed.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
method signalOnGCFin: semaphore
|
||||||
|
{
|
||||||
|
<primitive: #_processor_add_gcfin_semaphore>
|
||||||
|
self primitiveFailed.
|
||||||
|
}
|
||||||
|
|
||||||
method signal: semaphore onInput: file
|
method signal: semaphore onInput: file
|
||||||
{
|
{
|
||||||
<primitive: #_processor_add_input_semaphore>
|
<primitive: #_processor_add_input_semaphore>
|
||||||
|
@ -32,28 +32,31 @@ class System(Apex)
|
|||||||
|
|
||||||
method(#class) __gc_finalizer
|
method(#class) __gc_finalizer
|
||||||
{
|
{
|
||||||
| tmp gc |
|
| tmp gc fin_sem |
|
||||||
|
|
||||||
gc := false.
|
gc := false.
|
||||||
|
fin_sem := Semaphore new.
|
||||||
|
|
||||||
|
Processor signalOnGCFin: fin_sem.
|
||||||
|
[
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
|
||||||
while ((tmp := self _popCollectable) notError)
|
while ((tmp := self _popCollectable) notError)
|
||||||
{
|
{
|
||||||
## TODO: Do i have to protected this in an exception handler???
|
## TODO: Do i have to protected this in an exception handler???
|
||||||
if (tmp respondsTo: #finalize) { tmp finalize }.
|
if (tmp respondsTo: #finalize) { tmp finalize }.
|
||||||
}.
|
}.
|
||||||
|
|
||||||
##if (Processor runnable_count == 1 and: [Processor active == thisProcess])
|
if (Processor total_count == 1)
|
||||||
if (Processor runnable_count == 1 and: [Processor suspended_count == 0]) ## TODO: does it suffer from race condition?
|
|
||||||
{
|
{
|
||||||
## exit from this loop when there are no other processes running except this finalizer process
|
## exit from this loop when there are no other processes running except this finalizer process
|
||||||
if (gc)
|
if (gc)
|
||||||
{
|
{
|
||||||
System logNl: 'Exiting the GC finalization process...'.
|
System logNl: 'Exiting the GC finalization process'.
|
||||||
break
|
break
|
||||||
}.
|
}.
|
||||||
|
|
||||||
|
System logNl: 'Forcing garbage collection before termination in ' & (thisProcess id) asString.
|
||||||
self collectGarbage.
|
self collectGarbage.
|
||||||
gc := true.
|
gc := true.
|
||||||
}
|
}
|
||||||
@ -62,9 +65,15 @@ class System(Apex)
|
|||||||
gc := false.
|
gc := false.
|
||||||
}.
|
}.
|
||||||
|
|
||||||
##System logNl: 'gc_waiting....'.
|
##System logNl: '^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^gc_waiting....'.
|
||||||
Processor sleepFor: 1. ## TODO: wait on semaphore instead..
|
##Processor sleepFor: 1. ## TODO: wait on semaphore instead..
|
||||||
|
fin_sem wait.
|
||||||
|
##System logNl: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX gc_waitED....'.
|
||||||
}
|
}
|
||||||
|
] ensure: [
|
||||||
|
Processor unsignal: fin_sem.
|
||||||
|
System logNl: 'End of GC finalization process'.
|
||||||
|
].
|
||||||
}
|
}
|
||||||
|
|
||||||
method(#class,#primitive) _popCollectable.
|
method(#class,#primitive) _popCollectable.
|
||||||
|
260
moo/lib/exec.c
260
moo/lib/exec.c
@ -153,7 +153,18 @@ static MOO_INLINE void vm_muxwait (moo_t* moo, const moo_ntime_t* dur)
|
|||||||
static moo_oop_process_t make_process (moo_t* moo, moo_oop_context_t c)
|
static moo_oop_process_t make_process (moo_t* moo, moo_oop_context_t c)
|
||||||
{
|
{
|
||||||
moo_oop_process_t proc;
|
moo_oop_process_t proc;
|
||||||
|
moo_ooi_t total_count;
|
||||||
|
moo_ooi_t suspended_count;
|
||||||
|
|
||||||
|
total_count = MOO_OOP_TO_SMOOI(moo->processor->total_count);
|
||||||
|
if (total_count >= MOO_SMOOI_MAX)
|
||||||
|
{
|
||||||
|
#if defined(MOO_DEBUG_VM_PROCESSOR)
|
||||||
|
MOO_LOG0 (moo, MOO_LOG_IC | MOO_LOG_FATAL, "Processor - too many processes\n");
|
||||||
|
#endif
|
||||||
|
moo_seterrnum (moo, MOO_EPFULL);
|
||||||
|
return MOO_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
moo_pushtmp (moo, (moo_oop_t*)&c);
|
moo_pushtmp (moo, (moo_oop_t*)&c);
|
||||||
proc = (moo_oop_process_t)moo_instantiate (moo, moo->_process, MOO_NULL, moo->option.dfl_procstk_size);
|
proc = (moo_oop_process_t)moo_instantiate (moo, moo->_process, MOO_NULL, moo->option.dfl_procstk_size);
|
||||||
@ -181,6 +192,15 @@ static moo_oop_process_t make_process (moo_t* moo, moo_oop_context_t c)
|
|||||||
MOO_LOG2 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Processor - made process %O of size %zu\n", proc, MOO_OBJ_GET_SIZE(proc));
|
MOO_LOG2 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Processor - made process %O of size %zu\n", proc, MOO_OBJ_GET_SIZE(proc));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* a process is created in the SUSPENDED state. chain it to the suspended process list */
|
||||||
|
suspended_count = MOO_OOP_TO_SMOOI(moo->processor->suspended.count);
|
||||||
|
MOO_APPEND_TO_OOP_LIST (moo, &moo->processor->suspended, moo_oop_process_t, proc, ps);
|
||||||
|
suspended_count++;
|
||||||
|
moo->processor->suspended.count = MOO_SMOOI_TO_OOP(suspended_count);
|
||||||
|
|
||||||
|
total_count++;
|
||||||
|
moo->processor->total_count = MOO_SMOOI_TO_OOP(total_count);
|
||||||
|
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +219,7 @@ static MOO_INLINE void sleep_active_process (moo_t* moo, int state)
|
|||||||
moo->processor->active->state = MOO_SMOOI_TO_OOP(state);
|
moo->processor->active->state = MOO_SMOOI_TO_OOP(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOO_INLINE void wake_new_process (moo_t* moo, moo_oop_process_t proc)
|
static MOO_INLINE void wake_process (moo_t* moo, moo_oop_process_t proc)
|
||||||
{
|
{
|
||||||
/* activate the given process */
|
/* activate the given process */
|
||||||
proc->state = MOO_SMOOI_TO_OOP(PROC_STATE_RUNNING);
|
proc->state = MOO_SMOOI_TO_OOP(PROC_STATE_RUNNING);
|
||||||
@ -211,7 +231,7 @@ static MOO_INLINE void wake_new_process (moo_t* moo, moo_oop_process_t proc)
|
|||||||
SWITCH_ACTIVE_CONTEXT (moo, proc->current_context);
|
SWITCH_ACTIVE_CONTEXT (moo, proc->current_context);
|
||||||
|
|
||||||
#if defined(MOO_DEBUG_VM_PROCESSOR)
|
#if defined(MOO_DEBUG_VM_PROCESSOR)
|
||||||
MOO_LOG3 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Processor - woke up process %O context %O ip=%zd\n", moo->processor->active, moo->active_context, moo->ip);
|
MOO_LOG3 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Processor - woke up process [%zd] context %O ip=%zd\n", MOO_OOP_TO_SMOOI(moo->processor->active->id), moo->active_context, moo->ip);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,11 +245,18 @@ static void switch_to_process (moo_t* moo, moo_oop_process_t proc, int new_state
|
|||||||
proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_WAITING));
|
proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_WAITING));
|
||||||
|
|
||||||
sleep_active_process (moo, new_state_for_old_active);
|
sleep_active_process (moo, new_state_for_old_active);
|
||||||
wake_new_process (moo, proc);
|
wake_process (moo, proc);
|
||||||
|
|
||||||
moo->proc_switched = 1;
|
moo->proc_switched = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MOO_INLINE void switch_to_process_from_nil (moo_t* moo, moo_oop_process_t proc)
|
||||||
|
{
|
||||||
|
MOO_ASSERT (moo, moo->processor->active == moo->nil_process);
|
||||||
|
wake_process (moo, proc);
|
||||||
|
moo->proc_switched = 1;
|
||||||
|
}
|
||||||
|
|
||||||
static MOO_INLINE moo_oop_process_t find_next_runnable_process (moo_t* moo)
|
static MOO_INLINE moo_oop_process_t find_next_runnable_process (moo_t* moo)
|
||||||
{
|
{
|
||||||
moo_oop_process_t nrp;
|
moo_oop_process_t nrp;
|
||||||
@ -248,52 +275,41 @@ static MOO_INLINE void switch_to_next_runnable_process (moo_t* moo)
|
|||||||
if (nrp != moo->processor->active) switch_to_process (moo, nrp, PROC_STATE_RUNNABLE);
|
if (nrp != moo->processor->active) switch_to_process (moo, nrp, PROC_STATE_RUNNABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOO_INLINE int chain_into_processor (moo_t* moo, moo_oop_process_t proc)
|
static MOO_INLINE void chain_into_processor (moo_t* moo, moo_oop_process_t proc, int new_state)
|
||||||
{
|
{
|
||||||
/* the process is not scheduled at all.
|
/* the process is not scheduled at all.
|
||||||
* link it to the processor's process list. */
|
* link it to the processor's process list. */
|
||||||
moo_ooi_t runnable_count;
|
moo_ooi_t runnable_count;
|
||||||
|
moo_ooi_t suspended_count;
|
||||||
|
|
||||||
/*MOO_ASSERT (moo, (moo_oop_t)proc->ps.prev == moo->_nil);
|
/*MOO_ASSERT (moo, (moo_oop_t)proc->ps.prev == moo->_nil);
|
||||||
MOO_ASSERT (moo, (moo_oop_t)proc->ps.next == moo->_nil);*/
|
MOO_ASSERT (moo, (moo_oop_t)proc->ps.next == moo->_nil);*/
|
||||||
|
|
||||||
MOO_ASSERT (moo, proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_SUSPENDED));
|
MOO_ASSERT (moo, proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_SUSPENDED));
|
||||||
|
MOO_ASSERT (moo, new_state == PROC_STATE_RUNNABLE || new_state == PROC_STATE_RUNNING);
|
||||||
|
|
||||||
runnable_count = MOO_OOP_TO_SMOOI(moo->processor->runnable.count);
|
runnable_count = MOO_OOP_TO_SMOOI(moo->processor->runnable.count);
|
||||||
|
|
||||||
MOO_ASSERT (moo, runnable_count >= 0);
|
MOO_ASSERT (moo, runnable_count >= 0);
|
||||||
if (runnable_count >= MOO_SMOOI_MAX)
|
|
||||||
{
|
|
||||||
#if defined(MOO_DEBUG_VM_PROCESSOR)
|
|
||||||
MOO_LOG0 (moo, MOO_LOG_IC | MOO_LOG_FATAL, "Processor - too many processes\n");
|
|
||||||
#endif
|
|
||||||
moo_seterrnum (moo, MOO_EPFULL);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((moo_oop_t)proc->ps.next != moo->_nil || (moo_oop_t)proc->ps.prev != moo->_nil || proc == moo->processor->suspended.first)
|
|
||||||
{
|
|
||||||
moo_ooi_t suspended_count;
|
|
||||||
|
|
||||||
suspended_count = MOO_OOP_TO_SMOOI(moo->processor->suspended.count);
|
suspended_count = MOO_OOP_TO_SMOOI(moo->processor->suspended.count);
|
||||||
MOO_DELETE_FROM_OOP_LIST (moo, &moo->processor->suspended, proc, ps);
|
MOO_DELETE_FROM_OOP_LIST (moo, &moo->processor->suspended, proc, ps);
|
||||||
|
|
||||||
suspended_count--;
|
suspended_count--;
|
||||||
moo->processor->suspended.count = MOO_SMOOI_TO_OOP(suspended_count);
|
moo->processor->suspended.count = MOO_SMOOI_TO_OOP(suspended_count);
|
||||||
}
|
|
||||||
|
|
||||||
/* append to the runnable list */
|
/* append to the runnable list */
|
||||||
MOO_APPEND_TO_OOP_LIST (moo, &moo->processor->runnable, moo_oop_process_t, proc, ps);
|
MOO_APPEND_TO_OOP_LIST (moo, &moo->processor->runnable, moo_oop_process_t, proc, ps);
|
||||||
|
proc->state = MOO_SMOOI_TO_OOP(new_state);
|
||||||
|
|
||||||
runnable_count++;
|
runnable_count++;
|
||||||
moo->processor->runnable.count = MOO_SMOOI_TO_OOP(runnable_count);
|
moo->processor->runnable.count = MOO_SMOOI_TO_OOP(runnable_count);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOO_INLINE void unchain_from_processor (moo_t* moo, moo_oop_process_t proc, int state)
|
static MOO_INLINE void unchain_from_processor (moo_t* moo, moo_oop_process_t proc, int new_state)
|
||||||
{
|
{
|
||||||
moo_ooi_t runnable_count;
|
moo_ooi_t runnable_count;
|
||||||
|
moo_ooi_t suspended_count;
|
||||||
|
moo_ooi_t total_count;
|
||||||
|
|
||||||
/* the processor's process chain must be composed of running/runnable
|
/* the processor's process chain must be composed of running/runnable
|
||||||
* processes only */
|
* processes only */
|
||||||
@ -305,26 +321,28 @@ static MOO_INLINE void unchain_from_processor (moo_t* moo, moo_oop_process_t pro
|
|||||||
|
|
||||||
MOO_DELETE_FROM_OOP_LIST (moo, &moo->processor->runnable, proc, ps);
|
MOO_DELETE_FROM_OOP_LIST (moo, &moo->processor->runnable, proc, ps);
|
||||||
|
|
||||||
if (state != PROC_STATE_TERMINATED)
|
if (new_state == PROC_STATE_TERMINATED)
|
||||||
{
|
{
|
||||||
moo_ooi_t suspended_count;
|
/* do not chain it to the suspended process list as it's being terminated */
|
||||||
|
proc->ps.prev = (moo_oop_process_t)moo->_nil;
|
||||||
|
proc->ps.next = (moo_oop_process_t)moo->_nil;
|
||||||
|
|
||||||
suspended_count = MOO_OOP_TO_SMOOI(moo->processor->suspended.count);
|
total_count = MOO_OOP_TO_SMOOI(moo->processor->total_count);
|
||||||
|
total_count--;
|
||||||
/* append to the suspended list */
|
moo->processor->total_count = MOO_SMOOI_TO_OOP(total_count);
|
||||||
MOO_APPEND_TO_OOP_LIST (moo, &moo->processor->suspended, moo_oop_process_t, proc, ps);
|
|
||||||
|
|
||||||
|
|
||||||
suspended_count++;
|
|
||||||
moo->processor->suspended.count= MOO_SMOOI_TO_OOP(suspended_count);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
proc->ps.prev = (moo_oop_process_t)moo->_nil;
|
/* append to the suspended process list */
|
||||||
proc->ps.next = (moo_oop_process_t)moo->_nil;
|
MOO_ASSERT (moo, new_state == PROC_STATE_SUSPENDED);
|
||||||
|
|
||||||
|
suspended_count = MOO_OOP_TO_SMOOI(moo->processor->suspended.count);
|
||||||
|
MOO_APPEND_TO_OOP_LIST (moo, &moo->processor->suspended, moo_oop_process_t, proc, ps);
|
||||||
|
suspended_count++;
|
||||||
|
moo->processor->suspended.count= MOO_SMOOI_TO_OOP(suspended_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
proc->state = MOO_SMOOI_TO_OOP(state);
|
proc->state = MOO_SMOOI_TO_OOP(new_state);
|
||||||
|
|
||||||
runnable_count--;
|
runnable_count--;
|
||||||
if (runnable_count == 0) moo->processor->active = moo->nil_process;
|
if (runnable_count == 0) moo->processor->active = moo->nil_process;
|
||||||
@ -366,7 +384,7 @@ static void terminate_process (moo_t* moo, moo_oop_process_t proc)
|
|||||||
/* RUNNING/RUNNABLE ---> TERMINATED */
|
/* RUNNING/RUNNABLE ---> TERMINATED */
|
||||||
|
|
||||||
#if defined(MOO_DEBUG_VM_PROCESSOR)
|
#if defined(MOO_DEBUG_VM_PROCESSOR)
|
||||||
MOO_LOG1 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Processor - process %O RUNNING/RUNNABLE->TERMINATED\n", proc);
|
MOO_LOG1 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Processor - process [%zd] RUNNING/RUNNABLE->TERMINATED\n", MOO_OOP_TO_SMOOI(proc->id));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (proc == moo->processor->active)
|
if (proc == moo->processor->active)
|
||||||
@ -387,7 +405,7 @@ static void terminate_process (moo_t* moo, moo_oop_process_t proc)
|
|||||||
{
|
{
|
||||||
/* no runnable process after termination */
|
/* no runnable process after termination */
|
||||||
MOO_ASSERT (moo, moo->processor->active == moo->nil_process);
|
MOO_ASSERT (moo, moo->processor->active == moo->nil_process);
|
||||||
MOO_LOG0 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "No runnable process after process termination\n");
|
MOO_LOG1 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "No runnable process after termination - process %zd\n", MOO_OOP_TO_SMOOI(proc->id));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -404,10 +422,11 @@ static void terminate_process (moo_t* moo, moo_oop_process_t proc)
|
|||||||
{
|
{
|
||||||
/* SUSPENDED ---> TERMINATED */
|
/* SUSPENDED ---> TERMINATED */
|
||||||
#if defined(MOO_DEBUG_VM_PROCESSOR)
|
#if defined(MOO_DEBUG_VM_PROCESSOR)
|
||||||
MOO_LOG1 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Processor - process %O SUSPENDED->TERMINATED\n", proc);
|
MOO_LOG1 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Processor - process [%zd] SUSPENDED->TERMINATED\n", MOO_OOP_TO_SMOOI(proc->id));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
proc->state = MOO_SMOOI_TO_OOP(PROC_STATE_TERMINATED);
|
/*proc->state = MOO_SMOOI_TO_OOP(PROC_STATE_TERMINATED);*/
|
||||||
|
unchain_from_processor (moo, proc, PROC_STATE_TERMINATED);
|
||||||
proc->sp = MOO_SMOOI_TO_OOP(-1); /* invalidate the proce stack */
|
proc->sp = MOO_SMOOI_TO_OOP(-1); /* invalidate the proce stack */
|
||||||
|
|
||||||
if ((moo_oop_t)proc->sem != moo->_nil)
|
if ((moo_oop_t)proc->sem != moo->_nil)
|
||||||
@ -415,11 +434,13 @@ static void terminate_process (moo_t* moo, moo_oop_process_t proc)
|
|||||||
unchain_from_semaphore (moo, proc);
|
unchain_from_semaphore (moo, proc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
else if (proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_WAITING))
|
else if (proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_WAITING))
|
||||||
{
|
{
|
||||||
/* WAITING ---> TERMINATED */
|
/* WAITING ---> TERMINATED */
|
||||||
/* TODO: */
|
/* TODO: */
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void resume_process (moo_t* moo, moo_oop_process_t proc)
|
static void resume_process (moo_t* moo, moo_oop_process_t proc)
|
||||||
@ -431,15 +452,13 @@ static void resume_process (moo_t* moo, moo_oop_process_t proc)
|
|||||||
MOO_ASSERT (moo, (moo_oop_t)proc->ps.next == moo->_nil);*/
|
MOO_ASSERT (moo, (moo_oop_t)proc->ps.next == moo->_nil);*/
|
||||||
|
|
||||||
#if defined(MOO_DEBUG_VM_PROCESSOR)
|
#if defined(MOO_DEBUG_VM_PROCESSOR)
|
||||||
MOO_LOG1 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Processor - process %O SUSPENDED->RUNNING\n", proc);
|
MOO_LOG1 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Processor - process [%zd] SUSPENDED->RUNNING\n", MOO_OOP_TO_SMOOI(proc->id));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
chain_into_processor (moo, proc); /* TODO: error check */
|
/* don't switch to this process. just change the state to RUNNABLE.
|
||||||
|
* process switching should be triggerd by the process scheduler. */
|
||||||
|
chain_into_processor (moo, proc, PROC_STATE_RUNNABLE);
|
||||||
/*proc->current_context = proc->initial_context;*/
|
/*proc->current_context = proc->initial_context;*/
|
||||||
proc->state = MOO_SMOOI_TO_OOP(PROC_STATE_RUNNABLE);
|
|
||||||
|
|
||||||
/* don't switch to this process. just set the state to RUNNING */
|
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
else if (proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_RUNNABLE))
|
else if (proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_RUNNABLE))
|
||||||
@ -482,13 +501,15 @@ static void suspend_process (moo_t* moo, moo_oop_process_t proc)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* keep the unchained process at the runnable state for
|
/* unchain_from_processor moves the process to the suspended
|
||||||
* the immediate call to switch_to_process() below */
|
* process and sets its state to the given state(SUSPENDED here).
|
||||||
unchain_from_processor (moo, proc, PROC_STATE_RUNNABLE);
|
* it doesn't change the active process. we switch the active
|
||||||
/* unchain_from_processor() leaves the active process
|
* process with switch_to_process(). setting the state of the
|
||||||
* untouched unless the unchained process is the last
|
* old active process to SUSPENDED is redundant because it's
|
||||||
* running/runnable process. so calling switch_to_process()
|
* done in unchain_from_processor(). the state of the active
|
||||||
* which expects the active process to be valid is safe */
|
* process is somewhat wrong for a short period of time until
|
||||||
|
* switch_to_process() has changed the active process. */
|
||||||
|
unchain_from_processor (moo, proc, PROC_STATE_SUSPENDED);
|
||||||
MOO_ASSERT (moo, moo->processor->active != moo->nil_process);
|
MOO_ASSERT (moo, moo->processor->active != moo->nil_process);
|
||||||
switch_to_process (moo, nrp, PROC_STATE_SUSPENDED);
|
switch_to_process (moo, nrp, PROC_STATE_SUSPENDED);
|
||||||
}
|
}
|
||||||
@ -516,7 +537,7 @@ static void yield_process (moo_t* moo, moo_oop_process_t proc)
|
|||||||
if (nrp != proc)
|
if (nrp != proc)
|
||||||
{
|
{
|
||||||
#if defined(MOO_DEBUG_VM_PROCESSOR)
|
#if defined(MOO_DEBUG_VM_PROCESSOR)
|
||||||
MOO_LOG1 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Processor - process %O RUNNING->RUNNABLE\n", proc);
|
MOO_LOG1 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Processor - process [%zd] RUNNING->RUNNABLE\n", MOO_OOP_TO_SMOOI(proc->id));
|
||||||
#endif
|
#endif
|
||||||
switch_to_process (moo, nrp, PROC_STATE_RUNNABLE);
|
switch_to_process (moo, nrp, PROC_STATE_RUNNABLE);
|
||||||
}
|
}
|
||||||
@ -573,7 +594,7 @@ static moo_oop_process_t signal_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
|
|||||||
/* detach a process from a semaphore's waiting list and
|
/* detach a process from a semaphore's waiting list and
|
||||||
* make it runnable */
|
* make it runnable */
|
||||||
unchain_from_semaphore (moo, proc);
|
unchain_from_semaphore (moo, proc);
|
||||||
resume_process (moo, proc); /* TODO: error check */
|
resume_process (moo, proc);
|
||||||
|
|
||||||
if (MOO_OOP_TO_SMOOI(sem->io_index) >= 0) moo->sem_io_wait_count--;
|
if (MOO_OOP_TO_SMOOI(sem->io_index) >= 0) moo->sem_io_wait_count--;
|
||||||
|
|
||||||
@ -893,14 +914,18 @@ static void signal_io_semaphore (moo_t* moo, moo_ooi_t mask, void* ctx)
|
|||||||
{
|
{
|
||||||
/* this is the only runnable process.
|
/* this is the only runnable process.
|
||||||
* switch the process to the running state.
|
* switch the process to the running state.
|
||||||
* it uses wake_new_process() instead of
|
* it uses wake_process() instead of
|
||||||
* switch_to_process() as there is no running
|
* switch_to_process() as there is no running
|
||||||
* process at this moment */
|
* process at this moment */
|
||||||
MOO_ASSERT (moo, proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_RUNNABLE));
|
MOO_ASSERT (moo, proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_RUNNABLE));
|
||||||
MOO_ASSERT (moo, proc == moo->processor->runnable.first);
|
MOO_ASSERT (moo, proc == moo->processor->runnable.first);
|
||||||
|
|
||||||
wake_new_process (moo, proc); /* switch to running */
|
#if 0
|
||||||
|
wake_process (moo, proc); /* switch to running */
|
||||||
moo->proc_switched = 1;
|
moo->proc_switched = 1;
|
||||||
|
#else
|
||||||
|
switch_to_process_from_nil (moo, proc);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -922,8 +947,7 @@ static moo_oop_process_t start_initial_process (moo_t* moo, moo_oop_context_t c)
|
|||||||
proc = make_process (moo, c);
|
proc = make_process (moo, c);
|
||||||
if (!proc) return MOO_NULL;
|
if (!proc) return MOO_NULL;
|
||||||
|
|
||||||
if (chain_into_processor (moo, proc) <= -1) return MOO_NULL;
|
chain_into_processor (moo, proc, PROC_STATE_RUNNING);
|
||||||
proc->state = MOO_SMOOI_TO_OOP(PROC_STATE_RUNNING); /* skip RUNNABLE and go to RUNNING */
|
|
||||||
moo->processor->active = proc;
|
moo->processor->active = proc;
|
||||||
|
|
||||||
/* do somthing that resume_process() would do with less overhead */
|
/* do somthing that resume_process() would do with less overhead */
|
||||||
@ -1160,7 +1184,6 @@ static int start_initial_process_and_context (moo_t* moo, const moo_oocs_t* objn
|
|||||||
|
|
||||||
#if defined(INVOKE_DIRECTLY)
|
#if defined(INVOKE_DIRECTLY)
|
||||||
|
|
||||||
|
|
||||||
ass = moo_lookupsysdic (moo, objname);
|
ass = moo_lookupsysdic (moo, objname);
|
||||||
if (!ass || MOO_CLASSOF(moo, ass->value) != moo->_class)
|
if (!ass || MOO_CLASSOF(moo, ass->value) != moo->_class)
|
||||||
{
|
{
|
||||||
@ -1196,43 +1219,31 @@ TODO: overcome this problem - accept parameters....
|
|||||||
if (!mth)
|
if (!mth)
|
||||||
{
|
{
|
||||||
MOO_DEBUG0 (moo, "Cannot find the startup method in the system class");
|
MOO_DEBUG0 (moo, "Cannot find the startup method in the system class");
|
||||||
return -1;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MOO_OOP_TO_SMOOI(mth->tmpr_nargs) != 2)
|
if (MOO_OOP_TO_SMOOI(mth->tmpr_nargs) != 2)
|
||||||
{
|
{
|
||||||
MOO_DEBUG1 (moo, "Weird argument count %zd for a startup method - should be 2", MOO_OOP_TO_SMOOI(mth->tmpr_nargs));
|
MOO_DEBUG1 (moo, "Weird argument count %zd for a startup method - should be 2", MOO_OOP_TO_SMOOI(mth->tmpr_nargs));
|
||||||
moo_seterrnum (moo, MOO_EINVAL);
|
moo_seterrnum (moo, MOO_EINVAL);
|
||||||
return -1;
|
goto oops;
|
||||||
}
|
}
|
||||||
/* TODO: check if it's variadic.... it should be. and accept more than 2... */
|
/* TODO: check if it's variadic.... it should be. and accept more than 2... */
|
||||||
|
|
||||||
moo_pushtmp (moo, (moo_oop_t*)&mth); tmp_count++;
|
moo_pushtmp (moo, (moo_oop_t*)&mth); tmp_count++;
|
||||||
s1 = moo_makesymbol (moo, objname->ptr, objname->len);
|
s1 = moo_makesymbol (moo, objname->ptr, objname->len);
|
||||||
if (!s1)
|
if (!s1) goto oops;
|
||||||
{
|
|
||||||
moo_poptmps (moo, tmp_count);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
moo_pushtmp (moo, (moo_oop_t*)&s1);
|
moo_pushtmp (moo, (moo_oop_t*)&s1);
|
||||||
s2 = moo_makesymbol (moo, mthname->ptr, mthname->len);
|
s2 = moo_makesymbol (moo, mthname->ptr, mthname->len);
|
||||||
if (!s2)
|
if (!s2) goto oops;
|
||||||
{
|
|
||||||
moo_poptmps (moo, tmp_count);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
moo_pushtmp (moo, (moo_oop_t*)&s2);
|
moo_pushtmp (moo, (moo_oop_t*)&s2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* create a fake initial context. */
|
/* create a fake initial context. */
|
||||||
ctx = (moo_oop_context_t)moo_instantiate (moo, moo->_method_context, MOO_NULL, MOO_OOP_TO_SMOOI(mth->tmpr_nargs));
|
ctx = (moo_oop_context_t)moo_instantiate (moo, moo->_method_context, MOO_NULL, MOO_OOP_TO_SMOOI(mth->tmpr_nargs));
|
||||||
if (!ctx)
|
if (!ctx) goto oops;
|
||||||
{
|
|
||||||
moo_poptmps (moo, tmp_count);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
moo_pushtmp (moo, (moo_oop_t*)&ctx); tmp_count++;
|
moo_pushtmp (moo, (moo_oop_t*)&ctx); tmp_count++;
|
||||||
|
|
||||||
@ -1272,7 +1283,7 @@ TODO: overcome this problem - accept parameters....
|
|||||||
|
|
||||||
proc = start_initial_process (moo, ctx);
|
proc = start_initial_process (moo, ctx);
|
||||||
moo_poptmps (moo, tmp_count); tmp_count = 0;
|
moo_poptmps (moo, tmp_count); tmp_count = 0;
|
||||||
if (!proc) return -1;
|
if (!proc) goto oops;
|
||||||
|
|
||||||
#if defined(INVOKE_DIRECTLY)
|
#if defined(INVOKE_DIRECTLY)
|
||||||
MOO_STACK_PUSH (moo, ass->value); /* push the receiver - the object referenced by 'objname' */
|
MOO_STACK_PUSH (moo, ass->value); /* push the receiver - the object referenced by 'objname' */
|
||||||
@ -1294,6 +1305,10 @@ TODO: overcome this problem - accept parameters....
|
|||||||
#else
|
#else
|
||||||
return activate_new_method (moo, mth, 2);
|
return activate_new_method (moo, mth, 2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
oops:
|
||||||
|
if (tmp_count > 0) moo_poptmps (moo, tmp_count);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
@ -2146,7 +2161,7 @@ static moo_pfrc_t pf_process_resume (moo_t* moo, moo_ooi_t nargs)
|
|||||||
return MOO_PF_FAILURE;
|
return MOO_PF_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
resume_process (moo, (moo_oop_process_t)rcv); /* TODO: error check */
|
resume_process (moo, (moo_oop_process_t)rcv);
|
||||||
|
|
||||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
@ -2256,7 +2271,36 @@ static moo_pfrc_t pf_processor_schedule (moo_t* moo, moo_ooi_t nargs)
|
|||||||
return MOO_PF_FAILURE;
|
return MOO_PF_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
resume_process (moo, (moo_oop_process_t)arg); /* TODO: error check */
|
resume_process (moo, (moo_oop_process_t)arg);
|
||||||
|
return MOO_PF_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static moo_pfrc_t pf_processor_add_gcfin_semaphore (moo_t* moo, moo_ooi_t nargs)
|
||||||
|
{
|
||||||
|
moo_oop_t rcv;
|
||||||
|
moo_oop_semaphore_t sem;
|
||||||
|
|
||||||
|
MOO_ASSERT (moo, nargs == 1);
|
||||||
|
|
||||||
|
sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0);
|
||||||
|
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||||
|
|
||||||
|
if (rcv != (moo_oop_t)moo->processor)
|
||||||
|
{
|
||||||
|
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EMSGRCV);
|
||||||
|
return MOO_PF_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MOO_CLASSOF(moo,sem) != moo->_semaphore)
|
||||||
|
{
|
||||||
|
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
||||||
|
return MOO_PF_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: no overwriting.. */
|
||||||
|
moo->sem_gcfin = sem;
|
||||||
|
|
||||||
|
MOO_STACK_SETRETTORCV (moo, nargs); /* ^self */
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2414,7 +2458,7 @@ static moo_pfrc_t pf_processor_remove_semaphore (moo_t* moo, moo_ooi_t nargs)
|
|||||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||||
|
|
||||||
/* TODO: remove a semaphore from IO handler if it's registered...
|
/* TODO: remove a semaphore from IO handler if it's registered...
|
||||||
* remove a semaphore from XXXXXXXXXXXXXX */
|
* remove a semaphore from elsewhere registered too */
|
||||||
|
|
||||||
if (rcv != (moo_oop_t)moo->processor)
|
if (rcv != (moo_oop_t)moo->processor)
|
||||||
{
|
{
|
||||||
@ -2428,6 +2472,11 @@ static moo_pfrc_t pf_processor_remove_semaphore (moo_t* moo, moo_ooi_t nargs)
|
|||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sem == moo->sem_gcfin)
|
||||||
|
{
|
||||||
|
moo->sem_gcfin = (moo_oop_semaphore_t)moo->_nil;
|
||||||
|
}
|
||||||
|
|
||||||
if (MOO_OOP_IS_SMOOI(sem->heap_index) &&
|
if (MOO_OOP_IS_SMOOI(sem->heap_index) &&
|
||||||
sem->heap_index != MOO_SMOOI_TO_OOP(-1))
|
sem->heap_index != MOO_SMOOI_TO_OOP(-1))
|
||||||
{
|
{
|
||||||
@ -3875,14 +3924,14 @@ static pf_t pftab[] =
|
|||||||
{ "_block_value", { pf_block_value, 0, MA } },
|
{ "_block_value", { pf_block_value, 0, MA } },
|
||||||
{ "_block_new_process", { pf_block_new_process, 0, 1 } },
|
{ "_block_new_process", { pf_block_new_process, 0, 1 } },
|
||||||
|
|
||||||
|
{ "_processor_add_gcfin_semaphore", { pf_processor_add_gcfin_semaphore, 1, 1 } },
|
||||||
{ "_processor_schedule", { pf_processor_schedule, 1, 1 } },
|
|
||||||
{ "_processor_add_timed_semaphore", { pf_processor_add_timed_semaphore, 2, 3 } },
|
|
||||||
{ "_processor_add_input_semaphore", { pf_processor_add_input_semaphore, 2, 2 } },
|
{ "_processor_add_input_semaphore", { pf_processor_add_input_semaphore, 2, 2 } },
|
||||||
{ "_processor_add_output_semaphore", { pf_processor_add_output_semaphore, 2, 2 } },
|
|
||||||
{ "_processor_add_inoutput_semaphore", { pf_processor_add_inoutput_semaphore, 2, 2 } },
|
{ "_processor_add_inoutput_semaphore", { pf_processor_add_inoutput_semaphore, 2, 2 } },
|
||||||
|
{ "_processor_add_output_semaphore", { pf_processor_add_output_semaphore, 2, 2 } },
|
||||||
|
{ "_processor_add_timed_semaphore", { pf_processor_add_timed_semaphore, 2, 3 } },
|
||||||
{ "_processor_remove_semaphore", { pf_processor_remove_semaphore, 1, 1 } },
|
{ "_processor_remove_semaphore", { pf_processor_remove_semaphore, 1, 1 } },
|
||||||
{ "_processor_return_to", { pf_processor_return_to, 2, 2 } },
|
{ "_processor_return_to", { pf_processor_return_to, 2, 2 } },
|
||||||
|
{ "_processor_schedule", { pf_processor_schedule, 1, 1 } },
|
||||||
|
|
||||||
{ "_integer_add", { pf_integer_add, 1, 1 } },
|
{ "_integer_add", { pf_integer_add, 1, 1 } },
|
||||||
{ "_integer_sub", { pf_integer_sub, 1, 1 } },
|
{ "_integer_sub", { pf_integer_sub, 1, 1 } },
|
||||||
@ -4449,7 +4498,7 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo)
|
|||||||
proc = signal_semaphore (moo, moo->sem_heap[0]);
|
proc = signal_semaphore (moo, moo->sem_heap[0]);
|
||||||
/* [NOTE] no moo_pushtmp() on proc. no GC must occur
|
/* [NOTE] no moo_pushtmp() on proc. no GC must occur
|
||||||
* in the following line until it's used for
|
* in the following line until it's used for
|
||||||
* wake_new_process() below. */
|
* wake_process() below. */
|
||||||
delete_from_sem_heap (moo, 0); /* moo->sem_heap_count is decremented */
|
delete_from_sem_heap (moo, 0); /* moo->sem_heap_count is decremented */
|
||||||
|
|
||||||
/* if no process is waiting on the semaphore,
|
/* if no process is waiting on the semaphore,
|
||||||
@ -4459,14 +4508,17 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo)
|
|||||||
{
|
{
|
||||||
/* this is the only runnable process.
|
/* this is the only runnable process.
|
||||||
* switch the process to the running state.
|
* switch the process to the running state.
|
||||||
* it uses wake_new_process() instead of
|
* it uses wake_process() instead of
|
||||||
* switch_to_process() as there is no running
|
* switch_to_process() as there is no running
|
||||||
* process at this moment */
|
* process at this moment */
|
||||||
MOO_ASSERT (moo, proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_RUNNABLE));
|
MOO_ASSERT (moo, proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_RUNNABLE));
|
||||||
MOO_ASSERT (moo, proc == moo->processor->runnable.first);
|
MOO_ASSERT (moo, proc == moo->processor->runnable.first);
|
||||||
|
#if 0
|
||||||
wake_new_process (moo, proc); /* switch to running */
|
wake_process (moo, proc); /* switch to running */
|
||||||
moo->proc_switched = 1;
|
moo->proc_switched = 1;
|
||||||
|
#else
|
||||||
|
switch_to_process_from_nil (moo, proc);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (moo->processor->active == moo->nil_process)
|
else if (moo->processor->active == moo->nil_process)
|
||||||
@ -4482,7 +4534,7 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo)
|
|||||||
/* exit early if a process has been woken up.
|
/* exit early if a process has been woken up.
|
||||||
* the break in the else part further down will get hit
|
* the break in the else part further down will get hit
|
||||||
* eventually even if the following line doesn't exist.
|
* eventually even if the following line doesn't exist.
|
||||||
* having the following line causes to skip fireing the
|
* having the following line causes to skip firing the
|
||||||
* timed semaphore that would expire between now and the
|
* timed semaphore that would expire between now and the
|
||||||
* moment the next inspection occurs. */
|
* moment the next inspection occurs. */
|
||||||
if (moo->processor->active != moo->nil_process) goto finalization;
|
if (moo->processor->active != moo->nil_process) goto finalization;
|
||||||
@ -4524,6 +4576,38 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (moo->sem_gcfin_sigreq)
|
||||||
|
{
|
||||||
|
if ((moo_oop_t)moo->sem_gcfin != moo->_nil)
|
||||||
|
{
|
||||||
|
moo_oop_process_t proc;
|
||||||
|
MOO_LOG0 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Signalled GCFIN semaphore\n");
|
||||||
|
proc = signal_semaphore (moo, moo->sem_gcfin);
|
||||||
|
|
||||||
|
if (moo->processor->active == moo->nil_process && (moo_oop_t)proc != moo->_nil)
|
||||||
|
{
|
||||||
|
MOO_ASSERT (moo, proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_RUNNABLE));
|
||||||
|
MOO_ASSERT (moo, proc == moo->processor->runnable.first);
|
||||||
|
switch_to_process_from_nil (moo, proc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
moo->sem_gcfin_sigreq = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((moo_oop_t)moo->sem_gcfin != moo->_nil && moo->processor->active == moo->nil_process)
|
||||||
|
{
|
||||||
|
moo_oop_process_t proc;
|
||||||
|
proc = signal_semaphore (moo, moo->sem_gcfin);
|
||||||
|
if ((moo_oop_t)proc != moo->_nil)
|
||||||
|
{
|
||||||
|
MOO_ASSERT (moo, proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_RUNNABLE));
|
||||||
|
MOO_ASSERT (moo, proc == moo->processor->runnable.first);
|
||||||
|
switch_to_process_from_nil (moo, proc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (moo->processor->active == moo->nil_process)
|
if (moo->processor->active == moo->nil_process)
|
||||||
{
|
{
|
||||||
/* no more waiting semaphore and no more process */
|
/* no more waiting semaphore and no more process */
|
||||||
|
@ -291,6 +291,7 @@ static int ignite_2 (moo_t* moo)
|
|||||||
if (!tmp) return -1;
|
if (!tmp) return -1;
|
||||||
moo->processor = (moo_oop_process_scheduler_t)tmp;
|
moo->processor = (moo_oop_process_scheduler_t)tmp;
|
||||||
moo->processor->active = moo->nil_process;
|
moo->processor->active = moo->nil_process;
|
||||||
|
moo->processor->total_count = MOO_SMOOI_TO_OOP(0);
|
||||||
moo->processor->runnable.count = MOO_SMOOI_TO_OOP(0);
|
moo->processor->runnable.count = MOO_SMOOI_TO_OOP(0);
|
||||||
moo->processor->suspended.count = MOO_SMOOI_TO_OOP(0);
|
moo->processor->suspended.count = MOO_SMOOI_TO_OOP(0);
|
||||||
|
|
||||||
@ -687,6 +688,8 @@ void moo_gc (moo_t* moo)
|
|||||||
moo->sem_io[i] = (moo_oop_semaphore_t)moo_moveoop (moo, (moo_oop_t)moo->sem_io[i]);
|
moo->sem_io[i] = (moo_oop_semaphore_t)moo_moveoop (moo, (moo_oop_t)moo->sem_io[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moo->sem_gcfin = (moo_oop_semaphore_t)moo_moveoop (moo, (moo_oop_t)moo->sem_gcfin);
|
||||||
|
|
||||||
for (i = 0; i < moo->tmp_count; i++)
|
for (i = 0; i < moo->tmp_count; i++)
|
||||||
{
|
{
|
||||||
*moo->tmp_stack[i] = moo_moveoop (moo, *moo->tmp_stack[i]);
|
*moo->tmp_stack[i] = moo_moveoop (moo, *moo->tmp_stack[i]);
|
||||||
@ -757,6 +760,8 @@ void moo_gc (moo_t* moo)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (moo->active_method) SET_ACTIVE_METHOD_CODE (moo); /* update moo->active_code */
|
if (moo->active_method) SET_ACTIVE_METHOD_CODE (moo); /* update moo->active_code */
|
||||||
|
/*if (moo->sem_gcfin_count > 0) signal_semaphore (moo, moo->sem_gcfin);*/
|
||||||
|
if (moo->sem_gcfin_count > 0) moo->sem_gcfin_sigreq = 1;
|
||||||
|
|
||||||
/* TODO: include some gc statstics like number of live objects, gc performance, etc */
|
/* TODO: include some gc statstics like number of live objects, gc performance, etc */
|
||||||
MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO,
|
MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO,
|
||||||
@ -877,6 +882,7 @@ static void move_finalizable_objects (moo_t* moo)
|
|||||||
{
|
{
|
||||||
moo_finalizable_t* x, * y;
|
moo_finalizable_t* x, * y;
|
||||||
|
|
||||||
|
moo->sem_gcfin_count = 0;
|
||||||
for (x = moo->collectable.first; x; x = x->next)
|
for (x = moo->collectable.first; x; x = x->next)
|
||||||
{
|
{
|
||||||
MOO_ASSERT (moo, (MOO_OBJ_GET_FLAGS_GCFIN(x->oop) & (MOO_GCFIN_FINALIZABLE | MOO_GCFIN_FINALIZED)) == MOO_GCFIN_FINALIZABLE);
|
MOO_ASSERT (moo, (MOO_OBJ_GET_FLAGS_GCFIN(x->oop) & (MOO_GCFIN_FINALIZABLE | MOO_GCFIN_FINALIZED)) == MOO_GCFIN_FINALIZABLE);
|
||||||
@ -908,8 +914,7 @@ static void move_finalizable_objects (moo_t* moo)
|
|||||||
/* add it to the collectable list */
|
/* add it to the collectable list */
|
||||||
MOO_APPEND_TO_LIST (&moo->collectable, x);
|
MOO_APPEND_TO_LIST (&moo->collectable, x);
|
||||||
|
|
||||||
// TODO: singal semaphore..
|
moo->sem_gcfin_count++;
|
||||||
//signal_semaphore (moo, moo->collectable_semaphore);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -808,13 +808,14 @@ struct moo_semaphore_t
|
|||||||
moo_oop_t io_mask; /* SmallInteger */
|
moo_oop_t io_mask; /* SmallInteger */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MOO_PROCESS_SCHEDULER_NAMED_INSTVARS 7
|
#define MOO_PROCESS_SCHEDULER_NAMED_INSTVARS 8
|
||||||
typedef struct moo_process_scheduler_t moo_process_scheduler_t;
|
typedef struct moo_process_scheduler_t moo_process_scheduler_t;
|
||||||
typedef struct moo_process_scheduler_t* moo_oop_process_scheduler_t;
|
typedef struct moo_process_scheduler_t* moo_oop_process_scheduler_t;
|
||||||
struct moo_process_scheduler_t
|
struct moo_process_scheduler_t
|
||||||
{
|
{
|
||||||
MOO_OBJ_HEADER;
|
MOO_OBJ_HEADER;
|
||||||
moo_oop_process_t active; /* pointer to an active process in the runnable process list */
|
moo_oop_process_t active; /* pointer to an active process in the runnable process list */
|
||||||
|
moo_oop_t total_count; /* SmallIntger, total number of processes - runnable/running/suspended */
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@ -825,7 +826,7 @@ struct moo_process_scheduler_t
|
|||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
moo_oop_t count; /* SmallInteger */
|
moo_oop_t count; /* SmallInteger - suspended*/
|
||||||
moo_oop_process_t first;
|
moo_oop_process_t first;
|
||||||
moo_oop_process_t last;
|
moo_oop_process_t last;
|
||||||
} suspended;
|
} suspended;
|
||||||
@ -1171,6 +1172,11 @@ struct moo_t
|
|||||||
moo_oow_t sem_io_capa;
|
moo_oow_t sem_io_capa;
|
||||||
moo_oow_t sem_io_wait_count;
|
moo_oow_t sem_io_wait_count;
|
||||||
|
|
||||||
|
/* semaphore to notify finalizable objects */
|
||||||
|
moo_oop_semaphore_t sem_gcfin;
|
||||||
|
int sem_gcfin_sigreq;
|
||||||
|
moo_oow_t sem_gcfin_count;
|
||||||
|
|
||||||
moo_oop_t* tmp_stack[256]; /* stack for temporaries */
|
moo_oop_t* tmp_stack[256]; /* stack for temporaries */
|
||||||
moo_oow_t tmp_count;
|
moo_oow_t tmp_count;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user