
On 26 February 2005 12:14, Marcin 'Qrczak' Kowalczyk wrote:
Wolfgang Thaller
writes: Since the main thread is bound, and unbound threads are never executed on an OS thread which has some Haskell thread bound, this would imply that when the main thread spawns a Haskell thread and they synchronize a lot with each other using MVars, the synchronization needs OS-thread synchronization - the threads will not execute on a the same OS thread.
Correct.
Is it important which thread executes Haskell code (I bet no) and unsafe foreign calls (I don't know)? If not, couldn't the same OS thread execute code of both threads until a safe foreign call is made?
Actually in a bound thread, *all* foreign calls must be made using the correct OS thread, not just the safe ones. So your scheme would involve a context switch at every foreign call, which would end up being rather expensive. It's certainly a legitimate implementation, but I suspect not one that would lead to good performance. Cheers, Simon

"Simon Marlow"
Is it important which thread executes Haskell code (I bet no) and unsafe foreign calls (I don't know)? If not, couldn't the same OS thread execute code of both threads until a safe foreign call is made?
Actually in a bound thread, *all* foreign calls must be made using the correct OS thread, not just the safe ones. So your scheme would involve a context switch at every foreign call, which would end up being rather expensive.
Ok. As I understand this (and as I'm trying to implement a similar scheme for my language), when an unbound thread performs a safe C call, the current OS thread transforms from a worker to a bound thread, and another worker is spawn if needed for remaining Haskell threads. So I have another idea: Why is the main thread bound? Wouldn't it be sufficient that, in cases where it's important to have the main Haskell thread bound to the main OS thread, the programmer wraps the main computation in a function which calls C and then calls back Haskell? Such function, if executed before spawning other threads which perform safe C calls, would in effect bind the threads together. That way there would be no OS thread synchronization needed when the main Haskell thread synchronizes with unbound threads. -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/

Marcin 'Qrczak' Kowalczyk
Why is the main thread bound?
I can answer myself: if the main thread is unbound, the end of the program can be reached in a different OS thread, which may be a problem if we want to return cleanly to the calling code. I've now implemented a threaded runtime in my language Kogut, based on the design of Haskell. The main thread is bound. The thread which holds the capability performs I/O multiplexing itself, without a separate service thread. Producer/consumer ping-pong is 15 times slower between threads running on different OS threads than on two unbound threads. -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/

On Tuesday 01 March 2005 12:20, Marcin 'Qrczak' Kowalczyk wrote:
Marcin 'Qrczak' Kowalczyk
writes: Why is the main thread bound?
I can answer myself: if the main thread is unbound, the end of the program can be reached in a different OS thread, which may be a problem if we want to return cleanly to the calling code.
I've now implemented a threaded runtime in my language Kogut, based on the design of Haskell. The main thread is bound. The thread which holds the capability performs I/O multiplexing itself, without a separate service thread.
Producer/consumer ping-pong is 15 times slower between threads running on different OS threads than on two unbound threads.
Which OS? Ben

Benjamin Franksen
Producer/consumer ping-pong is 15 times slower between threads running on different OS threads than on two unbound threads.
Which OS?
Linux/NPTL. A context switch which changes OS threads involves: setitimer pthread_sigmask pthread_mutex_lock pthread_cond_signal pthread_cond_wait (starting) and in the other thread: pthread_cond_wait (returning) pthread_mutex_unlock pthread_sigmask setitimer setitimer is necessary because I tested that it is installed per thread rather than per process, even though SUSv3 says it should be per process. pthread_sigmask makes the thread holding the capability handle signals. I've heard that the interaction of signals and threads is broken in pre-NPTL Linux threads, I will have to check how it behaves and what should be used in this case (perhaps having signals unblocked in all threads). -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/
participants (3)
-
Benjamin Franksen
-
Marcin 'Qrczak' Kowalczyk
-
Simon Marlow