Warning, cross-references for /kernel/lwip/core/sys.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #include "lwip/opt.h"
0040
0041 #if (NO_SYS == 0)
0042
0043 #include "lwip/sys.h"
0044 #include "lwip/def.h"
0045 #include "lwip/memp.h"
0046 #include "lwip/tcpip.h"
0047
0048
0049
0050
0051
0052 struct sswt_cb
0053 {
0054 s16_t timeflag;
0055 sys_sem_t *psem;
0056 };
0057
0058
0059
0060
0061
0062
0063
0064
0065 void
0066 sys_mbox_fetch(sys_mbox_t mbox, void **msg)
0067 {
0068 u32_t time_needed;
0069 struct sys_timeouts *timeouts;
0070 struct sys_timeo *tmptimeout;
0071 sys_timeout_handler h;
0072 void *arg;
0073
0074 again:
0075 timeouts = sys_arch_timeouts();
0076
0077 if (!timeouts || !timeouts->next) {
0078 UNLOCK_TCPIP_CORE();
0079 time_needed = sys_arch_mbox_fetch(mbox, msg, 0);
0080 LOCK_TCPIP_CORE();
0081 } else {
0082 if (timeouts->next->time > 0) {
0083 UNLOCK_TCPIP_CORE();
0084 time_needed = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time);
0085 LOCK_TCPIP_CORE();
0086 } else {
0087 time_needed = SYS_ARCH_TIMEOUT;
0088 }
0089
0090 if (time_needed == SYS_ARCH_TIMEOUT) {
0091
0092
0093
0094 tmptimeout = timeouts->next;
0095 timeouts->next = tmptimeout->next;
0096 h = tmptimeout->h;
0097 arg = tmptimeout->arg;
0098 memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
0099 if (h != NULL) {
0100 LWIP_DEBUGF(SYS_DEBUG, ("smf calling h=%p(%p)\n", *(void**)&h, arg));
0101 h(arg);
0102 }
0103
0104
0105 goto again;
0106 } else {
0107
0108
0109
0110 if (time_needed < timeouts->next->time) {
0111 timeouts->next->time -= time_needed;
0112 } else {
0113 timeouts->next->time = 0;
0114 }
0115 }
0116 }
0117 }
0118
0119
0120
0121
0122
0123
0124
0125 void
0126 sys_sem_wait(sys_sem_t sem)
0127 {
0128 u32_t time_needed;
0129 struct sys_timeouts *timeouts;
0130 struct sys_timeo *tmptimeout;
0131 sys_timeout_handler h;
0132 void *arg;
0133
0134 again:
0135
0136 timeouts = sys_arch_timeouts();
0137
0138 if (!timeouts || !timeouts->next) {
0139 sys_arch_sem_wait(sem, 0);
0140 } else {
0141 if (timeouts->next->time > 0) {
0142 time_needed = sys_arch_sem_wait(sem, timeouts->next->time);
0143 } else {
0144 time_needed = SYS_ARCH_TIMEOUT;
0145 }
0146
0147 if (time_needed == SYS_ARCH_TIMEOUT) {
0148
0149
0150
0151 tmptimeout = timeouts->next;
0152 timeouts->next = tmptimeout->next;
0153 h = tmptimeout->h;
0154 arg = tmptimeout->arg;
0155 memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
0156 if (h != NULL) {
0157 LWIP_DEBUGF(SYS_DEBUG, ("ssw h=%p(%p)\n", *(void**)&h, (void *)arg));
0158 h(arg);
0159 }
0160
0161
0162 goto again;
0163 } else {
0164
0165
0166
0167 if (time_needed < timeouts->next->time) {
0168 timeouts->next->time -= time_needed;
0169 } else {
0170 timeouts->next->time = 0;
0171 }
0172 }
0173 }
0174 }
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187 void
0188 sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
0189 {
0190 struct sys_timeouts *timeouts;
0191 struct sys_timeo *timeout, *t;
0192
0193 timeout = memp_malloc(MEMP_SYS_TIMEOUT);
0194 if (timeout == NULL) {
0195 LWIP_ASSERT("sys_timeout: timeout != NULL", timeout != NULL);
0196 return;
0197 }
0198 timeout->next = NULL;
0199 timeout->h = h;
0200 timeout->arg = arg;
0201 timeout->time = msecs;
0202
0203 timeouts = sys_arch_timeouts();
0204
0205 LWIP_DEBUGF(SYS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" h=%p arg=%p\n",
0206 (void *)timeout, msecs, *(void**)&h, (void *)arg));
0207
0208 if (timeouts == NULL) {
0209 LWIP_ASSERT("sys_timeout: timeouts != NULL", timeouts != NULL);
0210 return;
0211 }
0212
0213 if (timeouts->next == NULL) {
0214 timeouts->next = timeout;
0215 return;
0216 }
0217
0218 if (timeouts->next->time > msecs) {
0219 timeouts->next->time -= msecs;
0220 timeout->next = timeouts->next;
0221 timeouts->next = timeout;
0222 } else {
0223 for(t = timeouts->next; t != NULL; t = t->next) {
0224 timeout->time -= t->time;
0225 if (t->next == NULL || t->next->time > timeout->time) {
0226 if (t->next != NULL) {
0227 t->next->time -= timeout->time;
0228 }
0229 timeout->next = t->next;
0230 t->next = timeout;
0231 break;
0232 }
0233 }
0234 }
0235 }
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247 void
0248 sys_untimeout(sys_timeout_handler h, void *arg)
0249 {
0250 struct sys_timeouts *timeouts;
0251 struct sys_timeo *prev_t, *t;
0252
0253 timeouts = sys_arch_timeouts();
0254
0255 if (timeouts == NULL) {
0256 LWIP_ASSERT("sys_untimeout: timeouts != NULL", timeouts != NULL);
0257 return;
0258 }
0259 if (timeouts->next == NULL) {
0260 return;
0261 }
0262
0263 for (t = timeouts->next, prev_t = NULL; t != NULL; prev_t = t, t = t->next) {
0264 if ((t->h == h) && (t->arg == arg)) {
0265
0266
0267 if (prev_t == NULL) {
0268 timeouts->next = t->next;
0269 } else {
0270 prev_t->next = t->next;
0271 }
0272
0273 if (t->next != NULL) {
0274 t->next->time += t->time;
0275 }
0276 memp_free(MEMP_SYS_TIMEOUT, t);
0277 return;
0278 }
0279 }
0280 return;
0281 }
0282
0283
0284
0285
0286
0287
0288 static void
0289 sswt_handler(void *arg)
0290 {
0291 struct sswt_cb *sswt_cb = (struct sswt_cb *) arg;
0292
0293
0294 sswt_cb->timeflag = 1;
0295 sys_sem_signal(*(sswt_cb->psem));
0296 }
0297
0298
0299
0300
0301
0302
0303
0304
0305 int
0306 sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout)
0307 {
0308 struct sswt_cb sswt_cb;
0309
0310 sswt_cb.psem = &sem;
0311 sswt_cb.timeflag = 0;
0312
0313
0314 if (timeout > 0) {
0315
0316 sys_timeout(timeout, sswt_handler, &sswt_cb);
0317 }
0318 sys_sem_wait(sem);
0319
0320 if (sswt_cb.timeflag) {
0321
0322 return 0;
0323 } else {
0324
0325 sys_untimeout(sswt_handler, &sswt_cb);
0326 return 1;
0327 }
0328 }
0329
0330
0331
0332
0333
0334
0335 void
0336 sys_msleep(u32_t ms)
0337 {
0338 sys_sem_t delaysem = sys_sem_new(0);
0339
0340 sys_sem_wait_timeout(delaysem, ms);
0341
0342 sys_sem_free(delaysem);
0343 }
0344
0345
0346 #endif