diff options
Diffstat (limited to 'firmware/export/kernel.h')
-rw-r--r-- | firmware/export/kernel.h | 103 |
1 files changed, 86 insertions, 17 deletions
diff --git a/firmware/export/kernel.h b/firmware/export/kernel.h index 3d70e49a4c..a72e004b33 100644 --- a/firmware/export/kernel.h +++ b/firmware/export/kernel.h | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <inttypes.h> | 23 | #include <inttypes.h> |
24 | #include "config.h" | 24 | #include "config.h" |
25 | 25 | ||
26 | #include "thread.h" | ||
27 | |||
26 | /* wrap-safe macros for tick comparison */ | 28 | /* wrap-safe macros for tick comparison */ |
27 | #define TIME_AFTER(a,b) ((long)(b) - (long)(a) < 0) | 29 | #define TIME_AFTER(a,b) ((long)(b) - (long)(a) < 0) |
28 | #define TIME_BEFORE(a,b) TIME_AFTER(b,a) | 30 | #define TIME_BEFORE(a,b) TIME_AFTER(b,a) |
@@ -31,6 +33,7 @@ | |||
31 | 33 | ||
32 | #define MAX_NUM_TICK_TASKS 8 | 34 | #define MAX_NUM_TICK_TASKS 8 |
33 | 35 | ||
36 | #define MAX_NUM_QUEUES 32 | ||
34 | #define QUEUE_LENGTH 16 /* MUST be a power of 2 */ | 37 | #define QUEUE_LENGTH 16 /* MUST be a power of 2 */ |
35 | #define QUEUE_LENGTH_MASK (QUEUE_LENGTH - 1) | 38 | #define QUEUE_LENGTH_MASK (QUEUE_LENGTH - 1) |
36 | 39 | ||
@@ -72,7 +75,7 @@ | |||
72 | #define SYS_SCREENDUMP MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 0) | 75 | #define SYS_SCREENDUMP MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 0) |
73 | #define SYS_CAR_ADAPTER_RESUME MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 1) | 76 | #define SYS_CAR_ADAPTER_RESUME MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 1) |
74 | 77 | ||
75 | struct event | 78 | struct queue_event |
76 | { | 79 | { |
77 | long id; | 80 | long id; |
78 | intptr_t data; | 81 | intptr_t data; |
@@ -91,20 +94,66 @@ struct queue_sender_list | |||
91 | 94 | ||
92 | struct event_queue | 95 | struct event_queue |
93 | { | 96 | { |
94 | struct event events[QUEUE_LENGTH]; | 97 | struct thread_queue queue; /* Waiter list */ |
95 | struct thread_entry *thread; | 98 | struct queue_event events[QUEUE_LENGTH]; /* list of events */ |
96 | unsigned int read; | 99 | unsigned int read; /* head of queue */ |
97 | unsigned int write; | 100 | unsigned int write; /* tail of queue */ |
98 | #ifdef HAVE_EXTENDED_MESSAGING_AND_NAME | 101 | #ifdef HAVE_EXTENDED_MESSAGING_AND_NAME |
99 | struct queue_sender_list *send; | 102 | struct queue_sender_list *send; /* list of threads waiting for |
103 | reply to an event */ | ||
104 | #endif | ||
105 | #if NUM_CORES > 1 | ||
106 | struct corelock cl; /* inter-core sync */ | ||
100 | #endif | 107 | #endif |
101 | }; | 108 | }; |
102 | 109 | ||
103 | struct mutex | 110 | struct mutex |
104 | { | 111 | { |
105 | uint32_t locked; | 112 | struct thread_entry *queue; /* Waiter list */ |
106 | struct thread_entry *thread; | 113 | #if CONFIG_CORELOCK == SW_CORELOCK |
114 | struct corelock cl; /* inter-core sync */ | ||
115 | #endif | ||
116 | struct thread_entry *thread; /* thread that owns lock */ | ||
117 | int count; /* lock owner recursion count */ | ||
118 | unsigned char locked; /* locked semaphore */ | ||
119 | }; | ||
120 | |||
121 | struct spinlock | ||
122 | { | ||
123 | #if NUM_CORES > 1 | ||
124 | struct corelock cl; /* inter-core sync */ | ||
125 | #endif | ||
126 | struct thread_entry *thread; /* lock owner */ | ||
127 | int count; /* lock owner recursion count */ | ||
128 | unsigned char locked; /* is locked if nonzero */ | ||
129 | #if NUM_CORES > 1 | ||
130 | unsigned char task_switch; /* can task switch? */ | ||
131 | #endif | ||
132 | }; | ||
133 | |||
134 | #ifdef HAVE_SEMAPHORE_OBJECTS | ||
135 | struct semaphore | ||
136 | { | ||
137 | struct thread_entry *queue; /* Waiter list */ | ||
138 | #if CONFIG_CORELOCK == SW_CORELOCK | ||
139 | struct corelock cl; /* inter-core sync */ | ||
140 | #endif | ||
141 | int count; /* # of waits remaining before unsignaled */ | ||
142 | int max; /* maximum # of waits to remain signaled */ | ||
143 | }; | ||
144 | #endif | ||
145 | |||
146 | #ifdef HAVE_EVENT_OBJECTS | ||
147 | struct event | ||
148 | { | ||
149 | struct thread_entry *queues[2]; /* waiters for each state */ | ||
150 | #if CONFIG_CORELOCK == SW_CORELOCK | ||
151 | struct corelock cl; /* inter-core sync */ | ||
152 | #endif | ||
153 | unsigned char automatic; /* event performs auto-reset */ | ||
154 | unsigned char state; /* state: 1 = signaled */ | ||
107 | }; | 155 | }; |
156 | #endif | ||
108 | 157 | ||
109 | /* global tick variable */ | 158 | /* global tick variable */ |
110 | #if defined(CPU_PP) && defined(BOOTLOADER) | 159 | #if defined(CPU_PP) && defined(BOOTLOADER) |
@@ -127,6 +176,7 @@ extern void yield(void); | |||
127 | extern void sleep(int ticks); | 176 | extern void sleep(int ticks); |
128 | int tick_add_task(void (*f)(void)); | 177 | int tick_add_task(void (*f)(void)); |
129 | int tick_remove_task(void (*f)(void)); | 178 | int tick_remove_task(void (*f)(void)); |
179 | extern void tick_start(unsigned int interval_in_ms); | ||
130 | 180 | ||
131 | struct timeout; | 181 | struct timeout; |
132 | 182 | ||
@@ -150,10 +200,17 @@ void timeout_register(struct timeout *tmo, timeout_cb_type callback, | |||
150 | int ticks, intptr_t data); | 200 | int ticks, intptr_t data); |
151 | void timeout_cancel(struct timeout *tmo); | 201 | void timeout_cancel(struct timeout *tmo); |
152 | 202 | ||
203 | #define STATE_NONSIGNALED 0 | ||
204 | #define STATE_SIGNALED 1 | ||
205 | |||
206 | #define WAIT_TIMEDOUT (-1) | ||
207 | #define WAIT_SUCCEEDED 1 | ||
208 | |||
153 | extern void queue_init(struct event_queue *q, bool register_queue); | 209 | extern void queue_init(struct event_queue *q, bool register_queue); |
154 | extern void queue_delete(struct event_queue *q); | 210 | extern void queue_delete(struct event_queue *q); |
155 | extern void queue_wait(struct event_queue *q, struct event *ev); | 211 | extern void queue_wait(struct event_queue *q, struct queue_event *ev); |
156 | extern void queue_wait_w_tmo(struct event_queue *q, struct event *ev, int ticks); | 212 | extern void queue_wait_w_tmo(struct event_queue *q, struct queue_event *ev, |
213 | int ticks); | ||
157 | extern void queue_post(struct event_queue *q, long id, intptr_t data); | 214 | extern void queue_post(struct event_queue *q, long id, intptr_t data); |
158 | #ifdef HAVE_EXTENDED_MESSAGING_AND_NAME | 215 | #ifdef HAVE_EXTENDED_MESSAGING_AND_NAME |
159 | extern void queue_enable_queue_send(struct event_queue *q, struct queue_sender_list *send); | 216 | extern void queue_enable_queue_send(struct event_queue *q, struct queue_sender_list *send); |
@@ -168,14 +225,26 @@ extern int queue_count(const struct event_queue *q); | |||
168 | extern int queue_broadcast(long id, intptr_t data); | 225 | extern int queue_broadcast(long id, intptr_t data); |
169 | 226 | ||
170 | extern void mutex_init(struct mutex *m); | 227 | extern void mutex_init(struct mutex *m); |
171 | static inline void spinlock_init(struct mutex *m) | ||
172 | { mutex_init(m); } /* Same thing for now */ | ||
173 | extern void mutex_lock(struct mutex *m); | 228 | extern void mutex_lock(struct mutex *m); |
174 | extern void mutex_unlock(struct mutex *m); | 229 | extern void mutex_unlock(struct mutex *m); |
175 | extern void spinlock_lock(struct mutex *m); | 230 | #define SPINLOCK_TASK_SWITCH 0x10 |
176 | extern void spinlock_unlock(struct mutex *m); | 231 | #define SPINLOCK_NO_TASK_SWITCH 0x00 |
177 | extern void tick_start(unsigned int interval_in_ms); | 232 | extern void spinlock_init(struct spinlock *l IF_COP(, unsigned int flags)); |
178 | 233 | extern void spinlock_lock(struct spinlock *l); | |
234 | extern void spinlock_unlock(struct spinlock *l); | ||
235 | extern int spinlock_lock_w_tmo(struct spinlock *l, int ticks); | ||
236 | #ifdef HAVE_SEMAPHORE_OBJECTS | ||
237 | extern void semaphore_init(struct semaphore *s, int max, int start); | ||
238 | extern void semaphore_wait(struct semaphore *s); | ||
239 | extern void semaphore_release(struct semaphore *s); | ||
240 | #endif /* HAVE_SEMAPHORE_OBJECTS */ | ||
241 | #ifdef HAVE_EVENT_OBJECTS | ||
242 | #define EVENT_AUTOMATIC 0x10 | ||
243 | #define EVENT_MANUAL 0x00 | ||
244 | extern void event_init(struct event *e, unsigned int flags); | ||
245 | extern void event_wait(struct event *e, unsigned int for_state); | ||
246 | extern void event_set_state(struct event *e, unsigned int state); | ||
247 | #endif /* HAVE_EVENT_OBJECTS */ | ||
179 | #define IS_SYSEVENT(ev) ((ev & SYS_EVENT) == SYS_EVENT) | 248 | #define IS_SYSEVENT(ev) ((ev & SYS_EVENT) == SYS_EVENT) |
180 | 249 | ||
181 | #endif | 250 | #endif /* _KERNEL_H_ */ |