Vladimir Tzankov writes:
> If the thread finishes - in order to remove it from the list of all
> threads - we will have to scan whether there are refernces to
> it. This is expensive operation and anyway is performed during GC.
Clearly something internally does not work as I expect.
To me the obvious solution was that
- make-thread would add the new thread to the list read by list-threads
- finishing a thread would remove it from that list
> This is stadnadrd read/write lock. While they are part of recent
> POSIX standards - not all pthreads implementation have them. That's
> the reason they are absent.
Sounds like it might be worth including in the mt package.
> It can be implemented via the mutex and exemptions that are
> available. Something like (barely tested and not refined):
As I expected, exemption documentation would have been helpful.
I look forward to seeing that.
(It's interesting that I found (I think) an alternative implementation,
which I suspect could actually be used as to implement exemptions
within lisp.)
Thanks. I'll try it out and see if I can deduce how exemptions work.
> > > both thread-state and thread-wait are not good if you do not have
> > > control over threads scheduler.
> > I don't see what control over the scheduler has to do with it.
> > Thread-wait seems to make sense if you're willing to busy wait,
> > which might be more reasonable if you include a sleep in the loop.
> See: http://gbbopen.org/hyperdoc/ref-portable-thread-entities.html -
> "What about Process Wait?"
I find the whole page to be very interesting - I was not aware it
existed. However I don't see that it answers the question of what
any of this has to do with control over the scheduler.
My view is that it has nothing to do with the scheduler.
I think process-wait was (is) a reasonable thing in single cpu
machines. There you know that when you are in the scheduler deciding
which process to run next, no other process could be running.
In the lisp machine, which as far as I know was the first place this
appeared, if the scheduler didn't find anything to do then the machine
didn't have anything better to do than keep checking. Later when mp
lisps started running as one process among many on non lisp machines
it was still reasonable to go through one cycle to check whether any
process was ready, and if none were ready then wait for some OS event
that might make one of them ready. That would not account for cases
like a process waiting for the time to be > 1PM, but the documentation
explained this and showed how you could get the right effect in some
other way (like sleep).
When we have multiple lisp threads running and one may do something
that causes another to be ready, without any explicit signal to that
effect, there seems no alternative to something like thread-wait (the
busy wait inside the thread), possibly mitigated by sleep. In some
cases this may actually be the most efficient implementation, as well
as the easiest to program.
It occurs to me that, if you view gbbopen portable threads as a
reasonable interface, you might implement it and make it part of
clisp. I notice in particular that it contains something called
as-atomic-operation, which I gather (let me know if I'm wrong about
this) has the semantics described above -- nothing else can be going
on at the same time. This is also what without-interrupts means on a
1-cpu machine, and in fact one correct (though perhaps not efficient)
way for me to port to clisp-mt would be to define without-interrupts
as as-atomic-operation.
The good thing about as-atomic-operation is that it is an adequate
basis for implementing all the other locking/scheduling/mutex stuff
in lisp (which in effect is what I have done). The bad thing is that
you have to stop all the other threads, which is a cost in efficiency
in two different ways. One is loss of parallelism, the other is the
cost of stopping all the other threads. You evidently already have a
way to do that, since I gather GC does it. How expensive is this
operation? (For that matter, I'd be interested in how it works.)
(BTW, another project I'd love to see is GC implemented as thread(s)
running in parallel with non-gc threads.)
> Whatever thread-state returns - until you process it in meaningful
> way - it may change.
Is thread-state supposed to be related to who-state in some way?
> Will remove both of them (anyway they are not implemented). Any
> objections?
At this point I can't tell what it is you plan to remove.
|