134ca7a464a9ce8c692d786652c1164d28287ea1
[reactos.git] / reactos / hal / halppc / generic / fmutex.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS HAL
4 * FILE: ntoskrnl/hal/x86/fmutex.c
5 * PURPOSE: Deprecated HAL Fast Mutex
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 */
8
9 /*
10 * NOTE: Even HAL itself has #defines to use the Exi* APIs inside NTOSKRNL.
11 * These are only exported here for compatibility with really old
12 * drivers. Also note that in theory, these can be made much faster
13 * by using assembly and inlining all the operations, including
14 * raising and lowering irql.
15 */
16
17 /* INCLUDES *****************************************************************/
18
19 #include <hal.h>
20 #define NDEBUG
21 #include <debug.h>
22
23 #undef ExAcquireFastMutex
24 #undef ExReleaseFastMutex
25
26 /* FUNCTIONS *****************************************************************/
27
28 VOID
29 FASTCALL
30 ExAcquireFastMutex(PFAST_MUTEX FastMutex)
31 {
32 KIRQL OldIrql;
33
34 /* Raise IRQL to APC */
35 KeRaiseIrql(APC_LEVEL, &OldIrql);
36
37 /* Decrease the count */
38 if (InterlockedDecrement(&FastMutex->Count))
39 {
40 /* Someone is still holding it, use slow path */
41 FastMutex->Contention++;
42 KeWaitForSingleObject(&FastMutex->Event,
43 WrExecutive,
44 KernelMode,
45 FALSE,
46 NULL);
47 }
48
49 /* Set the owner and IRQL */
50 FastMutex->Owner = KeGetCurrentThread();
51 FastMutex->OldIrql = OldIrql;
52 }
53
54 VOID
55 FASTCALL
56 ExReleaseFastMutex(PFAST_MUTEX FastMutex)
57 {
58 KIRQL OldIrql;
59
60 /* Erase the owner */
61 FastMutex->Owner = (PVOID)1;
62 OldIrql = FastMutex->OldIrql;
63
64 /* Increase the count */
65 if (InterlockedIncrement(&FastMutex->Count) <= 0)
66 {
67 /* Someone was waiting for it, signal the waiter */
68 KeSetEventBoostPriority(&FastMutex->Event, IO_NO_INCREMENT);
69 }
70
71 /* Lower IRQL back */
72 KeLowerIrql(OldIrql);
73 }
74
75 BOOLEAN
76 FASTCALL
77 ExiTryToAcquireFastMutex(PFAST_MUTEX FastMutex)
78 {
79 KIRQL OldIrql;
80
81 /* Raise to APC_LEVEL */
82 KeRaiseIrql(APC_LEVEL, &OldIrql);
83
84 /* Check if we can quickly acquire it */
85 if (InterlockedCompareExchange(&FastMutex->Count, 0, 1) == 1)
86 {
87 /* We have, set us as owners */
88 FastMutex->Owner = KeGetCurrentThread();
89 FastMutex->OldIrql = OldIrql;
90 return TRUE;
91 }
92 else
93 {
94 /* Acquire attempt failed */
95 KeLowerIrql(OldIrql);
96 return FALSE;
97 }
98 }
99
100 /* EOF */