diff --git a/moo/kernel/Mill.moo b/moo/kernel/Mill.moo index a0cf16c..32bbddb 100644 --- a/moo/kernel/Mill.moo +++ b/moo/kernel/Mill.moo @@ -246,7 +246,7 @@ class MyObject(Object) a dump. *) '---------- END ------------' dump. - ##Processor sleepFor: 20. + ##System sleepForSecs: 20. } @@ -340,7 +340,7 @@ a getUint32(1) dump. ##System _free(a). a free. - Processor sleepFor: 2. + System sleepForSecs: 2. } (* diff --git a/moo/kernel/Process.moo b/moo/kernel/Process.moo index bb10ae2..f8978cb 100644 --- a/moo/kernel/Process.moo +++ b/moo/kernel/Process.moo @@ -138,9 +138,9 @@ TODO: how to prohibit wait and signal??? ========= CASE 1 ==================== sg := SemaphoreGroup with (xxx, yyy, zzz). - Processor signal: xxx onInput: aaa. - Processor signal: yyy onInput: bbb. - Processor signal: zzz onOutput: ccc. + System signal: xxx onInput: aaa. + System signal: yyy onInput: bbb. + System signal: zzz onOutput: ccc. while (true) { @@ -166,9 +166,9 @@ TODO: how to prohibit wait and signal??? yyy signalAction: [ ... ]. zzz signalAction: [ ... ]. - Processor signal: xxx onInput: aaa. - Processor signal: yyy onInput: bbb. - Processor signal: zzz onOutput: ccc. + System signal: xxx onInput: aaa. + System signal: yyy onInput: bbb. + System signal: zzz onOutput: ccc. while (true) @@ -252,7 +252,7 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit self addSemaphore: s. ## arrange the processor to notify upon timeout. - Processor signal: s after: seconds. + System signal: s after: seconds. ## wait on the semaphore group. r := self wait. @@ -266,7 +266,7 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit self removeSemaphore: s. ## cancel the notification arrangement in case it didn't time out. - Processor unsignal: s. + System unsignal: s. ^r. } @@ -472,79 +472,9 @@ class(#final,#limited) ProcessScheduler(Object) *) } - (* ------------------- - method yield - { - - self primitiveFailed - } - ----------------- *) - - method signal: semaphore after: secs - { - - self primitiveFailed. - } - - method signal: semaphore after: secs and: nanosecs - { - - self primitiveFailed. - } - - method unsignal: semaphore - { - - self primitiveFailed. - } - - method signalOnGCFin: semaphore - { - - self primitiveFailed. - } - - method signal: semaphore onInput: file - { - - self primitiveFailed. - } - method signal: semaphore onOutput: file - { - - self primitiveFailed. - } - method signal: semaphore onInOutput: file - { - - self primitiveFailed. - } - method return: object to: context { self primitiveFailed. } - - method sleepFor: secs - { - ## ----------------------------------------------------- - ## put the calling process to sleep for given seconds. - ## ----------------------------------------------------- - | s | - s := Semaphore new. - self signal: s after: secs. - s wait. - } - - method sleepFor: secs and: nanosecs - { - ## ----------------------------------------------------- - ## put the calling process to sleep for given seconds. - ## ----------------------------------------------------- - | s | - s := Semaphore new. - self signal: s after: secs and: nanosecs. - s wait. - } } diff --git a/moo/kernel/Socket.moo b/moo/kernel/Socket.moo index 3b53440..4f516c5 100644 --- a/moo/kernel/Socket.moo +++ b/moo/kernel/Socket.moo @@ -60,8 +60,8 @@ extend Socket s2 := Semaphore new. sa := [:sem | - Processor unsignal: s1. - Processor unsignal: s2. + System unsignal: s1. + System unsignal: s2. System removeAsyncSemaphore: s1. System removeAsyncSemaphore: s2. connectBlock value: (sem == s1) @@ -71,8 +71,8 @@ extend Socket s2 signalAction: sa. ## TODO: unsignal s1 s2, remove them from System when exception occurs. - Processor signal: s1 onOutput: self.handle. - Processor signal: s2 after: 10. + System signal: s1 onOutput: self.handle. + System signal: s2 after: 10. System addAsyncSemaphore: s1. System addAsyncSemaphore: s2. @@ -92,8 +92,8 @@ extend Socket s1 signalAction: [:sem | readBlock value: true]. s2 signalAction: [:sem | readBlock value: false]. - Processor signal: s1 onInput: self.handle. - Processor signal: s2 after: 10. + System signal: s1 onInput: self.handle. + System signal: s2 after: 10. } (* @@ -106,8 +106,8 @@ extend Socket s1 signalAction: [:sem | writeBlock value: true]. s2 signalAction: [:sem | writeBlock value: false]. - Processor signal: s1 onOutput: self.handle. - Processor signal: s2 after: 10. + System signal: s1 onOutput: self.handle. + System signal: s2 after: 10. } *) diff --git a/moo/kernel/System.moo b/moo/kernel/System.moo index 3aa94c1..acc800f 100644 --- a/moo/kernel/System.moo +++ b/moo/kernel/System.moo @@ -55,7 +55,7 @@ class System(Apex) gc := false. fin_sem := Semaphore new. - Processor signalOnGCFin: fin_sem. + self signalOnGCFin: fin_sem. [ while (true) { @@ -85,18 +85,108 @@ class System(Apex) }. ##System logNl: '^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^gc_waiting....'. - ##Processor sleepFor: 1. ## TODO: wait on semaphore instead.. + ##System sleepForSecs: 1. ## TODO: wait on semaphore instead.. fin_sem wait. ##System logNl: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX gc_waitED....'. } ] ensure: [ - Processor unsignal: fin_sem. + System unsignal: fin_sem. System logNl: 'End of GC finalization process ' & (thisProcess id) asString. ]. } method(#class,#primitive) _popCollectable. method(#class,#primitive) collectGarbage. + + ## ======================================================================================= + + method(#class,#primitive) _signal: semaphore afterSecs: secs. + method(#class,#primitive) _signal: semaphore afterSecs: secs nanosecs: nanosecs. + method(#class,#primitive) _signal: semaphore onInOutput: file. + method(#class,#primitive) _signal: semaphore onInput: file. + method(#class,#primitive) _signal: semaphore onOutput: file. + method(#class,#primitive) _signalOnGCFin: semaphore. + method(#class,#primitive) _unsignal: semaphore. + + method(#class) signal: semaphore afterSecs: secs + { + | x | + x := self _signal: semaphore afterSecs: secs. + if (x isError) { Exception raise: 'Cannot register a semaphore for signaling - ' & (x asString) }. + ^x + } + + method(#class) signal: semaphore afterSecs: secs nanoSecs: nanosecs + { + | x | + x := self _signal: semaphore afterSecs: secs nanosecs: nanosecs. + if (x isError) { Exception raise: 'Cannot register a semaphore for signaling - ' & (x asString) }. + ^x + } + + method(#class) signal: semaphore onInput: file + { + | x | + x := self _signal: semaphore onInput: file. + if (x isError) { Exception raise: 'Cannot register a semaphore for signaling - ' & (x asString) }. + ^x + } + + method(#class) signal: semaphore onOutput: file + { + | x | + x := self _signal: semaphore onOutput: file. + if (x isError) { Exception raise: 'Cannot register a semaphore for signaling - ' & (x asString) }. + ^x + } + + method(#class) signal: semaphore onInOutput: file + { + | x | + x := self _signal: semaphore onInOutput: file. + if (x isError) { Exception raise: 'Cannot register a semaphore for signaling - ' & (x asString) }. + ^x + } + + method(#class) signalOnGCFin: semaphore + { + | x | + x := self _signalOnGCFin: semaphore. + if (x isError) { Exception raise: 'Cannot register a semaphore for GC finalization - ' & (x asString) }. + ^x + } + + method(#class) unsignal: semaphore + { + | x | + x := self _unsignal: semaphore. + if (x isError) { Exception raise: 'Cannot deregister a semaphore from signaling ' & (x asString) }. + ^x + } + + + ## ======================================================================================= + method(#class) sleepForSecs: secs + { + ## ----------------------------------------------------- + ## put the calling process to sleep for given seconds. + ## ----------------------------------------------------- + | s | + s := Semaphore new. + self signal: s afterSecs: secs. + s wait. + } + + method(#class) sleepForSecs: secs nanosecs: nanosecs + { + ## ----------------------------------------------------- + ## put the calling process to sleep for given seconds. + ## ----------------------------------------------------- + | s | + s := Semaphore new. + self signal: s afterSecs: secs nanosecs: nanosecs. + s wait. + } } pooldic System.Log diff --git a/moo/kernel/X11.moo b/moo/kernel/X11.moo index bb4f530..94a9563 100644 --- a/moo/kernel/X11.moo +++ b/moo/kernel/X11.moo @@ -589,7 +589,7 @@ extend X11 if (self.event_loop_sem isNil) { self.event_loop_sem := Semaphore new. - Processor signal: self.event_loop_sem onInput: (self _get_fd). + System signal: self.event_loop_sem onInput: (self _get_fd). self.event_loop_proc := [ | llevtbuf llevent ongoing | @@ -618,7 +618,7 @@ extend X11 'CLOSING X11 EVENT LOOP' dump. - Processor unsignal: self.event_loop_sem. + System unsignal: self.event_loop_sem. ## TODO: LOOK HERE FOR RACE CONDITION self.event_loop_sem := nil. self.event_loop_proc := nil. diff --git a/moo/kernel/test-002.moo b/moo/kernel/test-002.moo index 85c3af5..a715b51 100644 --- a/moo/kernel/test-002.moo +++ b/moo/kernel/test-002.moo @@ -11,7 +11,7 @@ class MyObject(Object) method(#class) proc1 { - [ Processor sleepFor: 1. a := a + 100 ] newProcess resume. + [ System sleepForSecs: 1. a := a + 100 ] newProcess resume. ^a } @@ -88,7 +88,7 @@ class MyObject(Object) | s | s := Semaphore new. s signalAction: [:sem | 'SIGNAL ACTION............' dump. ]. - [ Processor sleepFor: 1. s signal ] fork. + [ System sleepForSecs: 1. s signal ] fork. s wait. } @@ -110,7 +110,7 @@ class MyObject(Object) tc := %( ## 0 - 4 [ self proc1 == 100 ], - [ Processor sleepFor: 2. self proc1 == 200 ], + [ System sleepForSecs: 2. self proc1 == 200 ], [ self test_semaphore_heap == true ], [ self test_mutex = #(2000 6000) ], ####[ self test_sem_sig ], diff --git a/moo/kernel/test-004.moo b/moo/kernel/test-004.moo index 18eb526..8c6e282 100644 --- a/moo/kernel/test-004.moo +++ b/moo/kernel/test-004.moo @@ -38,9 +38,9 @@ class MyObject(Object) sg addSemaphore: s2. sg addSemaphore: s3. - Processor signal: s1 onInput: 0. - ##Processor signal: s2 onInput: 0. ## this should raise an exception. - ##Processor signal: s3 onInput: 0. + System signal: s1 onInput: 0. + ##System signal: s2 onInput: 0. ## this should raise an exception. + ##System signal: s3 onInput: 0. [ sg wait. ] fork. [ sg wait. ] fork. diff --git a/moo/kernel/test-010.moo b/moo/kernel/test-010.moo index 83e4280..b85b64a 100644 --- a/moo/kernel/test-010.moo +++ b/moo/kernel/test-010.moo @@ -61,7 +61,7 @@ class MyObject(TestObject) { | s3 | s3 := Semaphore new. - Processor signal: s3 after: 1 and: 50. + System signal: s3 afterSecs: 1 nanosecs: 50. s3 wait. 'END OF MAIN' dump. } @@ -182,18 +182,18 @@ class MyObject(TestObject) s3 := Semaphore new. t1 := [ - 10 timesRepeat: ['BLOCK #1' dump. Processor sleepFor: 1.]. + 10 timesRepeat: ['BLOCK #1' dump. System sleepForSecs: 1.]. s1 signal ] newProcess. t2 := [ - 5 timesRepeat: ['BLOCK #2' dump. "Processor sleepFor: 1." ]. + 5 timesRepeat: ['BLOCK #2' dump. "System sleepForSecs: 1." ]. 'SIGNALLING S2...' dump. s2 signal. ] newProcess. t1 resume. t2 resume. - Processor signal: s3 after: 10. + System signal: s3 after: 10. 'STARTED t1 and t2' dump. @@ -204,7 +204,7 @@ class MyObject(TestObject) 'WAITING ON S3...' dump. - ##Processor unsignal: s3. + ##System unsignal: s3. s3 wait. 10 timesRepeat: ['WAITED t1 and t2' dump]. diff --git a/moo/kernel/test-011.moo b/moo/kernel/test-011.moo index a11d0c0..a9bd444 100644 --- a/moo/kernel/test-011.moo +++ b/moo/kernel/test-011.moo @@ -221,7 +221,7 @@ class MyObject(TestObject) ## on: Exception do: [:ex | ex messageText dump]. 'SLEEPING FOR 10 seconds ....' dump. - Processor sleepFor: 10. + System sleepForSecs: 10. '>>>>> END OF MAIN' dump. } diff --git a/moo/kernel/test-013.moo b/moo/kernel/test-013.moo index bdcf2bb..2b91984 100644 --- a/moo/kernel/test-013.moo +++ b/moo/kernel/test-013.moo @@ -80,7 +80,7 @@ class MyObject(TestObject) v1 := [ [ [ - ##1 to: 20000 by: 1 do: [:i | System logNl: i asString. "Processor sleepFor: 1." ] + ##1 to: 20000 by: 1 do: [:i | System logNl: i asString. "System sleepForSecs: 1." ] Processor activeProcess terminate. ] ensure: [ System logNl: '<<>>' ]. @@ -89,7 +89,7 @@ class MyObject(TestObject) System logNl: 'RESUMING v1'. v1 resume. - Processor sleepFor: 1. + System sleepForSecs: 1. v1 terminate. ##[ diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 3033510..915911c 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -2735,7 +2735,10 @@ static moo_pfrc_t pf_processor_schedule (moo_t* moo, moo_ooi_t nargs) return MOO_PF_SUCCESS; } -static moo_pfrc_t pf_processor_add_gcfin_semaphore (moo_t* moo, moo_ooi_t nargs) + +/* ------------------------------------------------------------------ */ + +static moo_pfrc_t pf_system_add_gcfin_semaphore (moo_t* moo, moo_ooi_t nargs) { moo_oop_semaphore_t sem; @@ -2752,33 +2755,24 @@ static moo_pfrc_t pf_processor_add_gcfin_semaphore (moo_t* moo, moo_ooi_t nargs) return MOO_PF_SUCCESS; } -static moo_pfrc_t pf_processor_add_timed_semaphore (moo_t* moo, moo_ooi_t nargs) +static moo_pfrc_t pf_system_add_timed_semaphore (moo_t* moo, moo_ooi_t nargs) { moo_oop_t sec, nsec; moo_oop_semaphore_t sem; moo_ntime_t now, ft; - /*MOO_PF_CHECK_RCV (moo, MOO_STACK_GETRCV(moo, nargs) == (moo_oop_t)moo->processor);*/ + /* don't care about the receiver much as the receiver is not used at all. + * however, it's inteded to be called from the System class. */ MOO_ASSERT (moo, nargs >= 2 || nargs <= 3); - if (nargs == 3) - { - nsec = MOO_STACK_GETARG (moo, nargs, 2); - if (!MOO_OOP_IS_SMOOI(nsec)) goto einval; - } - else nsec = MOO_SMOOI_TO_OOP(0); - - sec = MOO_STACK_GETARG(moo, nargs, 1); sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0); + sec = MOO_STACK_GETARG(moo, nargs, 1); + nsec = (nargs == 3? MOO_STACK_GETARG(moo, nargs, 2): MOO_SMOOI_TO_OOP(0)); - /* ProcessScheduler>>signal:after: calls this primitive function. */ - if (MOO_CLASSOF(moo,sem) != moo->_semaphore || !MOO_OOP_IS_SMOOI(sec)) - { - einval: - MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL); - return MOO_PF_SUCCESS; - } + MOO_PF_CHECK_ARGS(moo, nargs, + moo_iskindof(moo, (moo_oop_t)sem, moo->_semaphore) && + MOO_OOP_IS_SMOOI(sec) && MOO_OOP_IS_SMOOI(nsec)); if (MOO_OOP_IS_SMOOI(sem->heap_index) && sem->heap_index != MOO_SMOOI_TO_OOP(-1)) @@ -2818,7 +2812,7 @@ static moo_pfrc_t pf_processor_add_timed_semaphore (moo_t* moo, moo_ooi_t nargs) return MOO_PF_SUCCESS; } -static moo_pfrc_t __processor_add_io_semaphore (moo_t* moo, moo_ooi_t nargs, moo_ooi_t mask) +static moo_pfrc_t __system_add_io_semaphore (moo_t* moo, moo_ooi_t nargs, moo_ooi_t mask) { moo_oop_t fd; moo_oop_semaphore_t sem; @@ -2880,22 +2874,22 @@ static moo_pfrc_t __processor_add_io_semaphore (moo_t* moo, moo_ooi_t nargs, moo return MOO_PF_SUCCESS; } -static moo_pfrc_t pf_processor_add_input_semaphore (moo_t* moo, moo_ooi_t nargs) +static moo_pfrc_t pf_system_add_input_semaphore (moo_t* moo, moo_ooi_t nargs) { - return __processor_add_io_semaphore (moo, nargs, MOO_SEMAPHORE_IO_MASK_INPUT); + return __system_add_io_semaphore (moo, nargs, MOO_SEMAPHORE_IO_MASK_INPUT); } -static moo_pfrc_t pf_processor_add_output_semaphore (moo_t* moo, moo_ooi_t nargs) +static moo_pfrc_t pf_system_add_output_semaphore (moo_t* moo, moo_ooi_t nargs) { - return __processor_add_io_semaphore (moo, nargs, MOO_SEMAPHORE_IO_MASK_OUTPUT); + return __system_add_io_semaphore (moo, nargs, MOO_SEMAPHORE_IO_MASK_OUTPUT); } -static moo_pfrc_t pf_processor_add_inoutput_semaphore (moo_t* moo, moo_ooi_t nargs) +static moo_pfrc_t pf_system_add_inoutput_semaphore (moo_t* moo, moo_ooi_t nargs) { - return __processor_add_io_semaphore (moo, nargs, MOO_SEMAPHORE_IO_MASK_INPUT | MOO_SEMAPHORE_IO_MASK_OUTPUT); + return __system_add_io_semaphore (moo, nargs, MOO_SEMAPHORE_IO_MASK_INPUT | MOO_SEMAPHORE_IO_MASK_OUTPUT); } -static moo_pfrc_t pf_processor_remove_semaphore (moo_t* moo, moo_ooi_t nargs) +static moo_pfrc_t pf_system_remove_semaphore (moo_t* moo, moo_ooi_t nargs) { /* remove a semaphore from processor's signal scheduling */ @@ -2946,6 +2940,8 @@ static moo_pfrc_t pf_processor_remove_semaphore (moo_t* moo, moo_ooi_t nargs) return MOO_PF_SUCCESS; } +/* ------------------------------------------------------------------ */ + static moo_pfrc_t pf_processor_return_to (moo_t* moo, moo_ooi_t nargs) { moo_oop_t ret, ctx; @@ -4326,12 +4322,6 @@ static pf_t pftab[] = { "_block_value", { pf_block_value, 0, MA } }, { "_block_new_process", { pf_block_new_process, 0, 1 } }, - { "_processor_add_gcfin_semaphore", { pf_processor_add_gcfin_semaphore, 1, 1 } }, - { "_processor_add_input_semaphore", { pf_processor_add_input_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_return_to", { pf_processor_return_to, 2, 2 } }, { "_processor_schedule", { pf_processor_schedule, 1, 1 } }, @@ -4431,6 +4421,14 @@ static pf_t pftab[] = { "System__putUint32", { pf_system_put_uint32, 3, 3 } }, { "System__putUint64", { pf_system_put_uint64, 3, 3 } }, + { "System__signal:afterSecs:", { pf_system_add_timed_semaphore, 2, 2 } }, + { "System__signal:afterSecs:nanosecs:", { pf_system_add_timed_semaphore, 3, 3 } }, + { "System__signal:onInput:", { pf_system_add_input_semaphore, 2, 2 } }, + { "System__signal:onInOutput:", { pf_system_add_inoutput_semaphore, 2, 2 } }, + { "System__signal:onOutput:", { pf_system_add_output_semaphore, 2, 2 } }, + { "System__signalOnGCFin:", { pf_system_add_gcfin_semaphore, 1, 1 } }, + { "System__unsignal:", { pf_system_remove_semaphore, 1, 1 } }, + { "System_collectGarbage", { pf_system_collect_garbage, 0, 0 } }, { "System_log", { pf_system_log, 2, MA } } };