From f5880ee5d5559d45771e4a626c54309c88f437e7 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka <gniibe@fsij.org> Date: Fri, 1 Jul 2016 09:51:32 +0900 Subject: Change API of chopstx_setpriority --- ChangeLog | 4 ++++ chopstx.c | 39 ++++++++++++++++++++++++--------------- chopstx.h | 2 +- example-fs-bb48/touch.c | 6 ++++++ 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2c4b0b5..3e1e1e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2016-07-01 NIIBE Yutaka <gniibe@fsij.org> + + * chopstx.c (chopstx_setpriority): Change the API. + 2016-06-30 NIIBE Yutaka <gniibe@fsij.org> * example-cdc/usb-cdc.c (tty_recv, tty_main): Follow the change of diff --git a/chopstx.c b/chopstx.c index 4aa9d75..6d9de04 100644 --- a/chopstx.c +++ b/chopstx.c @@ -1868,6 +1868,7 @@ chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *pd_array[]) * @prio: priority * * Change the schedule priority with @prio. + * Returns the old priority. * * In general, it is not recommended to use this function because * dynamically changing schedule priorities complicates the system. @@ -1875,25 +1876,33 @@ chopstx_poll (uint32_t *usec_p, int n, struct chx_poll_head *pd_array[]) * which starts its execution with priority of CHX_PRIO_MAIN_INIT, and * let it change its priority after initialization of other threads. */ -void -chopstx_setpriority (chopstx_prio_t prio) +chopstx_prio_t +chopstx_setpriority (chopstx_prio_t prio_new) { struct chx_thread *tp = running; + chopstx_prio_t prio_orig, prio_cur; - if (tp->prio < CHOPSTX_PRIO_INHIBIT_PREEMPTION - && prio >= CHOPSTX_PRIO_INHIBIT_PREEMPTION) - { - chx_cpu_sched_lock (); - tp->prio = tp->prio_orig = prio; - } - else if (tp->prio >= CHOPSTX_PRIO_INHIBIT_PREEMPTION - && prio < CHOPSTX_PRIO_INHIBIT_PREEMPTION) - { - tp->prio = tp->prio_orig = prio; - chx_cpu_sched_unlock (); - } + chx_cpu_sched_lock (); + prio_orig = tp->prio_orig; + prio_cur = tp->prio; + + tp->prio_orig = prio_new; + if (prio_cur == prio_orig) + /* No priority inheritance is active. */ + tp->prio = prio_new; else - tp->prio = tp->prio_orig = prio; + /* Priority inheritance is active. */ + /* In this case, only when new priority is greater, change the + priority of this thread. */ + if (prio_new > prio_cur) + tp->prio = prio_new; + + if (tp->prio < prio_cur) + chx_sched (CHX_YIELD); + else if (tp->prio < CHOPSTX_PRIO_INHIBIT_PREEMPTION) + chx_cpu_sched_unlock (); + + return prio_orig; } /* diff --git a/chopstx.h b/chopstx.h index b8daa0e..54153e6 100644 --- a/chopstx.h +++ b/chopstx.h @@ -113,7 +113,7 @@ typedef struct chx_cleanup { void chopstx_cleanup_push (chopstx_cleanup_t *clp); void chopstx_cleanup_pop (int execute); -void chopstx_setpriority (chopstx_prio_t); +chopstx_prio_t chopstx_setpriority (chopstx_prio_t); enum { CHOPSTX_POLL_COND = 0, diff --git a/example-fs-bb48/touch.c b/example-fs-bb48/touch.c index 127be23..960692e 100644 --- a/example-fs-bb48/touch.c +++ b/example-fs-bb48/touch.c @@ -27,6 +27,10 @@ static chopstx_intr_t tpm1_intr; uint16_t touch_get (void) { + chopstx_prio_t prio_old; + + prio_old = chopstx_setpriority (CHOPSTX_PRIO_INHIBIT_PREEMPTION); + /* Assert LOW. */ PORTB->PCR1 = (1<<8) /* GPIO */ | (0<<6) /* DriveStrengthEnable=0 */ @@ -51,6 +55,8 @@ touch_get (void) | (0<<0) /* puddselect= 0 */ ; + chopstx_setpriority (prio_old); + chopstx_intr_wait (&tpm1_intr); /* Clear overflow and CH1 capture. */ TPM1->STATUS = 0x102; -- cgit v1.2.3