aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2015-09-09 17:04:59 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2015-09-09 17:04:59 +0900
commit79b13fb4a9f8c1e7d4158b19870a396b05144061 (patch)
tree364d2870c125d312388d96bd3f37614bbaef7dfb
parente9521648d5a4ff1238b76c3549f77e8aa4c6c417 (diff)
Cancellation fixes
-rw-r--r--ChangeLog8
-rw-r--r--NEWS11
-rw-r--r--chopstx.c39
-rw-r--r--chopstx.h1
-rw-r--r--example-cdc/usb-cdc.c10
5 files changed, 63 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 0cc54a4..711f8ae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2015-09-09 Niibe Yutaka <gniibe@fsij.org>
+ * example-cdc/usb-cdc.c (usb_cb_ctrl_write_finish): Distinguish
+ DTR signal.
+ (usb_cb_device_reset): Fix USB reset handling.
+
+ * chopstx.c (chopstx_usec_wait_var, chopstx_cond_wait)
+ (chopstx_intr_wait): Call chopstx_testcancel.
+ (chopstx_setcancelstate): New.
+
* chopstx.c (chx_systick_reset, chx_systick_reload)
(chx_systick_get): Factor out systick functions.
(chx_prio_init): Factor out.
diff --git a/NEWS b/NEWS
index ee2e78a..580bafd 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,17 @@
NEWS - Noteworthy changes
+* Major changes in Chopstx 0.09
+
+ Released 2015-09-??
+
+** New board support: Nitrokey-Start
+It is contributed by Mateusz Zalega.
+
+** Thread cancellation
+Add new API: chopstx_setcancelstate.
+
+
* Major changes in Chopstx 0.08
Released 2015-07-31
diff --git a/chopstx.c b/chopstx.c
index 7c3fb46..285f4e9 100644
--- a/chopstx.c
+++ b/chopstx.c
@@ -290,7 +290,8 @@ struct chx_thread {
uint32_t flag_got_cancel : 1;
uint32_t flag_join_req : 1;
uint32_t flag_sched_rr : 1;
- uint32_t : 8;
+ uint32_t flag_cancelable : 1;
+ uint32_t : 7;
uint32_t prio_orig : 8;
uint32_t prio : 8;
uint32_t v;
@@ -636,7 +637,7 @@ chx_init (struct chx_thread *tp)
tp->mutex_list = NULL;
tp->clp = NULL;
tp->state = THREAD_RUNNING;
- tp->flag_got_cancel = tp->flag_join_req = 0;
+ tp->flag_got_cancel = tp->flag_join_req = tp->flag_cancelable = 0;
tp->flag_sched_rr = (CHX_FLAGS_MAIN & CHOPSTX_SCHED_RR)? 1 : 0;
tp->flag_detached = (CHX_FLAGS_MAIN & CHOPSTX_DETACHED)? 1 : 0;
tp->prio_orig = CHX_PRIO_MAIN_INIT;
@@ -782,7 +783,7 @@ extern void cause_link_time_error_unexpected_size_of_struct_chx_thread (void);
* @thread_entry: Entry function of new thread
* @arg: Argument to the thread entry function
*
- * Create a thread.
+ * Create a thread. Returns thread ID.
*/
chopstx_t
chopstx_create (uint32_t flags_and_prio,
@@ -816,7 +817,7 @@ chopstx_create (uint32_t flags_and_prio,
tp->mutex_list = NULL;
tp->clp = NULL;
tp->state = THREAD_EXITED;
- tp->flag_got_cancel = tp->flag_join_req = 0;
+ tp->flag_got_cancel = tp->flag_join_req = tp->flag_cancelable = 0;
tp->flag_sched_rr = (flags_and_prio & CHOPSTX_SCHED_RR)? 1 : 0;
tp->flag_detached = (flags_and_prio & CHOPSTX_DETACHED)? 1 : 0;
tp->prio_orig = tp->prio = prio;
@@ -851,6 +852,7 @@ chopstx_usec_wait_var (uint32_t *var)
asm volatile ("mov %0, %1" : "=r" (r8) : "r" (usec_p));
while (1)
{
+ chopstx_testcancel ();
chx_cpu_sched_lock ();
if (!r8) /* awakened */
break;
@@ -1019,6 +1021,7 @@ chopstx_cond_wait (chopstx_cond_t *cond, chopstx_mutex_t *mutex)
{
struct chx_thread *tp = running;
+ chopstx_testcancel ();
chx_cpu_sched_lock ();
if (mutex)
@@ -1185,6 +1188,7 @@ chopstx_release_irq_thread (struct chx_thread *tp)
void
chopstx_intr_wait (chopstx_intr_t *intr)
{
+ chopstx_testcancel ();
chx_cpu_sched_lock ();
if (intr->ready == 0)
{
@@ -1369,6 +1373,12 @@ chopstx_cancel (chopstx_t thd)
/* Assume it's UP, it's *never*: tp->state==RUNNING on SMP??? */
chx_cpu_sched_lock ();
tp->flag_got_cancel = 1;
+ if (!tp->flag_cancelable)
+ {
+ chx_cpu_sched_unlock ();
+ return;
+ }
+
/* Cancellation points: cond_wait, intr_wait, and usec_wait. */
if (tp->state == THREAD_WAIT_CND || tp->state == THREAD_WAIT_INT
|| tp->state == THREAD_WAIT_TIME)
@@ -1405,9 +1415,28 @@ chopstx_cancel (chopstx_t thd)
void
chopstx_testcancel (void)
{
- if (running->flag_got_cancel)
+ if (running->flag_cancelable && running->flag_got_cancel)
chopstx_exit ((void *)CHOPSTX_EXIT_CANCELED_IN_SYNC);
}
+
+
+/**
+ * chopstx_setcancelstate - set cancelability state
+ * @cancel_disable: 0 to enable cancelation, otherwise disabled.
+ *
+ * Calling chopstx_setcancelstate sets cancelability state.
+ *
+ * Returns old state which is 0 when it was enabled.
+ */
+int
+chopstx_setcancelstate (int cancel_disable)
+{
+ int old_state = !running->flag_cancelable;
+
+ running->flag_cancelable = (cancel_disable == 0);
+ chopstx_testcancel ();
+ return old_state;
+}
/*
* Lower layer architecture specific exception handling entries.
diff --git a/chopstx.h b/chopstx.h
index 5c9b216..330593d 100644
--- a/chopstx.h
+++ b/chopstx.h
@@ -118,6 +118,7 @@ enum {
void chopstx_cancel (chopstx_t thd);
void chopstx_testcancel (void);
+int chopstx_setcancelstate (int);
struct chx_cleanup {
struct chx_cleanup *next;
diff --git a/example-cdc/usb-cdc.c b/example-cdc/usb-cdc.c
index 310e454..52871c2 100644
--- a/example-cdc/usb-cdc.c
+++ b/example-cdc/usb-cdc.c
@@ -173,9 +173,17 @@ usb_cb_device_reset (void)
/* Initialize Endpoint 0 */
usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR, 64);
+
+ chopstx_mutex_lock (&usb_mtx);
+ connected = 0;
+ bDeviceState = ATTACHED;
+ chopstx_cond_signal (&cnd_usb);
+ chopstx_mutex_unlock (&usb_mtx);
}
+#define CDC_CTRL_DTR 0x0001
+
void
usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value)
{
@@ -186,7 +194,7 @@ usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value)
{
/* Open/close the connection. */
chopstx_mutex_lock (&usb_mtx);
- connected = (value != 0)? 1 : 0;
+ connected = ((value & CDC_CTRL_DTR) != 0)? 1 : 0;
chopstx_cond_signal (&cnd_usb);
chopstx_mutex_unlock (&usb_mtx);
}