diff options
Diffstat (limited to 'firmware/export/thread.h')
-rw-r--r-- | firmware/export/thread.h | 88 |
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 |
36 | struct regs | 52 | struct 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 |
45 | struct regs | 61 | struct 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) |
53 | struct regs | 69 | struct 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 |
61 | struct regs | 77 | struct 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 | ||
69 | struct thread_entry { | 96 | struct 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 | ||
76 | struct core_entry { | 111 | struct 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 | ||
84 | int create_thread(void (*function)(void), void* stack, int stack_size, | 123 | struct thread_entry* |
85 | const char *name); | 124 | create_thread(void (*function)(void), void* stack, int stack_size, |
86 | int 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 | |
88 | void remove_thread(int threadnum); | 127 | struct thread_entry* |
89 | void remove_thread_on_core(unsigned int core, int threadnum); | 128 | create_thread_on_core(unsigned int core, void (*function)(void), |
90 | void switch_thread(void); | 129 | void* stack, int stack_size, |
91 | void sleep_thread(void); | 130 | const char *name |
92 | void wake_up_thread(void); | 131 | IF_PRIO(, int priority)); |
132 | |||
133 | void remove_thread(struct thread_entry *thread); | ||
134 | void switch_thread(bool save_context, struct thread_entry **blocked_list); | ||
135 | void sleep_thread(int ticks); | ||
136 | void block_thread(struct thread_entry **thread, int timeout); | ||
137 | void wakeup_thread(struct thread_entry **thread); | ||
138 | void thread_set_priority(struct thread_entry *thread, int priority); | ||
93 | void init_threads(void); | 139 | void init_threads(void); |
94 | int thread_stack_usage(int threadnum); | 140 | int thread_stack_usage(const struct thread_entry *thread); |
95 | int thread_stack_usage_on_core(unsigned int core, int threadnum); | 141 | int thread_get_status(const struct thread_entry *thread); |
96 | #ifdef RB_PROFILE | 142 | #ifdef RB_PROFILE |
97 | void profile_thread(void); | 143 | void profile_thread(void); |
98 | #endif | 144 | #endif |