Date: Thu, 18 Sep 2003 14:43:40 +1000 (EST) From: Bruce Evans <bde@zeta.org.au> To: Alan Cox <alc@cs.rice.edu> Cc: smp@freebsd.org Subject: Re: atomicity of unlocked reads Message-ID: <20030918134424.N1635@gamplex.bde.org> In-Reply-To: <20030917182237.GM12711@cs.rice.edu> References: <XFMail.20030917114537.jhb@FreeBSD.org> <20030917182237.GM12711@cs.rice.edu>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 17 Sep 2003, Alan Cox wrote: > On Wed, Sep 17, 2003 at 10:50:58AM -0700, Frank Mayhar wrote: > > John Baldwin wrote: > > > I think you can assume that the read will be atomic. I don't think FreeBSD > > > would work very well on a machine where aligned pointer reads/writes weren't > > > atomic. > > > > I dunno, I tend to think that making such assumptions may well come back to > > bite me in the ass when I least expect it. In such situation, I invariably > > use some kind of "atomic_xxx_load/store" primitive that does the job safely > > and in a machine-dependent way while hiding the details from the MI code. > > Indeed. Atomicity of the read is not the only issue. Unless I > misunderstood, Bruce is proposing to perform an unsynchronized read of > a location that is updated by a different processor. This > unsynchronized read is to obtain a pointer. In weaker memory > consistency models (than that of the x86), there is no guarantee that > the data that the pointer refers to will be consistent. In other > words, updates to the data that the pointer refers to may not have > completed, even though the update to the memory location containing > the pointer has completed. The data is known to be consistent in my application. I'm just implementing a circular buffer with essentially 1 writer and 1 reader (they can be on different CPUs and the writer can be different, but locking for each gives coherency. Only the writer writes to the buffer, so the data is always consistent. The reader advances the read pointer (normally without telling the writer), and the writer only needs the read pointer to determine the space available for writing. If it sees an old value then it underestimates the space, but there is no a problem because the writer will get woken up by the reader when the space goes below a watermark. If the writer sees a garbage value then it will compute a garbage amount of space and may write more than fits. Reading the read pointer without locking is only a micro-optimization here, but I believe there are some lengthy list traversals that would benefit from similar optimizations. (Don't lock each element or the whole list, but somehow ensure that the elements or the list pointers in them are not garbage even if they are stale.) > This is what an "acquire load" is for. Roughly speaking, it should > guarantee that any updates prior to a corresponding "release store" > (by a different processor) will be seen. For the optimized circular buffer, stricter locking of the write pointer is required for essentially this reason. The situation with the read and write pointers is not symmetrical like I said when I started this thread. Fortunately, stricter locking for the write pointer is more natural and I already did it without thinking much about it. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030918134424.N1635>