Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

237 lines
7.8 KiB

  1. /*++
  2. Copyright (c) 1995-2000 Microsoft Corporation
  3. Module Name:
  4. synlock.c
  5. Abstract:
  6. Implementation of the intel locked instructions. All locked instructions
  7. wait on a single global mutex (shared between processes). This takes care
  8. of any synchronization problem between intel processes. Instructions which
  9. access aligned 32bit memory are also synchronized with native processes
  10. via the functions in lock.c.
  11. Author:
  12. 22-Aug-1995 t-orig (Ori Gershony)
  13. Revision History:
  14. 24-Aug-1999 [askhalid] copied from 32-bit wx86 directory and make work for 64bit.
  15. --*/
  16. #include <nt.h>
  17. #include <ntrtl.h>
  18. #include <nturtl.h>
  19. #include <windows.h>
  20. #include <stdio.h>
  21. #include "fragp.h"
  22. #include "cpumain.h"
  23. #include "lock.h"
  24. #include "synlock.h"
  25. //
  26. // The following two variables are used to synchronize intel instructions
  27. // with the LOCK prefix. The critical section is a lot faster, but it does
  28. // not guarantee synchronization in shared memory. Eventually we should use
  29. // the critical section by default, and the mutex for certain applications which
  30. // need it (maybe get a list from the registry).
  31. //
  32. HANDLE Wx86LockSynchMutexHandle;
  33. RTL_CRITICAL_SECTION Wx86LockSynchCriticalSection;
  34. //
  35. // The following variable decided which synchronization object is used
  36. // Remove the '#define' below to allow runtime selection of whether
  37. // x86 LOCK: prefixes on 8-bit and 16-bit instructions and unaligned
  38. // 32-bit instructions are synchronized across the entire machine
  39. // or only within the current process. With the '#define' present,
  40. // LOCK: prefixes imply only per-process synchronization.
  41. //
  42. SYNCHOBJECTTYPE SynchObjectType;
  43. #define SynchObjectType USECRITICALSECTION
  44. #define GET_SYNCHOBJECT \
  45. if (SynchObjectType == USECRITICALSECTION){ \
  46. RtlEnterCriticalSection(&Wx86LockSynchCriticalSection); \
  47. } else { \
  48. WaitForSingleObject(Wx86LockSynchMutexHandle, INFINITE);\
  49. }
  50. #define RELEASE_SYNCHOBJECT \
  51. if (SynchObjectType == USECRITICALSECTION){ \
  52. RtlLeaveCriticalSection(&Wx86LockSynchCriticalSection); \
  53. } else { \
  54. ReleaseMutex(Wx86LockSynchMutexHandle); \
  55. }
  56. //
  57. // Macros for 8 bit fragments
  58. //
  59. #define SLOCKFRAG1_8(x) \
  60. FRAG1(SynchLock ## x ## Frag8, unsigned char) \
  61. { \
  62. GET_SYNCHOBJECT \
  63. x ## Frag8 (cpu, pop1); \
  64. RELEASE_SYNCHOBJECT \
  65. }
  66. #define SLOCKFRAG2_8(x) \
  67. FRAG2(SynchLock ## x ## Frag8, unsigned char) \
  68. { \
  69. GET_SYNCHOBJECT \
  70. x ## Frag8 (cpu, pop1, op2); \
  71. RELEASE_SYNCHOBJECT \
  72. }
  73. #define SLOCKFRAG2REF_8(x) \
  74. FRAG2REF(SynchLock ## x ## Frag8, unsigned char) \
  75. { \
  76. GET_SYNCHOBJECT \
  77. x ## Frag8 (cpu, pop1, pop2); \
  78. RELEASE_SYNCHOBJECT \
  79. }
  80. //
  81. // Macros for 16 bit fragments
  82. //
  83. #define SLOCKFRAG1_16(x) \
  84. FRAG1(SynchLock ## x ## Frag16, unsigned short) \
  85. { \
  86. GET_SYNCHOBJECT \
  87. x ## Frag16 (cpu, pop1); \
  88. RELEASE_SYNCHOBJECT \
  89. }
  90. #define SLOCKFRAG2_16(x) \
  91. FRAG2(SynchLock ## x ## Frag16, unsigned short) \
  92. { \
  93. GET_SYNCHOBJECT \
  94. x ## Frag16 (cpu, pop1, op2); \
  95. RELEASE_SYNCHOBJECT \
  96. }
  97. #define SLOCKFRAG2REF_16(x) \
  98. FRAG2REF(SynchLock ## x ## Frag16, unsigned short) \
  99. { \
  100. GET_SYNCHOBJECT \
  101. x ## Frag16 (cpu, pop1, pop2); \
  102. RELEASE_SYNCHOBJECT \
  103. }
  104. //
  105. // Macros for 32 bit fragments
  106. // Note: in the 32bit case, we check if pop1 is aligned and
  107. // call the lock version if it is.
  108. //
  109. #define SLOCKFRAG1_32(x) \
  110. FRAG1(SynchLock ## x ## Frag32, unsigned long) \
  111. { \
  112. GET_SYNCHOBJECT \
  113. if (((ULONG)(ULONGLONG)pop1 & 0x3) == 0){ \
  114. Lock ## x ## Frag32 (cpu, pop1); \
  115. } else { \
  116. x ## Frag32 (cpu, pop1); \
  117. } \
  118. RELEASE_SYNCHOBJECT \
  119. }
  120. #define SLOCKFRAG2_32(x) \
  121. FRAG2(SynchLock ## x ## Frag32, unsigned long) \
  122. { \
  123. GET_SYNCHOBJECT \
  124. if (((ULONG) (ULONGLONG)pop1 & 0x3) == 0){ \
  125. Lock ## x ## Frag32 (cpu, pop1, op2); \
  126. } else { \
  127. x ## Frag32 (cpu, pop1, op2); \
  128. } \
  129. RELEASE_SYNCHOBJECT \
  130. }
  131. #define SLOCKFRAG2REF_32(x) \
  132. FRAG2REF(SynchLock ## x ## Frag32, unsigned long) \
  133. { \
  134. GET_SYNCHOBJECT \
  135. if (((ULONG)(ULONGLONG)pop1 & 0x3) == 0){ \
  136. Lock ## x ## Frag32 (cpu, pop1, pop2); \
  137. } else { \
  138. x ## Frag32 (cpu, pop1, pop2); \
  139. } \
  140. RELEASE_SYNCHOBJECT \
  141. }
  142. //
  143. // Monster macros!
  144. //
  145. #define SLOCKFRAG1(x) \
  146. SLOCKFRAG1_8(x) \
  147. SLOCKFRAG1_16(x) \
  148. SLOCKFRAG1_32(x)
  149. #define SLOCKFRAG2(x) \
  150. SLOCKFRAG2_8(x) \
  151. SLOCKFRAG2_16(x) \
  152. SLOCKFRAG2_32(x)
  153. #define SLOCKFRAG2REF(x) \
  154. SLOCKFRAG2REF_8(x) \
  155. SLOCKFRAG2REF_16(x) \
  156. SLOCKFRAG2REF_32(x)
  157. //
  158. // Now finally the actual fragments
  159. //
  160. SLOCKFRAG2(Add)
  161. SLOCKFRAG2(Or)
  162. SLOCKFRAG2(Adc)
  163. SLOCKFRAG2(Sbb)
  164. SLOCKFRAG2(And)
  165. SLOCKFRAG2(Sub)
  166. SLOCKFRAG2(Xor)
  167. SLOCKFRAG1(Not)
  168. SLOCKFRAG1(Neg)
  169. SLOCKFRAG1(Inc)
  170. SLOCKFRAG1(Dec)
  171. SLOCKFRAG2REF(Xchg)
  172. SLOCKFRAG2REF(Xadd)
  173. SLOCKFRAG2REF(CmpXchg)
  174. FRAG2REF(SynchLockCmpXchg8bFrag32, ULONGLONG)
  175. {
  176. GET_SYNCHOBJECT
  177. if (((ULONG)(ULONGLONG)pop1 & 0x7) == 0){
  178. LockCmpXchg8bFrag32 (cpu, pop1, pop2);
  179. } else {
  180. CmpXchg8bFrag32 (cpu, pop1, pop2);
  181. }
  182. RELEASE_SYNCHOBJECT
  183. }
  184. //
  185. // Bts, Btr and Btc only come in 16bit and 32bit flavors
  186. //
  187. SLOCKFRAG2_16(BtsMem)
  188. SLOCKFRAG2_16(BtsReg)
  189. SLOCKFRAG2_16(BtrMem)
  190. SLOCKFRAG2_16(BtrReg)
  191. SLOCKFRAG2_16(BtcMem)
  192. SLOCKFRAG2_16(BtcReg)
  193. SLOCKFRAG2_32(BtsMem)
  194. SLOCKFRAG2_32(BtsReg)
  195. SLOCKFRAG2_32(BtrMem)
  196. SLOCKFRAG2_32(BtrReg)
  197. SLOCKFRAG2_32(BtcMem)
  198. SLOCKFRAG2_32(BtcReg)