[M3devel] race conditions under loose memory models/ compiler/processor reordering
Jay
jay.krell at cornell.edu
Mon Jan 5 06:01:49 CET 2009
This code is very likely buggy, due to compiler or processor reordering, in a multithread environment, which we have.
Prior to my change, it only required multiple threads to have a race condition.
We need some sort of "barriers", as they are called.
The writes to null_done must "divide" the code before it and the code after it.
While they appear to, in the source, this is not likely guaranteed by the compiler or processor.
It doesn't matter in a single threaded environment, but they don't generally exist.
Or maybe an ability to mark variables as "volatile".
In C, a fairly portable overkill fix is to sprinkle around volatile, but that generally makes the code more deoptimized than necessary. Volatile inhibits any reads or writes of the variable from being optimized away, and generally any reordering. However not all reads/writes need such treatment. Imagine a function that initialized a global on-demand, and then return that global plus itself -- the addition need only fetch the value once.
What to do?
VAR null_done := FALSE; null_stat: Ustat.struct_stat; null_fd: INTEGER;
PROCEDURE IsDevNull(READONLY statbuf: Ustat.struct_stat): BOOLEAN RAISES {} = VAR result: INTEGER; BEGIN IF NOT null_done THEN null_fd := Unix.open(M3toC.FlatTtoS("/dev/null"), Unix.O_RDONLY, Unix.Mrwrwrw); IF null_fd < 0 THEN; null_done := TRUE; RETURN FALSE ELSE result := Ustat.fstat(null_fd, ADR(null_stat)); EVAL Unix.close(null_fd); IF result # 0 THEN null_fd := -1 END END; null_done := TRUE; END; RETURN null_fd >= 0 AND statbuf.st_rdev = null_stat.st_rdev END IsDevNull;
- Jay> Date: Mon, 5 Jan 2009 05:37:13 +0000> To: m3commit at elegosoft.com> From: jkrell at elego.de> Subject: [M3commit] CVS Update: cm3> > CVSROOT: /usr/cvs> Changes by: jkrell at birch. 09/01/05 05:37:13> > Modified files:> cm3/m3-libs/libm3/src/os/POSIX/: FilePosix.m3 > > Log message:> reduce but don't eliminate race condition; before there was a race in a multithreaded code, now there is 'only' a race in multithreaded code under optimization that reorders writes (we need MemoryBarrier() for this kind of lock free on demand initialization of globals..)>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20090105/51ba8b61/attachment-0001.html>
More information about the M3devel
mailing list