summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2011-03-11 23:38:36 +0000
committerThomas Martitz <kugel@rockbox.org>2011-03-11 23:38:36 +0000
commit204ac257fe97dafdcd106c9051386ccf09710c4f (patch)
tree3465f36fa8cf34029b633eeba3f084d2f34d64ef /firmware/target
parent662ba4868af3981dcc64e271f49ee0bd72cd19e5 (diff)
Android: Switch to pthread_cond+SIGEV_THREAD for tick task handling.
The implementation wasn't really safe (sem_post from signal handler), and the new one simplifies things a bit. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29575 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/hosted/android/kernel-android.c45
1 files changed, 19 insertions, 26 deletions
diff --git a/firmware/target/hosted/android/kernel-android.c b/firmware/target/hosted/android/kernel-android.c
index bac6d2a8fd..80ff88fd12 100644
--- a/firmware/target/hosted/android/kernel-android.c
+++ b/firmware/target/hosted/android/kernel-android.c
@@ -24,7 +24,7 @@
#include <signal.h>
#include <errno.h>
#include <unistd.h>
-#include <semaphore.h>
+#include <pthread.h>
#include "config.h"
#include "system.h"
#include "button.h"
@@ -32,12 +32,13 @@
#include "panic.h"
-static sem_t wfi_sem;
+static pthread_cond_t wfi_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t wfi_mtx = PTHREAD_MUTEX_INITIALIZER;
/*
* call tick tasks and wake the scheduler up */
-void timer_signal(int sig)
+void timer_signal(union sigval arg)
{
- (void)sig;
+ (void)arg;
call_tick_tasks();
interrupt();
}
@@ -48,18 +49,14 @@ void timer_signal(int sig)
* other mechanisms could use them as well */
void wait_for_interrupt(void)
{
- sem_wait(&wfi_sem);
+ pthread_cond_wait(&wfi_cond, &wfi_mtx);
}
+/*
+ * Wakeup the kernel, if sleeping (shall not be called from a signal handler) */
void interrupt(void)
{
- int s;
- /* unless idling, we usually have more interrupt() than wait_for_interrupt()
- * don't post unecessarily because wait_for_interrupt() would need to
- * decrement for each wasted sem_post(), instead of sleeping directly */
- sem_getvalue(&wfi_sem, &s);
- if (s <= 0)
- sem_post(&wfi_sem);
+ pthread_cond_signal(&wfi_cond);
}
/*
@@ -67,30 +64,26 @@ void interrupt(void)
void tick_start(unsigned int interval_in_ms)
{
int ret = 0;
- sigset_t proc_set;
timer_t timerid;
struct itimerspec ts;
- sigevent_t sigev = {
- .sigev_notify = SIGEV_SIGNAL,
- .sigev_signo = SIGUSR2,
- };
+ sigevent_t sigev;
+
+ /* initializing in the declaration causes some weird warnings */
+ memset(&sigev, 0, sizeof(sigevent_t));
+ sigev.sigev_notify = SIGEV_THREAD,
+ sigev.sigev_notify_function = timer_signal,
ts.it_value.tv_sec = ts.it_interval.tv_sec = 0;
ts.it_value.tv_nsec = ts.it_interval.tv_nsec = interval_in_ms*1000*1000;
- /* add the signal handler */
- signal(SIGUSR2, timer_signal);
-
/* add the timer */
ret |= timer_create(CLOCK_REALTIME, &sigev, &timerid);
ret |= timer_settime(timerid, 0, &ts, NULL);
- /* unblock SIGUSR2 so the handler can run */
- ret |= sigprocmask(0, NULL, &proc_set);
- ret |= sigdelset(&proc_set, SIGUSR2);
- ret |= sigprocmask(SIG_SETMASK, &proc_set, NULL);
-
- ret |= sem_init(&wfi_sem, 0, 0);
+ /* Grab the mutex already now and leave it to this thread. We don't
+ * care about race conditions when signaling the condition (because
+ * they are not critical), but a mutex is necessary due to the API */
+ pthread_mutex_lock(&wfi_mtx);
if (ret != 0)
panicf("%s(): %s\n", __func__, strerror(errno));