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>