Re: [Oorexx-devel] Ad new classes .eventSemaphore and .mutexSemaphore (Re: An example of the new counter modifier on loops ...

2019-03-08 Thread Rony G. Flatscher
Rick,
 
thank you very much for your kind words and the important correction!

If deemed helpful how about adopting the text and the sample for the 
documentation? Although I
cannot directly supply a suitable patch (not being able to use the publishing 
infrastructure) I
could try to edit the text and simplify the examples a little bit more to meet 
the documentation style.

---rony

P.S.: If it was possible to use reply in normal routines would allow to 
simplify even more (and put
other languages into shade :) ).

On 08.03.2019 00:10, Rick McGuire wrote:
> Rony, 
>
> An excellent write up here. One small correction I would make, when 
> MutexSempahores have multiple
> waiters, they are not necessarily queued. Which waiting thread gets the mutex 
> next is determined
> by the OS dispatch mechanisms, so which thread gets it next is not 
> predictable. 
>
> Rick
>
> On Thu, Mar 7, 2019 at 12:13 PM Rony G. Flatscher  > wrote:
>
> To run the example programs you would need a version of ooRexx from 
> "sandbox/rick/sem". The
> 32-bit Windows "sandbox/rick/sem" version of ooRexx can be temporarily 
> found here:
> 
> 
> 
> .
>
> ---
>
> Prologue
> 
>
> Semaphores get used in multithreaded scenarios. As ooRexx allows one to 
> run method routines on
> different threads in parallel, semaphores could come in handy.
>
> Even regular ooRexx routines can be called asynchroneously, such that one 
> can write a Rexx
> routine (using the "::routine" directive) and run it on a different 
> thread. This is done by
> fetching the routine object from the .routines directory (this directory 
> is set up by the
> interpreter and makes all routines of the Rexx program available to the 
> programmer). To
> invoke/run a routine object one sends it the "call" message. If arguments 
> should be supplied
> then one mereley adds them.
>
> The following two Rexx samples, one demonstrating an eventSemaphore, one 
> a mutexSemaphore,
> fetch the routine object representing the "::routine worker" routine. The 
> routine object gets
> asynchroneously run (executed on another thread in parallel to the main 
> thread) by using the
> start-message (defined in the root class object), which expects the name 
> of the method to send
> asynchroneously (in this case "call", which runs the routine) and 
> optionally arguments (in
> this case the semaphore and the invocation number for sending the "call" 
> message
> asynchroneously).
>
> The example programs may look a little bit weird, because the output 
> should be formatted in a
> way that makes it rather easy to find the output from the main thread and 
> the output from the
> three worker threads (the "worker" object gets three 'call' messages sent 
> in a loop causing
> three threads to be created on which the routine object gets executed).
>
> 
> 
>
> EventSemaphore
>
> ---
>
> An "event semaphore" allows one thread "A" to synchronize multiple 
> threads (like "B", "C",
> ...) with whom the event semaphore gets shared. Thread "A" creates the 
> event semaphore and
> sends it the "reset" message. Then thread "A" supplies the event 
> semaphore to the threads "B",
> "C", ..., which each send the received event semaphore a "wait" message. 
> This will block the
> threads "B", "C", ..., until thread "A" sends the "post" message to the 
> event semaphore. At
> this time all threads waiting on the event semaphore get released and can 
> run in parallel on
> their threads.
>
> Using introspection on the new class "EventSemaphore" the following 
> methods are currently
> defined for it: "close", "isPosted", "post", "reset", "wait".
>
> The following example will fetch the routine object "WORKER" and in a 
> loop will send the
> routine object the message "start" (defined in the ooRexx root class 
> "Object") supplying the
> message name ("call") to be sent on a new (asynchroneous) thread, and as 
> arguments the event
> semaphore to wait on and the number of the loop for the respective 
> asynchroneous message.
>
> The main program creates an event semaphore and sends the message "reset" 
> to it. Then it sends
> the "start" message three times to the routine object in the loop, 
> causing the routine
> "worker" to run on three different threads, where in each thread the 
> executed routine then
> waits on the event semaphore ("wait" message to the event semaphore). The 
> main program then
> sleeps for five seconds, before sending the "post" message to the event 
> semaphore, which w

Re: [Oorexx-devel] Ad new classes .eventSemaphore and .mutexSemaphore (Re: An example of the new counter modifier on loops ...

2019-03-07 Thread Rick McGuire
Rony,

An excellent write up here. One small correction I would make, when
MutexSempahores have multiple waiters, they are not necessarily queued.
Which waiting thread gets the mutex next is determined by the OS dispatch
mechanisms, so which thread gets it next is not predictable.

Rick

On Thu, Mar 7, 2019 at 12:13 PM Rony G. Flatscher 
wrote:

> To run the example programs you would need a version of ooRexx from
> "sandbox/rick/sem". The 32-bit Windows "sandbox/rick/sem" version of ooRexx
> can be temporarily found here:
> 
> .
>
>
> ---
>
> Prologue
> 
>
> Semaphores get used in multithreaded scenarios. As ooRexx allows one to
> run method routines on different threads in parallel, semaphores could come
> in handy.
>
> Even regular ooRexx routines can be called asynchroneously, such that one
> can write a Rexx routine (using the "::routine" directive) and run it on a
> different thread. This is done by fetching the routine object from the
> .routines directory (this directory is set up by the interpreter and makes
> all routines of the Rexx program available to the programmer). To
> invoke/run a routine object one sends it the "call" message. If arguments
> should be supplied then one mereley adds them.
>
> The following two Rexx samples, one demonstrating an eventSemaphore, one a
> mutexSemaphore, fetch the routine object representing the "::routine
> worker" routine. The routine object gets asynchroneously run (executed on
> another thread in parallel to the main thread) by using the start-message
> (defined in the root class object), which expects the name of the method to
> send asynchroneously (in this case "call", which runs the routine) and
> optionally arguments (in this case the semaphore and the invocation number
> for sending the "call" message asynchroneously).
>
> The example programs may look a little bit weird, because the output
> should be formatted in a way that makes it rather easy to find the output
> from the main thread and the output from the three worker threads (the
> "worker" object gets three 'call' messages sent in a loop causing three
> threads to be created on which the routine object gets executed).
>
>
> 
> EventSemaphore
>
> ---
>
> An "event semaphore" allows one thread "A" to synchronize multiple threads
> (like "B", "C", ...) with whom the event semaphore gets shared. Thread "A"
> creates the event semaphore and sends it the "reset" message. Then thread
> "A" supplies the event semaphore to the threads "B", "C", ..., which each
> send the received event semaphore a "wait" message. This will block the
> threads "B", "C", ..., until thread "A" sends the "post" message to the
> event semaphore. At this time all threads waiting on the event semaphore
> get released and can run in parallel on their threads.
>
> Using introspection on the new class "EventSemaphore" the following
> methods are currently defined for it: "close", "isPosted", "post", "reset",
> "wait".
>
> The following example will fetch the routine object "WORKER" and in a loop
> will send the routine object the message "start" (defined in the ooRexx
> root class "Object") supplying the message name ("call") to be sent on a
> new (asynchroneous) thread, and as arguments the event semaphore to wait on
> and the number of the loop for the respective asynchroneous message.
>
> The main program creates an event semaphore and sends the message "reset"
> to it. Then it sends the "start" message three times to the routine object
> in the loop, causing the routine "worker" to run on three different
> threads, where in each thread the executed routine then waits on the event
> semaphore ("wait" message to the event semaphore). The main program then
> sleeps for five seconds, before sending the "post" message to the event
> semaphore, which will awake the routines on the three threads, ie. they
> return from the wait message and execute on their threads in parallel,
> causing each to sleep for two seconds before returning from the routine
> invocation.
>
> Here is the program "testEventSemaphore.rex":
>
> /* ---rgf, 20190307, testing new class .EventSemaphore which defines the 
> methods:
>   close, isPosted, post, reset, wait
> */
>
> eventSem=.eventSemaphore~new
> say "/main\"~left(11,".")  pp(.dateTime~new) 
> "eventSem~isPosted="pp(eventSem~isPosted)
> eventSem~reset
> say "/main\"~left(11,".")  pp(.dateTime~new) "after eventSem~reset, 
> eventSem~isPosted="pp(eventSem~isPosted)
>
> w=.routines~waiter  -- get routine object
> do i=1 to 3
>say "main"~left(11,".")  "running routine 'WAITER' #" pp(i) 
> "asynchroneously"
>w~start("call", eventSem, i)  -- run the routine object on a separate 
> thread
> end

[Oorexx-devel] Ad new classes .eventSemaphore and .mutexSemaphore (Re: An example of the new counter modifier on loops ...

2019-03-07 Thread Rony G. Flatscher
To run the example programs you would need a version of ooRexx from 
"sandbox/rick/sem". The 32-bit
Windows "sandbox/rick/sem" version of ooRexx can be temporarily found here:
.

---

Prologue


Semaphores get used in multithreaded scenarios. As ooRexx allows one to run 
method routines on
different threads in parallel, semaphores could come in handy.

Even regular ooRexx routines can be called asynchroneously, such that one can 
write a Rexx routine
(using the "::routine" directive) and run it on a different thread. This is 
done by fetching the
routine object from the .routines directory (this directory is set up by the 
interpreter and makes
all routines of the Rexx program available to the programmer). To invoke/run a 
routine object one
sends it the "call" message. If arguments should be supplied then one mereley 
adds them.

The following two Rexx samples, one demonstrating an eventSemaphore, one a 
mutexSemaphore, fetch the
routine object representing the "::routine worker" routine. The routine object 
gets asynchroneously
run (executed on another thread in parallel to the main thread) by using the 
start-message (defined
in the root class object), which expects the name of the method to send 
asynchroneously (in this
case "call", which runs the routine) and optionally arguments (in this case the 
semaphore and the
invocation number for sending the "call" message asynchroneously).

The example programs may look a little bit weird, because the output should be 
formatted in a way
that makes it rather easy to find the output from the main thread and the 
output from the three
worker threads (the "worker" object gets three 'call' messages sent in a loop 
causing three threads
to be created on which the routine object gets executed).



EventSemaphore

---

An "event semaphore" allows one thread "A" to synchronize multiple threads 
(like "B", "C", ...) with
whom the event semaphore gets shared. Thread "A" creates the event semaphore 
and sends it the
"reset" message. Then thread "A" supplies the event semaphore to the threads 
"B", "C", ..., which
each send the received event semaphore a "wait" message. This will block the 
threads "B", "C", ...,
until thread "A" sends the "post" message to the event semaphore. At this time 
all threads waiting
on the event semaphore get released and can run in parallel on their threads.

Using introspection on the new class "EventSemaphore" the following methods are 
currently defined
for it: "close", "isPosted", "post", "reset", "wait".

The following example will fetch the routine object "WORKER" and in a loop will 
send the routine
object the message "start" (defined in the ooRexx root class "Object") 
supplying the message name
("call") to be sent on a new (asynchroneous) thread, and as arguments the event 
semaphore to wait on
and the number of the loop for the respective asynchroneous message.

The main program creates an event semaphore and sends the message "reset" to 
it. Then it sends the
"start" message three times to the routine object in the loop, causing the 
routine "worker" to run
on three different threads, where in each thread the executed routine then 
waits on the event
semaphore ("wait" message to the event semaphore). The main program then sleeps 
for five seconds,
before sending the "post" message to the event semaphore, which will awake the 
routines on the three
threads, ie. they return from the wait message and execute on their threads in 
parallel, causing
each to sleep for two seconds before returning from the routine invocation.

Here is the program "testEventSemaphore.rex":

/* ---rgf, 20190307, testing new class .EventSemaphore which defines the 
methods:
  close, isPosted, post, reset, wait
*/

eventSem=.eventSemaphore~new
say "/main\"~left(11,".")  pp(.dateTime~new) 
"eventSem~isPosted="pp(eventSem~isPosted)
eventSem~reset
say "/main\"~left(11,".")  pp(.dateTime~new) "after eventSem~reset, 
eventSem~isPosted="pp(eventSem~isPosted)

w=.routines~waiter  -- get routine object
do i=1 to 3
   say "main"~left(11,".")  "running routine 'WAITER' #" pp(i) 
"asynchroneously"
   w~start("call", eventSem, i)  -- run the routine object on a separate 
thread
end
say

sleepTime=5
say "/main\"~left(11,".")  pp(.dateTime~new) " sleeping" pp(sleepTime) 
"seconds ..."
call sysSleep sleepTime -- sleep five seconds

say "/main\"~left(11,".")  pp(.dateTime~new) " awoke, about doing an 
'eventSem~post' ..."
say
eventSem~post   -- stop any thread waiting on this event semaphore
say "\main/"~left(11,".")  pp(.dateTime~new) " leaving main."

::routine waiter
   use arg eventSem, nr
   s=.dateTime~new
   say .context~name" #" nr":