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 e102997..7e053bc 100644 --- a/firmware/export/thread.h +++ b/firmware/export/thread.h @@ -21,8 +21,24 @@ #include <stdbool.h> +/* Priority scheduling (when enabled with HAVE_PRIORITY_SCHEDULING) works + * by giving high priority threads more CPU time than less priority threads + * when they need it. + * + * If software playback codec pcm buffer is going down to critical, codec + * can change it own priority to REALTIME to override user interface and + * prevent playback skipping. + */ +#define PRIORITY_REALTIME 1 +#define PRIORITY_USER_INTERFACE 4 /* The main thread */ +#define PRIORITY_RECORDING 4 /* Recording thread */ +#define PRIORITY_PLAYBACK 4 /* or REALTIME when needed */ +#define PRIORITY_BUFFERING 4 /* Codec buffering thread */ +#define PRIORITY_SYSTEM 6 /* All other firmware threads */ +#define PRIORITY_BACKGROUND 8 /* Normal application threads */ + #if CONFIG_CODEC == SWCODEC -#define MAXTHREADS 16 +#define MAXTHREADS 15 #else #define MAXTHREADS 11 #endif @@ -32,7 +48,7 @@ #ifndef SIMULATOR /* Need to keep structures inside the header file because debug_menu * needs them. */ -#ifdef CPU_COLDFIRE +# ifdef CPU_COLDFIRE struct regs { unsigned int macsr; /* EMAC status register */ @@ -41,7 +57,7 @@ struct regs void *sp; /* Stack pointer (a7) */ void *start; /* Thread start address, or NULL when started */ }; -#elif CONFIG_CPU == SH7034 +# elif CONFIG_CPU == SH7034 struct regs { unsigned int r[7]; /* Registers r8 thru r14 */ @@ -49,7 +65,7 @@ struct regs void *pr; /* Procedure register */ void *start; /* Thread start address, or NULL when started */ }; -#elif defined(CPU_ARM) +# elif defined(CPU_ARM) struct regs { unsigned int r[8]; /* Registers r4-r11 */ @@ -57,42 +73,72 @@ struct regs unsigned int lr; /* r14 (lr) */ void *start; /* Thread start address, or NULL when started */ }; -#elif CONFIG_CPU == TCC730 +# elif CONFIG_CPU == TCC730 struct regs { void *sp; /* Stack pointer (a15) */ void *start; /* Thread start address */ int started; /* 0 when not started */ }; -#endif +# endif + +#endif /* !SIMULATOR */ + +#define STATE_RUNNING 0 +#define STATE_BLOCKED 1 +#define STATE_SLEEPING 2 +#define STATE_BLOCKED_W_TMO 3 + +#define GET_STATE_ARG(state) (state & 0x3FFFFFFF) +#define GET_STATE(state) ((state >> 30) & 3) +#define SET_STATE(state,arg) ((state << 30) | (arg)) struct thread_entry { +#ifndef SIMULATOR struct regs context; +#endif const char *name; void *stack; - int stack_size; + unsigned long statearg; + unsigned short stack_size; +#ifdef HAVE_PRIORITY_SCHEDULING + unsigned short priority; + long last_run; +#endif + struct thread_entry *next, *prev; }; struct core_entry { - int num_threads; - volatile int num_sleepers; - int current_thread; struct thread_entry threads[MAXTHREADS]; + struct thread_entry *running; + struct thread_entry *sleeping; }; + +#ifdef HAVE_PRIORITY_SCHEDULING +#define IF_PRIO(empty, type) , type +#else +#define IF_PRIO(empty, type) #endif -int create_thread(void (*function)(void), void* stack, int stack_size, - const char *name); -int create_thread_on_core(unsigned int core, void (*function)(void), void* stack, int stack_size, - const char *name); -void remove_thread(int threadnum); -void remove_thread_on_core(unsigned int core, int threadnum); -void switch_thread(void); -void sleep_thread(void); -void wake_up_thread(void); +struct thread_entry* + create_thread(void (*function)(void), void* stack, int stack_size, + const char *name IF_PRIO(, int priority)); + +struct thread_entry* + create_thread_on_core(unsigned int core, void (*function)(void), + void* stack, int stack_size, + const char *name + IF_PRIO(, int priority)); + +void remove_thread(struct thread_entry *thread); +void switch_thread(bool save_context, struct thread_entry **blocked_list); +void sleep_thread(int ticks); +void block_thread(struct thread_entry **thread, int timeout); +void wakeup_thread(struct thread_entry **thread); +void thread_set_priority(struct thread_entry *thread, int priority); void init_threads(void); -int thread_stack_usage(int threadnum); -int thread_stack_usage_on_core(unsigned int core, int threadnum); +int thread_stack_usage(const struct thread_entry *thread); +int thread_get_status(const struct thread_entry *thread); #ifdef RB_PROFILE void profile_thread(void); #endif |