Re: Native Threads in the RTS

2003-01-10 Thread Wolfgang Thaller
I've been watching the discussion about native threads, and getting
thoroughly confused.


Understandable ;-) .


But before investing effort in fiddling with it, I thought it'd be good
to see whether anyone finds it helpful.


Yes, it does seem to be a good idea.


Feel free to modify it.  E.g. add inline comments, alternative rules,
and whatever.


OK, I'll get to work :-)


Cheers,

Wolfgang

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



RE: Native Threads in the RTS

2002-12-03 Thread Simon Marlow

 2. It seems perfectly reasonable to want to have the Haskell 
 called-back code throw an exception that is caught by the Haskell code

 that called out to foreign code.  Reusing the Haskell thread is
 necessary  (though not sufficient) to achieve such behavior.

This is a particularly tricky problem, and I prefer to leave it up to
the programmer to handle such things.  Propagating the exception to the
original (Haskell) caller automatically is unlikely to be the right
thing to do, because the foreign code will almost certainly want to do
some clean up.

If the foreign language supports exceptions then it is conceivable that
we could turn a Haskell exception into a foreign exception (and
vice-versa), but for plain C I think we should leave well alone.

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: Native Threads in the RTS

2002-12-03 Thread Wolfgang Thaller
Dean Herrington wrote:


[...] Rather, I find it
nonintuitive that calling from Haskell to foreign code and back into 
Haskell
should create a new Haskell thread, when these two Haskell threads 
really
are just different portions of a single thread of computation
(deliberately vague term).

I agree to that. Creating a new thread for calling back into Haskell 
_only_ makes sense if you look at it from inside the GHC RTS. Before I 
had a look at the relevant parts of the RTS, I would never have thought 
of that.

I don't know if there's any advantage/disadvantage to changing GHC's 
internals. The only _observable_ difference is the thread's ThreadIds, 
and this should at least be clearly documented (or, even better, it 
should be explicitly undocumented, so that no one will be suprised if 
the behaviour is changed in the future).

Off the top of my head I can think of two
situations in which having separate threads is bothersome.


3. Throwing exceptions to a thread
If I manually translate haskell exceptions to foreign exceptions and 
back, there is no reason why I shouldn't want to raise an exception in 
a thread I have a threadId for, even if that thread called a foreign 
function which in turn called back to haskell.
I think that the behaviour can always be emulated using MVars however, 
so I think there's no immediate action required.

---

I've tried to rephrase my proposal for native threads, this time 
treating GHC's behaviour in this situation as an implementation detail. 
I think the meaning of the proposal becomes clearer because of this. 
The proposal doesn't comment on ThreadIds, so the non-intuitive (IMHO) 
behaviour in GHC is independent of the bound threads proposal.

I think I've understood both my own specification and the current RTS 
well enough to start trying to implement a prototype soon. The intended 
meaning of the specification hasn't changed for the third revision in a 
row.

Does anyone have concrete suggestions for the syntax change to foreign 
export and foreign import wrapper?

Cheers,

Wolfgang

=
Bound Threads Proposal, version 5

Goals
~

Since foreign libraries sometimes exploit thread local state, it is
necessary to provide some control over which thread is used to execute
foreign code.  In particular, it is important that it should be
possible for Haskell code to arrange that a sequence of calls to a
given library are performed by the same native thread and that if an
external library calls into Haskell, then any outgoing calls from
Haskell are performed by the same native thread.

This specification is intended to be implementable both by
multithreaded Haskell implementations and by single-threaded
implementations and so it does not comment on which particular OS
thread is used to execute Haskell code.

Definitions
~~~

A native thread is a thread as defined by the operating system.

A Haskell thread encapsulates the execution of a Haskell I/O action.
A Haskell thread is created by forkIO, and dies when the I/O action
completes.
When a Haskell thread calls a foreign imported function, it is not 
considered to be blocked (in the GHC runtime system, the calling thread 
is blocked; This is considered an implementation detail for the 
purposes of this specification, but be aware that myThreadId might 
return several different values for one Haskell thread as defined 
here). If the foreign function calls back to Haskell, the callback is 
said to run in the same Haskell thread.

Design
~~

Haskell threads may be associated at thread creation time with either
zero or one native threads. Each Native thread is associated with at 
most one Haskell thread.

A native thread that is associated with a Haskell thread is called a 
bound Haskell thread. A Haskell thread that is associated with a native 
thread is called a bound native thread.

A Haskell thread is always executed by a native thread. This 
specification places absolutely no restrictions on which native thread 
is used to execute a particular Haskell thread. The Haskell thread need 
not be associated with the native thread used to execute it, and one 
Haskell thread may be executed by more than one native thread during 
its lifetime [but not by several native threads at once].

A bound native thread may not be used for executing any Haskell thread 
except the one it is bound to.

It is implementation dependent whether the main thread, threads created 
using forkIO and threads created for running finalizers or signal 
handlers are bound or not.

When a foreign imported function is invoked [by Haskell code], the 
foreign code is executed in the native thread associated with the 
current Haskell thread, if an association exists. If the current 
Haskell thread is not associated to a native thread, the implementation 
may decide which native thread to run the foreign function in. The 
native thread that is used may not be bound to another Haskell thread.
The existing distinction 

RE: Native Threads in the RTS

2002-12-02 Thread Simon Peyton-Jones
| 2. Calling from foreign code into Haskell to a bound foreign import
will
| require some special handling to ensure that a subsequent call out to
| foreign code will use the same native thread.  Why couldn't this
special
| handling select the same Haskell thread instead of creating a new one?

This is just an efficiency issue, right?   If creating a Haskell thread
from scratch is very cheap, then it's easier to do that each time rather
than to try to find the carcass of a completed Haskell thread.   If you
do the latter, you need to get into carcass management.  

But maybe there is more to it than efficiency in your mind?

Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: Native Threads in the RTS

2002-12-02 Thread Wolfgang Thaller
I've postponed writing up a new proposal again...

But I'm going to sum up some requirements that I would like to see 
fulfilled - to make it clearer to others why I'm proposing such strange 
things...

*) It should be possible for Haskell code to arrange that a sequence of 
calls to a given library are performed by the same native thread and 
that if an external library calls into Haskell, then any outgoing calls 
from Haskell are performed by the same native thread.

*) The specification should be implementable in a way that allows a lot 
of foreign calls to be made with no additional overhead with respect to 
GHC's current unsafe foreign calls.

*) The good performance of the existing lightweight green threads in 
GHC should not be sacrificed. Performance should still OK when using 
the new features with only a few threads (i.e. not more than commonly 
used from multithreaded C programs).

*) The specification shouldn't explicitly require lightweight green 
threads to exist. The specification should be implementable in a simple 
and obvious way in haskell systems that always use a 1:1 correspondence 
between Haskell threads and OS threads.

*) The specification shouldn't specify which particular OS thread 
should be used to execute Haskell code. It should be possible to 
implement it with e.g. a Haskell interpreter running in one OS thread 
that just uses other OS threads for foreign calls.

*) There should be no unexpected blocking. Especially, threadsafe calls 
should never cause other threads to block.

I'm currently stuck thinking about one particular problem that I 
discovered in my current version of the spec. What happens when an 
unbound Haskell thread calls a threadsafe foreign function which in 
turn calls a bound foreign exported function? Well, I think my current 
proposal says relatively clearly what's supposed to happen, but I 
discovered it's not as easy to fit that in the current implementation 
of GHC as I thought... in fact it might be quite difficult. I'll have 
to do more thinking before I can be sure, though.


That's it for today,

Regards,

Wolfgang

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Native Threads in the RTS

2002-12-01 Thread Dean Herington
On 29 Nov 2002, Alastair Reid wrote:

 Consider Haskell functions a,b,c,d and C functions A,B,C,D and a call
 pattern
 
   a - A - b - B - c - C - d - D
 
 That is, a calls A, calls b, calls B, calls ...
 
 Suppose we want A,B,C,D executed by the same foreign thread.
 
 Each of a,b,c,d are executed by different Haskell threads (because a
 new Haskell thread is spawned for each call into Haskell) so we have
 multiple Haskell threads associated with a single foreign thread.

It doesn't feel right to me that a,b,c,d are executed by different Haskell
threads.  Why shouldn't they all be the *same* Haskell thread?

1. Reasonable exception handling across the Haskell/foreign boundary is
not currently supported, but if we imagine moving in that direction, it
would seem we'd want a single thread for the given example.

2. Calling from foreign code into Haskell to a bound foreign import will
require some special handling to ensure that a subsequent call out to
foreign code will use the same native thread.  Why couldn't this special
handling select the same Haskell thread instead of creating a new one?

Dean

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: Native Threads in the RTS

2002-11-29 Thread Alastair Reid

[Note: I'm consistently using 'foreign thread' instead of 'native
thread'.  The Haskell-spec necessarily treats Haskell as the centre of
the universe.  So what a Linux kernel hacker might think of as a
'native thread' is really quite foreign to Haskell.  Feel free to
ignore this little experiment with the language.]

 *) Exactly one Haskell thread associated with the native thread is
 executing. All other associated Haskell threads are blocked. No
 foreign code is being executed by the native thread.  

This isn't quite right - or, at least, needs clarified.

Consider Haskell functions a,b,c,d and C functions A,B,C,D and a call
pattern

  a - A - b - B - c - C - d - D

That is, a calls A, calls b, calls B, calls ...

Suppose we want A,B,C,D executed by the same foreign thread.

Each of a,b,c,d are executed by different Haskell threads (because a
new Haskell thread is spawned for each call into Haskell) so we have
multiple Haskell threads associated with a single foreign thread.  Now,
when D is called, which of these threads is 'executing' and which are
'blocked'?

I think the quoted text assumes that a,b,c,d are blocked during the
call to D.

The GHC implementation might well perform a context switch on making
the calls into C so we could, perhaps, say that a Haskell thread is
'blocked' while making an ffi call.  But, for normal function calls
(i.e., all in Haskell or all in C, no ffi stuff), we don't say that
the caller is 'blocked' until the callee returns.  I think it's better
to reserve the word is 'blocked' for its normal usage and avoid
possibly over-specifying what implementations must do to implement the
spec.

Possible rewording:

  Definitions:

Let $f$ be a foreign thread.

$uses(f)$ is the number of foreign calls by Haskell threads bound to $f$.
$bindees(f)$ is the number of Haskell threads bound to $f$.

  Invariant:

$0 = bindees(f) - uses(f) = 1$

  Proof:

(Should be possible by) structural induction over relevant IO
operations (forkIO, forkNativeIO, etc.)


This needs careful interpretation if we want to be able to bind
finalizers to foreign threads.  In particular, if a finalizer is bound
to a foreign thread, we don't increment 'bindees(f)' until the
finalizer starts and we don't start the finalizer unless either:

  bindees(f) - uses(f) == 0   

or, maybe even,

  bindees(f) == 0   



Or, we can adopt a much weaker semantics than Wolfgang intended and have:

$0 = bindees(f) - uses(f)$

This would allow several currently running, active Haskell threads to
all be bound to the same foreign thread.  When any of these threads
makes a foreign call, the other threads could all keep running and
they would only block if they too tried to make foreign calls.  From
an implementation point of view, this requires:

1) That foreign threads are _not_ used to execute Haskell code.

2) That we maintain a lock on foreign threads so that only one
   Haskell thread tries to use it at a time.

I see two potential problems with this (but would like to hear which,
if either, dominates your thoughts):

1) If foreign threads cannot be used to execute Haskell code, foreign
   calls require (OS-level) context switches which are expensive.

2) Adding an implicit lock to foreign calls might surprise programmers.


--
Alastair
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



RE: Native Threads in the RTS

2002-11-29 Thread Simon Marlow
 Or, we can adopt a much weaker semantics than Wolfgang 
 intended and have:
 
 $0 = bindees(f) - uses(f)$
 
 This would allow several currently running, active Haskell threads to
 all be bound to the same foreign thread.  When any of these threads
 makes a foreign call, the other threads could all keep running and
 they would only block if they too tried to make foreign calls.  From
 an implementation point of view, this requires:
 
 1) That foreign threads are _not_ used to execute Haskell code.
 
 2) That we maintain a lock on foreign threads so that only one
Haskell thread tries to use it at a time.
 
 I see two potential problems with this (but would like to hear which,
 if either, dominates your thoughts):
 
 1) If foreign threads cannot be used to execute Haskell code, foreign
calls require (OS-level) context switches which are expensive.
 
 2) Adding an implicit lock to foreign calls might surprise 
 programmers.

Another problem, from an implementation point of view, is that we would
have to surround unsafe foreign calls with a lot of context-switching
gumph, in case the calling Haskell thread is bound to a native thread.
I really think we don't want to do this.

The thread groups idea is similar, but only allows one of the Haskell
threads in a group to be executing at any one time.  This means you can
run the Haskell thread using its native thread, and you don't have to
context switch on every C call.  However, I believe it would be tricky
to implement this correctly in the scheduler (not impossible, just
tricky and hard to test).

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: Native Threads in the RTS

2002-11-29 Thread Alastair Reid

Simon Marlow:

 Another problem, from an implementation point of view, is that we
 would have to surround unsafe foreign calls with a lot of
 context-switching gumph, in case the calling Haskell thread is bound
 to a native thread.  I really think we don't want to do this.

Note that you only have to do this to foreign calls of the form:

  foreign import bound foo :: ...

since any other calls are free to use whatever thread they feel like.

So, we can say that foreign functions of the form:

  foreign import bound unsafe bar :: ...

are illegal or we can allow them and provide warnings or we can allow
them and trust the programmer to know that bar is much more expensive
than they think.  (I favour the first two.)


--
Alastair
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



RE: Native Threads in the RTS

2002-11-29 Thread Simon Marlow

  This is all getting highly confusing, as it seems we're working with
  different ideas of what's on the table.  Alastair: you seem to be
  working on your own proposal - could you write it down either as a
  complete proposal or diffs to Wolfgangs?
 
 I did.  You sent comments on it and I sent back a cleaned up version.
 Here it is again.

My apologies - I didn't notice you'd already proposed 'foreign import
bound' so I thought you were working with a definition that we hadn't
seen.  Never mind.

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: Native Threads in the RTS

2002-11-29 Thread Wolfgang Thaller
So, we can say that foreign functions of the form:

  foreign import bound unsafe bar :: ...

are illegal or we can allow them and provide warnings or we can allow
them and trust the programmer to know that bar is much more expensive
than they think.  (I favour the first two.)


NOOO! Don't do that! Please don't!


I see two potential problems with this (but would like to hear which,
if either, dominates your thoughts):

1) If foreign threads cannot be used to execute Haskell code, foreign
   calls require (OS-level) context switches which are expensive.

2) Adding an implicit lock to foreign calls might surprise programmers.


I'm slightly concerned about 2), but 1) Is an absolute show-stopper for 
me.

It should stay possible to implement an unsafe call as just a call - no 
special RTS management, no context switches, no nothing, just a few 
machine code instructions to move the parameters to the stack and/or 
registers.
And I definitely do want to keep that efficiency for bound Haskell 
threads.
The reason why I startet this discussion is that I want to use OpenGL 
in my Haskell Programs (which works fine with GHC's current 
non-threaded RTS). OpenGL requires a lot of calls to functions that 
don't take much time to execute and that don't call back to haskell 
land. Using safe or even threadsafe for these calls would kill 
performance utterly and completely.


*) Exactly one Haskell thread associated with the native thread is
executing. All other associated Haskell threads are blocked. No
foreign code is being executed by the native thread.


This isn't quite right - or, at least, needs clarified.

Consider Haskell functions a,b,c,d and C functions A,B,C,D and a call
pattern

  a - A - b - B - c - C - d - D

That is, a calls A, calls b, calls B, calls ...

Suppose we want A,B,C,D executed by the same foreign thread.

[...]

I think the quoted text assumes that a,b,c,d are blocked during the
call to D.


Yes. For the purpose of the above paragraph (and the neighboring 
paragraphs in the spec), a Haskell thread is considered blocked 
during a call to a foreign imported function. I admit that this 
terminology is inspired by implementation details of GHC, but it makes 
[some] sense: After all, if there is no Haskell code to execute [it's 
foreign code only now], the Haskell thread can not be executed. A 
Haskell thread can be either blocked or executing Haskell code.

This needs careful interpretation if we want to be able to bind
finalizers to foreign threads.  In particular, if a finalizer is bound
to a foreign thread, we don't increment 'bindees(f)' until the
finalizer starts and we don't start the finalizer unless either:


I'm not currently planning to allow finalizers to be bound to 
native(foreign) threads, as I have so far failed to see a solution that 
 I'm happy with.

[...] From an implementation point of view, this requires:

1) That foreign threads are _not_ used to execute Haskell code.


One of my design goals is to allow the native threads to be used to 
execute Haskell code. Implementations are not required to do so, but it 
should be possible.
For that reason I also dislike the term foreign thread. It sounds 
great until I want to say the implementation may use the foreign 
thread to execute Haskell code.


And just as I went back to the computer after a long pause in order to 
finish this message, a new proposal arrived. I'll take more time to 
study it more completely. I just want to reiterate one thing:

The notion of bound foreign imports could be eliminated by saying that
all foreign calls are performed by the bound thread if one exists and
eliminate the concept of 'bound foreign imports'.  The only reason to
allow any flexibility is to allow for faster implementations which
perform less context switching - this is especially important for
'unsafe' foreign calls.


I definitely need zero-overhead bound unsafe calls. Everything else 
would be basically unusable for me.

I'll be back later.

Cheers,

Wolfgang

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


RE: Native Threads in the RTS

2002-11-28 Thread Simon Peyton-Jones
Improving.  Want to put it in CVS?  Simon M can suggest where.

Simon


| Definitions
| ~~~
| A native thread (aka OS thread) is a thread as defined by the
operating
| system.
| A Haskell thread is [*** FIXME - How shall I put this? ***] the thing
| you see from  Haskell land.

A Haskell thread encapsulates the execution of a Haskell I/O action.
A Haskell thread is created by forkIO, and dies when the I/O action
completes.  

A Haskell thread is always executed by a native thread.  The Haskell RTS
creates one or more worker native threads to execute Haskell threads.

| Haskell threads may be associated at thread creation time with either
| zero or one native threads. Each Native thread is associated with zero
| or more native threads.

zero or more *Haskell* threads.

Can you give an example of when a native thread is associated with more
than one Haskell thread?

To avoid A Haskell thread associated with a native thread I'd prefer
to define the term a bound Haskell thread.  I would also like to
describe a bound native thread as one that has associated Haskell
thread(s).

| If a native thread is associated with one or more Haskell threads,
| exactly one of the following must be true:
| *) Exactly one Haskell thread associated with the native thread is
| executing.
| *) The native thread is executing foreign code.
| *) The native thread and all Haskell threads associated with it are
| blocked.

You don't say (but you do mean)

A bound Haskell thread can be executed only by its associated
native thread

You don't say (and I'm not sure if you mean)

If a bound native thread blocks, all of its associated Haskell 
threads are blocked too

If a bound Haskell thread blocks, its associate native thread
and all its 
associated Haskell threads also block.

| The thread that main runs in, threads created using forkIO and threads
| created for running finalizers or signal handlers are not necessarily
| associated with a native thread. However, an implementation might
| choose to do so.

But the impl may *not* choose a bound native thread.  These must be kept
inviolate.

| When a free foreign exported function is invoked, the implementation
| may freely choose what kind of Haskell thread the function is executed
| in. It is not specified whether this thread is associated with a
| particular OS thread or not.

Again, it must not be a bound native thread.

| When a foreign imported function is invoked [by Haskell code], the
| foreign code is executed in the native thread associated with the
| current Haskell thread, if an association exists. If the current
| Haskell thread is not associated to a native thread, the
implementation
| may freely decide which thread to run the foreign function in.
| The existing distinction between unsafe, safe and threadsafe calls
| remains unchanged.

If a bound Haskell thread 
calls a foreign import that is not labelled 'threadsafe'
which calls a bound foreign export
does that work?  What if the foreign export was not bound?

Similarly, if the foreign import was labelled 'threadsafe', would it
work?  It's not obvious to me.  Some kind of semantics would be good.


___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



RE: Native Threads in the RTS

2002-11-28 Thread Simon Marlow
Simon P.J. writes:
 Can you give an example of when a native thread is associated 
 with more than one Haskell thread?

I gave an example in my previous message.  It's when a bound Haskell
thread makes a foreign call which re-enters Haskell via a bound foreign
export.

 You don't say (and I'm not sure if you mean)
 
   If a bound native thread blocks, all of its associated Haskell 
   threads are blocked too

When Bagpuss goes to sleep, all his friends go to sleep too. :-)
(apologies to those who never watched British childrens TV in the 70s).

Actually, for any given native thread, only one of its bound Haskell
threads can be runnable, the others must all be blocked waiting on the
result of a foreign call.  So you don't really have to worry about a
native thread being bound to multiple Haskell threads; this would be
quite tricky to implement in the scheduler anyway.

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: Native Threads in the RTS

2002-11-28 Thread Wolfgang Thaller
I'll write up a new version of the proposal tomorrow. For now, here are 
some answers and [at the end] a question about the current FFI 
specification.

Simon Peyton Jones wrote:
You don't say (but you do mean)

	A bound Haskell thread can be executed only by its associated
native thread


No I don't mean that, and I've been avoiding to say that. This is how 
the GHC implementation will probably handle it, but I do not want to 
put that in the general specification. Alastair remarked a while ago:

For that matter, I'd like it to be possible to implement this spec in
Hugs.  Hugs is internally single-threaded but this spec is concerned
with what happens when Haskell calls out to C and we could arrange to
switch into the appropriate native thread when Hugs calls out to C.


After all, the only thing which needs to be guaranteed is that foreign 
functions called by the Haskell thread are executed in the associated 
native thread.

You don't say (and I'm not sure if you mean)

	If a bound native thread blocks, all of its associated Haskell
	threads are blocked too

	If a bound Haskell thread blocks, its associate native thread
and all its
	associated Haskell threads also block.


Does this sound clearer:

*) Exactly one Haskell thread associated with the native thread is 
executing. All other associated Haskell threads are blocked. No foreign 
code is being executed by the native thread.
*) The native thread is executing foreign code. No Haskell code is 
executing in any of the associated Haskell threads.
*) The native thread and all Haskell threads associated with it are 
blocked.

| The thread that main runs in, threads created using forkIO and 
threads
| created for running finalizers or signal handlers are not necessarily
| associated with a native thread. However, an implementation might
| choose to do so.

But the impl may *not* choose a bound native thread.  These must be 
kept
inviolate.

[...]
Again, it must not be a bound native thread.

Good point, I had overlooked that.


If a bound Haskell thread
	calls a foreign import that is not labelled 'threadsafe'
	which calls a bound foreign export
does that work?  What if the foreign export was not bound?

Similarly, if the foreign import was labelled 'threadsafe', would it
work?  It's not obvious to me.  Some kind of semantics would be good.


Good question. I reread Section 3.3 of the FFI document (RC7), and now 
I think I cannot clarify my specification in this respect without first 
asking others to clarify the current specs - can someone explain the 
distinction between unsafe, safe and threadsafe in the current FFI to 
me? I think I know what it does in GHC, but what's the general 
definition? I've read the description in the FFI document, but it's not 
clear to me. Is there any reason why safe is the default and not 
threadsafe? After all, safe is less safe (it might cause the whole 
program to block). To me, safe seems to be an odd middle ground 
between speed and safety. What is safe guaranteed/allowed to do? Is 
it _guaranteed_ to block other Haskell threads under certain 
conditions? Or is that only an artifact of current implementations? Why 
are implementations allowed to _silently_ fall back to safe when 
threadsafe is not supported? Isn't that dangerous?

If I'm not mistaken, threadsafe calls from bound Haskell threads 
would have exactly the same overhead as safe calls. Should we make 
sure that safe calls somehow block other threads? If so, why?


Thats all for now

Wolfgang

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Native Threads in the RTS

2002-11-27 Thread Johan Steunenberg
Typo:
 Being fresh to Haskell, I suggest that the naming continues to be
 native and free.

I did mean native and green

Have a nice day, once again.

Johan Steunenberg

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



RE: Native Threads in the RTS

2002-11-27 Thread Simon Marlow

 When a bound foreign exported function is invoked [by 
 foreign code], 
 the implementation checks whether a Haskell thread is associated with 
 the current OS thread.
 If there is one, this Haskell thread is used to execute the callback.
 If there is none, a new Haskell thread is created and associated with 
 the native thread. This is the only situation where a Haskell 
 thread is 
 associated with a native thread. The new associated Haskell thread is 
 then used to execute the callback. When the callback finishes, the 
 Haskell thread is terminated, the association is dissolved, 
 but the OS thread continues to run.

This is the bit I have trouble with too.

If the OS thread trying to call a foreign export has an associated
Haskell thread, then it must be because the Haskell thread called out to
C in the first place.  This Haskell thread will be waiting for the call
to return, and has all the state associated with its current execution
context, so we can't just use that thread to run the foreign export.

I don't see the problem with forking a new Haskell thread for each
foreign export, and associating it with the current native thread if the
foreign export is marked bound.  It does mean we can get multiple
Haskell threads bound to the same native thread, but only one can be
runnable at any one time (this is an important invariant from the point
of view of the implementation, I believe).

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: Native Threads in the RTS

2002-11-27 Thread Alastair Reid

 Are you sure you intend to change the type of forkIO? Currently it's

   forkIO :: IO () - IO ThreadId

Sorry, no, I did not.

--
Alastair
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: Native Threads in the RTS

2002-11-27 Thread Wolfgang Thaller
Simon Marlow wrote:


I don't see the problem with forking a new Haskell thread for each
foreign export, and associating it with the current native thread if 
the
foreign export is marked bound.  It does mean we can get multiple
Haskell threads bound to the same native thread, but only one can be
runnable at any one time (this is an important invariant from the point
of view of the implementation, I believe).

Of course, you're right.

Simon Peyton-Jones wrote:


I offer myself as such a guinea pig.  I'm afraid I don't understand it
yet.  It's hard to describe precisely.   Comments below.


Yes, I do need a guinea pig ;-) . I really have trouble expressing my 
ideas accurately, and I keep changing them.

Better start with some definitions, for
'Haskell thread'
and'native thread'

I think I know what you mean, but better to be sure.


Well, yes. I didn't manage to come up with a decent definition for it 
yet.
I intend native thread to be the thing you get using pthread_create 
on unix, and Haskell thread to be the same thing as it currently is 
in the GHC RTS. Can anyone think of a way of defining that in a way 
that is accurate, general and understandable?

| If there is one, this Haskell thread is used to execute the callback.

OK, so this is where I get completely confused.  A Haskell thread is 
not
(currently) an execution platform.

Oops... The best way to confuse other people is to be confused yourself 
;-) --- I had a slight misconception about the RTS there --- I think 
I've corrected that.

===

Threads Proposal, version 4

Goals
~

Since foreign libraries sometimes exploit thread local state, it is
necessary to provide some control over which thread is used to execute
foreign code.  In particular, it is important that it should be
possible for Haskell code to arrange that a sequence of calls to a
given library are performed by the same native thread and that if an
external library calls into Haskell, then any outgoing calls from
Haskell are performed by the same native thread.

This specification is intended to be implementable both by
multithreaded Haskell implementations and by single-threaded
implementations and so it does not comment on which particular OS
thread is used to execute Haskell code.

Definitions
~~~
A native thread (aka OS thread) is a thread as defined by the operating 
system.
A Haskell thread is [*** FIXME - How shall I put this? ***] the thing 
you see from  Haskell land.

Design
~~

Haskell threads may be associated at thread creation time with either
zero or one native threads. Each Native thread is associated with zero 
or more native threads.

If a native thread is associated with one or more Haskell threads, 
exactly one of the following must be true:
*) Exactly one Haskell thread associated with the native thread is 
executing.
*) The native thread is executing foreign code.
*) The native thread and all Haskell threads associated with it are 
blocked.

The thread that main runs in, threads created using forkIO and threads 
created for running finalizers or signal handlers are not necessarily 
associated with a native thread. However, an implementation might 
choose to do so.

There are now two kinds of foreign exported [and foreign import 
wrapped] functions: bound and free. The FFI syntax should be extended 
appropriately [which of the two should be the default, if any?].

When a bound foreign exported function is invoked [by foreign code], 
a new Haskell thread is created and associated with the native thread. 
The new associated Haskell thread is then used to execute the callback.

When a free foreign exported function is invoked, the implementation 
may freely choose what kind of Haskell thread the function is executed 
in. It is not specified whether this thread is associated with a 
particular OS thread or not.

When a foreign imported function is invoked [by Haskell code], the 
foreign code is executed in the native thread associated with the 
current Haskell thread, if an association exists. If the current 
Haskell thread is not associated to a native thread, the implementation 
may freely decide which thread to run the foreign function in.
The existing distinction between unsafe, safe and threadsafe calls 
remains unchanged.

A new library routine, forkNativeThread :: IO () - IO ThreadID, should 
spawn a new Haskell Thread (like forkIO) and associate it with a new 
native thread (forkIO is not guaranteed to do this). It may be 
implemented using the FFI and an OS-specific thread creation routine. 
It would just pass a bound callback as an entry point for a new OS 
thread.

Issues
~~

Finalizers and signal handlers cannot be associated with a particular 
native thread. If they have to trigger an action in a particular native 
thread, a message has to be sent manually (via MVars and friends) to 
the Haskell thread associated with the native thread in question.

This introduces a change in the syntax for 

Re: Native Threads in the RTS

2002-11-26 Thread Dean Herington
On 26 Nov 2002, Alastair Reid wrote:

 ps Better names than 'native' and 'green' surely exist.  Something
 which conveys the idea that the thread will be remembered for later
 use seems appropriate but no good words spring to mind.

Perhaps bound and free?


___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



RE: Native Threads in the RTS

2002-11-26 Thread Simon Marlow
Alastair Reid wrote:
 Design
 ~~
 
 Haskell threads may be associated at thread creation time with either
 zero or one native threads.  There are only two ways to create Haskell
 threads so there are two cases to consider:

Umm, Alastair, I think you've got things a bit mixed up here.  Did you
mean two ways to create a native thread?  

There are currently three ways to create a Haskell thread (forkIO,
foreign export, finalizers) and Wolfgang has proposed a fourth
(forkNativeThread).

Or perhaps you're proposing we do away with forkIO and only have
forkNativeThread?  That was discounted a while back because we want to
continue to have light-weight threads independent of OS threads.

 1) forkNativeThread :: IO () - IO ()
 
The fresh Haskell thread is associated with a fresh native thread.
 
(ToDo: do we really need to use a fresh native thread or would a
pool of threads be ok?  The issue could be avoided by separating
creation of the native thread from the 'associate' operation.)
 
 2) Calls to a threadsafe foreign export allocate a fresh Haskell
thread which is then associated with the Haskell thread.

I don't know what you mean by a threadsafe foreign export.  Did you
mean threadsafe foreign import perhaps?  And I'm not sure how a fresh
Haskell thread is associated with a Haskell thread ;-)

 Calls to threadsafe foreign imports by threads which have an
 associated native thread are performed by that native thread.
 
 Calls to any other foreign imports (i.e., 'safe' or 'unsafe' calls)
 may be made in other threads or, if it exists, in the associated
 native thread at the implementation's discretion.
 
 [ToDo: can Haskell threads with no associated thread make foreign
 calls using a thread associated with some other thread?  

er... overloading the word thread was maybe not such a good idea.  I
think you're asking whether a green thread can grab a native thread to
make a foreign call.  The current answer is no... but can you think of a
reason we might want this feature?

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: Native Threads in the RTS

2002-11-26 Thread Seth Kurtzberg
On Tue, 2002-11-26 at 08:32, Dean Herington wrote:
 On 26 Nov 2002, Alastair Reid wrote:
 
  ps Better names than 'native' and 'green' surely exist.  Something
  which conveys the idea that the thread will be remembered for later
  use seems appropriate but no good words spring to mind.
 
 Perhaps bound and free?

Won't that be confused with bound and free as used in lambda calculus? 
Or am I missing the point and you mean that they are analogous to bound
and free in lambda calculus?  (If the latter, I need to reread my lambda
calculus books.  :))

 
 
 ___
 Glasgow-haskell-users mailing list
 [EMAIL PROTECTED]
 http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
-- 
Seth Kurtzberg
M. I. S. Corp
480-661-1849
Pager 888-605-9296, or [EMAIL PROTECTED]


___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: Native Threads in the RTS

2002-11-26 Thread Dean Herington
On 26 Nov 2002, Alastair Reid wrote:

  Umm, Alastair, I think you've got things a bit mixed up here.  Did
  you mean two ways to create a native thread?
 
 No.
 
  There are currently three ways to create a Haskell thread (forkIO,
  foreign export, finalizers) and Wolfgang has proposed a fourth
  (forkNativeThread).

Invocation of a signal handler also creates a Haskell thread, doesn't it?

 I was (implicitly) viewing forkIO and forkNativeThread as two variants
 of the same operation.  Both fork a Haskell thread, one of them also
 creates a native thread.  (It may also choose to use the native thread
 as the Haskell thread but that's not externally observable.)
 
 I was putting off finalizers until the end.
 
  1) forkNativeThread :: IO () - IO ()
  
  The fresh Haskell thread is associated with a fresh native thread.
  
  (ToDo: do we really need to use a fresh native thread or would a
  pool of threads be ok?  The issue could be avoided by separating
  creation of the native thread from the 'associate' operation.)
  
  2) Calls to a threadsafe foreign export allocate a fresh Haskell
  thread which is then associated with the Haskell thread.
 
  I don't know what you mean by a threadsafe foreign export.  Did
  you mean threadsafe foreign import perhaps?  And I'm not sure how
  a fresh Haskell thread is associated with a Haskell thread ;-)
 
 Using the bound/free terminology suggested by Seth, what I meant was
 bound foreign import.  

Actually, I proposed the terms, and Seth criticized the proposal.  Perhaps
bound and unbound might be a bit better and partially avoid the
possible confusion with lambda calculus variables.

  [ToDo: can Haskell threads with no associated thread make foreign
  calls using a thread associated with some other thread?
 
  er... overloading the word thread was maybe not such a good idea.
  I think you're asking whether a green thread can grab a native
  thread to make a foreign call.  The current answer is no... but can
  you think of a reason we might want this feature?
 
 My question was of the form: 'is a correct implementation allowed to
 use a native thread even if the programmer didn't ask for it?' not
 'can we make this happen?'
 
 Sorry for all the confusion, here's the key part of the proposal again
 - hopefully without the ambiguity.
 
 
   Haskell threads may be bound with either zero or one native threads.
   Binding occurs at thread creation time.  There are four ways to
   create Haskell threads so there are four cases to consider:

How about:
A Haskell thread may be bound to a native thread.
Such binding occurs when the Haskell thread is created and persists for
the lifetime of the Haskell thread.
A Haskell thread that is not bound to a native thread is called unbound.
There are four ways ...

   1) forkNativeThread :: IO () - IO ()
  The fresh Haskell thread is bound to a fresh native thread.
 
   2) forkIO :: IO () - IO ()
  The fresh Haskell thread is not bound to a native thread.
 
   3) Calls to a bound foreign export allocate a fresh Haskell
  thread which is then bound to the calling thread thread.

... which is bound to the calling native thread ?
 
  Bound foreign exports have the form
 
foreign export bound foo :: type
 
  and otherwise behave like normal foreign exports.
 
   4) ToDo: For completeness, there ought to be a way to 'bind'
  finalizers to native threads but no concrete proposal currently
  exists.
   
   [ToDo: The following could be simplified by saying that all foreign
   calls are performed by the bound thread if one exists and eliminate
   the concept of 'bound foreign imports'.  The only reason to allow
   any flexibility is to allow for faster implementations.]  
   Calls to bound foreign imports by threads which are bound to a
   native thread are performed by that native thread.
   
  Bound foreign imports have the form
 
foreign import bound foo :: type
 
  and otherwise behave like normal foreign imports.
 
   Calls to any free (i.e., not bound) foreign imports may be made in
   the bound thread (if it exists) or by some other native thread at
   the implementation's discretion.
 
 
 --
 Alastair

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: Native Threads in the RTS

2002-11-26 Thread Ashley Yakeley
At 2002-11-26 09:37, Alastair Reid wrote:

  1) forkNativeThread :: IO () - IO ()
 The fresh Haskell thread is bound to a fresh native thread.

  2) forkIO :: IO () - IO ()
 The fresh Haskell thread is not bound to a native thread.

Are you sure you intend to change the type of forkIO? Currently it's

  forkIO :: IO () - IO ThreadId


-- 
Ashley Yakeley, Seattle WA

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: Native Threads in the RTS

2002-11-26 Thread Wolfgang Thaller
Nice design, Alastair. I've stolen lots of ideas and some text for the 
complete rewrite of the proposal. The concept of associating haskell 
threads to native threads proved to be a good way of explaining my 
original idea in a different way --- and then I found out that 
forkNativeThread needn't be a primitive, but can be implemented on top 
of the FFI. After that I found out what the bound/free exports 
buisiness was all about and why we might need it.

As for the questions regarding my previous proposal, I think they are 
answered in the new one. If they aren't, let me know. [It's no use 
explaining what I meant to say if I already want to say something 
different ;-) ]

Cheers,

Wolfgang
===

Threads Proposal, version 3

Goals
~

Since foreign libraries sometimes exploit thread local state, it is
necessary to provide some control over which thread is used to execute
foreign code.  In particular, it is important that it should be
possible for Haskell code to arrange that a sequence of calls to a
given library are performed by the same native thread and that if an
external library calls into Haskell, then any outgoing calls from
Haskell are performed by the same native thread.

This specification is intended to be implementable both by
multithreaded Haskell implementations and by single-threaded
implementations and so it does not comment on which particular OS
thread is used to execute Haskell code.

Design
~~

Haskell threads may be associated at thread creation time with either
zero or one native threads. Each Native thread is associated with zero 
or one Haskell threads (no native thread may be associated with two 
Haskell threads at a time).

An associated pair of a Haskell thread and a native thread can only 
execute either foreign code or haskell code at any one time.

The thread that main runs in, threads created using forkIO and threads 
created for running finalizers or signal handlers are not associated 
with a native thread [Actually, we might make this an implementation 
detail: These Haskell threads are not guaranteed to be associated with 
a native thread. If it makes sense for some implementation, all threads 
might be associated with native threads].

There are now two kinds of foreign exported [and foreign import 
wrapped] functions: bound and free [I'm not happy with these names, for 
the same reasons as given by Seth before].

When a bound foreign exported function is invoked [by foreign code], 
the implementation checks whether a Haskell thread is associated with 
the current OS thread.
If there is one, this Haskell thread is used to execute the callback.
If there is none, a new Haskell thread is created and associated with 
the native thread. This is the only situation where a Haskell thread is 
associated with a native thread. The new associated Haskell thread is 
then used to execute the callback. When the callback finishes, the 
Haskell thread is terminated, the association is dissolved, but the OS 
thread continues to run.

When a free foreign exported function is invoked, the implementation 
may freely choose what Haskell thread the function is executed in. It 
is not specified whether this thread is associated with a particular OS 
thread or not.

When a foreign imported function is invoked [by Haskell code], the 
foreign code is executed in the native thread associated with the 
current Haskell thread, if an association exists. If the current 
Haskell thread is not associated to a native thread, the implementation 
may freely decide which thread to run the foreign function in.
This must be done for all foreign imports, including  unsafe.
An unsafe call must not call back to Haskell or otherwise cause a 
garbage collection. Other Haskell threads may be blocked while the 
unsafe call executes.
A safe call allows callbacks to Haskell. Other Haskell threads may be 
blocked while the unsafe call executes.
A threadsafe call additionally guarantees other Haskell threads not to 
block.

forkNativeThread :: IO () - IO ThreadID may be implemented using the 
FFI and an OS-specific thread creation routine.

Issues
~~

Finalizers and signal handlers cannot be associated with a particular 
native thread. If they have to trigger an action in a particular native 
thread, a message has to be sent manually (via MVars and friends) to 
the Haskell thread associated with the native thread in question. This 
might be tedious, but if we want to avoid the nastiness of multiple 
Haskell threads associated with one OS thread (lots of unpredictable 
blocking), it looks like our only choice.

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Native Threads in the RTS

2002-11-22 Thread Nicolas Oury
Hello,
I read your proposal. It's great but I have a few remarks :

* I think that, if it is not too much complicated, it could be great to 
put many threads in the OpenGL OS thread. The goal of concurrent Haskell 
was to allow concurrency for expressivity. It would be a pity to lose 
this in part of programs for technical reason. Having this possibility 
would also be a pro this language : Haskell would be the only language 
to have safe multithreaded OpenGL programming.

*Another problem can raise : if one render in two different OpenGL 
windows, he may want to use different threads for these rendering. 
However, this is impossible for the moment because it would implies that 
user threads know when a switch has occurred to a thread rendering in 
another context and swap OpenGL context.  This implies a notion of 
either : allowing to execute arbitrary code on switch ; either 
introducing a notion of family of threads. When a switch occurs to a 
member of a family different of the last member of the family executed , 
some user defined code should be  executed (in that case the code 
perform a context switch). family and members of family would be defined 
by user.  It seems that family and OS threads are independent : it could 
either be multiple OS threads for a family or multiple families for an 
OS threads. I think a thread could be member of multiple families (even 
if I can't see pertinent example so far). I also think that multiple 
threads can be the same member of a family (multiple threads drawing in 
the same window).

* A simple way of introducing these new notions (family, members,  OS 
threads) would be to define them as first class value.
  This would ease the problem of callback : an OpenGL callback would 
simply be a call to an operator telling the OpenGL thread to execute 
really the callback. threadsafe could be a short hand for wrapping a 
callback in a call to the thread currently executing (at time of the 
call to threadsafe function) and give it to extern function.


* To protect OpenGL operations, it would perhaps be useful to introduce 
a mechanism forbidding to switch between members of a family between a 
critical section. (I don't know what do a context switch between a 
glBegin and glEnd).

I don't know if my proposal is pertinent but it addresses some problems 
that would arise. It's quite complicated but i think that there is no 
overcost for people who don't need using it.


Best regards,
Nicolas Oury

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Native Threads in the RTS

2002-11-22 Thread Wolfgang Thaller
Nicolas Oury a écrit:


* I think that, if it is not too much complicated, it could be great 
to put many threads in the OpenGL OS thread. The goal of concurrent 
Haskell was to allow concurrency for expressivity. It would be a pity 
to lose this in part of programs for technical reason. Having this 
possibility would also be a pro this language : Haskell would be the 
only language to have safe multithreaded OpenGL programming.

You can safely render into two different OpenGL contexts from two 
different OS threads. I don't think that rendering into the same 
context from two green threads would work - the OpenGL interface is far 
too thread-based for this to be useful.

*Another problem can raise : if one render in two different OpenGL 
windows, he may want to use different threads for these rendering. 
However, this is impossible for the moment because it would implies 
that user threads know when a switch has occurred to a thread 
rendering in another context and swap OpenGL context.  This implies a 
notion of either : allowing to execute arbitrary code on switch ;  
[...]

If we want to render into two different OpenGL windows in parallel, we 
can use two OS threads. OpenGL keeps a reference to its current OpenGL 
context on a per-OS-thread basis (some old OpenGL implementations might 
not support this, but I think we can ignore them).

[...] some user defined code should be  executed (in that case the 
code perform a context switch) [...]

Haskell Code won't work here [after all, we're between two haskell 
threads...]. C code would be no problem. I actually proposed something 
like this as a stopgap measure for making OpenGL work with the threaded 
RTS in summer, but I was convinced by others on this list that this is 
a hackish solution that relies on internals of the RTS far too much.

It seems that family and OS threads are independent : it could either 
be multiple OS threads for a family or multiple families for an OS 
threads. I think a thread could be member of multiple families (even 
if I can't see pertinent example so far). I also think that multiple 
threads can be the same member of a family (multiple threads drawing 
in the same window).

What would it mean if a thread was a member of more than one thread 
families? Would it mean that it might execute in several different OS 
threads? Also, how would these thread groups interact with the existing 
threaded RTS? Would the existing features still be available without 
additional effort? Would they be implemented on top of these thread 
families?

I'm not quite convinced that the thread families approach would be 
worth the additional complexity. What would it be used for?

* To protect OpenGL operations, it would perhaps be useful to 
introduce a mechanism forbidding to switch between members of a family 
between a critical section. (I don't know what do a context switch 
between a glBegin and glEnd).

We already have MVars, they can be used for things like that.

Can anybody else think of reasons why we should need a more complicated 
design where threads are put into different families or groups, 
where each thread group executes in exactly one OS thread?
This has been proposed at least twice now, but I fail to see the 
advantages (it looks more flexible, but what's it _for_?).
Some disadvantages of a thread groups approach are:
*) More complexity.
*) Foreign calls will block other threads in the same group.
*) It would be even less meaningful for a haskell implementation that 
always uses OS threads --- the native/green threads proposal could be 
implemented as a no-op (forkNativeThread = forkIO) without breaking 
programs that use it.
Somebody else please fill in the advantages.

Cheers,
Wolfgang

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Native Threads in the RTS

2002-11-20 Thread Wolfgang Thaller
Great, thanks.  I hope you'll keep it up to date so that by the time  
the
discussion converges it can serve as a specification and rationale.  We
can put it in CVS too... Simon will think of where!

Until then, I'll play the role of a human CVS server.


Ultimately it'd be
worth integrating with
http://www.cse.unsw.edu.au/~chak/haskell/ghc/comm/rts-libs/multi- 
thread.
html

Of course. Some parts should be part of the user documentation, while  
others should probably be considered implentation details.

| A foreign exported
| callback that is called from C code executing in that OS thread is
| executed in the native haskell thread.

This is the bit I don't understand.   Is the only scenario you have in
mind here

	native Haskell thread
	calls C
	which calls Haskell

and you want all that in the same native thread?


Yes, exactly.


What about this?

	native Haskell thread
	calls C
	which installs a pointer to a foreign-exported Haskell function
		 in some C data structure

Later... some other Haskell thread
	calls C
	which waits for an event
	which calls the callback
So the callback was installed by a native thread, but won't be executed
by it.  Is that ok?


Definitely. It's the same way it works in C. What thread some code  
executes in depends on what thread the code is called from.

Anyway I think it would be worth explaining what is
guaranteed a bit more clearly.


I'm not sure how... to me it looks like I already specified this  
exactly ;-). Anyway, I've added some examples to the proposal to  
clarify what I mean.

| If a green haskell thread enters a foreign imported function marked
| as safe, all other green threads are blocked. Native haskell  
threads
| continue to run in their own OS threads.

No, I don't think so.  The reason that 'safe' is cheaper than
'threadsafe' is that the current worker OS thread does not need to
release the Big Lock it holds on the Haskell heap, thereby allowing
other green threads to run.   Instead, it holds the lock, executes the
call, and returns.  At least I think this is the idea, but it's all
jolly slippery.

I thought that was unsafe? The safe version still does quite a lot  
(after all, a callbacks are allowed, so is GC). In addition,  
threadsafe may start a new OS thread in order to keep executing green  
threads.
On the other hand, we might simply leave it unspecified: If people want  
to know what happens to other threads, they should use threadsafe or  
unsafe. The exact behaviour of safe seems to be an implementation  
detail.

| Other things I'm not sure about:

Presumably if a native thread spawns a thread using forkIO, it gets  
just
a green thread?  If it used forkNativeThread it gets a distinct native
thread.  Better say this.

The main program and all haskell threads forked using forkIO are green  
threads. Threads forked using forkNativeThread :: IO () - IO () are  
native threads.
I thought that was clear enough... I've added a note.

Cheers,

Wolfgang
*
Native Threads Proposal, version 2

Some foreign libraries (for example OpenGL) rely on a mechanism  
called thread-local storage. The meaning of an OpenGL call therefore  
usually depends on which OS thread it is called from. Therefore, some  
kind of direct mapping from Haskell threads to OS threads is necessary  
in order to use the affected foreign libraries.
Executing every haskell thread in its own OS thread is not feasible for  
performance reasons. However, perfomance of native OS threads is not  
too bad as long as there aren't too many, so I propose that some  
threads get their own OS threads, and some don't:

Every Haskell Thread can be either a green thread or a native  
thread.
For each native thread, there is exactly one OS thread created by the  
RTS. For a green thread, it is unspecified which OS thread it is  
executed in.
The main program and all haskell threads forked using forkIO are green  
threads. Threads forked using forkNativeThread :: IO () - IO () are  
native threads. (Note: The type of the current haskell thread does  
_not_ matter when forking new threads)

Execution of a green thread might move from one OS thread to another at  
any time. A green thread is never executed in an OS thread that is  
reserved for a native thread.
A native haskell thread and all foreign imported functions that it  
calls are executed in its associated OS thread. A foreign exported  
callback that is called from C code executing in that OS thread is  
executed in the native haskell thread.
A foreign exported callback that is called from C code executing in an  
OS thread that is not associated with a native haskell thread is  
executed in a new green haskell thread.

Only one OS thread can execute Haskell code at any given time.

If a native haskell thread enters a foreign imported function that is  
marked as safe or threadsafe, all other Haskell threads keep  
running. If the imported function is marked as unsafe, no other  
threads are executed until the call 

Re: Native Threads in the RTS

2002-11-19 Thread Nicolas Oury
Hello,
Le mardi 19 novembre 2002, à 01:28 , Wolfgang Thaller a écrit :


Nicolas Oury wrote:


I don't know if what I say is pertinent, but there was another problem 
that was discussed in the thread about threaded RTS.
One may want to use a finalizer in a particular thread.
For example, a finalizer that put make a rotating cube on screen must 
be ran in the same thread as the Opengl/GLUT things...

Good point. That feature won't be covered by my first proposal (As I 
said, I'll write up a proper document about that ASAP, that is, as soon 
as I find an entire hour of free time). It sounds useful at first, but 
I'm not that sure about it: after all, we can't rely on when the 
finalizer will be executed: the thread might no longer be around, and 
the GLUT window might be long closed. We should definitely think about 
it a little more, though.


These problems always appears with finalizer. An example (maybe a bit 
strange but) : one can want to close a window when the program can't 
reach it anymore. It may sound more realistic if it is closing an 
unreachable database with a databasse library made for one thread only...

I don't know if it is planned but I think it could be great to be able 
to have, in the new OS thread for OpenGL, an expressivity only
concurrence system. I mean that to be able to fork user threads that 
are executed in the new OS thread. These new threads  would be  
blocked on other threads in that kernel thread blocked, but can all 
access to this library, and will make programming easier.

This sounds a lot like the thread group idea that somebody had when 
we last discussed this. I think it gives us added flexibility at the 
cost of more difficult implementation and the danger of accidentally 
blocking OS threads [it might be just yet another source of bugs].


It is not bad that threads working in the OpenGL world are blocked when 
OpenGL can't receive orders.
The user would see new OS thread as a thread for a kind of group : group 
of people using OpenGL, are blocked wwhen OpenGl blocks. Think again of 
other example : imagine the glorious haskell web server  using a 
database library allowing only one thread access. One can't write all 
the request in only one thread, the programmer will have to add a 
monothreaded layer that serve requests from other threads that are 
preparing pages with database datas.

I don't know if that library (database monothread) exits but a good 
exercise would be to all try to find example library relevant to this 
problem.

I can start adding a small example :
SDL, which allows to manage every low level parts of 2D games and all 
that isn't OpenGl in an OpenGl game.

I have a small and dirty binder to SDL, and in SDL one have to use the 
same thread for pumping events (asking what have be done), than the one 
which was use to open video window !!!

A program would here be far better organize if multithreaded is allowed 
in one thread...

With that kind of problem, having a way to program multithreaded and run 
monothread is a power. As  there already is user level threads, it would 
be a pity to lose that.

I'll first write up something in order to explain/accurately define the 
simple solution I proposed. After that, we can still design a more 
complex solution that addresses these two issues.

Great,

Best regards,
Nicolas Oury



Cheers,

Wolfgang Thaller

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



RE: Native Threads in the RTS

2002-11-18 Thread Simon Peyton-Jones

| I propose adding something like
| 
| forkNativeThread :: IO () - IO ()

I haven't talked to Simon about this, but it sounds possible.  Three
thoughts.

First, before doing anything like this I'd like to ask you or someone
else, or a group, to write a clear exposition of what the problem is and
what the solution is, to add to the GHC user manual.  (If there are
implementation related questions, they can go into the Commentary.)  As
you say, this is a topic that we have visited regularly, and it's a
slippery one, so I'd like to capture it.

Second, there's the question of what it really means.  In particular,
what if that thread forks further (Haskell, green) threads?  Are they
too bound to the native thread?  A library you call might in principle
fork threads to get its job done...

Third

| If a callback is entered and the current OS thread corresponds to a
| native haskell thread, the callback should be executed in the current
| OS thread.
| Other haskell threads continue to run in the worker thread or in their
| own dedicated OS thread.

I'm not sure what this means.  What is the current OS thread?  Perhaps
an example? 

Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



RE: Native Threads in the RTS

2002-11-18 Thread Simon Marlow
 I'm still unconvinced that the  current optional
 RTS support for mixed green/native threads is the right way 
 to go. It looks to
 me like a workaround for poor OS support for really 
 lightweight threads.

It is a workaround for the lack of truly lightweight threads at the OS
level.  But I don't expect that situation to change, even with the
recent improvements on the Linux front.  The new RedHat Linux threads
folk claim to be able to create 10^5 threads in a couple of seconds,
whereas we can create 10^6 threads in about that time (on an old 500MHz
machine, too).

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: Native Threads in the RTS

2002-11-17 Thread Sven Panne
Wolfgang Thaller wrote:
 [...] I propose adding something like

 forkNativeThread :: IO () - IO ()

 which forks a new Haskell thread that has its own OS thread to execute
 in. Note that the fact that only one Haskell thread may execute at a
 time remains unchanged. [...]

I haven't thought very deeply about your proposal yet, but I don't understand
the remark above: What about e.g. a multi-processor Solaris machine (where
pthreads work as intended, not the rather poor stuff currently shipped with
Linux)? In such an environment there are often multiple processors executing
different threads (or LWPs, or whatever you call it) of the same process
simultaneously. Perhaps I misunderstood something here...  :-}

Nevertheless, you make a good point: Better support for real multi-threading
is definitely an area where I'd like to see some improvement for the next
non-patchlevel release of GHC. I'm still unconvinced that the current optional
RTS support for mixed green/native threads is the right way to go. It looks to
me like a workaround for poor OS support for really lightweight threads.

Cheers,
   S.

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: Native Threads in the RTS

2002-11-17 Thread Duncan Coutts
On Sun, 17 Nov 2002 12:23:06 +0100
Sven Panne [EMAIL PROTECTED] wrote:
 Nevertheless, you make a good point: Better support for real
 multi-threading is definitely an area where I'd like to see some
 improvement for the next non-patchlevel release of GHC. I'm still
 unconvinced that the current optional RTS support for mixed
 green/native threads is the right way to go. It looks to me like a
 workaround for poor OS support for really lightweight threads.

Which of course has been improving greatly recently - on Linux at least.
The 2.6 kernel will apparently have threading on par with Solaris. In
fact, the next Linux pthreads library looks as though it will be based
on a 1:1 model rather than a M:N model because it is simpler and (with
the recent threading improvements) performs better.

So that means that all of ghc's major platforms (Solaris, Linux, Win32)
will have good OS thread support in the near future.

Duncan
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: Native Threads in the RTS

2002-11-17 Thread William Lee Irwin III
On Sun, 17 Nov 2002 12:23:06 +0100 Sven Panne wrote:
 Nevertheless, you make a good point: Better support for real
 multi-threading is definitely an area where I'd like to see some
 improvement for the next non-patchlevel release of GHC. I'm still
 unconvinced that the current optional RTS support for mixed
 green/native threads is the right way to go. It looks to me like a
 workaround for poor OS support for really lightweight threads.

On Sun, Nov 17, 2002 at 11:33:44AM +, Duncan Coutts wrote:
 Which of course has been improving greatly recently - on Linux at least.
 The 2.6 kernel will apparently have threading on par with Solaris. In
 fact, the next Linux pthreads library looks as though it will be based
 on a 1:1 model rather than a M:N model because it is simpler and (with
 the recent threading improvements) performs better.
 So that means that all of ghc's major platforms (Solaris, Linux, Win32)
 will have good OS thread support in the near future.

1:1 threading is inferior by virtue of resource scalability on 32-bit
machines. This is not the final word.


Bill
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



Re: Native Threads in the RTS

2002-11-17 Thread Wolfgang Thaller
I wrote:

 [...] Note that the fact that only one Haskell thread may execute at 
a
 time remains unchanged. [...]

Sven Panne wrote:

I haven't thought very deeply about your proposal yet, but I don't 
understand
the remark above: What about e.g. a multi-processor Solaris machine 
(where
pthreads work as intended,  [...]

We can't currently allow several Haskell threads to really run 
simultaneosly [e.g. on two separate processors, or preemtively 
scheduled on a single processor], because they always mutate the same 
global heap. Currently, GHC switches its green threads only at times 
when the heap is in a defined state [not truly preemptively]. There 
seems to be some SMP support in the RTS, I don't know if it ever 
worked. If anyone wants to fix/finish it, that would be great, but it's 
not what I'm proposing here.
My proposal is only a minimum solution intended to resolve the inherent 
incompatibility between the threaded RTS and libraries like OpenGL, 
which require thread-local-state.

Cheers,

Wolfgang


___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Native Threads in the RTS

2002-11-15 Thread Wolfgang Thaller
Hello All,

A while ago there was a discussion on the shortcomings of the threaded 
RTS (in short, it doesn't work with foreign APIs that use thread-local 
state, and that breaks HOpenGL). Back then, it was decided to just keep 
the threaded RTS off by default and to do something about it some time 
after 5.04.
I believe it's time to think about it again, so I'll take the liberty 
of proposing an extension to the RTS that might solve the problem.

I propose adding something like

forkNativeThread :: IO () - IO ()

which forks a new Haskell thread that has its own OS thread to execute 
in. Note that the fact that only one Haskell thread may execute at a 
time remains unchanged.
Whenever the scheduler determines that a native haskell thread is 
next, it sends the OS worker thread to sleep and wakes up the OS thread 
corresponding to the native haskell thread. When the native haskell 
thread yields again, so does the corresponding OS thread.

Foreign calls from normal (non-native) haskell threads should be 
handled in exactly the same way as they are currently.

If a callback is entered and the current OS thread corresponds to a 
native haskell thread, the callback should be executed in the current 
OS thread.
Other haskell threads continue to run in the worker thread or in their 
own dedicated OS thread.

Programs that don't use forkNativeThread won't be affected by the 
change. Thread switching to and from native threads will be slower, but 
not painfully slow.

Wrapping an entire HOpenGL program in forkNativeThread should solve the 
OpenGL/GLUT thread-local-state problem, for example, and who knows what 
else it is good for.

Any comments? Opinions?


Wolfgang

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users