From owner-freebsd-arch Tue Sep 12 12:54:43 2000 Delivered-To: freebsd-arch@freebsd.org Received: from pcnet1.pcnet.com (pcnet1.pcnet.com [204.213.232.3]) by hub.freebsd.org (Postfix) with ESMTP id 89C9A37B423 for ; Tue, 12 Sep 2000 12:54:38 -0700 (PDT) Received: (from eischen@localhost) by pcnet1.pcnet.com (8.8.7/PCNet) id PAA27821; Tue, 12 Sep 2000 15:54:17 -0400 (EDT) Date: Tue, 12 Sep 2000 15:54:17 -0400 (EDT) From: Daniel Eischen To: Jason Evans Cc: Matthew Jacob , arch@FreeBSD.ORG Subject: Re: Necessary synchronization primitives (was Re: cvs commit: [...] yarrow.c [...]) In-Reply-To: <20000912113445.F31089@blitz.canonware.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On 12 Sep 2000, Jason Evans wrote: > Executive summary: My experience has indicated that 1) mutexes, 2) > condition variables, 3) barriers, and 4) message queues are an adequate set > of locking primitives for almost any problem. > > I've been drooling over threads since being introduced to OS/2 in 1992. I > actually started using threads in significant ways in about 1996. The last > 5 years have taught me a few lessons about what is useful versus what > sounds good on paper. To make it clear where this email is going, I'll > start off by saying "reader/writer locks are rarely useful", and later on > will add support to that opinion. > > Here's a laundry list of synchronization primitives, in approximately > increasing order of complexity: > > * mutex {blocking, spinning, adaptive, recursive} > > Simple mutual exclusion lock, in many flavors. Only one thread can own a > mutex at a time. > > - blocking > > If a thread tries to acquire a mutex that is already owned, the thread > will block until it is granted the mutex (i.e. the previous owner > releases the mutex). > > - spinning > > If a thread tries to acquire a mutex that is already owned, the threads > spins in a tight loop, trying again and again to acquire the mutex > until it succeeds. Spin mutexes tend to be very dangerous and > difficult to use correctly. In userland, spinning mutexes are almost > always a bad idea (though not *always*). In the kernel, and in > threading library implementations, there are decidedly legitimate > reasons for using spinning mutexes. > > - adaptive > > A spinning mutex that blocks after a certain amount of spinning. In > userland programming, these pretty much remove any need for pure > spinning mutexes. > > - recursive > > A thread can acquire the same mutex more than once, recursively. Until > the SMP work, I never used recursive mutexes. In my opinion, if > recursive mutexes are needed to solve a programming problem, then the > problem needs to be re-thought. That is, recursive mutexes are a > crutch, not a necessity. However, given that we're converting an old > piece of code to being threaded, there are a number of places where > recursive mutexes save us from having to rip major portions of the > kernel to pieces. Hopefully we can keep recursive mutex use to a > minimum, but from a pragmatic point of view, we need them, at least > for now. I agree with everything you've said here, elsewhere in this Email, and in recommending the Butenhof book. I also want to add that I hate recursive mutexes :-) Perhaps now is not the right time, but I'd like to see our kernel mutex (mtx) not support recursve mutexes. We could provide a different set of functions (and perhaps a different data structure) that would be optimized explicitly for recursive mutexes (still discouraging their use). This would hopefully help us in eliminating the hideous flags needed for mtx_enter(), instead relying on the flags provided at mtx_init() time. -- Dan Eischen To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message