Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 7 Jul 1997 11:22:13 -0700 (MST)
From:      Terry Lambert <terry@lambert.org>
To:        wes@bogon.net (Wes Santee)
Cc:        hackers@FreeBSD.ORG
Subject:   Re: Is there a thread-happy recv()?
Message-ID:  <199707071822.LAA18058@phaeton.artisoft.com>
In-Reply-To: <199707070459.VAA05316@kryten.bogon.net> from "Wes Santee" at Jul 6, 97 09:59:58 pm

next in thread | previous in thread | raw e-mail | index | archive | help
> Hi all.  I noticed in a chunk of code I'm writing that a blocking call
> to recv() is putting the entire process to sleep such that even the
> other threads in the process are blocked from executing.  I'm linking
> against libc_r (2.2-STABLE cvsup'd July 3rd) right now, is there
> anything else I should be doing to stop recv() (or any blocking call
> for that matter) from suspending the entire process?

Yes.

The threads package operates through call conversion, where a
call on a putatively blocking fd is made instead on a non-blocking
fd, and select is used as a multiplexer.

Note that mutexes are not selectable objects.

I had a similar problem under DEC's MTS when extending Mentat Streams
for VMS (MTS is an internal DEC product: "MultiThreading Services").
I ended up having to add event flags, and so on (my BLISS was rusty
at the time; so far as I know, DEC just took the code in its
entirety).

Probably the correct method of dealing with the problem is to
use rfork() instead; this is one planned option; effectively it
means mapping user space threads to kernel "threads".

Another possibility is to use an async call gate instead of
non-blocking I/O.  A call which could block would be tagged,
and a context record generated.  If the call blocked, the
context record would be returned; if not, the call would
complete.  This is similar to the VMS soloution for mutexes,
using event flag clusters, which I ended up with for event
dispatch.  Effectively, you are implementing asynchronus
system traps.

Unfortunately, neither of these soloutions is available without
more than a bit of hacking (mostly on the threads implementation).


> At first I thought this shouldn't be possible, but I set up another
> test where no blocking calls are issued in either thread ('cept for
> the pthread calls themselves), and everything worked just fine.

This is an order-of-operation issue.  You might also be able to
overcome it by issuing an explicit yield before attempting to
acquire the mutex in T1 so that T2 has the CPU in order to
complete it's processing.  This is a bit of a kludge, given
that it requires you to know when there are potential lock-stepping
issues.  The code that results will be implementation dependent,
meaning that the workaround might cause the code to fail on another
(different) threads implementation.  If portability isn't an issue,
then this is probably the way to go.


					Terry Lambert
					terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199707071822.LAA18058>