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