1 /* spinlock.h: Header file for cygwin time-sensitive synchronization primitive.
3 This file is part of Cygwin.
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
14 #define SPINLOCK_WAIT (15000LL * 10000LL)
25 InterlockedExchange (locker
, what
);
32 if (NtQuerySystemTime (&t
) == STATUS_SUCCESS
)
37 spinlock (LONG
& locktest
, LONG wanted_val
= 1, LONGLONG timeout
= SPINLOCK_WAIT
):
38 locker (&locktest
), setto (wanted_val
)
40 /* Quick test to see if we're already initialized */
41 if ((val
= locktest
) == wanted_val
)
43 /* Slightly less quick test to see if we are the first cygwin process */
44 else if ((val
= InterlockedExchange (locker
, -1)) == 0)
45 /* We're armed and dangerous */;
46 else if (val
== wanted_val
)
47 done (val
); /* This was initialized while we weren't looking */
50 long long then
= time ();
51 /* Loop waiting for some other process to set locktest to something
52 other than -1, indicating that initialization has finished. Or,
53 wait a default of 15 seconds for that to happen and, if it doesn't
54 just grab the lock ourselves. */
55 while ((val
= InterlockedExchange (locker
, -1)) == -1
56 && (time () - then
) < timeout
)
58 /* Reset the lock back to wanted_value under the assumption that is
59 what caused the above loop to kick out. */
61 val
= 0; /* Timed out. We'll initialize things ourselves. */
63 done (val
); /* Put back whatever was there before, assuming that
64 it is actually wanted_val. */
67 ~spinlock () {done (setto
);}
68 operator ULONG () const {return (ULONG
) val
;}
69 /* FIXME: This should be handled in a more general fashion, probably by
70 establishing a linked list of spinlocks which are freed on process exit. */
71 void multiple_cygwin_problem (const char *w
, unsigned m
, unsigned v
)
74 ::multiple_cygwin_problem (w
, m
, v
);
78 #endif /*_SPINLOCK_H*/