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 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