[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