Select the types of activity you want to include in your feed.
Add queue_send synchronous message sending. Right now only for SWCODEC. Actual usage to be added to playback and recording shortly in upcoming commits.
···3333#define QUEUE_LENGTH 16 /* MUST be a power of 2 */
3434#define QUEUE_LENGTH_MASK (QUEUE_LENGTH - 1)
35353636-/* System defined message ID's, occupying the top 5 bits of the event ID */
3636+/* System defined message ID's, occupying the top 8 bits of the event ID */
3737#define SYS_EVENT (long)0x80000000 /* SYS events are negative */
3838#define SYS_USB_CONNECTED ((SYS_EVENT | ((long)1 << 27)))
3939#define SYS_USB_CONNECTED_ACK ((SYS_EVENT | ((long)2 << 27)))
···5555 void *data;
5656};
57575858+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
5959+struct queue_sender
6060+{
6161+ struct thread_entry *thread;
6262+ void *retval;
6363+};
6464+6565+struct queue_sender_list
6666+{
6767+ /* If non-NULL, there is a thread waiting for the corresponding event */
6868+ struct queue_sender *senders[QUEUE_LENGTH];
6969+ /* Send info for last message dequeued or NULL if replied or not sent */
7070+ struct queue_sender *curr_sender;
7171+};
7272+#endif /* HAVE_EXTENDED_MESSAGING_AND_NAME */
7373+5874struct event_queue
5975{
6076 struct event events[QUEUE_LENGTH];
6177 struct thread_entry *thread;
6278 unsigned int read;
6379 unsigned int write;
8080+ struct queue_sender_list *send;
6481};
65826683struct mutex
···90107int tick_remove_task(void (*f)(void));
9110892109extern void queue_init(struct event_queue *q, bool register_queue);
110110+extern void queue_enable_queue_send(struct event_queue *q, struct queue_sender_list *send);
93111extern void queue_delete(struct event_queue *q);
94112extern void queue_wait(struct event_queue *q, struct event *ev);
95113extern void queue_wait_w_tmo(struct event_queue *q, struct event *ev, int ticks);
96114extern void queue_post(struct event_queue *q, long id, void *data);
115115+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
116116+extern void * queue_send(struct event_queue *q, long id, void *data);
117117+extern void queue_reply(struct event_queue *q, void *retval);
118118+extern bool queue_in_queue_send(struct event_queue *q);
119119+#endif /* HAVE_EXTENDED_MESSAGING_AND_NAME */
97120extern bool queue_empty(const struct event_queue* q);
9898-void queue_clear(struct event_queue* q);
121121+extern void queue_clear(struct event_queue* q);
99122extern void queue_remove_from_head(struct event_queue *q, long id);
100123extern int queue_broadcast(long id, void *data);
101124
+7
firmware/export/thread.h
···143143void sleep_thread(int ticks);
144144void block_thread(struct thread_entry **thread);
145145void block_thread_w_tmo(struct thread_entry **thread, int timeout);
146146+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
147147+void set_irq_level_and_block_thread(struct thread_entry **thread, int level);
148148+#if 0
149149+void set_irq_level_and_block_thread_w_tmo(struct thread_entry **list,
150150+ int timeout, int level)
151151+#endif
152152+#endif
146153void wakeup_thread(struct thread_entry **thread);
147154#ifdef HAVE_PRIORITY_SCHEDULING
148155int thread_set_priority(struct thread_entry *thread, int priority);
+191-18
firmware/kernel.c
···8686/****************************************************************************
8787 * Queue handling stuff
8888 ****************************************************************************/
8989+9090+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
9191+/* Moves waiting thread's descriptor to the current sender when a
9292+ message is dequeued */
9393+static void queue_fetch_sender(struct queue_sender_list *send,
9494+ unsigned int i)
9595+{
9696+ int old_level = set_irq_level(HIGHEST_IRQ_LEVEL);
9797+ struct queue_sender **spp = &send->senders[i];
9898+9999+ if(*spp)
100100+ {
101101+ send->curr_sender = *spp;
102102+ *spp = NULL;
103103+ }
104104+105105+ set_irq_level(old_level);
106106+}
107107+108108+/* Puts the specified return value in the waiting thread's return value
109109+ and wakes the thread - a sender should be confirmed to exist first */
110110+static void queue_release_sender(struct queue_sender **sender, void *retval)
111111+{
112112+ (*sender)->retval = retval;
113113+ wakeup_thread(&(*sender)->thread);
114114+ *sender = NULL;
115115+}
116116+117117+/* Releases any waiting threads that are queued with queue_send -
118118+ reply with NULL */
119119+static void queue_release_all_senders(struct event_queue *q)
120120+{
121121+ if(q->send)
122122+ {
123123+ unsigned int i;
124124+ for(i = q->read; i != q->write; i++)
125125+ {
126126+ struct queue_sender **spp =
127127+ &q->send->senders[i & QUEUE_LENGTH_MASK];
128128+ if(*spp)
129129+ {
130130+ queue_release_sender(spp, NULL);
131131+ }
132132+ }
133133+ }
134134+}
135135+136136+/* Enables queue_send on the specified queue - caller allocates the extra
137137+ data structure */
138138+void queue_enable_queue_send(struct event_queue *q,
139139+ struct queue_sender_list *send)
140140+{
141141+ q->send = send;
142142+ memset(send, 0, sizeof(*send));
143143+}
144144+#endif /* HAVE_EXTENDED_MESSAGING_AND_NAME */
145145+146146+89147void queue_init(struct event_queue *q, bool register_queue)
90148{
9191- q->read = 0;
9292- q->write = 0;
149149+ q->read = 0;
150150+ q->write = 0;
93151 q->thread = NULL;
9494-9595- if (register_queue)
152152+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
153153+ q->send = NULL; /* No message sending by default */
154154+#endif
155155+156156+ if(register_queue)
96157 {
97158 /* Add it to the all_queues array */
98159 all_queues[num_queues++] = q;
···118179119180 if(found)
120181 {
182182+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
183183+ /* Release waiting threads and reply to any dequeued message
184184+ waiting for one. */
185185+ queue_release_all_senders(q);
186186+ queue_reply(q, NULL);
187187+#endif
121188 /* Move the following queues up in the list */
122189 for(;i < num_queues-1;i++)
123190 {
···130197131198void queue_wait(struct event_queue *q, struct event *ev)
132199{
133133- if (q->read == q->write)
200200+ unsigned int rd;
201201+202202+ if(q->read == q->write)
134203 {
135204 block_thread(&q->thread);
136205 }
137206138138- *ev = q->events[(q->read++) & QUEUE_LENGTH_MASK];
207207+ rd = q->read++ & QUEUE_LENGTH_MASK;
208208+ *ev = q->events[rd];
209209+210210+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
211211+ if(q->send && q->send->senders[rd])
212212+ {
213213+ /* Get data for a waiting thread if one */
214214+ queue_fetch_sender(q->send, rd);
215215+ }
216216+#endif
139217}
140218141219void queue_wait_w_tmo(struct event_queue *q, struct event *ev, int ticks)
142220{
143143- if (q->read == q->write && ticks > 0)
221221+ if(q->read == q->write && ticks > 0)
144222 {
145223 block_thread_w_tmo(&q->thread, ticks);
146224 }
147225148148- if (q->read != q->write)
226226+ if(q->read != q->write)
149227 {
150150- *ev = q->events[(q->read++) & QUEUE_LENGTH_MASK];
228228+ unsigned int rd = q->read++ & QUEUE_LENGTH_MASK;
229229+ *ev = q->events[rd];
230230+231231+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
232232+ if(q->send && q->send->senders[rd])
233233+ {
234234+ /* Get data for a waiting thread if one */
235235+ queue_fetch_sender(q->send, rd);
236236+ }
237237+#endif
151238 }
152239 else
153240 {
···157244158245void queue_post(struct event_queue *q, long id, void *data)
159246{
160160- int wr;
161161- int oldlevel;
247247+ int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
248248+ unsigned int wr = q->write++ & QUEUE_LENGTH_MASK;
162249163163- oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
164164- wr = (q->write++) & QUEUE_LENGTH_MASK;
250250+ q->events[wr].id = id;
251251+ q->events[wr].data = data;
165252166166- q->events[wr].id = id;
253253+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
254254+ if(q->send)
255255+ {
256256+ struct queue_sender **spp = &q->send->senders[wr];
257257+258258+ if(*spp)
259259+ {
260260+ /* overflow protect - unblock any thread waiting at this index */
261261+ queue_release_sender(spp, NULL);
262262+ }
263263+ }
264264+#endif
265265+266266+ wakeup_thread(&q->thread);
267267+ set_irq_level(oldlevel);
268268+}
269269+270270+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
271271+void * queue_send(struct event_queue *q, long id, void *data)
272272+{
273273+ int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
274274+ unsigned int wr = q->write++ & QUEUE_LENGTH_MASK;
275275+276276+ q->events[wr].id = id;
167277 q->events[wr].data = data;
168168-278278+279279+ if(q->send)
280280+ {
281281+ struct queue_sender **spp = &q->send->senders[wr];
282282+ struct queue_sender sender;
283283+284284+ if(*spp)
285285+ {
286286+ /* overflow protect - unblock any thread waiting at this index */
287287+ queue_release_sender(spp, NULL);
288288+ }
289289+290290+ *spp = &sender;
291291+ sender.thread = NULL;
292292+293293+ wakeup_thread(&q->thread);
294294+ set_irq_level_and_block_thread(&sender.thread, oldlevel);
295295+ return sender.retval;
296296+ }
297297+298298+ /* Function as queue_post if sending is not enabled */
169299 wakeup_thread(&q->thread);
170170-171300 set_irq_level(oldlevel);
301301+ return NULL;
172302}
173303304304+#if 0 /* not used now but probably will be later */
305305+/* Query if the last message dequeued was added by queue_send or not */
306306+bool queue_in_queue_send(struct event_queue *q)
307307+{
308308+ return q->send && q->send->curr_sender;
309309+}
310310+#endif
311311+312312+/* Replies with retval to any dequeued message sent with queue_send */
313313+void queue_reply(struct event_queue *q, void *retval)
314314+{
315315+ if(q->send && q->send->curr_sender)
316316+ {
317317+ queue_release_sender(&q->send->curr_sender, retval);
318318+ }
319319+}
320320+#endif /* HAVE_EXTENDED_MESSAGING_AND_NAME */
321321+174322bool queue_empty(const struct event_queue* q)
175323{
176324 return ( q->read == q->write );
···179327void queue_clear(struct event_queue* q)
180328{
181329 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
330330+331331+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
332332+ /* Release all thread waiting in the queue for a reply -
333333+ dequeued sent message will be handled by owning thread */
334334+ queue_release_all_senders(q);
335335+#endif
336336+182337 q->read = 0;
183338 q->write = 0;
184339 set_irq_level(oldlevel);
···188343{
189344 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
190345191191- while (q->read != q->write &&
192192- q->events[(q->read) & QUEUE_LENGTH_MASK].id == id)
346346+ while(q->read != q->write)
193347 {
348348+ unsigned int rd = q->read & QUEUE_LENGTH_MASK;
349349+350350+ if(q->events[rd].id != id)
351351+ {
352352+ break;
353353+ }
354354+355355+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
356356+ if(q->send)
357357+ {
358358+ struct queue_sender **spp = &q->send->senders[rd];
359359+360360+ if(*spp)
361361+ {
362362+ /* Release any thread waiting on this message */
363363+ queue_release_sender(spp, NULL);
364364+ }
365365+ }
366366+#endif
194367 q->read++;
195368 }
196369
+35
firmware/thread.c
···3939static int boosted_threads IBSS_ATTR;
4040#endif
41414242+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
4343+#define STAY_IRQ_LEVEL -1
4444+static int switch_to_irq_level = STAY_IRQ_LEVEL;
4545+#endif
4646+4247/* Define to enable additional checks for blocking violations etc. */
4348#define THREAD_EXTRA_CHECKS
4449···388393389394 /* Rearrange thread lists as needed */
390395 change_thread_state(blocked_list);
396396+397397+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
398398+ /* This has to be done after the scheduler is finished with the
399399+ blocked_list pointer so that an IRQ can't kill us by attempting
400400+ a wake but before attempting any core sleep. */
401401+ if (switch_to_irq_level != STAY_IRQ_LEVEL)
402402+ {
403403+ int level = switch_to_irq_level;
404404+ switch_to_irq_level = STAY_IRQ_LEVEL;
405405+ set_irq_level(level);
406406+ }
407407+#endif
391408 }
392409393410 /* Go through the list of sleeping task to check if we need to wake up
···471488 /* Set the state to blocked and ask the scheduler to switch tasks,
472489 * this takes us off of the run queue until we are explicitly woken */
473490 SET_STATE(current->statearg, STATE_BLOCKED, 0);
491491+474492 switch_thread(true, list);
475493476494#ifdef HAVE_SCHEDULER_BOOSTCTRL
···521539 /* It is now safe for another thread to block on this "list" */
522540 *list = NULL;
523541}
542542+543543+#if defined(HAVE_EXTENDED_MESSAGING_AND_NAME) && !defined(SIMULATOR)
544544+void set_irq_level_and_block_thread(struct thread_entry **list, int level)
545545+{
546546+ switch_to_irq_level = level;
547547+ block_thread(list);
548548+}
549549+550550+#if 0
551551+void set_irq_level_and_block_thread_w_tmo(struct thread_entry **list,
552552+ int timeout, int level)
553553+{
554554+ switch_to_irq_level = level;
555555+ block_thread_w_tmo(list, timeout);
556556+}
557557+#endif
558558+#endif /* HAVE_EXTENDED_MESSAGING_AND_NAME */
524559525560void wakeup_thread(struct thread_entry **list)
526561{
+178-11
uisimulator/sdl/kernel.c
···1818 ****************************************************************************/
19192020#include <stdlib.h>
2121+#include "memory.h"
2122#include "uisdl.h"
2223#include "kernel.h"
2324#include "thread-sdl.h"
···3233 return (_lv = level);
3334}
34353636+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
3737+/* Moves waiting thread's descriptor to the current sender when a
3838+ message is dequeued */
3939+static void queue_fetch_sender(struct queue_sender_list *send,
4040+ unsigned int i)
4141+{
4242+ int old_level = set_irq_level(15<<4);
4343+ struct queue_sender **spp = &send->senders[i];
4444+4545+ if(*spp)
4646+ {
4747+ send->curr_sender = *spp;
4848+ *spp = NULL;
4949+ }
5050+5151+ set_irq_level(old_level);
5252+}
5353+5454+/* Puts the specified return value in the waiting thread's return value
5555+ and wakes the thread - a sender should be confirmed to exist first */
5656+static void queue_release_sender(struct queue_sender **sender, void *retval)
5757+{
5858+ (*sender)->retval = retval;
5959+ *sender = NULL;
6060+}
6161+6262+/* Releases any waiting threads that are queued with queue_send -
6363+ reply with NULL */
6464+static void queue_release_all_senders(struct event_queue *q)
6565+{
6666+ if(q->send)
6767+ {
6868+ unsigned int i;
6969+ for(i = q->read; i != q->write; i++)
7070+ {
7171+ struct queue_sender **spp =
7272+ &q->send->senders[i & QUEUE_LENGTH_MASK];
7373+ if(*spp)
7474+ {
7575+ queue_release_sender(spp, NULL);
7676+ }
7777+ }
7878+ }
7979+}
8080+8181+/* Enables queue_send on the specified queue - caller allocates the extra
8282+ data structure */
8383+void queue_enable_queue_send(struct event_queue *q,
8484+ struct queue_sender_list *send)
8585+{
8686+ q->send = send;
8787+ memset(send, 0, sizeof(*send));
8888+}
8989+#endif /* HAVE_EXTENDED_MESSAGING_AND_NAME */
9090+3591void queue_init(struct event_queue *q, bool register_queue)
3692{
3793 (void)register_queue;
38943939- q->read = 0;
4040- q->write = 0;
9595+ q->read = 0;
9696+ q->write = 0;
4197 q->thread = NULL;
9898+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
9999+ q->send = NULL; /* No message sending by default */
100100+#endif
42101}
4310244103void queue_delete(struct event_queue *q)
···4810749108void queue_wait(struct event_queue *q, struct event *ev)
50109{
110110+ unsigned int rd;
111111+51112 while(q->read == q->write)
52113 {
53114 switch_thread(true, NULL);
54115 }
551165656- *ev = q->events[(q->read++) & QUEUE_LENGTH_MASK];
117117+ rd = q->read++ & QUEUE_LENGTH_MASK;
118118+ *ev = q->events[rd];
119119+120120+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
121121+ if(q->send && q->send->senders[rd])
122122+ {
123123+ /* Get data for a waiting thread if one */
124124+ queue_fetch_sender(q->send, rd);
125125+ }
126126+#endif
57127}
5812859129void queue_wait_w_tmo(struct event_queue *q, struct event *ev, int ticks)
···6713768138 if(q->read != q->write)
69139 {
7070- *ev = q->events[(q->read++) & QUEUE_LENGTH_MASK];
140140+ unsigned int rd = q->read++ & QUEUE_LENGTH_MASK;
141141+ *ev = q->events[rd];
142142+143143+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
144144+ if(q->send && q->send->senders[rd])
145145+ {
146146+ /* Get data for a waiting thread if one */
147147+ queue_fetch_sender(q->send, rd);
148148+ }
149149+#endif
71150 }
72151 else
73152 {
···7715678157void queue_post(struct event_queue *q, long id, void *data)
79158{
8080- int wr;
8181- int oldlevel;
159159+ int oldlevel = set_irq_level(15<<4);
160160+ unsigned int wr = q->write++ & QUEUE_LENGTH_MASK;
161161+162162+ q->events[wr].id = id;
163163+ q->events[wr].data = data;
164164+165165+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
166166+ if(q->send)
167167+ {
168168+ struct queue_sender **spp = &q->send->senders[wr];
821698383- oldlevel = set_irq_level(15<<4);
8484- wr = (q->write++) & QUEUE_LENGTH_MASK;
170170+ if(*spp)
171171+ {
172172+ /* overflow protect - unblock any thread waiting at this index */
173173+ queue_release_sender(spp, NULL);
174174+ }
175175+ }
176176+#endif
851778686- q->events[wr].id = id;
178178+ set_irq_level(oldlevel);
179179+}
180180+181181+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
182182+void * queue_send(struct event_queue *q, long id, void *data)
183183+{
184184+ int oldlevel = set_irq_level(15<<4);
185185+ unsigned int wr = q->write++ & QUEUE_LENGTH_MASK;
186186+187187+ q->events[wr].id = id;
87188 q->events[wr].data = data;
189189+190190+ if(q->send)
191191+ {
192192+ struct queue_sender **spp = &q->send->senders[wr];
193193+ struct queue_sender sender;
194194+195195+ if(*spp)
196196+ {
197197+ /* overflow protect - unblock any thread waiting at this index */
198198+ queue_release_sender(spp, NULL);
199199+ }
200200+201201+ *spp = &sender;
202202+203203+ set_irq_level(oldlevel);
204204+ while (*spp != NULL)
205205+ {
206206+ switch_thread(true, NULL);
207207+ }
208208+209209+ return sender.retval;
210210+ }
211211+212212+ /* Function as queue_post if sending is not enabled */
88213 set_irq_level(oldlevel);
214214+ return NULL;
89215}
90216217217+#if 0 /* not used now but probably will be later */
218218+/* Query if the last message dequeued was added by queue_send or not */
219219+bool queue_in_queue_send(struct event_queue *q)
220220+{
221221+ return q->send && q->send->curr_sender;
222222+}
223223+#endif
224224+225225+/* Replies with retval to any dequeued message sent with queue_send */
226226+void queue_reply(struct event_queue *q, void *retval)
227227+{
228228+ if(q->send && q->send->curr_sender)
229229+ {
230230+ queue_release_sender(&q->send->curr_sender, retval);
231231+ }
232232+}
233233+#endif /* HAVE_EXTENDED_MESSAGING_AND_NAME */
234234+91235bool queue_empty(const struct event_queue* q)
92236{
93237 return ( q->read == q->write );
···96240void queue_clear(struct event_queue* q)
97241{
98242 /* fixme: This is potentially unsafe in case we do interrupt-like processing */
243243+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
244244+ /* Release all thread waiting in the queue for a reply -
245245+ dequeued sent message will be handled by owning thread */
246246+ queue_release_all_senders(q);
247247+#endif
99248 q->read = 0;
100249 q->write = 0;
101250}
···104253{
105254 int oldlevel = set_irq_level(15<<4);
106255107107- while (q->read != q->write &&
108108- q->events[(q->read) & QUEUE_LENGTH_MASK].id == id)
256256+ while(q->read != q->write)
109257 {
258258+ unsigned int rd = q->read & QUEUE_LENGTH_MASK;
259259+260260+ if(q->events[rd].id != id)
261261+ {
262262+ break;
263263+ }
264264+265265+#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
266266+ if(q->send)
267267+ {
268268+ struct queue_sender **spp = &q->send->senders[rd];
269269+270270+ if(*spp)
271271+ {
272272+ /* Release any thread waiting on this message */
273273+ queue_release_sender(spp, NULL);
274274+ }
275275+ }
276276+#endif
110277 q->read++;
111278 }
112279