ReactOS 0.4.16-dev-1946-g52006dd
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
10
14
16
17typedef struct _thread_t
18{
24
26{
27 LARGE_INTEGER CurrentTime;
28
29 KeQuerySystemTime(&CurrentTime);
30
31 return (CurrentTime.QuadPart - StartTime.QuadPart) / 10000;
32}
33
34void
36{
37 /* Acquire the global resource to prevent other CPUs from running */
39 *lev = ++GlobalLockLevel;
40}
41
42void
44{
45 /* Release the global resource */
46 ASSERT((GlobalLockLevel > 0) && (lev == GlobalLockLevel));
49}
50
53{
54 ASSERT(count == 0 || count == 1);
55
56 /* It seems lwIP uses the semaphore implementation as either a completion event or a lock
57 * so I optimize for this case by using a synchronization event and setting its initial state
58 * to signalled for a lock and non-signalled for a completion event */
59
61
62 sem->Valid = 1;
63
64 return ERR_OK;
65}
66
68{
69 return sem->Valid;
70}
71
73{
74 sem->Valid = 0;
75}
76
77void
79{
80 /* No op (allocated in stack) */
81
83}
84
85void
87{
89}
90
93{
94 LARGE_INTEGER LargeTimeout, PreWaitTime, PostWaitTime;
95 UINT64 TimeDiff;
97 PVOID WaitObjects[] = {&sem->Event, &TerminationEvent};
98
99 LargeTimeout.QuadPart = Int32x32To64(timeout, -10000);
100
101 KeQuerySystemTime(&PreWaitTime);
102
104 WaitObjects,
105 WaitAny,
106 Executive,
108 FALSE,
109 timeout != 0 ? &LargeTimeout : NULL,
110 NULL);
111 if (Status == STATUS_WAIT_0)
112 {
113 KeQuerySystemTime(&PostWaitTime);
114 TimeDiff = PostWaitTime.QuadPart - PreWaitTime.QuadPart;
115 TimeDiff /= 10000;
116
117 return TimeDiff;
118 }
119 else if (Status == STATUS_WAIT_1)
120 {
121 /* DON'T remove ourselves from the thread list! */
123
124 /* We should never get here! */
125 ASSERT(FALSE);
126
127 return 0;
128 }
129
130 return SYS_ARCH_TIMEOUT;
131}
132
133err_t
135{
137
139
141
142 mbox->Valid = 1;
143
144 return ERR_OK;
145}
146
148{
149 return mbox->Valid;
150}
151
153{
154 mbox->Valid = 0;
155}
156
157void
159{
160 ASSERT(IsListEmpty(&mbox->ListHead));
161
163}
164
165void
167{
168 PLWIP_MESSAGE_CONTAINER Container;
169
170 Container = ExAllocatePool(NonPagedPool, sizeof(*Container));
171 ASSERT(Container);
172
173 Container->Message = msg;
174
176 &Container->ListEntry,
177 &mbox->Lock);
178
180}
181
182u32_t
184{
185 LARGE_INTEGER LargeTimeout, PreWaitTime, PostWaitTime;
186 UINT64 TimeDiff;
189 PLWIP_MESSAGE_CONTAINER Container;
192 PVOID WaitObjects[] = {&mbox->Semaphore, &TerminationEvent};
193
194 LargeTimeout.QuadPart = Int32x32To64(timeout, -10000);
195
196 KeQuerySystemTime(&PreWaitTime);
197
199 WaitObjects,
200 WaitAny,
201 Executive,
203 FALSE,
204 timeout != 0 ? &LargeTimeout : NULL,
205 NULL);
206
207 if (Status == STATUS_WAIT_0)
208 {
210 ASSERT(!IsListEmpty(&mbox->ListHead));
211 Entry = RemoveHeadList(&mbox->ListHead);
213
214 Container = CONTAINING_RECORD(Entry, LWIP_MESSAGE_CONTAINER, ListEntry);
215 Message = Container->Message;
216 ExFreePool(Container);
217
218 if (msg)
219 *msg = Message;
220
221 KeQuerySystemTime(&PostWaitTime);
222 TimeDiff = PostWaitTime.QuadPart - PreWaitTime.QuadPart;
223 TimeDiff /= 10000;
224
225 return TimeDiff;
226 }
227 else if (Status == STATUS_WAIT_1)
228 {
229 /* DON'T remove ourselves from the thread list! */
231
232 /* We should never get here! */
233 ASSERT(FALSE);
234
235 return 0;
236 }
237
238 return SYS_ARCH_TIMEOUT;
239}
240
241u32_t
243{
245 return 0;
246 else
247 return SYS_MBOX_EMPTY;
248}
249
250err_t
252{
253 sys_mbox_post(mbox, msg);
254
255 return ERR_OK;
256}
257
258VOID
259NTAPI
261{
262 thread_t Container = (thread_t)Context;
264
266
267 Container->ThreadFunction(Container->ThreadContext);
268
270 RemoveEntryList(&Container->ListEntry);
272
273 ExFreePool(Container);
274
276}
277
279sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
280{
281 thread_t Container;
283
284 Container = ExAllocatePool(NonPagedPool, sizeof(*Container));
285 if (!Container)
286 return 0;
287
288 Container->ThreadFunction = thread;
289 Container->ThreadContext = arg;
290
291 Status = PsCreateSystemThread(&Container->Handle,
293 NULL,
294 NULL,
295 NULL,
297 Container);
298
299 if (!NT_SUCCESS(Status))
300 {
301 ExFreePool(Container);
302 return 0;
303 }
304
305 return 0;
306}
307
308void
310{
313
315
317
319 NULL,
320 NULL,
321 0,
322 sizeof(struct lwip_callback_msg),
324 0);
325
327 NULL,
328 NULL,
329 0,
330 sizeof(QUEUE_ENTRY),
332 0);
333}
334
335void
337{
338 PLIST_ENTRY CurrentEntry;
339 thread_t Container;
340
341 /* Set the termination event */
343
344 /* Loop through the thread list and wait for each to die */
346 {
347 Container = CONTAINING_RECORD(CurrentEntry, struct _thread_t, ListEntry);
348
349 if (Container->ThreadFunction)
350 {
351 KeWaitForSingleObject(Container->Handle,
352 Executive,
354 FALSE,
355 NULL);
356
357 ZwClose(Container->Handle);
358 }
359 }
360
363}
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 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 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
ULONG ERESOURCE
Definition: env_spec_w32.h:594
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
#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:152
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
Definition: sys_arch.c:183
void sys_mbox_post(sys_mbox_t *mbox, void *msg)
Definition: sys_arch.c:166
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
Definition: sys_arch.c:251
err_t sys_mbox_new(sys_mbox_t *mbox, int size)
Definition: sys_arch.c:134
void sys_mbox_free(sys_mbox_t *mbox)
Definition: sys_arch.c:158
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
Definition: sys_arch.c:242
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
Definition: sys_arch.c:279
void sys_init(void)
Definition: sys_arch.c:309
void sys_sem_set_invalid(sys_sem_t *sem)
Definition: sys_arch.c:72
void sys_sem_free(sys_sem_t *sem)
Definition: sys_arch.c:78
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
Definition: sys_arch.c:92
void sys_sem_signal(sys_sem_t *sem)
Definition: sys_arch.c:86
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
Definition: sys_arch.c:52
u32_t sys_now(void)
Definition: sys_arch.c:25
u32_t sys_prot_t
Definition: sys_arch.h:18
u32_t sys_thread_t
Definition: sys_arch.h:20
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 ERESOURCE GlobalLock
Definition: sys_arch.c:8
static LIST_ENTRY ThreadListHead
Definition: sys_arch.c:6
void sys_arch_protect(sys_prot_t *lev)
Definition: sys_arch.c:35
static KSPIN_LOCK ThreadListLock
Definition: sys_arch.c:7
void sys_arch_unprotect(sys_prot_t lev)
Definition: sys_arch.c:43
static LARGE_INTEGER StartTime
Definition: sys_arch.c:15
KEVENT TerminationEvent
Definition: sys_arch.c:11
NPAGED_LOOKASIDE_LIST MessageLookasideList
Definition: sys_arch.c:12
void sys_shutdown(void)
Definition: sys_arch.c:336
struct _thread_t * thread_t
VOID NTAPI LwipThreadMain(PVOID Context)
Definition: sys_arch.c:260
NPAGED_LOOKASIDE_LIST QueueEntryLookasideList
Definition: sys_arch.c:13
static ULONG GlobalLockLevel
Definition: sys_arch.c:9
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:38
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1342
#define Int32x32To64(a, b)
@ NotificationEvent
@ SynchronizationEvent
@ WaitAny
PVOID NTAPI ExEnterCriticalRegionAndAcquireResourceExclusive(IN PERESOURCE Resource)
Definition: resource.c:2194
VOID FASTCALL ExReleaseResourceAndLeaveCriticalRegion(IN PERESOURCE Resource)
Definition: resource.c:2283
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:330
#define STATUS_WAIT_1
Definition: ntstatus.h:123
VOID NTAPI KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit)
Definition: semphobj.c:22
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
#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
KSEMAPHORE Semaphore
Definition: sys_arch.h:14
int Valid
Definition: sys_arch.h:15
LIST_ENTRY ListHead
Definition: sys_arch.h:13
void(* ThreadFunction)(void *arg)
Definition: sys_arch.c:20
void * ThreadContext
Definition: sys_arch.c:21
HANDLE Handle
Definition: sys_arch.c:19
LIST_ENTRY ListEntry
Definition: sys_arch.c:22
Definition: name.c:39
Definition: dhcpd.h:248
#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
uint32_t ULONG
Definition: typedefs.h:59
#define MAXLONG
Definition: umtypes.h:116
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:467