diff options
author | Miika Pekkarinen <miipekk@ihme.org> | 2006-09-16 16:18:11 +0000 |
---|---|---|
committer | Miika Pekkarinen <miipekk@ihme.org> | 2006-09-16 16:18:11 +0000 |
commit | a85044bf9eaa0a7206c1978d3cfd57ab2d7fae2f (patch) | |
tree | a30695ed540bf32365d577f46398f712c7a494c4 /firmware/export/thread.h | |
parent | baf5494341cdd6cdb9590e21d429920b9bc4a2c6 (diff) | |
download | rockbox-a85044bf9eaa0a7206c1978d3cfd57ab2d7fae2f.tar.gz rockbox-a85044bf9eaa0a7206c1978d3cfd57ab2d7fae2f.zip |
New scheduler, with priorities for swcodec platforms. Frequent task
switching should be more efficient and tasks are stored in linked
lists to eliminate unnecessary task switching to improve performance.
Audio should no longer skip on swcodec targets caused by too CPU
hungry UI thread or background threads.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10958 a1c6a512-1295-4272-9138-f99709370657
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 |