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.

398 lines
12 KiB

  1. title "Interlocked Support"
  2. ;++
  3. ;
  4. ; Copyright (c) 2000 Microsoft Corporation
  5. ;
  6. ; Module Name:
  7. ;
  8. ; intrlock.asm
  9. ;
  10. ; Abstract:
  11. ;
  12. ; This module implements functions to support interlocked operations.
  13. ;
  14. ; Author:
  15. ;
  16. ; David N. Cutler (davec) 23-Jun-2000
  17. ;
  18. ; Environment:
  19. ;
  20. ; Any mode.
  21. ;
  22. ;--
  23. include ksamd64.inc
  24. subttl "ExInterlockedAddLargeInteger"
  25. ;++
  26. ;
  27. ; LARGE_INTEGER
  28. ; ExInterlockedAddLargeInteger (
  29. ; IN PLARGE_INTEGER Addend,
  30. ; IN LARGE_INTEGER Increment,
  31. ; IN PKSPIN_LOCK Lock
  32. ; )
  33. ;
  34. ; Routine Description:
  35. ;
  36. ; This function performs an interlocked add of an increment value to an
  37. ; addend variable of type unsigned large integer. The initial value of
  38. ; the addend variable is returned as the function value.
  39. ;
  40. ; N.B. The specification of this function requires that the given lock
  41. ; must be used to synchronize the update even though on AMD64 the
  42. ; operation can actually be done atomically without using the lock.
  43. ;
  44. ; Arguments:
  45. ;
  46. ; Addend (rcx) - Supplies a pointer to a variable whose value is to be
  47. ; adjusted by the increment value.
  48. ;
  49. ; Increment (rdx) - Supplies the increment value to be added to the
  50. ; addend variable.
  51. ;
  52. ; Lock (r8) - Supplies a pointer to a spin lock to be used to synchronize
  53. ; access to the addend variable.
  54. ;
  55. ; Return Value:
  56. ;
  57. ; The initial value of the addend variable is returned.
  58. ;
  59. ;--
  60. LEAF_ENTRY ExInterlockedAddLargeInteger, _TEXT$00
  61. cli ; disable interrupts
  62. AcquireSpinLock r8 ; acquire spin lock
  63. mov rax, [rcx] ; get initial addend value
  64. add [rcx], rdx ; compute sum of addend and increment
  65. ReleaseSpinLock r8 ; release spin lock
  66. sti ; enable interrupts
  67. ret ; return
  68. LEAF_END ExInterlockedAddLargeInteger, _TEXT$00
  69. subttl "Interlocked Add Unsigned Long"
  70. ;++
  71. ;
  72. ; ULONG
  73. ; ExInterlockedAddUlong (
  74. ; IN PULONG Addend,
  75. ; IN ULONG Increment,
  76. ; IN PKSPIN_LOCK Lock
  77. ; )
  78. ;
  79. ; Routine Description:
  80. ;
  81. ; This function performs an interlocked add of an increment value to an
  82. ; addend variable of type unsinged long. The initial value of the addend
  83. ; variable is returned as the function value.
  84. ;
  85. ; N.B. The specification of this function requires that the given lock
  86. ; must be used to synchronize the update even though on AMD64 the
  87. ; opearion can actually be done atomically without using the lock.
  88. ;
  89. ; Arguments:
  90. ;
  91. ; Addend (rcx) - Supplies a pointer to a variable whose value is to be
  92. ; adjusted by the increment value.
  93. ;
  94. ; Increment (edx) - Supplies the increment value to be added to the
  95. ; addend variable.
  96. ;
  97. ; Lock (r8) - Supplies a pointer to a spin lock to be used to synchronize
  98. ; access to the addend variable.
  99. ;
  100. ; Return Value:
  101. ;
  102. ; The initial value of the addend variable.
  103. ;
  104. ;--
  105. LEAF_ENTRY ExInterlockedAddUlong, _TEXT$00
  106. cli ; disable interrupts
  107. AcquireSpinLock r8 ; acquire spin lock
  108. mov eax, [rcx] ; get initial addend value
  109. add [rcx], edx ; compute sum of addend and increment
  110. ReleaseSpinLock r8 ; release spin lock
  111. sti ; enable interrupts
  112. ret ; return
  113. LEAF_END ExInterlockedAddUlong, _TEXT$00
  114. subttl "Interlocked Insert Head List"
  115. ;++
  116. ;
  117. ; PLIST_ENTRY
  118. ; ExInterlockedInsertHeadList (
  119. ; IN PLIST_ENTRY ListHead,
  120. ; IN PLIST_ENTRY ListEntry,
  121. ; IN PKSPIN_LOCK Lock
  122. ; )
  123. ;
  124. ; Routine Description:
  125. ;
  126. ; This function inserts an entry at the head of a doubly linked list
  127. ; so that access to the list is synchronized in a multiprocessor system.
  128. ;
  129. ; Arguments:
  130. ;
  131. ; ListHead (rcx) - Supplies a pointer to the head of the doubly linked
  132. ; list into which an entry is to be inserted.
  133. ;
  134. ; ListEntry (rdx) - Supplies a pointer to the entry to be inserted at the
  135. ; head of the list.
  136. ;
  137. ; Lock (r8) - Supplies a pointer to a spin lock to be used to synchronize
  138. ; access to the list.
  139. ;
  140. ; Return Value:
  141. ;
  142. ; Pointer to entry that was at the head of the list or NULL if the list
  143. ; was empty.
  144. ;
  145. ;--
  146. LEAF_ENTRY ExInterlockedInsertHeadList, _TEXT$00
  147. cli ; disable interrupts
  148. AcquireSpinLock r8 ; acquire spin lock
  149. mov rax, LsFlink[rcx] ; get address of first entry
  150. mov LsFlink[rdx], rax ; set next link in entry
  151. mov LsBlink[rdx], rcx ; set back link in entry
  152. mov LsFlink[rcx], rdx ; set next link in head
  153. mov LsBlink[rax], rdx ; set back link in next
  154. ReleaseSpinLock r8 ; release spin lock
  155. sti ; enable interrupts
  156. xor rcx, rax ; check if list was empty
  157. jnz short Ih10 ; if nz, list not empty
  158. xor eax, eax ; list was empty
  159. Ih10: ret ; return
  160. LEAF_END ExInterlockedInsertHeadList, _TEXT$00
  161. subttl "Interlocked Insert Tail List"
  162. ;++
  163. ;
  164. ; PLIST_ENTRY
  165. ; ExInterlockedInsertTailList (
  166. ; IN PLIST_ENTRY ListHead,
  167. ; IN PLIST_ENTRY ListEntry,
  168. ; IN PKSPIN_LOCK Lock
  169. ; )
  170. ;
  171. ; Routine Description:
  172. ;
  173. ; This function inserts an entry at the tail of a doubly linked list
  174. ; so that access to the list is synchronized in a multiprocessor system.
  175. ;
  176. ; Arguments:
  177. ;
  178. ; ListHead (rcx) - Supplies a pointer to the head of the doubly linked
  179. ; list into which an entry is to be inserted.
  180. ;
  181. ; ListEntry (rdx) - Supplies a pointer to the entry to be inserted at the
  182. ; tail of the list.
  183. ;
  184. ; Lock (r8) - Supplies a pointer to a spin lock to be used to synchronize
  185. ; access to the list.
  186. ;
  187. ; Return Value:
  188. ;
  189. ; Pointer to entry that was at the tail of the list or NULL if the list
  190. ; was empty.
  191. ;
  192. ;--
  193. LEAF_ENTRY ExInterlockedInsertTailList, _TEXT$00
  194. cli ; disable interrupts
  195. AcquireSpinLock r8 ; acquire spin lock
  196. mov rax, LsBlink[rcx] ; get address of last entry
  197. mov LsFlink[rdx], rcx ; set next link in entry
  198. mov LsBlink[rdx], rax ; set back link in entry
  199. mov LsBlink[rcx], rdx ; set back link in head
  200. mov LsFlink[rax], rdx ; set next link in last
  201. ReleaseSpinLock r8 ; release spin lock
  202. sti ; enable interrupts
  203. xor rcx, rax ; check if list was empty
  204. jnz short It10 ; if nz, list not empty
  205. xor eax, eax ; list was empty
  206. It10: ret ; return
  207. LEAF_END ExInterlockedInsertTailList, _TEXT$00
  208. subttl "Interlocked Remove Head List"
  209. ;++
  210. ;
  211. ; PLIST_ENTRY
  212. ; ExInterlockedRemoveHeadList (
  213. ; IN PLIST_ENTRY ListHead,
  214. ; IN PKSPIN_LOCK Lock
  215. ; )
  216. ;
  217. ; Routine Description:
  218. ;
  219. ; This function removes an entry from the head of a doubly linked list
  220. ; so that access to the list is synchronized in a multiprocessor system.
  221. ; If there are no entries in the list, then a value of NULL is returned.
  222. ; Otherwise, the address of the entry that is removed is returned as the
  223. ; function value.
  224. ;
  225. ; Arguments:
  226. ;
  227. ; ListHead (rcx) - Supplies a pointer to the head of the doubly linked
  228. ; list from which an entry is to be removed.
  229. ;
  230. ; Lock (rdx) - Supplies a pointer to a spin lock to be used to synchronize
  231. ; access to the list.
  232. ;
  233. ; Return Value:
  234. ;
  235. ; The address of the entry removed from the list, or NULL if the list is
  236. ; empty.
  237. ;
  238. ;--
  239. LEAF_ENTRY ExInterlockedRemoveHeadList, _TEXT$00
  240. cli ; disable interrupt
  241. AcquireSpinLock rdx ; acquire spin lock
  242. mov rax, LsFlink[rcx] ; get address of first entry
  243. cmp rax, rcx ; check if list is empty
  244. je short Rh10 ; if e, list is empty
  245. mov r8, LsFlink[rax] ; get address of next entry
  246. mov LsFlink[rcx], r8 ; set address of first entry
  247. mov LsBlink[r8], rcx ; set back in next entry
  248. Rh10: ReleaseSpinLock rdx ; release spin lock
  249. sti ; enable interrupts
  250. xor rcx, rax ; check if list was empty
  251. jnz short Rh20 ; if nz, list not empty
  252. xor eax, eax ; list was empty
  253. Rh20: ret ; return
  254. LEAF_END ExInterlockedRemoveHeadList, _TEXT$00
  255. subttl "Interlocked Pop Entry List"
  256. ;++
  257. ;
  258. ; PSINGLE_LIST_ENTRY
  259. ; ExInterlockedPopEntryList (
  260. ; IN PSINGLE_LIST_ENTRY ListHead,
  261. ; IN PKSPIN_LOCK Lock
  262. ; )
  263. ;
  264. ; Routine Description:
  265. ;
  266. ; This function removes an entry from the front of a singly linked list
  267. ; so that access to the list is synchronized in a multiprocessor system.
  268. ; If there are no entries in the list, then a value of NULL is returned.
  269. ; Otherwise, the address of the entry that is removed is returned as the
  270. ; function value.
  271. ;
  272. ; Arguments:
  273. ;
  274. ; ListHead (rcx) - Supplies a pointer to the head of the singly linked
  275. ; list from which an entry is to be removed.
  276. ;
  277. ; Lock (rdx) - Supplies a pointer to a spin lock to be used to synchronize
  278. ; access to the list.
  279. ;
  280. ; Return Value:
  281. ;
  282. ; The address of the entry removed from the list, or NULL if the list is
  283. ; empty.
  284. ;
  285. ;--
  286. LEAF_ENTRY ExInterlockedPopEntryList, _TEXT$00
  287. cli ; disable interrupts
  288. AcquireSpinLock rdx ; acquire spin lock
  289. mov rax, [rcx] ; get address of first entry
  290. test rax, rax ; check if list is empty
  291. jz short Pe10 ; if z, list is empty
  292. mov r8, [rax] ; get address of next entry
  293. mov [rcx], r8 ; set address of first entry
  294. Pe10: ReleaseSpinLock rdx ; release spin lock
  295. sti ; enable interrupts
  296. ret ; return
  297. LEAF_END ExInterlockedPopEntryList, _TEXT$00
  298. subttl "Interlocked Push Entry List"
  299. ;++
  300. ;
  301. ; PSINGLE_LIST_ENTRY
  302. ; ExInterlockedPushEntryList (
  303. ; IN PSINGLE_LIST_ENTRY ListHead,
  304. ; IN PSINGLE_LIST_ENTRY ListEntry,
  305. ; IN PKSPIN_LOCK Lock
  306. ; )
  307. ;
  308. ; Routine Description:
  309. ;
  310. ; This function inserts an entry at the head of a singly linked list
  311. ; so that access to the list is synchronized in a multiprocessor system.
  312. ;
  313. ; Arguments:
  314. ;
  315. ; ListHead (rcx) - Supplies a pointer to the head of the singly linked
  316. ; list into which an entry is to be inserted.
  317. ;
  318. ; ListEntry (rdx) - Supplies a pointer to the entry to be inserted at the
  319. ; head of the list.
  320. ;
  321. ; Lock (r8) - Supplies a pointer to a spin lock to be used to synchronize
  322. ; access to the list.
  323. ;
  324. ; Return Value:
  325. ;
  326. ; Previous contents of ListHead. NULL implies list went from empty to not
  327. ; empty.
  328. ;
  329. ;--
  330. LEAF_ENTRY ExInterlockedPushEntryList, _TEXT$00
  331. cli ; disable interrupts
  332. AcquireSpinLock r8 ; acquire spin lock
  333. mov rax, [rcx] ; get address of first entry
  334. mov [rdx], rax ; set address of next entry
  335. mov [rcx], rdx ; set address of first entry
  336. ReleaseSpinLock r8 ; release spin lock
  337. sti ; enable interrupts
  338. ret ;
  339. LEAF_END ExInterlockedPushEntryList, _TEXT$00
  340. end