OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [lwIP_Demo_Rowley_ARM7/] [lwip-1.1.0/] [src/] [core/] [sys.c] - Blame information for rev 583

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 583 jeremybenn
/*
2
 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without modification,
6
 * are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. The name of the author may not be used to endorse or promote products
14
 *    derived from this software without specific prior written permission.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19
 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
25
 * OF SUCH DAMAGE.
26
 *
27
 * This file is part of the lwIP TCP/IP stack.
28
 *
29
 * Author: Adam Dunkels <adam@sics.se>
30
 *
31
 */
32
 
33
#include "lwip/sys.h"
34
#include "lwip/opt.h"
35
#include "lwip/def.h"
36
#include "lwip/memp.h"
37
 
38
#if (NO_SYS == 0)
39
 
40
struct sswt_cb
41
{
42
    int timeflag;
43
    sys_sem_t *psem;
44
};
45
 
46
 
47
 
48
void
49
sys_mbox_fetch(sys_mbox_t mbox, void **msg)
50
{
51
  u32_t time;
52
  struct sys_timeouts *timeouts;
53
  struct sys_timeout *tmptimeout;
54
  sys_timeout_handler h;
55
  void *arg;
56
 
57
 
58
 again:
59
  timeouts = sys_arch_timeouts();
60
 
61
  if (!timeouts || !timeouts->next) {
62
    sys_arch_mbox_fetch(mbox, msg, 0);
63
  } else {
64
    if (timeouts->next->time > 0) {
65
      time = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time);
66
    } else {
67
      time = SYS_ARCH_TIMEOUT;
68
    }
69
 
70
    if (time == SYS_ARCH_TIMEOUT) {
71
      /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
72
   could be fetched. We should now call the timeout handler and
73
   deallocate the memory allocated for the timeout. */
74
      tmptimeout = timeouts->next;
75
      timeouts->next = tmptimeout->next;
76
      h = tmptimeout->h;
77
      arg = tmptimeout->arg;
78
      memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
79
      if (h != NULL) {
80
        LWIP_DEBUGF(SYS_DEBUG, ("smf calling h=%p(%p)\n", (void *)h, (void *)arg));
81
        h(arg);
82
      }
83
 
84
      /* We try again to fetch a message from the mbox. */
85
      goto again;
86
    } else {
87
      /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
88
   occured. The time variable is set to the number of
89
   milliseconds we waited for the message. */
90
      if (time <= timeouts->next->time) {
91
  timeouts->next->time -= time;
92
      } else {
93
  timeouts->next->time = 0;
94
      }
95
    }
96
 
97
  }
98
}
99
 
100
void
101
sys_sem_wait(sys_sem_t sem)
102
{
103
  u32_t time;
104
  struct sys_timeouts *timeouts;
105
  struct sys_timeout *tmptimeout;
106
  sys_timeout_handler h;
107
  void *arg;
108
 
109
  /*  while (sys_arch_sem_wait(sem, 1000) == 0);
110
      return;*/
111
 
112
 again:
113
 
114
  timeouts = sys_arch_timeouts();
115
 
116
  if (!timeouts || !timeouts->next) {
117
    sys_arch_sem_wait(sem, 0);
118
  } else {
119
    if (timeouts->next->time > 0) {
120
      time = sys_arch_sem_wait(sem, timeouts->next->time);
121
    } else {
122
      time = SYS_ARCH_TIMEOUT;
123
    }
124
 
125
    if (time == SYS_ARCH_TIMEOUT) {
126
      /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
127
   could be fetched. We should now call the timeout handler and
128
   deallocate the memory allocated for the timeout. */
129
      tmptimeout = timeouts->next;
130
      timeouts->next = tmptimeout->next;
131
      h = tmptimeout->h;
132
      arg = tmptimeout->arg;
133
      memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
134
      if (h != NULL) {
135
        LWIP_DEBUGF(SYS_DEBUG, ("ssw h=%p(%p)\n", (void *)h, (void *)arg));
136
        h(arg);
137
      }
138
 
139
 
140
      /* We try again to fetch a message from the mbox. */
141
      goto again;
142
    } else {
143
      /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
144
   occured. The time variable is set to the number of
145
   milliseconds we waited for the message. */
146
      if (time <= timeouts->next->time) {
147
  timeouts->next->time -= time;
148
      } else {
149
  timeouts->next->time = 0;
150
      }
151
    }
152
 
153
  }
154
}
155
 
156
void
157
sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
158
{
159
  struct sys_timeouts *timeouts;
160
  struct sys_timeout *timeout, *t;
161
 
162
  timeout = memp_malloc(MEMP_SYS_TIMEOUT);
163
  if (timeout == NULL) {
164
    return;
165
  }
166
  timeout->next = NULL;
167
  timeout->h = h;
168
  timeout->arg = arg;
169
  timeout->time = msecs;
170
 
171
  timeouts = sys_arch_timeouts();
172
 
173
  LWIP_DEBUGF(SYS_DEBUG, ("sys_timeout: %p msecs=%lu h=%p arg=%p\n",
174
    (void *)timeout, msecs, (void *)h, (void *)arg));
175
 
176
  LWIP_ASSERT("sys_timeout: timeouts != NULL", timeouts != NULL);
177
 
178
  if (timeouts->next == NULL) {
179
    timeouts->next = timeout;
180
    return;
181
  }
182
 
183
  if (timeouts->next->time > msecs) {
184
    timeouts->next->time -= msecs;
185
    timeout->next = timeouts->next;
186
    timeouts->next = timeout;
187
  } else {
188
    for(t = timeouts->next; t != NULL; t = t->next) {
189
      timeout->time -= t->time;
190
      if (t->next == NULL || t->next->time > timeout->time) {
191
        if (t->next != NULL) {
192
          t->next->time -= timeout->time;
193
        }
194
        timeout->next = t->next;
195
        t->next = timeout;
196
        break;
197
      }
198
    }
199
  }
200
 
201
}
202
 
203
/* Go through timeout list (for this task only) and remove the first matching entry,
204
   even though the timeout has not triggered yet.
205
*/
206
 
207
void
208
sys_untimeout(sys_timeout_handler h, void *arg)
209
{
210
    struct sys_timeouts *timeouts;
211
    struct sys_timeout *prev_t, *t;
212
 
213
    timeouts = sys_arch_timeouts();
214
 
215
    if (timeouts->next == NULL)
216
        return;
217
 
218
    for (t = timeouts->next, prev_t = NULL; t != NULL; prev_t = t, t = t->next)
219
    {
220
        if ((t->h == h) && (t->arg == arg))
221
        {
222
            /* We have a match */
223
            /* Unlink from previous in list */
224
            if (prev_t == NULL)
225
                timeouts->next = t->next;
226
            else
227
                prev_t->next = t->next;
228
            /* If not the last one, add time of this one back to next */
229
            if (t->next != NULL)
230
                t->next->time += t->time;
231
            memp_free(MEMP_SYS_TIMEOUT, t);
232
            return;
233
        }
234
    }
235
    return;
236
}
237
 
238
 
239
 
240
 
241
 
242
static void
243
sswt_handler(void *arg)
244
{
245
    struct sswt_cb *sswt_cb = (struct sswt_cb *) arg;
246
 
247
    /* Timeout. Set flag to TRUE and signal semaphore */
248
    sswt_cb->timeflag = 1;
249
    sys_sem_signal(*(sswt_cb->psem));
250
}
251
 
252
/* Wait for a semaphore with timeout (specified in ms) */
253
/* timeout = 0: wait forever */
254
/* Returns 0 on timeout. 1 otherwise */
255
 
256
int
257
sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout)
258
{
259
    struct sswt_cb sswt_cb;
260
 
261
    sswt_cb.psem = &sem;
262
    sswt_cb.timeflag = 0;
263
 
264
    /* If timeout is zero, then just wait forever */
265
    if (timeout > 0)
266
        /* Create a timer and pass it the address of our flag */
267
        sys_timeout(timeout, sswt_handler, &sswt_cb);
268
    sys_sem_wait(sem);
269
    /* Was it a timeout? */
270
    if (sswt_cb.timeflag)
271
    {
272
        /* timeout */
273
        return 0;
274
    } else {
275
        /* Not a timeout. Remove timeout entry */
276
        sys_untimeout(sswt_handler, &sswt_cb);
277
        return 1;
278
    }
279
 
280
}
281
 
282
 
283
void
284
sys_msleep(u32_t ms)
285
{
286
  sys_sem_t delaysem = sys_sem_new(0);
287
 
288
  sys_sem_wait_timeout(delaysem, ms);
289
 
290
  sys_sem_free(delaysem);
291
}
292
 
293
 
294
#endif /* NO_SYS */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.