summaryrefslogtreecommitdiff
path: root/firmware/export/thread.h
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/export/thread.h')
-rw-r--r--firmware/export/thread.h88
1 files changed, 67 insertions, 21 deletions
diff --git a/firmware/export/thread.h b/firmware/export/thread.h
index e102997dae..7e053bc507 100644
--- a/firmware/export/thread.h
+++ b/firmware/export/thread.h
@@ -21,8 +21,24 @@
21 21
22#include <stdbool.h> 22#include <stdbool.h>
23 23
24/* Priority scheduling (when enabled with HAVE_PRIORITY_SCHEDULING) works
25 * by giving high priority threads more CPU time than less priority threads
26 * when they need it.
27 *
28 * If software playback codec pcm buffer is going down to critical, codec
29 * can change it own priority to REALTIME to override user interface and
30 * prevent playback skipping.
31 */
32#define PRIORITY_REALTIME 1
33#define PRIORITY_USER_INTERFACE 4 /* The main thread */
34#define PRIORITY_RECORDING 4 /* Recording thread */
35#define PRIORITY_PLAYBACK 4 /* or REALTIME when needed */
36#define PRIORITY_BUFFERING 4 /* Codec buffering thread */
37#define PRIORITY_SYSTEM 6 /* All other firmware threads */
38#define PRIORITY_BACKGROUND 8 /* Normal application threads */
39
24#if CONFIG_CODEC == SWCODEC 40#if CONFIG_CODEC == SWCODEC
25#define MAXTHREADS 16 41#define MAXTHREADS 15
26#else 42#else
27#define MAXTHREADS 11 43#define MAXTHREADS 11
28#endif 44#endif
@@ -32,7 +48,7 @@
32#ifndef SIMULATOR 48#ifndef SIMULATOR
33/* Need to keep structures inside the header file because debug_menu 49/* Need to keep structures inside the header file because debug_menu
34 * needs them. */ 50 * needs them. */
35#ifdef CPU_COLDFIRE 51# ifdef CPU_COLDFIRE
36struct regs 52struct regs
37{ 53{
38 unsigned int macsr; /* EMAC status register */ 54 unsigned int macsr; /* EMAC status register */
@@ -41,7 +57,7 @@ struct regs
41 void *sp; /* Stack pointer (a7) */ 57 void *sp; /* Stack pointer (a7) */
42 void *start; /* Thread start address, or NULL when started */ 58 void *start; /* Thread start address, or NULL when started */
43}; 59};
44#elif CONFIG_CPU == SH7034 60# elif CONFIG_CPU == SH7034
45struct regs 61struct regs
46{ 62{
47 unsigned int r[7]; /* Registers r8 thru r14 */ 63 unsigned int r[7]; /* Registers r8 thru r14 */
@@ -49,7 +65,7 @@ struct regs
49 void *pr; /* Procedure register */ 65 void *pr; /* Procedure register */
50 void *start; /* Thread start address, or NULL when started */ 66 void *start; /* Thread start address, or NULL when started */
51}; 67};
52#elif defined(CPU_ARM) 68# elif defined(CPU_ARM)
53struct regs 69struct regs
54{ 70{
55 unsigned int r[8]; /* Registers r4-r11 */ 71 unsigned int r[8]; /* Registers r4-r11 */
@@ -57,42 +73,72 @@ struct regs
57 unsigned int lr; /* r14 (lr) */ 73 unsigned int lr; /* r14 (lr) */
58 void *start; /* Thread start address, or NULL when started */ 74 void *start; /* Thread start address, or NULL when started */
59}; 75};
60#elif CONFIG_CPU == TCC730 76# elif CONFIG_CPU == TCC730
61struct regs 77struct regs
62{ 78{
63 void *sp; /* Stack pointer (a15) */ 79 void *sp; /* Stack pointer (a15) */
64 void *start; /* Thread start address */ 80 void *start; /* Thread start address */
65 int started; /* 0 when not started */ 81 int started; /* 0 when not started */
66}; 82};
67#endif 83# endif
84
85#endif /* !SIMULATOR */
86
87#define STATE_RUNNING 0
88#define STATE_BLOCKED 1
89#define STATE_SLEEPING 2
90#define STATE_BLOCKED_W_TMO 3
91
92#define GET_STATE_ARG(state) (state & 0x3FFFFFFF)
93#define GET_STATE(state) ((state >> 30) & 3)
94#define SET_STATE(state,arg) ((state << 30) | (arg))
68 95
69struct thread_entry { 96struct thread_entry {
97#ifndef SIMULATOR
70 struct regs context; 98 struct regs context;
99#endif
71 const char *name; 100 const char *name;
72 void *stack; 101 void *stack;
73 int stack_size; 102 unsigned long statearg;
103 unsigned short stack_size;
104#ifdef HAVE_PRIORITY_SCHEDULING
105 unsigned short priority;
106 long last_run;
107#endif
108 struct thread_entry *next, *prev;
74}; 109};
75 110
76struct core_entry { 111struct core_entry {
77 int num_threads;
78 volatile int num_sleepers;
79 int current_thread;
80 struct thread_entry threads[MAXTHREADS]; 112 struct thread_entry threads[MAXTHREADS];
113 struct thread_entry *running;
114 struct thread_entry *sleeping;
81}; 115};
116
117#ifdef HAVE_PRIORITY_SCHEDULING
118#define IF_PRIO(empty, type) , type
119#else
120#define IF_PRIO(empty, type)
82#endif 121#endif
83 122
84int create_thread(void (*function)(void), void* stack, int stack_size, 123struct thread_entry*
85 const char *name); 124 create_thread(void (*function)(void), void* stack, int stack_size,
86int create_thread_on_core(unsigned int core, void (*function)(void), void* stack, int stack_size, 125 const char *name IF_PRIO(, int priority));
87 const char *name); 126
88void remove_thread(int threadnum); 127struct thread_entry*
89void remove_thread_on_core(unsigned int core, int threadnum); 128 create_thread_on_core(unsigned int core, void (*function)(void),
90void switch_thread(void); 129 void* stack, int stack_size,
91void sleep_thread(void); 130 const char *name
92void wake_up_thread(void); 131 IF_PRIO(, int priority));
132
133void remove_thread(struct thread_entry *thread);
134void switch_thread(bool save_context, struct thread_entry **blocked_list);
135void sleep_thread(int ticks);
136void block_thread(struct thread_entry **thread, int timeout);
137void wakeup_thread(struct thread_entry **thread);
138void thread_set_priority(struct thread_entry *thread, int priority);
93void init_threads(void); 139void init_threads(void);
94int thread_stack_usage(int threadnum); 140int thread_stack_usage(const struct thread_entry *thread);
95int thread_stack_usage_on_core(unsigned int core, int threadnum); 141int thread_get_status(const struct thread_entry *thread);
96#ifdef RB_PROFILE 142#ifdef RB_PROFILE
97void profile_thread(void); 143void profile_thread(void);
98#endif 144#endif