| 38 |
#include <time.h> |
#include <time.h> |
| 39 |
|
|
| 40 |
#include <lwip/opt.h> |
#include <lwip/opt.h> |
| 41 |
|
#include <lwip/arch.h> |
| 42 |
#include <lwip/stats.h> |
#include <lwip/stats.h> |
| 43 |
#include <lwip/debug.h> |
#include <lwip/debug.h> |
| 44 |
#include <lwip/sys.h> |
#include <lwip/sys.h> |
| 61 |
return (u32_t)(((ret)*1000)/freq.QuadPart); |
return (u32_t)(((ret)*1000)/freq.QuadPart); |
| 62 |
} |
} |
| 63 |
|
|
| 64 |
|
u32_t sys_jiffies() |
| 65 |
|
{ |
| 66 |
|
return (u32_t)sys_get_ms_longlong(); |
| 67 |
|
} |
| 68 |
|
|
| 69 |
u32_t sys_now() |
u32_t sys_now() |
| 70 |
{ |
{ |
| 71 |
return sys_get_ms_longlong(); |
return (u32_t)sys_get_ms_longlong(); |
| 72 |
} |
} |
| 73 |
|
|
| 74 |
CRITICAL_SECTION critSec; |
CRITICAL_SECTION critSec; |
| 94 |
InitSysArchProtect(); |
InitSysArchProtect(); |
| 95 |
} |
} |
| 96 |
|
|
| 97 |
#if !NO_SYS |
void sys_init() |
| 98 |
|
{ |
| 99 |
|
msvc_sys_init(); |
| 100 |
|
} |
| 101 |
|
|
| 102 |
#define MAX_QUEUE_ENTRIES 100 |
#if !NO_SYS |
| 103 |
|
|
| 104 |
struct threadlist { |
struct threadlist { |
|
struct sys_timeouts timeouts; |
|
| 105 |
DWORD id; |
DWORD id; |
| 106 |
struct threadlist *next; |
struct threadlist *next; |
| 107 |
}; |
}; |
| 108 |
|
|
|
struct lwip_mbox { |
|
|
HANDLE sem; |
|
|
void* q_mem[MAX_QUEUE_ENTRIES]; |
|
|
u32_t head, tail; |
|
|
}; |
|
|
|
|
| 109 |
struct threadlist *lwip_win32_threads = NULL; |
struct threadlist *lwip_win32_threads = NULL; |
| 110 |
|
|
|
void sys_init() |
|
|
{ |
|
|
msvc_sys_init(); |
|
|
} |
|
|
|
|
| 111 |
void do_sleep(int ms) |
void do_sleep(int ms) |
| 112 |
{ |
{ |
| 113 |
Sleep(ms); |
Sleep(ms); |
| 114 |
} |
} |
| 115 |
|
|
| 116 |
sys_sem_t sys_sem_new(u8_t count) |
err_t sys_sem_new(sys_sem_t *sem, u8_t count) |
| 117 |
{ |
{ |
| 118 |
HANDLE new_sem = NULL; |
HANDLE new_sem = NULL; |
| 119 |
|
|
| 120 |
|
LWIP_ASSERT("sem != NULL", sem != NULL); |
| 121 |
|
|
| 122 |
new_sem = CreateSemaphore(0, count, 100000, 0); |
new_sem = CreateSemaphore(0, count, 100000, 0); |
| 123 |
LWIP_ASSERT("Error creating semaphore", new_sem != NULL); |
LWIP_ASSERT("Error creating semaphore", new_sem != NULL); |
| 124 |
if(new_sem != NULL) { |
if(new_sem != NULL) { |
| 125 |
#if LWIP_STATS |
SYS_STATS_INC_USED(sem); |
| 126 |
SYS_STATS_INC(sem.used); |
#if LWIP_STATS && SYS_STATS |
| 127 |
LWIP_ASSERT("sys_sem_new() counter overflow", lwip_stats.sys.sem.used != 0 ); |
LWIP_ASSERT("sys_sem_new() counter overflow", lwip_stats.sys.sem.used != 0 ); |
| 128 |
if (lwip_stats.sys.sem.used > lwip_stats.sys.sem.max) { |
#endif /* LWIP_STATS && SYS_STATS*/ |
| 129 |
lwip_stats.sys.sem.max = lwip_stats.sys.sem.used; |
sem->sem = new_sem; |
| 130 |
} |
return ERR_OK; |
|
#endif /* LWIP_STATS */ |
|
|
return new_sem; |
|
| 131 |
} |
} |
| 132 |
|
|
| 133 |
/* failed to allocate memory... */ |
/* failed to allocate memory... */ |
|
#if LWIP_STATS |
|
| 134 |
SYS_STATS_INC(sem.err); |
SYS_STATS_INC(sem.err); |
| 135 |
#endif /* LWIP_STATS */ |
sem->sem = SYS_SEM_NULL; |
| 136 |
return SYS_SEM_NULL; |
return ERR_MEM; |
| 137 |
} |
} |
| 138 |
|
|
| 139 |
void sys_sem_free(sys_sem_t sem) |
void sys_sem_free(sys_sem_t *sem) |
| 140 |
{ |
{ |
| 141 |
/* parameter check */ |
/* parameter check */ |
| 142 |
LWIP_ASSERT("sem != NULL", sem != NULL); |
LWIP_ASSERT("sem != NULL", sem != NULL); |
| 143 |
LWIP_ASSERT("sem != INVALID_HANDLE_VALUE", sem != INVALID_HANDLE_VALUE); |
LWIP_ASSERT("sem->sem != SYS_SEM_NULL", sem->sem != SYS_SEM_NULL); |
| 144 |
CloseHandle(sem); |
LWIP_ASSERT("sem->sem != INVALID_HANDLE_VALUE", sem->sem != INVALID_HANDLE_VALUE); |
| 145 |
|
CloseHandle(sem->sem); |
| 146 |
|
|
|
#if LWIP_STATS |
|
| 147 |
SYS_STATS_DEC(sem.used); |
SYS_STATS_DEC(sem.used); |
| 148 |
|
#if LWIP_STATS && SYS_STATS |
| 149 |
LWIP_ASSERT("sys_sem_free() closed more than created", lwip_stats.sys.sem.used != (u16_t)-1); |
LWIP_ASSERT("sys_sem_free() closed more than created", lwip_stats.sys.sem.used != (u16_t)-1); |
| 150 |
#endif /* LWIP_STATS */ |
#endif /* LWIP_STATS && SYS_STATS */ |
| 151 |
|
sem->sem = NULL; |
| 152 |
} |
} |
| 153 |
|
|
| 154 |
u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout) |
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) |
| 155 |
{ |
{ |
| 156 |
DWORD ret; |
DWORD ret; |
| 157 |
LONGLONG starttime, endtime; |
LONGLONG starttime, endtime; |
| 161 |
{ |
{ |
| 162 |
/* wait infinite */ |
/* wait infinite */ |
| 163 |
starttime = sys_get_ms_longlong(); |
starttime = sys_get_ms_longlong(); |
| 164 |
ret = WaitForSingleObject(sem, INFINITE); |
ret = WaitForSingleObject(sem->sem, INFINITE); |
| 165 |
LWIP_ASSERT("Error waiting for mutex", ret == WAIT_OBJECT_0); |
LWIP_ASSERT("Error waiting for semaphore", ret == WAIT_OBJECT_0); |
| 166 |
endtime = sys_get_ms_longlong(); |
endtime = sys_get_ms_longlong(); |
| 167 |
/* return the time we waited for the sem */ |
/* return the time we waited for the sem */ |
| 168 |
return (u32_t)(endtime - starttime); |
return (u32_t)(endtime - starttime); |
| 171 |
{ |
{ |
| 172 |
int ret; |
int ret; |
| 173 |
starttime = sys_get_ms_longlong(); |
starttime = sys_get_ms_longlong(); |
| 174 |
ret = WaitForSingleObject(sem, timeout); |
ret = WaitForSingleObject(sem->sem, timeout); |
| 175 |
LWIP_ASSERT("Error waiting for mutex", (ret == WAIT_OBJECT_0) || (ret == WAIT_TIMEOUT)); |
LWIP_ASSERT("Error waiting for semaphore", (ret == WAIT_OBJECT_0) || (ret == WAIT_TIMEOUT)); |
| 176 |
if(ret == WAIT_OBJECT_0) |
if(ret == WAIT_OBJECT_0) |
| 177 |
{ |
{ |
| 178 |
endtime = sys_get_ms_longlong(); |
endtime = sys_get_ms_longlong(); |
| 187 |
} |
} |
| 188 |
} |
} |
| 189 |
|
|
| 190 |
void sys_sem_signal(sys_sem_t sem) |
void sys_sem_signal(sys_sem_t *sem) |
| 191 |
{ |
{ |
| 192 |
DWORD ret; |
DWORD ret; |
| 193 |
LWIP_ASSERT("sem != NULL", sem != NULL); |
LWIP_ASSERT("sem != NULL", sem != NULL); |
| 194 |
LWIP_ASSERT("sem != INVALID_HANDLE_VALUE", sem != INVALID_HANDLE_VALUE); |
LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL); |
| 195 |
ret = ReleaseSemaphore(sem, 1, NULL); |
LWIP_ASSERT("sem->sem != INVALID_HANDLE_VALUE", sem->sem != INVALID_HANDLE_VALUE); |
| 196 |
LWIP_ASSERT("Error releasing mutex", ret != 0); |
ret = ReleaseSemaphore(sem->sem, 1, NULL); |
| 197 |
|
LWIP_ASSERT("Error releasing semaphore", ret != 0); |
| 198 |
} |
} |
| 199 |
|
|
| 200 |
struct sys_timeouts *sys_arch_timeouts(void) |
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio) |
|
{ |
|
|
struct sys_timeouts *ret = NULL; |
|
|
struct threadlist *t, *new_thread; |
|
|
DWORD threadID; |
|
|
SYS_ARCH_DECL_PROTECT(lev); |
|
|
|
|
|
threadID = GetCurrentThreadId(); |
|
|
SYS_ARCH_PROTECT(lev); |
|
|
for(t = lwip_win32_threads; t != NULL; t = t->next) |
|
|
{ |
|
|
if(t->id == threadID) |
|
|
{ |
|
|
ret = &(t->timeouts); |
|
|
SYS_ARCH_UNPROTECT(lev); |
|
|
return ret; |
|
|
} |
|
|
} |
|
|
new_thread = (struct threadlist*)malloc(sizeof(struct threadlist)); |
|
|
LWIP_ASSERT("new_thread != NULL", new_thread != NULL); |
|
|
if(new_thread != NULL) { |
|
|
OutputDebugString("First call to sys_arch_timeouts for thread"); |
|
|
new_thread->next = lwip_win32_threads; |
|
|
lwip_win32_threads = new_thread; |
|
|
new_thread->id = threadID; |
|
|
new_thread->timeouts.next = NULL; |
|
|
ret = &(new_thread->timeouts); |
|
|
SYS_ARCH_UNPROTECT(lev); |
|
|
return ret; |
|
|
} |
|
|
SYS_ARCH_UNPROTECT(lev); |
|
|
LWIP_ASSERT("should not come here", 0); |
|
|
return 0; |
|
|
} |
|
|
|
|
|
sys_thread_t sys_thread_new(char *name, void (* function)(void *arg), void *arg, int stacksize, int prio) |
|
| 201 |
{ |
{ |
| 202 |
struct threadlist *new_thread; |
struct threadlist *new_thread; |
| 203 |
HANDLE h; |
HANDLE h; |
| 213 |
SYS_ARCH_PROTECT(lev); |
SYS_ARCH_PROTECT(lev); |
| 214 |
new_thread->next = lwip_win32_threads; |
new_thread->next = lwip_win32_threads; |
| 215 |
lwip_win32_threads = new_thread; |
lwip_win32_threads = new_thread; |
|
new_thread->timeouts.next = NULL; |
|
| 216 |
|
|
| 217 |
h = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)function, arg, 0, &(new_thread->id)); |
h = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)function, arg, 0, &(new_thread->id)); |
| 218 |
LWIP_ASSERT("h != 0", h != 0); |
LWIP_ASSERT("h != 0", h != 0); |
| 224 |
return 0; |
return 0; |
| 225 |
} |
} |
| 226 |
|
|
| 227 |
sys_mbox_t sys_mbox_new(int size) |
err_t sys_mbox_new(sys_mbox_t *mbox, int size) |
| 228 |
{ |
{ |
| 229 |
struct lwip_mbox *new_mbox; |
LWIP_ASSERT("mbox != NULL", mbox != NULL); |
|
|
|
| 230 |
LWIP_UNUSED_ARG(size); |
LWIP_UNUSED_ARG(size); |
| 231 |
|
|
| 232 |
new_mbox = (struct lwip_mbox*)malloc(sizeof(struct lwip_mbox)); |
mbox->sem = CreateSemaphore(0, 0, MAX_QUEUE_ENTRIES, 0); |
| 233 |
LWIP_ASSERT("new_mbox != NULL", new_mbox != NULL); |
LWIP_ASSERT("Error creating semaphore", mbox->sem != NULL); |
| 234 |
if(new_mbox == NULL) { |
if(mbox->sem == NULL) { |
|
#if LWIP_STATS |
|
| 235 |
SYS_STATS_INC(mbox.err); |
SYS_STATS_INC(mbox.err); |
| 236 |
#endif /* LWIP_STATS */ |
return ERR_MEM; |
|
return SYS_SEM_NULL; |
|
| 237 |
} |
} |
| 238 |
new_mbox->sem = CreateSemaphore(0, 0, MAX_QUEUE_ENTRIES, 0); |
memset(&mbox->q_mem, 0, sizeof(u32_t)*MAX_QUEUE_ENTRIES); |
| 239 |
LWIP_ASSERT("Error creating semaphore", new_mbox->sem != NULL); |
mbox->head = 0; |
| 240 |
if(new_mbox->sem == NULL) { |
mbox->tail = 0; |
| 241 |
#if LWIP_STATS |
SYS_STATS_INC_USED(mbox); |
| 242 |
SYS_STATS_INC(mbox.err); |
#if LWIP_STATS && SYS_STATS |
|
#endif /* LWIP_STATS */ |
|
|
free(new_mbox); |
|
|
new_mbox = NULL; |
|
|
return SYS_SEM_NULL; |
|
|
} |
|
|
memset(&new_mbox->q_mem, 0, sizeof(u32_t)*MAX_QUEUE_ENTRIES); |
|
|
new_mbox->head = 0; |
|
|
new_mbox->tail = 0; |
|
|
#if LWIP_STATS |
|
|
SYS_STATS_INC(mbox.used); |
|
| 243 |
LWIP_ASSERT("sys_mbox_new() counter overflow", lwip_stats.sys.mbox.used != 0 ); |
LWIP_ASSERT("sys_mbox_new() counter overflow", lwip_stats.sys.mbox.used != 0 ); |
| 244 |
if (lwip_stats.sys.mbox.used > lwip_stats.sys.mbox.max) { |
#endif /* LWIP_STATS && SYS_STATS */ |
| 245 |
lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used; |
return ERR_OK; |
|
} |
|
|
#endif /* LWIP_STATS */ |
|
|
return new_mbox; |
|
| 246 |
} |
} |
| 247 |
|
|
| 248 |
void sys_mbox_free(sys_mbox_t mbox) |
void sys_mbox_free(sys_mbox_t *mbox) |
| 249 |
{ |
{ |
| 250 |
/* parameter check */ |
/* parameter check */ |
| 251 |
LWIP_ASSERT("sys_mbox_free ", mbox != SYS_MBOX_NULL ); |
LWIP_ASSERT("mbox != NULL", mbox != NULL); |
| 252 |
LWIP_ASSERT("mbox->sem != NULL", mbox->sem != NULL); |
LWIP_ASSERT("mbox->sem != NULL", mbox->sem != NULL); |
| 253 |
LWIP_ASSERT("mbox->sem != INVALID_HANDLE_VALUE", mbox->sem != INVALID_HANDLE_VALUE); |
LWIP_ASSERT("mbox->sem != INVALID_HANDLE_VALUE", mbox->sem != INVALID_HANDLE_VALUE); |
| 254 |
|
|
| 255 |
CloseHandle(mbox->sem); |
CloseHandle(mbox->sem); |
|
free(mbox); |
|
| 256 |
|
|
|
#if LWIP_STATS |
|
| 257 |
SYS_STATS_DEC(mbox.used); |
SYS_STATS_DEC(mbox.used); |
| 258 |
|
#if LWIP_STATS && SYS_STATS |
| 259 |
LWIP_ASSERT( "sys_mbox_free() ", lwip_stats.sys.mbox.used!= (u16_t)-1 ); |
LWIP_ASSERT( "sys_mbox_free() ", lwip_stats.sys.mbox.used!= (u16_t)-1 ); |
| 260 |
#endif /* LWIP_STATS */ |
#endif /* LWIP_STATS && SYS_STATS */ |
| 261 |
|
mbox->sem = NULL; |
| 262 |
} |
} |
| 263 |
|
|
| 264 |
void sys_mbox_post(sys_mbox_t q, void *msg) |
void sys_mbox_post(sys_mbox_t *q, void *msg) |
| 265 |
{ |
{ |
| 266 |
DWORD ret; |
DWORD ret; |
| 267 |
SYS_ARCH_DECL_PROTECT(lev); |
SYS_ARCH_DECL_PROTECT(lev); |
| 268 |
|
|
| 269 |
/* parameter check */ |
/* parameter check */ |
| 270 |
LWIP_ASSERT("sys_mbox_free ", q != SYS_MBOX_NULL ); |
LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL); |
| 271 |
LWIP_ASSERT("q->sem != NULL", q->sem != NULL); |
LWIP_ASSERT("q->sem != NULL", q->sem != NULL); |
| 272 |
LWIP_ASSERT("q->sem != INVALID_HANDLE_VALUE", q->sem != INVALID_HANDLE_VALUE); |
LWIP_ASSERT("q->sem != INVALID_HANDLE_VALUE", q->sem != INVALID_HANDLE_VALUE); |
| 273 |
|
|
| 284 |
SYS_ARCH_UNPROTECT(lev); |
SYS_ARCH_UNPROTECT(lev); |
| 285 |
} |
} |
| 286 |
|
|
| 287 |
err_t sys_mbox_trypost(sys_mbox_t q, void *msg) |
err_t sys_mbox_trypost(sys_mbox_t *q, void *msg) |
| 288 |
{ |
{ |
| 289 |
u32_t new_head; |
u32_t new_head; |
| 290 |
DWORD ret; |
DWORD ret; |
| 291 |
SYS_ARCH_DECL_PROTECT(lev); |
SYS_ARCH_DECL_PROTECT(lev); |
| 292 |
|
|
| 293 |
/* parameter check */ |
/* parameter check */ |
| 294 |
LWIP_ASSERT("sys_mbox_free ", q != SYS_MBOX_NULL ); |
LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL); |
| 295 |
LWIP_ASSERT("q->sem != NULL", q->sem != NULL); |
LWIP_ASSERT("q->sem != NULL", q->sem != NULL); |
| 296 |
LWIP_ASSERT("q->sem != INVALID_HANDLE_VALUE", q->sem != INVALID_HANDLE_VALUE); |
LWIP_ASSERT("q->sem != INVALID_HANDLE_VALUE", q->sem != INVALID_HANDLE_VALUE); |
| 297 |
|
|
| 316 |
return ERR_OK; |
return ERR_OK; |
| 317 |
} |
} |
| 318 |
|
|
| 319 |
u32_t sys_arch_mbox_fetch(sys_mbox_t q, void **msg, u32_t timeout) |
u32_t sys_arch_mbox_fetch(sys_mbox_t *q, void **msg, u32_t timeout) |
| 320 |
{ |
{ |
| 321 |
DWORD ret; |
DWORD ret; |
| 322 |
LONGLONG starttime, endtime; |
LONGLONG starttime, endtime; |
| 323 |
SYS_ARCH_DECL_PROTECT(lev); |
SYS_ARCH_DECL_PROTECT(lev); |
| 324 |
|
|
| 325 |
/* parameter check */ |
/* parameter check */ |
| 326 |
LWIP_ASSERT("sys_mbox_free ", q != SYS_MBOX_NULL ); |
LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL); |
| 327 |
LWIP_ASSERT("q->sem != NULL", q->sem != NULL); |
LWIP_ASSERT("q->sem != NULL", q->sem != NULL); |
| 328 |
LWIP_ASSERT("q->sem != INVALID_HANDLE_VALUE", q->sem != INVALID_HANDLE_VALUE); |
LWIP_ASSERT("q->sem != INVALID_HANDLE_VALUE", q->sem != INVALID_HANDLE_VALUE); |
| 329 |
|
|
| 356 |
} |
} |
| 357 |
} |
} |
| 358 |
|
|
| 359 |
u32_t sys_arch_mbox_tryfetch(sys_mbox_t q, void **msg) |
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *q, void **msg) |
| 360 |
{ |
{ |
| 361 |
DWORD ret; |
DWORD ret; |
| 362 |
SYS_ARCH_DECL_PROTECT(lev); |
SYS_ARCH_DECL_PROTECT(lev); |
| 363 |
|
|
| 364 |
/* parameter check */ |
/* parameter check */ |
| 365 |
LWIP_ASSERT("sys_mbox_free ", q != SYS_MBOX_NULL ); |
LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL); |
| 366 |
LWIP_ASSERT("q->sem != NULL", q->sem != NULL); |
LWIP_ASSERT("q->sem != NULL", q->sem != NULL); |
| 367 |
LWIP_ASSERT("q->sem != INVALID_HANDLE_VALUE", q->sem != INVALID_HANDLE_VALUE); |
LWIP_ASSERT("q->sem != INVALID_HANDLE_VALUE", q->sem != INVALID_HANDLE_VALUE); |
| 368 |
|
|
| 389 |
return SYS_ARCH_TIMEOUT; |
return SYS_ARCH_TIMEOUT; |
| 390 |
} |
} |
| 391 |
} |
} |
| 392 |
|
|
| 393 |
#endif /* !NO_SYS */ |
#endif /* !NO_SYS */ |