blob: 55d2143adaa377ff9eede31394e47fa10268bdaf [file] [log] [blame]
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -07001/*
2 * Copyright (c) 2006 Travis Geiselbrecht
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23#include <debug.h>
24#include <err.h>
25#include <malloc.h>
26#include <kernel/thread.h>
27#include <kernel/timer.h>
28#include <platform.h>
29#include <lwip/sys.h>
30
31static struct sys_timeouts timeouts;
32
33void sys_init(void)
34{
35}
36
37/*---------------------------------------
38 * Thread stuff
39 *---------------------------------------*/
40sys_thread_t sys_thread_new(void (* thread)(void *arg), void *arg, int prio)
41{
42 thread_t *t;
43
44 t = thread_create("lwip thread", (thread_start_routine)thread, arg, prio, DEFAULT_STACK_SIZE);
45 if (t)
46 thread_resume(t);
47
48 return t;
49}
50
51struct sys_timeouts *sys_arch_timeouts(void)
52{
53 // XXX I think this needs to be per thread
54 return &timeouts;
55}
56
57/*---------------------------------------
58 * Semaphore stuff
59 *---------------------------------------*/
60
61sys_sem_t sys_sem_new(u8_t count)
62{
63 struct sys_sem_struct *sem;
64
65// dprintf("sys_sem_new: count %d\n", count);
66
67 sem = malloc(sizeof(struct sys_sem_struct));
68 if (!sem)
69 return SYS_SEM_NULL;
70
71 sem->count = count;
72 wait_queue_init(&sem->wait);
73
74// dprintf("sys_sem_new: count %d returning sem %p\n", count, sem);
75
76 return sem;
77}
78
79void sys_sem_signal(sys_sem_t sem)
80{
81 enter_critical_section();
82
83 sem->count++;
84 if (sem->count <= 0)
85 wait_queue_wake_one(&sem->wait, true, NO_ERROR);
86
87 exit_critical_section();
88}
89
90u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout)
91{
92 status_t err;
93 u32_t ret = 0;
94
95// dprintf("sys_arch_sem_wait: sem %p, timeout %d\n", sem, timeout);
96
97 enter_critical_section();
98
99 sem->count--;
100 if (sem->count < 0) {
101 ret = current_time();
102
103 err = wait_queue_block(&sem->wait, timeout);
104 if (err == ERR_TIMED_OUT) {
105 ret = SYS_ARCH_TIMEOUT;
106 } else if (err >= 0) {
107 ret = current_time() - ret;
108 } else {
109 panic("sys_arch_sem_wait: funny retcode from wait_queue_block %d\n", err);
110 }
111 }
112
113 exit_critical_section();
114
115 return ret;
116}
117
118void sys_sem_free(sys_sem_t sem)
119{
120 enter_critical_section();
121 wait_queue_destroy(&sem->wait, true);
122 exit_critical_section();
123 free(sem);
124}
125
126/*---------------------------------------
127 * Mailbox stuff
128 *---------------------------------------*/
129
130sys_mbox_t sys_mbox_new(void)
131{
132 struct sys_mbox_struct *mbox;
133
134 mbox = malloc(sizeof(struct sys_mbox_struct));
135 if (!mbox)
136 return SYS_MBOX_NULL;
137
138 mbox->msg = NULL;
139 wait_queue_init(&mbox->wait);
140
141// dprintf("sys_mbox_new: returning mbox %p\n", mbox);
142
143 return mbox;
144}
145
146void sys_mbox_post(sys_mbox_t mbox, void *msg)
147{
148 enter_critical_section();
149
150// dprintf("sys_mbox_post: mbox %p, msg %p\n", mbox, msg);
151
152 mbox->msg = msg;
153 wait_queue_wake_one(&mbox->wait, true, NO_ERROR);
154
155 exit_critical_section();
156}
157
158u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout)
159{
160 status_t err;
161 u32_t ret = 0;
162
163// dprintf("sys_arch_mbox_fetch: mbox %p, msg %p, timeout %d\n", mbox, msg, timeout);
164
165 enter_critical_section();
166
167 if (mbox->msg == NULL) {
168 ret = current_time();
169
170 err = wait_queue_block(&mbox->wait, timeout);
171 if (err == ERR_TIMED_OUT) {
172 ret = SYS_ARCH_TIMEOUT;
173 goto out;
174 } else if (err >= 0) {
175 ret = current_time() - ret;
176 } else {
177 panic("sys_arch_mbox_fetch: funny retcode from wait_queue_block %d\n", err);
178 }
179 }
180
181 /* retrieve the message */
182 if (msg)
183 *msg = mbox->msg;
184 mbox->msg = NULL;
185
186out:
187// dprintf("sys_arch_mbox_fetch: returning with err code %d\n", ret);
188
189 exit_critical_section();
190
191 return ret;
192}
193
194void sys_mbox_free(sys_mbox_t mbox)
195{
196 enter_critical_section();
197 wait_queue_destroy(&mbox->wait, true);
198 exit_critical_section();
199 free(mbox);
200}
201