From: xstream
Subject: Modifying or not the Property List of a Global Symbol
Date: 
Message-ID: <10lm54p885fk4bf@corp.supernews.com>
Maybe a naive problem. I have been experimenting with various methods that
could allow me to have several threads communicating back and forth with
each other. I am encoding an elaborate secure-handshake protocol multicast
simulator between remote systems and not only do I need to handle the steps
but I also need (for debugging purposes) a full trace of previous states.

I have not been able to come up with a stack-like (PUSH and POP style)
global semaphore-type of structure that easily keeps a record of its
previous states. Any ideas will be appreciated. I want it accessible
globally.

More specifically, I would like to ask how (un)desirable is to do it by
having the threads modify (initiating action each time from their own
lexical local function environment) and query (likewise from local processes
using GET etc.) the corresponding property values in the property list of an
appropriately structured, dynamically-changing property list of a few GLOBAL
symbols (to make things easier assume all symbols are in the very same USER
package)?

The problem I have is bigger than otherwise as I am trying to rapidly
develop/test this piece of code in an interpreted CL environment where
threads and time must be simulated sequentially.

Any ideas?

Thanks in anticipation
-- 
Panos C. Lekkas

From: Peter Seibel
Subject: Re: Modifying or not the Property List of a Global Symbol
Date: 
Message-ID: <m3zn38delf.fsf@javamonkey.com>
"xstream" <·······@attglobal.net> writes:

> Maybe a naive problem. I have been experimenting with various methods that
> could allow me to have several threads communicating back and forth with
> each other. I am encoding an elaborate secure-handshake protocol multicast
> simulator between remote systems and not only do I need to handle the steps
> but I also need (for debugging purposes) a full trace of previous states.
>
> I have not been able to come up with a stack-like (PUSH and POP style)
> global semaphore-type of structure that easily keeps a record of its
> previous states. Any ideas will be appreciated. I want it accessible
> globally.

Uh, how about a thread-safe queue? Assuming appropriate definitions
for MAKE-LOCK and WITH-LOCK why is it any harder than:

  (defclass thread-safe-queue
    ((lock :initform (make-lock))
     (head :initform nil)))

  (defun queue-push (item queue)
    (with-lock ((lock queue))
      (push item (head queue))))

  (defun queue-pop (queue)
    (with-lock ((lock queue))
      (pop (head queue))))

> More specifically, I would like to ask how (un)desirable is to do it
> by having the threads modify (initiating action each time from their
> own lexical local function environment) and query (likewise from
> local processes using GET etc.) the corresponding property values in
> the property list of an appropriately structured,
> dynamically-changing property list of a few GLOBAL symbols (to make
> things easier assume all symbols are in the very same USER package)?

Do you have some guarantee that symbol's property lists can be
concurrently modified without your own locking?

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: xstream
Subject: Re: Modifying or not the Property List of a Global Symbol
Date: 
Message-ID: <10lm7oojp860mad@corp.supernews.com>
"Peter Seibel" <·····@javamonkey.com> wrote in message
···················@javamonkey.com...
> "xstream" <·······@attglobal.net> writes:
>
> > Maybe a naive problem. I have been experimenting with various methods
that
> > could allow me to have several threads communicating back and forth with
> > each other. I am encoding an elaborate secure-handshake protocol
multicast
> > simulator between remote systems and not only do I need to handle the
steps
> > but I also need (for debugging purposes) a full trace of previous
states.
> >
> > I have not been able to come up with a stack-like (PUSH and POP style)
> > global semaphore-type of structure that easily keeps a record of its
> > previous states. Any ideas will be appreciated. I want it accessible
> > globally.
>
> Uh, how about a thread-safe queue? Assuming appropriate definitions
> for MAKE-LOCK and WITH-LOCK why is it any harder than:
>
>   (defclass thread-safe-queue
>     ((lock :initform (make-lock))
>      (head :initform nil)))
>
>   (defun queue-push (item queue)
>     (with-lock ((lock queue))
>       (push item (head queue))))
>
>   (defun queue-pop (queue)
>     (with-lock ((lock queue))
>       (pop (head queue))))
>

This is a neat idea and it might work. Given time constraints I did not give
objects/classes the slightest thought. I will try it. I appreciate the cue.

> > More specifically, I would like to ask how (un)desirable is to do it
> > by having the threads modify (initiating action each time from their
> > own lexical local function environment) and query (likewise from
> > local processes using GET etc.) the corresponding property values in
> > the property list of an appropriately structured,
> > dynamically-changing property list of a few GLOBAL symbols (to make
> > things easier assume all symbols are in the very same USER package)?
>
> Do you have some guarantee that symbol's property lists can be
> concurrently modified without your own locking?

None formally at this point. I am thinking about setting up some accessor or
counter-like function that serves as "front-end guard" keeping track of any
calls to the GLOBAL symbol of interest (maybe keeping track of accesses say
by  GENSYM-generated transient symbols) and ensure the appropriate locking
mechanism. A slot in the property list for instance could be the lock status
of the symbol and if it is set to "locked" then the access is not granted to
anyone for modification. Upon completion of modification or querying of the
status the slot would be reset to "released" for other functions. Some sort
of self-imposed discipline for rapid prototype development but certainly not
a robust solution long-term.

Thanks for your time and insight.

Panos



>
> -Peter
>
> -- 
> Peter Seibel                                      ·····@javamonkey.com
>
>          Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Juhan Leemet
Subject: Re: Modifying or not the Property List of a Global Symbol
Date: 
Message-ID: <pan.2004.09.29.22.06.13.784377@logicognosis.com>
On Wed, 29 Sep 2004 20:11:55 +0000, Peter Seibel wrote:
> "xstream" <·······@attglobal.net> writes:
>> Maybe a naive problem. I have been experimenting with various methods that
>> could allow me to have several threads communicating back and forth...
> 
> Uh, how about a thread-safe queue? Assuming appropriate definitions for
> MAKE-LOCK and WITH-LOCK why is it any harder than:
> 
>   (defclass thread-safe-queue
>     ((lock :initform (make-lock))
>      (head :initform nil)))
> 
>   (defun queue-push (item queue)
>     (with-lock ((lock queue))
>       (push item (head queue))))
> 
>   (defun queue-pop (queue)
>     (with-lock ((lock queue))
>       (pop (head queue))))

Sounds like a good idea... but...

Is it just me that has the stack push/pop semantics so ingrained that
I find them confusing when used with something called a queue? I'm used to
seeing queue (FIFO) functions: enqueue, dequeue or stack (last in, first
out) functions: push, pop. I get confused with queue-push. Does that mean
to push the item at the head of the queue (exceptional case?). It looks
like that is what the code does, but then it is not really a queue? looks
more like a stack? I find myself griding mental gears. Maybe it's just me?

OTOH, I'm a Lisp neophyte (albeit a computer old timer), so maybe I
haven't grokked the contexts and conventions that you guys use.

-- 
Juhan Leemet
Logicognosis, Inc.
From: xstream
Subject: Re: Modifying or not the Property List of a Global Symbol
Date: 
Message-ID: <10lmi3cc11uqidd@corp.supernews.com>
You are right.  This does behave more or less like a traditional stack
except that here it is formulated in a class approach (CLOS) and
consequently in an object-oriented manner.

However the original premise of the problem I was trying to solve is a
sequence of internal states, some of or all of which one may want to
retrieve at some point in time for "post-mortem" analysis of meta-events,
protocol flow etc. The term 'queue'  was coined by Peter (maybe
unfortunately in this case if you insist on seeing it as you describe it) to
denote a sequence of values the head of which can be popped out of or pushed
down into that structure. It could have been an array of values instead or
even an array of lists with CAR of each list maybe a counter value so one
can access the n-th element of the "queue" and get the (CDR) of that n-th
list in the data structure, thereby obtaining the sought after value, and so
forth, imagination being the only limitation..

If it walks like a duck, swims like a duck, squats like a duck, sounds like
a duck, and even looks like a duck, I believe no one will reproach you for
calling it a duck.

Panos C. Lekkas


"Juhan Leemet" <·····@logicognosis.com> wrote in message
···································@logicognosis.com...
> On Wed, 29 Sep 2004 20:11:55 +0000, Peter Seibel wrote:
> > "xstream" <·······@attglobal.net> writes:
> >> Maybe a naive problem. I have been experimenting with various methods
that
> >> could allow me to have several threads communicating back and forth...
> >
> > Uh, how about a thread-safe queue? Assuming appropriate definitions for
> > MAKE-LOCK and WITH-LOCK why is it any harder than:
> >
> >   (defclass thread-safe-queue
> >     ((lock :initform (make-lock))
> >      (head :initform nil)))
> >
> >   (defun queue-push (item queue)
> >     (with-lock ((lock queue))
> >       (push item (head queue))))
> >
> >   (defun queue-pop (queue)
> >     (with-lock ((lock queue))
> >       (pop (head queue))))
>
> Sounds like a good idea... but...
>
> Is it just me that has the stack push/pop semantics so ingrained that
> I find them confusing when used with something called a queue? I'm used to
> seeing queue (FIFO) functions: enqueue, dequeue or stack (last in, first
> out) functions: push, pop. I get confused with queue-push. Does that mean
> to push the item at the head of the queue (exceptional case?). It looks
> like that is what the code does, but then it is not really a queue? looks
> more like a stack? I find myself griding mental gears. Maybe it's just me?
>
> OTOH, I'm a Lisp neophyte (albeit a computer old timer), so maybe I
> haven't grokked the contexts and conventions that you guys use.
>
> -- 
> Juhan Leemet
> Logicognosis, Inc.
>
From: Peter Seibel
Subject: Re: Modifying or not the Property List of a Global Symbol
Date: 
Message-ID: <m3llescumy.fsf@javamonkey.com>
Juhan Leemet <·····@logicognosis.com> writes:

> On Wed, 29 Sep 2004 20:11:55 +0000, Peter Seibel wrote:
>> "xstream" <·······@attglobal.net> writes:
>>> Maybe a naive problem. I have been experimenting with various methods that
>>> could allow me to have several threads communicating back and forth...
>> 
>> Uh, how about a thread-safe queue? Assuming appropriate definitions for
>> MAKE-LOCK and WITH-LOCK why is it any harder than:
>> 
>>   (defclass thread-safe-queue
>>     ((lock :initform (make-lock))
>>      (head :initform nil)))
>> 
>>   (defun queue-push (item queue)
>>     (with-lock ((lock queue))
>>       (push item (head queue))))
>> 
>>   (defun queue-pop (queue)
>>     (with-lock ((lock queue))
>>       (pop (head queue))))
>
> Sounds like a good idea... but...
>
> Is it just me that has the stack push/pop semantics so ingrained that
> I find them confusing when used with something called a queue? 

No, you're right. I got my wires crossed. (Queues are a fundamental
data structure for doing multithreaded programming as in
producer/consumer queues (sometimes called buffers) so they were on my
mind but the OP asked for PUSH and POP operations and I mixed up the
two things.) Replace "queue" with "stack".

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp