This is the mail archive of the cygwin-developers@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

consistent version of Interlocked* functions

[Get raw message]
A while ago, I wrote (or acquired -- can't remember exactly) some inline
assembly versions of the Interlocked* functions but never ended up
adding them to cygwin.

It occurred to me today that I should dust these off again and use them
in the cygwin source.  Why?  In addition to the fact that they should be
faster than the ones available from the library, they also are
consistent on all versions of Windows.  I.e., the value returned by
InterlockedIncrement is the incremented value, not some random value
with the same sign as the value.

The only thing I'm not sure about is if there is a corner case that I
missed.  Everything works fine "for me" but you never know...

The functions are below.

Are there any objections to my using these?  Robert?  The thread code
would be the most affected, of course.

cgf

#ifndef _INTERLOCK_H
#define _INTERLOCK_H
extern __inline__ long ilockincr (long *m)
{
  register int __res;
  __asm__ __volatile__ ("\n\
	movl	$1,%0\n\
	lock	xadd %0,(%1)\n\
	inc	%0\n\
	": "=a" (__res), "=r" (m): "1" (m));
  return __res;
}
extern __inline__ long ilockdecr (long *m)
{
  register int __res;
  __asm__ __volatile__ ("\n\
	movl	$0xffffffff,%0\n\
	lock	xadd %0,(%1)\n\
	dec	%0\n\
	": "=a" (__res), "=r" (m): "1" (m));
  return __res;
}
extern __inline__ long ilockexch (long *t, long v)
{
  register int __res;
  __asm__ __volatile__ ("\n\
	movl	(%2),%0\n\
1:	lock	cmpxchgl %3,(%1)\n\
	jne 1b\n\
 	": "=a" (__res), "=c" (t): "1" (t), "d" (v));
  return __res;
}
#endif /*_INTERLOCK_H*/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]