From owner-freebsd-hackers Thu Jul 19 6:47:46 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from mx2.magma.ca (mx2.magma.ca [206.191.0.250]) by hub.freebsd.org (Postfix) with ESMTP id 7775237B401 for ; Thu, 19 Jul 2001 06:47:40 -0700 (PDT) (envelope-from louisphilippe@macadamian.com) Received: from mail3.magma.ca (mail3.magma.ca [206.191.0.221]) by mx2.magma.ca (8.9.3/8.9.3) with ESMTP id JAA23957; Thu, 19 Jul 2001 09:47:38 -0400 (EDT) Received: from durandal (mothership.macadamian.com [206.191.21.204]) by mail3.magma.ca (8.9.3/8.9.3) with SMTP id JAA07462; Thu, 19 Jul 2001 09:47:38 -0400 (EDT) Message-ID: <203501c11059$35755420$2964a8c0@macadamian.com> From: "Louis-Philippe Gagnon" To: Cc: References: <1fbd01c10fba$499834d0$2964a8c0@macadamian.com> <3B5690A1.8EDD0812@mindspring.com> Subject: Re: flock/pthread bug? Date: Thu, 19 Jul 2001 09:46:27 -0400 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 5.50.4133.2400 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Lots of ideas to try (esp. since I don't need FIFO); thanks! LPG ----- Original Message ----- From: "Terry Lambert" > Louis-Philippe Gagnon wrote: > > > > From: "Julian Elischer" > > > probably you should try : > > > > > > #define LOCK_NB 0x04 /* don't block when locking */ > > > > > But I do want to block; I just don't want the whole process to block. > > You can't block just a thread, since there is no "queue a > lock request" interface, only a "try to get the lock, and > return if you can't" or a "block and wait for the lock". > > In other words, flock() is one call that can't really be > reasonably implemented by the threads library, since > there is no way to map it safely, and still guarantee > against an order inversion deadlock. > > > > > Also if you have shared memory, why not use > > > > > > /* Get a spin lock, handle recursion inline (as the less common case) */ > > > Using the "cmpxchgl" instruction is your best approach; > I personally would not use the whole thing, as Julian > suggested, since I think the SMP synchronization ops > are much, much heavier than they should be. You don't > need that much overhead, you don't need reentrancy, and > you don't need it to do counting (neither does SMP). > > The easiest way to get shared memory is to use mmap() in > both programs on a file, and to madvise() the caching and > cache writeback off. This is much beeter than SYSV shared > memory (shmat, shmget, etc.), since it is properly resource > tracked, and you will not have a startup order of operation > problem, nor will you have the common problem of trying to > get rid of the segments, should any of your programs exit > abnormally. > > > I'd rather have something portable though, and I would > > still like to know if what I was doing should have worked... > > The answer is "no". Threads are not processes, they exist > in a single process context, as they currently exist. In > the future, what you are doing will work, but will have a > very high comparative overhead to other approaches. > > If you read Stevens, you will see that flock() is much > higher overhead than doing semop() calls. > > To wrap either, you would need to: > > retry: > st = try_non_blocking_get(); > if (st == FAIL) { > yield(); > goto retry; > } > > Note that the "yield" system call is non-standard, and you > will buzz-loop somewhat, depressing your priority. You > will also have a race window, subject to the "thundering > herd" problem. You could put a "sleep(1);" in place of > the "yield();" call... this would eliminate the buzzing > (somewhat), but would widen the race window. > > Another alternative is to use a multiended pipe, where > you write a single character token down the pipe, and > your programs block waiting for a single character read > to complete (you could use a FIFO or socket, in place of > the pipe). The point is that only a single reader can > get the character (the "token") at a time. > > Unfortuantely, since file I/O is implemented as a > conversion of a blocking call to a non-blocking call > plus a context switch (normal for a threads library), > you still have the "thundering herd" problem. > > Further, if your intent was to have the callers serviced > in the order they called the read, you can't: you will > never have a guarantee about who will be permitted to > complete the read first. > > So, for FIFO ordering, there's no way for you to solve > the problem; for semop or flock, you can solve the problem > portably with a "sleep - retry" loop, and not burn too > many cycles (but still lose FIFO ordering). > > If you absolutely _must_ have a FIFO, then you need to > either wait, or install the Linux threads port (Linux > threads are hideously expensive, compared to the current > FreeBSD threads implementation, since they effectively > create a new process for each thread, just like Linux > does), and use blocking operations using them. > > Probably, if you need FIFO ordering, whatever you are > doing would be better implemented as a finite state > automaton, or a "work-to-do" model, where you don't > really care who wins a race in a "thundering herd", > since all of your programs waiting on the condition > are identical. > > Worse comes to worse, you should consider implementing > your threads as real seperate processes (and not fake > ones, like in the Linux threads library). > > -- Terry > To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message