From: leonardo77
Subject: Clisp threads
Date: 
Message-ID: <1141576454.147102.8680@j33g2000cwa.googlegroups.com>
I have heard that there are issues with multithreaded virtual machines
qute a few times and have been wondering what those could be.

Today I played around with cffi a bit and tried the following:

(defcfun "CloseHandle" :boolean
	     (handle :pointer))

(defcfun ("CreateThread" CreateThread) :pointer
	   (lpThreadAttributes :pointer)
	   (dwStackSize :ulong)
	   (lpStartAddress :pointer)
	   (lpParameter :pointer)
	   (dwCreationFlags :ulong)
	   (lpThreadId :pointer))

(defcallback threadfun :ulong ((param :pointer))
	   (declare (ignore param))
	   (locally (declare (special *threaded-function*))
	     (funcall *threaded-function*))
	   0)
(defun make-thread (thunk)
	   (locally (declare (special *threaded-function*))
	     (setf *threaded-function* thunk)
	     (createthread nil 0 (callback threadfun) nil 0 nil)))

I did a few tests and it worked.
Now I know that this implementation is brain-dead,but that's not the
main point.
After a few tests it seems like these definitions do the job.
Have I missed something?

From: Marcin 'Qrczak' Kowalczyk
Subject: Re: Clisp threads
Date: 
Message-ID: <87zmk44n2w.fsf@qrnik.zagroda>
"leonardo77" <······@thedoghousemail.com> writes:

> After a few tests it seems like these definitions do the job.
> Have I missed something?

I don't know internals of Clisp, so here is a generic answer.
(I suppose Clisp doesn't provide any sort of threads and has a
non-reentrant runtime.)

There are a few ways to integrate the runtime of a high level language
with threads on common platforms:

1. The runtime is thread-safe: different OS threads may access the
   runtime concurrently, and activities applied to logically separate
   data don't interfere with one another.

   That is, different OS threads may concurrently allocate objects,
   call functions, make bindings of special variables, use the reader
   etc., as long as there are no concurrent writes or writes concurrent
   with reads of the same logical object.

   This is done by avoiding implementing logically local operations
   using physically shared data (e.g. passing arguments to functions
   doesn't rely on global variables), and by using atomic operations
   with proper memory synchronization and/or locks when data is
   physically shared (e.g. for garbage collection).

   Examples: C, C++, Java, C#.

2. It is assumed that only one OS thread has access to the runtime at
   the given time. There is a central lock: OS threads acquire it for
   running the program, and release it periodically, or for a lengthy
   work which doesn't access the runtime (e.g. blocking syscalls).

   Examples: OCaml, Python.

3. Logical threads are dispatched in a single OS thread. It is often
   assumed that only a single OS thread exists.

   Examples: Ruby, old Glasgow Haskell, Hugs (a Haskell interpreter).

4. Hybrid approaches, e.g. http://www.haskell.org/~simonmar/bib/concffi04.bib
   describes a hybrid between 2 and 3. Since recently Glasgow Haskell
   supports a hybrid between 1, 2, and 3: several OS threads have
   access to the runtime at the same time, but only some logical
   threads are bound to a concrete OS threads, others are dispatched
   internally. My implementation of my language Kogut uses a hybrid
   between 2 and 3.

For choices 1 and 2 there is only little extra work needed to support
calling back to our language from an OS thread that the runtime has
not seen before. But in case 2 the runtime must explicitly account for
that (in case 1 it might be automatic). With choice 3 it won't work at
all.

If the implementation has taken care to support any of this, it
probably already provides threads to the language; implementing each
choice requires work which wasn't meant to be wasted. If it doesn't
provide threads, most probably its runtime is not reentrant and trying
to use it from multiple OS threads will crash even when threads work
on distinct objects.

In case of some interpreters which don't use global data at all
(possibly Lua, I'm not sure) it's fine to use them from multiple OS
threads, but the threads are independent and can't share objects.

So there is very little chance that calling OS thread primitives in an
implementation of a high level language which doesn't already provide
threads will work. Most probably there are areas which would seem to
be independent from the logical point of view, but which physically
interfere (e.g. garbage collection, exceptions, symbol tables).

I recently made the binding between Kogut and Python thread-aware:
you can create threads in either language and call back and forth
between languages from any thread, and running neither language
prevents scheduling threads of the other. Both implementations have
non-reentrant runtimes, so it did not come for free: both runtimes
had to provide mechanisms to arrange access to them from multiple
OS threads, and they had to be explicitly used by the binding.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Alex Mizrahi
Subject: Re: Clisp threads
Date: 
Message-ID: <440b4e7d$0$15787$14726298@news.sunsite.dk>
(message (Hello 'leonardo77)
(you :wrote  :on '(5 Mar 2006 08:34:14 -0800))
(

 l> I have heard that there are issues with multithreaded virtual machines
 l> qute a few times and have been wondering what those could be.

seems you never did multithread programming..
main problem there is interference between multiple threads -- if they are 
working on data simultaneously, results are chaotic.
common appoach is to either guard data with synchronization object ('mutex') 
so only one thread works with data at a time, or provide each thread it's 
own data.
if you do it in C, for example, you know yourself which data is shared and 
how, so you can build multithread program.
but it doesn't work with Lisp -- there's lots of shared data -- packages, 
symbols, so it's requires significant changes in implementation. also such 
data structures like hashtables should be thread-safe normally so you'll 
never get corrupted ht.
simplistic approach is to add locks to all that structures. but that is not 
what people want from threads in lisp -- typically they want threads to 
inherit context (special var bindings) from caller, but further rebinding of 
them are thread-local. (there are more rules of that kind).
so some structures need to be duplicated for each thread, and there should 
be some way of inheritance, etc.

so this is not easy at all :).
by the way, as far as i know, no implementation offers native threads 
support across multiple platforms, except ABCL that runs over Java -- they 
were unable to provide it even in commercial implementations (at least last 
time i checked about a year ago).
so if you'll add threads to ABCL and it will work stable enough many people 
will be happy, also there's a bounty for it as far as i know :)

)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
"People who lust for the Feel of keys on their fingertips (c) Inity") 
From: Kaz Kylheku
Subject: Re: Clisp threads
Date: 
Message-ID: <1141667406.421447.303270@p10g2000cwp.googlegroups.com>
leonardo77 wrote:
> I did a few tests and it worked.

Don't you think that if it was that easy, the CLISP project would
provide such functions and declare support for threads?