aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2016-07-01 09:51:32 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2016-07-01 09:51:32 +0900
commitf5880ee5d5559d45771e4a626c54309c88f437e7 (patch)
treee56e5e14d6d91fa3a8d9a044a918eaebeae082e8
parentc7e571eca0c925008be99efb4e7ba3bc876a7309 (diff)
Change API of chopstx_setpriority
-rw-r--r--ChangeLog4
-rw-r--r--chopstx.c39
-rw-r--r--chopstx.h2
-rw-r--r--example-fs-bb48/touch.c6
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;