Moved win32k
[reactos.git] / reactos / subsystems / win32 / win32k / eng / semaphor.c
1 #include <w32k.h>
2
3 #define NDEBUG
4 #include <debug.h>
5
6 /*
7 * @implemented
8 */
9 HSEMAPHORE
10 STDCALL
11 EngCreateSemaphore ( VOID )
12 {
13 // www.osr.com/ddk/graphics/gdifncs_95lz.htm
14 PERESOURCE psem = ExAllocatePool ( NonPagedPool, sizeof(ERESOURCE) );
15 if ( !psem )
16 return NULL;
17 if ( !NT_SUCCESS(ExInitializeResourceLite ( psem )) )
18 {
19 ExFreePool ( psem );
20 return NULL;
21 }
22 return (HSEMAPHORE)psem;
23 }
24
25 /*
26 * @implemented
27 */
28 VOID
29 STDCALL
30 EngAcquireSemaphore ( IN HSEMAPHORE hsem )
31 {
32 // www.osr.com/ddk/graphics/gdifncs_14br.htm
33 ASSERT(hsem);
34 KeEnterCriticalRegion();
35 ExAcquireResourceExclusiveLite ( (PERESOURCE)hsem, TRUE );
36 }
37
38 /*
39 * @implemented
40 */
41 VOID
42 STDCALL
43 EngReleaseSemaphore ( IN HSEMAPHORE hsem )
44 {
45 // www.osr.com/ddk/graphics/gdifncs_5u3r.htm
46 ASSERT(hsem);
47 ExReleaseResourceLite ( (PERESOURCE)hsem );
48 KeLeaveCriticalRegion();
49 }
50
51 /*
52 * @implemented
53 */
54 VOID
55 STDCALL
56 EngDeleteSemaphore ( IN HSEMAPHORE hsem )
57 {
58 // www.osr.com/ddk/graphics/gdifncs_13c7.htm
59 ASSERT ( hsem );
60 ExFreePool ( (PVOID)hsem );
61 }
62
63 /*
64 * @implemented
65 */
66 BOOL
67 STDCALL
68 EngIsSemaphoreOwned ( IN HSEMAPHORE hsem )
69 {
70 // www.osr.com/ddk/graphics/gdifncs_6wmf.htm
71 ASSERT(hsem);
72 return (((PERESOURCE)hsem)->ActiveCount > 0);
73 }
74
75 /*
76 * @implemented
77 */
78 BOOL
79 STDCALL
80 EngIsSemaphoreOwnedByCurrentThread ( IN HSEMAPHORE hsem )
81 {
82 // www.osr.com/ddk/graphics/gdifncs_9yxz.htm
83 ASSERT(hsem);
84 return ExIsResourceAcquiredExclusiveLite ( (PERESOURCE)hsem );
85 }
86
87 /*
88 * @implemented
89 */
90 BOOL STDCALL
91 EngInitializeSafeSemaphore(
92 OUT ENGSAFESEMAPHORE *Semaphore)
93 {
94 HSEMAPHORE hSem;
95
96 if (InterlockedIncrement(&Semaphore->lCount) == 1)
97 {
98 /* Create the semaphore */
99 hSem = EngCreateSemaphore();
100 if (hSem == 0)
101 {
102 InterlockedDecrement(&Semaphore->lCount);
103 return FALSE;
104 }
105 InterlockedExchangePointer((volatile PVOID *)&Semaphore->hsem, hSem);
106 }
107 else
108 {
109 /* Wait for the other thread to create the semaphore */
110 ASSERT(Semaphore->lCount > 1);
111 ASSERT_IRQL(PASSIVE_LEVEL);
112 while (Semaphore->hsem == NULL);
113 }
114
115 return TRUE;
116 }
117
118 /*
119 * @implemented
120 */
121 VOID STDCALL
122 EngDeleteSafeSemaphore(
123 IN OUT ENGSAFESEMAPHORE *Semaphore)
124 {
125 if (InterlockedDecrement(&Semaphore->lCount) == 0)
126 {
127 EngDeleteSemaphore(Semaphore->hsem);
128 InterlockedExchangePointer((volatile PVOID *)&Semaphore->hsem, NULL);
129 }
130 }
131
132