* fhandler.h (refcnt): Add i interlocked. Explain why.
* winbase.h (ilockadd): New function. (InterlockedAdd): Define as ilockadd.
This commit is contained in:
		| @@ -1,3 +1,9 @@ | ||||
| 2012-05-23  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* fhandler.h (refcnt): Add i interlocked.  Explain why. | ||||
| 	* winbase.h (ilockadd): New function. | ||||
| 	(InterlockedAdd): Define as ilockadd. | ||||
|  | ||||
| 2012-05-22  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* devices.in: Fix native name of /dev/kmem. | ||||
|   | ||||
| @@ -185,7 +185,11 @@ class fhandler_base | ||||
|   long refcnt(long i = 0) | ||||
|   { | ||||
|     debug_only_printf ("%p, %s, i %d, refcnt %ld", this, get_name (), i, _refcnt + i); | ||||
|     return _refcnt += i; | ||||
|     /* This MUST be an interlocked operation.  If multiple threads access the | ||||
|        same descriptor in quick succession, a context switch can interrupt | ||||
|        the += operation and we wrongly end up with a refcnt of 0 in the | ||||
|        cygheap_fdget destructor. */ | ||||
|     return i ? InterlockedAdd (&_refcnt, i) : _refcnt; | ||||
|   } | ||||
|   class fhandler_base *archetype; | ||||
|   int usecount; | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| /* winbase.h | ||||
|  | ||||
|    Copyright 2002, 2003, 2004, 2008 Red Hat, Inc. | ||||
|    Copyright 2002, 2003, 2004, 2008, 2012 Red Hat, Inc. | ||||
|  | ||||
| This software is a copyrighted work licensed under the terms of the | ||||
| Cygwin license.  Please consult the file "CYGWIN_LICENSE" for | ||||
| @@ -11,6 +11,21 @@ details. */ | ||||
| #ifndef _WINBASE2_H | ||||
| #define _WINBASE2_H | ||||
|  | ||||
| /* For some unknown reason, InterlockedAdd is only supported on Itanium | ||||
|    when using the Windows headers.  Fortunately we're not restricted to the | ||||
|    Windows headers :) */ | ||||
| extern __inline__ long | ||||
| ilockadd (volatile long *m, long value) | ||||
| { | ||||
|   register int __res; | ||||
|   __asm__ __volatile__ ("\n\ | ||||
| 	movl	%3,%0\n\ | ||||
| 	lock	xadd %0,%1\n\ | ||||
| 	addl	%3,%0\n\ | ||||
| 	": "=&r" (__res), "=m" (*m): "m" (*m), "r" (value): "cc"); | ||||
|   return __res; | ||||
| } | ||||
|  | ||||
| extern __inline__ long | ||||
| ilockincr (volatile long *m) | ||||
| { | ||||
| @@ -65,6 +80,8 @@ ilockcmpexch (volatile long *t, long v, long c) | ||||
|   }); | ||||
| } | ||||
|  | ||||
| #undef InterlockedAdd | ||||
| #define InterlockedAdd ilockadd | ||||
| #undef InterlockedIncrement | ||||
| #define InterlockedIncrement ilockincr | ||||
| #undef InterlockedDecrement | ||||
|   | ||||
		Reference in New Issue
	
	Block a user