ReactOS 0.4.16-dev-340-g0540c21
sys_arch.c
Go to the documentation of this file.
1#include <debug.h>
2#include <lwip/sys.h>
3
4#include "lwip_glue.h"
5
8
12
14
15typedef struct _thread_t
16{
22
24{
25 LARGE_INTEGER CurrentTime;
26
27 KeQuerySystemTime(&CurrentTime);
28
29 return (CurrentTime.QuadPart - StartTime.QuadPart) / 10000;
30}
31
32void
34{
35 /* Preempt the dispatcher */
37}
38
39void
41{
42 KeLowerIrql(lev);
43}
44
47{
48 ASSERT(count == 0 || count == 1);
49
50 /* It seems lwIP uses the semaphore implementation as either a completion event or a lock
51 * so I optimize for this case by using a synchronization event and setting its initial state
52 * to signalled for a lock and non-signalled for a completion event */
53
55
56 sem->Valid = 1;
57
58 return ERR_OK;
59}
60
62{
63 return sem->Valid;
64}
65
67{
68 sem->Valid = 0;
69}
70
71void
73{
74 /* No op (allocated in stack) */
75
77}
78
79void
81{
83}
84
87{
88 LARGE_INTEGER LargeTimeout, PreWaitTime, PostWaitTime;
89 UINT64 TimeDiff;
91 PVOID WaitObjects[] = {&sem->Event, &TerminationEvent};
92
93 LargeTimeout.QuadPart = Int32x32To64(timeout, -10000);
94
95 KeQuerySystemTime(&PreWaitTime);
96
98 WaitObjects,
99 WaitAny,
100 Executive,
102 FALSE,
103 timeout != 0 ? &LargeTimeout : NULL,
104 NULL);
105 if (Status == STATUS_WAIT_0)
106 {
107 KeQuerySystemTime(&PostWaitTime);
108 TimeDiff = PostWaitTime.QuadPart - PreWaitTime.QuadPart;
109 TimeDiff /= 10000;
110
111 return TimeDiff;
112 }
113 else if (Status == STATUS_WAIT_1)
114 {
115 /* DON'T remove ourselves from the thread list! */
117
118 /* We should never get here! */
119 ASSERT(FALSE);
120
121 return 0;
122 }
123
124 return SYS_ARCH_TIMEOUT;
125}
126
127err_t
129{
131
133
135
136 mbox->Valid = 1;
137
138 return ERR_OK;
139}
140
142{
143 return mbox->Valid;
144}
145
147{
148 mbox->Valid = 0;
149}
150
151void
153{
154 ASSERT(IsListEmpty(&mbox->ListHead));
155
157}
158
159void
161{
162 PLWIP_MESSAGE_CONTAINER Container;
163
164 Container = ExAllocatePool(NonPagedPool, sizeof(*Container));
165 ASSERT(Container);
166
167 Container->Message = msg;
168
170 &Container->ListEntry,
171 &mbox->Lock);
172
174}
175
176u32_t
178{
179 LARGE_INTEGER LargeTimeout, PreWaitTime, PostWaitTime;
180 UINT64 TimeDiff;
183 PLWIP_MESSAGE_CONTAINER Container;
186 PVOID WaitObjects[] = {&mbox->Event, &TerminationEvent};
187
188 LargeTimeout.QuadPart = Int32x32To64(timeout, -10000);
189
190 KeQuerySystemTime(&PreWaitTime);
191
193 WaitObjects,
194 WaitAny,
195 Executive,
197 FALSE,
198 timeout != 0 ? &LargeTimeout : NULL,
199 NULL);
200
201 if (Status == STATUS_WAIT_0)
202 {
204 Entry = RemoveHeadList(&mbox->ListHead);
205 ASSERT(Entry);
206 if (IsListEmpty(&mbox->ListHead))
207 KeClearEvent(&mbox->Event);
209
210 Container = CONTAINING_RECORD(Entry, LWIP_MESSAGE_CONTAINER, ListEntry);
211 Message = Container->Message;
212 ExFreePool(Container);
213
214 if (msg)
215 *msg = Message;
216
217 KeQuerySystemTime(&PostWaitTime);
218 TimeDiff = PostWaitTime.QuadPart - PreWaitTime.QuadPart;
219 TimeDiff /= 10000;
220
221 return TimeDiff;
222 }
223 else if (Status == STATUS_WAIT_1)
224 {
225 /* DON'T remove ourselves from the thread list! */
227
228 /* We should never get here! */
229 ASSERT(FALSE);
230
231 return 0;
232 }
233
234 return SYS_ARCH_TIMEOUT;
235}
236
237u32_t
239{
241 return 0;
242 else
243 return SYS_MBOX_EMPTY;
244}
245
246err_t
248{
249 sys_mbox_post(mbox, msg);
250
251 return ERR_OK;
252}
253
254VOID
255NTAPI
257{
258 thread_t Container = (thread_t)Context;
260
262
263 Container->ThreadFunction(Container->ThreadContext);
264
266 RemoveEntryList(&Container->ListEntry);
268
269 ExFreePool(Container);
270
272}
273
275sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
276{
277 thread_t Container;
279
280 Container = ExAllocatePool(NonPagedPool, sizeof(*Container));
281 if (!Container)
282 return 0;
283
284 Container->ThreadFunction = thread;
285 Container->ThreadContext = arg;
286
287 Status = PsCreateSystemThread(&Container->Handle,
289 NULL,
290 NULL,
291 NULL,
293 Container);
294
295 if (!NT_SUCCESS(Status))
296 {
297 ExFreePool(Container);
298 return 0;
299 }
300
301 return 0;
302}
303
304void
306{
309
311
313
315 NULL,
316 NULL,
317 0,
318 sizeof(struct lwip_callback_msg),
320 0);
321
323 NULL,
324 NULL,
325 0,
326 sizeof(QUEUE_ENTRY),
328 0);
329}
330
331void
333{
334 PLIST_ENTRY CurrentEntry;
335 thread_t Container;
336
337 /* Set the termination event */
339
340 /* Loop through the thread list and wait for each to die */
342 {
343 Container = CONTAINING_RECORD(CurrentEntry, struct _thread_t, ListEntry);
344
345 if (Container->ThreadFunction)
346 {
347 KeWaitForSingleObject(Container->Handle,
348 Executive,
350 FALSE,
351 NULL);
352
353 ZwClose(Container->Handle);
354 }
355 }
356
359}
unsigned long long UINT64
#define msg(x)
Definition: auth_time.c:54
LONG NTSTATUS
Definition: precomp.h:26
static HANDLE thread
Definition: service.c:33
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
static const WCHAR Message[]
Definition: register.c:74
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
Status
Definition: gdiplustypes.h:25
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
uint32_t u32_t
Definition: arch.h:129
uint8_t u8_t
Definition: arch.h:125
s8_t err_t
Definition: err.h:96
@ ERR_OK
Definition: err.h:55
void sys_mbox_set_invalid(sys_mbox_t *mbox)
Definition: sys_arch.c:146
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
Definition: sys_arch.c:177
void sys_mbox_post(sys_mbox_t *mbox, void *msg)
Definition: sys_arch.c:160
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
Definition: sys_arch.c:247
err_t sys_mbox_new(sys_mbox_t *mbox, int size)
Definition: sys_arch.c:128
void sys_mbox_free(sys_mbox_t *mbox)
Definition: sys_arch.c:152
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
Definition: sys_arch.c:238
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
Definition: sys_arch.c:275
void sys_init(void)
Definition: sys_arch.c:305
void sys_sem_set_invalid(sys_sem_t *sem)
Definition: sys_arch.c:66
void sys_sem_free(sys_sem_t *sem)
Definition: sys_arch.c:72
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
Definition: sys_arch.c:86
void sys_sem_signal(sys_sem_t *sem)
Definition: sys_arch.c:80
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
Definition: sys_arch.c:46
u32_t sys_now(void)
Definition: sys_arch.c:23
u32_t sys_thread_t
Definition: sys_arch.h:20
KIRQL sys_prot_t
Definition: sys_arch.h:18
PLIST_ENTRY NTAPI ExInterlockedInsertHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:114
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
PLIST_ENTRY NTAPI ExInterlockedRemoveHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:166
static LIST_ENTRY ThreadListHead
Definition: sys_arch.c:6
void sys_arch_protect(sys_prot_t *lev)
Definition: sys_arch.c:33
static KSPIN_LOCK ThreadListLock
Definition: sys_arch.c:7
void sys_arch_unprotect(sys_prot_t lev)
Definition: sys_arch.c:40
static LARGE_INTEGER StartTime
Definition: sys_arch.c:13
KEVENT TerminationEvent
Definition: sys_arch.c:9
NPAGED_LOOKASIDE_LIST MessageLookasideList
Definition: sys_arch.c:10
void sys_shutdown(void)
Definition: sys_arch.c:332
struct _thread_t * thread_t
VOID NTAPI LwipThreadMain(PVOID Context)
Definition: sys_arch.c:256
NPAGED_LOOKASIDE_LIST QueueEntryLookasideList
Definition: sys_arch.c:11
VOID NTAPI ExDeleteNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside)
Definition: lookas.c:170
VOID NTAPI ExInitializeNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth)
Definition: lookas.c:218
#define sys_mbox_valid(mbox)
Definition: sys_arch.h:50
#define sys_sem_valid(sema)
Definition: sys_arch.h:36
#define LWIP_MESSAGE_TAG
Definition: lwip_glue.h:11
#define LWIP_QUEUE_TAG
Definition: lwip_glue.h:12
DWORD ThreadFunction
Definition: mmdrv.h:85
#define ASSERT(a)
Definition: mode.c:44
static HANDLE sem
Definition: sync.c:674
#define KernelMode
Definition: asm.h:34
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
#define Int32x32To64(a, b)
@ NotificationEvent
@ SynchronizationEvent
@ WaitAny
NTSTATUS NTAPI KeWaitForMultipleObjects(IN ULONG Count, IN PVOID Object[], IN WAIT_TYPE WaitType, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL, OUT PKWAIT_BLOCK WaitBlockArray OPTIONAL)
Definition: wait.c:586
NTSTATUS NTAPI PsTerminateSystemThread(IN NTSTATUS ExitStatus)
Definition: kill.c:1145
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
Definition: thread.c:602
#define STATUS_WAIT_0
Definition: ntstatus.h:237
#define STATUS_WAIT_1
Definition: ntstatus.h:71
#define STATUS_SUCCESS
Definition: shellext.h:65
base of all file and directory entries
Definition: entries.h:83
Definition: typedefs.h:120
LIST_ENTRY ListEntry
Definition: sys_arch.h:25
Definition: lwip_glue.h:18
KSPIN_LOCK Lock
Definition: sys_arch.h:12
int Valid
Definition: sys_arch.h:15
KEVENT Event
Definition: sys_arch.h:14
LIST_ENTRY ListHead
Definition: sys_arch.h:13
void(* ThreadFunction)(void *arg)
Definition: sys_arch.c:18
void * ThreadContext
Definition: sys_arch.c:19
HANDLE Handle
Definition: sys_arch.c:17
LIST_ENTRY ListEntry
Definition: sys_arch.c:20
Definition: name.c:39
Definition: dhcpd.h:245
#define SYS_MBOX_EMPTY
Definition: sys.h:92
#define SYS_ARCH_TIMEOUT
Definition: sys.h:87
void(* lwip_thread_fn)(void *arg)
Definition: sys.h:98
#define NTAPI
Definition: typedefs.h:36
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
LONGLONG QuadPart
Definition: typedefs.h:114
void * arg
Definition: msvc.h:10
struct LOOKASIDE_ALIGN _NPAGED_LOOKASIDE_LIST NPAGED_LOOKASIDE_LIST
#define IO_NO_INCREMENT
Definition: iotypes.h:598
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
@ Executive
Definition: ketypes.h:415