1 #include <arch/sys_arch.h>
2 #include <lwip/err.h>
3 #include <lwip/sys.h>
4 #include <lwip/tcpip.h>
5 #include <platform.h>
6 #include <assert.h>
7 #include <lk/trace.h>
8 #include <lk/err.h>
9 #include <stdbool.h>
10 #include <lk/init.h>
11 
12 #define LOCAL_TRACE 1
13 
sys_init(void)14 void sys_init(void)
15 {
16 }
17 
sys_thread_new(const char * name,lwip_thread_fn func,void * arg,int stacksize,int prio)18 sys_thread_t sys_thread_new(const char *name, lwip_thread_fn func, void *arg, int stacksize, int prio)
19 {
20     thread_t *t = thread_create(name, (void*) func, arg, prio, stacksize);
21     DEBUG_ASSERT(t);
22 
23     thread_detach(t);
24     thread_resume(t);
25 
26     return t;
27 }
28 
sys_sem_new(sys_sem_t * sem,u8_t count)29 err_t sys_sem_new(sys_sem_t *sem, u8_t count)
30 {
31     sem_init(sem, count);
32     return ERR_OK;
33 }
34 
sys_sem_free(sys_sem_t * sem)35 void sys_sem_free(sys_sem_t * sem)
36 {
37     sem_destroy(sem);
38 }
39 
sys_sem_valid(sys_sem_t * sem)40 int sys_sem_valid(sys_sem_t *sem)
41 {
42     return sem->magic == SEMAPHORE_MAGIC;
43 }
44 
sys_sem_set_invalid(sys_sem_t * sem)45 void sys_sem_set_invalid(sys_sem_t *sem)
46 {
47     // sem_destroy() does this
48 }
49 
sys_sem_signal(sys_sem_t * sem)50 void sys_sem_signal(sys_sem_t * sem)
51 {
52     sem_post(sem, true);
53 }
54 
sys_arch_sem_wait(sys_sem_t * sem,u32_t timeout)55 u32_t sys_arch_sem_wait(sys_sem_t * sem, u32_t timeout)
56 {
57     lk_time_t start = current_time();
58 
59     status_t err = sem_timedwait(sem, timeout ? timeout : INFINITE_TIME);
60     if (err == ERR_TIMED_OUT)
61         return SYS_ARCH_TIMEOUT;
62 
63     return current_time() - start;
64 }
65 
sys_mbox_new(sys_mbox_t * mbox,int size)66 err_t sys_mbox_new(sys_mbox_t * mbox, int size)
67 {
68     sem_init(&mbox->empty, size);
69     sem_init(&mbox->full, 0);
70     mutex_init(&mbox->lock);
71 
72     mbox->magic = MBOX_MAGIC;
73     mbox->head = 0;
74     mbox->tail = 0;
75     mbox->size = size;
76 
77     mbox->queue = calloc(size, sizeof(void *));
78     if (!mbox->queue)
79         return ERR_MEM;
80 
81     return ERR_OK;
82 }
83 
sys_mbox_free(sys_mbox_t * mbox)84 void sys_mbox_free(sys_mbox_t *mbox)
85 {
86     free(mbox->queue);
87     mbox->queue = NULL;
88 }
89 
sys_mbox_post(sys_mbox_t * mbox,void * msg)90 void sys_mbox_post(sys_mbox_t * mbox, void *msg)
91 {
92     sem_wait(&mbox->empty);
93     mutex_acquire(&mbox->lock);
94 
95     mbox->queue[mbox->head] = msg;
96     mbox->head = (mbox->head + 1) % mbox->size;
97 
98     mutex_release(&mbox->lock);
99     sem_post(&mbox->full, true);
100 }
101 
sys_arch_mbox_tryfetch(sys_mbox_t * mbox,void ** msg)102 u32_t sys_arch_mbox_tryfetch(sys_mbox_t * mbox, void **msg)
103 {
104     //LTRACE_ENTRY;
105 
106     status_t res;
107 
108     res = sem_trywait(&mbox->full);
109     if (res == ERR_NOT_READY) {
110         //LTRACE_EXIT;
111         return SYS_MBOX_EMPTY;
112     }
113 
114     mutex_acquire(&mbox->lock);
115 
116     *msg = mbox->queue[mbox->tail];
117     mbox->tail = (mbox->tail + 1) % mbox->size;
118 
119     mutex_release(&mbox->lock);
120     sem_post(&mbox->empty, true);
121 
122     //LTRACE_EXIT;
123     return 0;
124 }
125 
sys_arch_mbox_fetch(sys_mbox_t * mbox,void ** msg,u32_t timeout)126 u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
127 {
128     //LTRACE_ENTRY;
129 
130     status_t res;
131     lk_time_t start = current_time();
132 
133     res = sem_timedwait(&mbox->full, timeout ? timeout : INFINITE_TIME);
134     if (res == ERR_TIMED_OUT) {
135         //LTRACE_EXIT;
136         return SYS_ARCH_TIMEOUT; //timeout ? SYS_ARCH_TIMEOUT : 0;
137     }
138 
139     mutex_acquire(&mbox->lock);
140 
141     *msg = mbox->queue[mbox->tail];
142     mbox->tail = (mbox->tail + 1) % mbox->size;
143 
144     mutex_release(&mbox->lock);
145     sem_post(&mbox->empty, true);
146 
147     //LTRACE_EXIT;
148     return current_time() - start;
149 }
150 
sys_mbox_trypost(sys_mbox_t * mbox,void * msg)151 err_t sys_mbox_trypost(sys_mbox_t * mbox, void *msg)
152 {
153     status_t res;
154 
155     res = sem_trywait(&mbox->empty);
156     if (res == ERR_NOT_READY)
157         return ERR_TIMEOUT;
158 
159     mutex_acquire(&mbox->lock);
160 
161     mbox->queue[mbox->head] = msg;
162     mbox->head = (mbox->head + 1) % mbox->size;
163 
164     mutex_release(&mbox->lock);
165     sem_post(&mbox->full, true);
166 
167     return ERR_OK;
168 }
169 
sys_mbox_valid(sys_mbox_t * mbox)170 int sys_mbox_valid(sys_mbox_t *mbox)
171 {
172     return mbox->magic == MBOX_MAGIC;
173 }
174 
sys_mbox_set_invalid(sys_mbox_t * mbox)175 void sys_mbox_set_invalid(sys_mbox_t *mbox)
176 {
177     mbox->magic = 'xobm';
178 }
179 
sys_mutex_new(sys_mutex_t * mutex)180 err_t sys_mutex_new(sys_mutex_t *mutex)
181 {
182     mutex_init(mutex);
183     return ERR_OK;
184 }
185 
sys_mutex_lock(sys_mutex_t * mutex)186 void sys_mutex_lock(sys_mutex_t *mutex)
187 {
188     mutex_acquire(mutex);
189 }
190 
sys_mutex_unlock(sys_mutex_t * mutex)191 void sys_mutex_unlock(sys_mutex_t *mutex)
192 {
193     mutex_release(mutex);
194 }
195 
sys_mutex_free(sys_mutex_t * mutex)196 void sys_mutex_free(sys_mutex_t *mutex)
197 {
198     mutex_destroy(mutex);
199 }
200 
201 /* run lwip init as soon as threads are running */
lwip_init_hook(uint level)202 void lwip_init_hook(uint level)
203 {
204     tcpip_init(NULL, NULL);
205 }
206 
207 LK_INIT_HOOK(lwip, &lwip_init_hook, LK_INIT_LEVEL_THREADING);
208 
209