Re: Wiki Article: Asynchronous Events and Family IPC

2022-05-07 Thread Jean-Christophe Helary
By the way, the picolisp twitter account is great !!! :-)

JC

> On May 8, 2022, at 14:08, Alexander Burger  wrote:
> 
> Hi all,
> 
> a new Wiki article about internal background processing, asynchronous events 
> and
> family IPC in PicoLisp:
> 
>   https://picolisp.com/wiki/?background
> 
> I think this was not yet documented anywhere.
> 
> ☺/ A!ex
> 
> -- 
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe

-- 
Jean-Christophe Helary @brandelune
https://mac4translators.blogspot.com
https://sr.ht/~brandelune/omegat-as-a-book/


--
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Wiki Article: Asynchronous Events and Family IPC

2022-05-07 Thread Alexander Burger
Hi all,

a new Wiki article about internal background processing, asynchronous events and
family IPC in PicoLisp:

   https://picolisp.com/wiki/?background

I think this was not yet documented anywhere.

☺/ A!ex

-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: IPC

2009-02-09 Thread Tomas Hlavaty
Hi Alex,

 The fifo is there to defer requests for chopsticks when the
 philosopher is hungry or eating.  Do you have any other mechanism in
 mind?

 As the tell - hear mechanism is a pipe, it behaves like a fifo. So I
 would expect that this would suffice.

Not due to the logic of the algorithm, e.g. when the philosopher is
hungry, he must hand over dirty forks immediately but not clean forks.
He must remember that he was asked for it and hand it over when he is
finished.

 I should explain that the internal tell - hear mechanism maintains
 dynamic buffers for each parent/child connection, to avoid blocking
 if a child should not fetch (hear) its data fast enough. This way,
 the standard limitation of the PIPE_BUF size is avoided.

That's good to know.

Thank you,

Tomas
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: IPC

2009-02-08 Thread Tomas Hlavaty
Hi Alex,

 There is no other place where the internal event loop (the
 C-function waitFd()) is called.

I see.

 I'm wondering whether the 'fifo' is really necessary?

The fifo is there to defer requests for chopsticks when the
philosopher is hungry or eating.  Do you have any other mechanism in
mind?

Cheers,

Tomas
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: IPC

2009-02-07 Thread Tomas Hlavaty
Hi all,

the Chandy / Misra solution to Dining Philosophers Problem in picolisp
seems to be working now so the code is now at
http://logand.com/sw/phil.l for anybody interested.

The problem with the previous code was that once the hungry
philosopher handed over his dirty fork, he had to ask to get it back.
This was the message I thought was getting lost but it was not
generated in the first place.

Thanks Alex for your suggestions.

Cheers,

Tomas
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: IPC

2009-02-02 Thread Tomas Hlavaty
Hi Alex,

 as in 'open'. Therefore, I would rather reduce the functionality of
 'hear', so that from now on it only accepts a file descriptor (and no
 longer a symbolic argument). I'll write it into the ReleaseNotes.

I see, thank you.

 You tried to use 'rpc' to send messages to the other
 philosophers. While this is basically a correct idea, 'rpc' is not
 suitable in the current situation. It sends the message via standard
 output, and is intended to be used in a 'pipe' call.

What is the functional difference between 'rpc' and 'pr' and why the
specific constraint on 'rpc' being suitable only for stdout?

With 'rpc' I get:

: (hear (pipe (do 3 (wait 2000) (rpc 'println ''Ok
- 3
: Ok
Ok
Ok

and with 'pr' I get the same thing:

: (hear (pipe (do 3 (wait 2000) (pr '(println 'Ok)) (flush
- 3
: Ok
Ok
Ok

 If you look in the reference for 'hear', it says hear is usually
 only called explicitly by a top level parent process. The reason is
 that upon a 'fork', the 'hear' channel is automatically set up in
 the child process to be used by the built-in IPC routines.

I see, where can I find this automatic channel, is it a named pipe?
If not, what channel is used for communication?

 As a consequence, if you re-open that channel with 'hear', the child
 is effectively cut off from its parent and could, for example, not
 synchronize on DB operations.

I noticed that 'tell' did not work for me when I opened the fifos, so
this is why:-)

 So the recommended and natural way is to use 'tell'. In combination with
 'pid', it can also send messages selectively to other processes.

Using 'tell' I cannot send a message to the parent process though.  I
would like to have the philosophers talking to a monitor process which
cannot be the parent but must be another child for 'tell' to work.  Is
that correct?  How are children supposed to communicate with the
parent process?

 As an example, I modified your phil.l (I hope I understood it). Each
 philosopher (process) keeps the PIDs of his neighbors in the global
 variables '*LeftNeighbor' and '*RightNeighbor', and the state of the
 forks in '*LeftFork' and '*RightFork'. In the beginning, he waits until
 he received the PIDs from the parent process.

That's interesting, thank you.

'tell' seems to be asynchronous.  If I want to query the philosopher
processes about their state, I cannot use something like:

(de philState ()
   (list *Pid *State *LeftFork *RightFork) )

.. and in *Monitor process call...

  (let S (tell 'pid P 'philState)
 (println S)

because 'tell' does not return the result of calling 'philState'.  Is
there a standard/easy way of achieving this?

Thank you,

Tomas
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


Re: IPC

2009-02-01 Thread Alexander Burger
Hi Tomas,

for phil.l, I'd suggest another change (besides the call to 'hear').

You tried to use 'rpc' to send messages to the other philosophers. While
this is basically a correct idea, 'rpc' is not suitable in the current
situation. It sends the message via standard output, and is intended to
be used in a 'pipe' call.

Instead, you could directly call 'pr', so that

   (rpc 'obtain I)

becomes

   (pr (list 'obtain I))

and

   (rpc 'give I)

becomes

   (pr (list 'give I))

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe


IPC

2009-01-31 Thread Tomas Hlavaty
Hi Alex,

I am struggling to understand picolisp IPC functions (hear, tell, rpc,
sync...).  I have attached code for the Dining Philosophers problem
which gets stuck after calling 'hear' in the philosopher (child)
process.  The idea is that each philosopher is a process which opens a
fifo and all philosophers talk to their neighbours via those fifos.

'hear' in the following snippet seems to block the whole process:

   ...
   (log 'before)
   (hear (mailbox I))
   (log 'after)
   ...

outputs

$ ~/picolisp/p phil.l
0 -1 0 before
1 -1 0 before
2 -1 0 before
3 -1 0 before
4 -1 0 before
: 

..only and does nothing afterwards.  I would expect 'hear' to install
some kind of event handler which would evaluate incoming messages and
then carry on immediately with the next (log 'after) line.  Is my
understanding correct?  I though that 'hear' was working in the
background so why the code blocks?

Thank you,

Tomas

# ~/picolisp/p phil.l
# http://en.wikipedia.org/wiki/Dining_philosophers_problem
# Chandy / Misra solution
# philosophers: N = total, I = current, P = other
# forks: L = left, R = right; lt0 ~ dirty, =0 none, gt0 ~ clean

(de log @
   (pass println I L R)
   (flush) )

(de idle ()
   (wait (rand 1000 3000)) )

(de left ()
   (% (+ N (- I 1)) N) )
   
(de right ()
   (% (+ I 1) N) )

(de mailbox (P)
   (pack phil P) )

(de obtain (P)
   (log 'obtain P)
   (when (= P (left))
  (if (=0 L)
 (setq L 1)
 (quit Already have the left fork) ) )
   (when (= P (right))
  (if (=0 R)
 (setq R 1)
 (quit Already have the right fork) ) ) )

(de give (P)
   (log 'give P)
   (when (and (= P (left)) (lt0 L))
  (out (mailbox P)
 (rpc 'obtain I) )
  (setq L 0) )
   (when (and (= P (right)) (lt0 R))
  (out (mailbox P)
 (rpc 'obtain I) )
  (setq R 0) ) )
   
(de grab ()
   (while (or (=0 L) (=0 R))
  (when (lt0 L)
 (setq L 1) )
  (when (lt0 R)
 (setq R 1) )
  (when (=0 L)
 (out (mailbox (left))
(rpc 'give I) ) )
  (when (=0 R)
 (out (mailbox (right))
(rpc 'give I) ) )
  (wait 500) ) )

(de phil (I N L R)
   (unless (info (mailbox I))
  (call 'mkfifo (mailbox I)) )
   (log 'before)
   (hear (mailbox I))
   (log 'after)
   (loop
  (log 'thinking)
  (idle) # think
  (log 'hungry)
  (grab)
  (log 'eating)
  (idle) # eat
  (setq L -1 R -1) ) ) # dirty

(de main (N)
   (push '*Bye '(mapc 'kill *C))
   (for (I 0 ( I N) (inc I))
  (if (fork)
 (push '*C @)
 (phil I N -1 0) ) ) )

(main 5)