4 Commits

Author SHA1 Message Date
a8e9074faf Add switch pin for ST-Dongle 2022-07-30 12:35:28 +02:00
NIIBE Yutaka
e12a7e0bb3 Version 1.21.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2022-04-22 11:11:05 +09:00
NIIBE Yutaka
fdbe91600d Backport struct qh changes from master.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2022-04-21 13:01:30 +09:00
NIIBE Yutaka
daca396027 Backport struct chx_qh changes from master.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2022-04-08 19:50:21 +09:00
10 changed files with 194 additions and 97 deletions

View File

@@ -1,3 +1,43 @@
2022-04-22 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.21.
* doc/chopstx.texi (VERSION): 1.21.
2022-04-21 NIIBE Yutaka <gniibe@fsij.org>
Backport the changes from master.
* chopstx.c (struct chx_pq): Use struct qh.
(struct chx_px): Use struct qh.
(struct chx_thread): Use struct qh.
(FOR_QUEUE): Remove.
(ll_dequeue): Follow the changes of above.
(ll_prio_push): Use struct qh for the loop.
(ll_prio_enqueue): Likewise.
(chx_set_timer): Use struct qh for the first argument.
(chx_timer_insert, chx_timer_dequeue): Use struct qh for the loop.
(chx_timer_expired): Likewise.
(chx_init, chopstx_create, chx_proxy_init): Use the address at q.
(chx_exit): Use struct qh for the loop.
(chx_mutex_unlock): Fix the calculation of the priority.
* chopstx-cortex-m.c (chx_handle_intr): Not use FOR_QUEUE macro.
* chopstx-gnu-linux.c (chx_handle_intr): Not use FOR_QUEUE macro.
2022-04-08 NIIBE Yutaka <gniibe@fsij.org>
Backport the changes from master.
* chopstx.h (struct chx_qh): Change the type for next and prev.
* chopstx.c (FOR_QUEUE): New macro.
(ll_empty): Follow the change of struct chx_qh.
(ll_insert): Change the type of the first argument.
(ll_pop): Follow the change of struct chx_qh.
(ll_prio_push): Use FOR_QUEUE macro. Follow the change of
ll_insert.
(ll_prio_enqueue, chx_timer_insert): Likewise.
(chx_timer_dequeue, chx_init, chx_exit): Likewise.
(chopstx_mutex_init, chopstx_cond_init): Likewise.
* chopstx-cortex-m.c (chx_handle_intr): Use FOR_QUEUE macro.
* chopstx-gnu-linux.c (chx_handle_intr): Use FOR_QUEUE macro.
2021-10-12 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.20.

10
NEWS
View File

@@ -1,6 +1,16 @@
NEWS - Noteworthy changes
* Major changes in Chopstx 1.21
Released 2022-04-22
** Fix of struct chx_qh and struct chx_thread/pq/px.
Good compiler complains/warns for possible different size of
structures. To avoid this, access to the objects are fixed.
* Major changes in Chopstx 1.20
Released 2021-10-12

4
README
View File

@@ -1,6 +1,6 @@
Chopstx - Threads and only Threads
Version 1.20
2021-10-12
Version 1.21
2021-04-22
Niibe Yutaka
Flying Stone Technology

View File

@@ -1 +1 @@
release/1.20
release/1.21

View File

@@ -267,7 +267,7 @@ chx_cpu_sched_unlock (void)
void
chx_handle_intr (void)
{
struct chx_pq *p;
struct chx_qh *q;
register uint32_t irq_num;
asm volatile ("mrs %0, IPSR\n\t"
@@ -276,16 +276,20 @@ chx_handle_intr (void)
chx_disable_intr (irq_num);
chx_spin_lock (&q_intr.lock);
for (p = q_intr.q.next; p != (struct chx_pq *)&q_intr.q; p = p->next)
if (p->v == irq_num)
{ /* should be one at most. */
struct chx_px *px = (struct chx_px *)p;
for (q = q_intr.q.next; q != &q_intr.q; q = q->next)
{
struct chx_pq *p = (struct chx_pq *)q;
ll_dequeue (p);
chx_wakeup (p);
chx_request_preemption (px->master->prio);
break;
}
if (p->v == irq_num)
{ /* should be one at most. */
struct chx_px *px = (struct chx_px *)p;
ll_dequeue (p);
chx_wakeup (p);
chx_request_preemption (px->master->prio);
break;
}
}
chx_spin_unlock (&q_intr.lock);
}

View File

@@ -154,21 +154,24 @@ idle (void)
void
chx_handle_intr (uint32_t irq_num)
{
struct chx_pq *p;
struct chx_qh *q;
chx_disable_intr (irq_num);
chx_spin_lock (&q_intr.lock);
for (p = q_intr.q.next; p != (struct chx_pq *)&q_intr.q; p = p->next)
if (p->v == irq_num)
{ /* should be one at most. */
struct chx_px *px = (struct chx_px *)p;
for (q = q_intr.q.next; q != &q_intr.q; q = q->next)
{
struct chx_pq *p = (struct chx_pq *)q;
if (p->v == irq_num)
{ /* should be one at most. */
struct chx_px *px = (struct chx_px *)p;
ll_dequeue (p);
chx_wakeup (p);
chx_spin_unlock (&q_intr.lock);
chx_request_preemption (px->master->prio);
return;
}
ll_dequeue (p);
chx_wakeup (p);
chx_spin_unlock (&q_intr.lock);
chx_request_preemption (px->master->prio);
return;
}
}
chx_spin_unlock (&q_intr.lock);
}

173
chopstx.c
View File

@@ -88,6 +88,9 @@ struct chx_queue {
struct chx_spinlock lock;
};
/* Forward declaration. */
struct chx_pq;
/* READY: priority queue. */
static struct chx_queue q_ready;
@@ -126,7 +129,7 @@ static void chx_spin_unlock (struct chx_spinlock *lk)
/**************/
struct chx_pq {
struct chx_pq *next, *prev;
struct chx_qh q;
uint32_t : 4;
uint32_t : 5;
uint32_t : 6;
@@ -138,7 +141,7 @@ struct chx_pq {
};
struct chx_px { /* inherits PQ */
struct chx_pq *next, *prev;
struct chx_qh q;
uint32_t : 4;
uint32_t : 5;
uint32_t : 6;
@@ -154,7 +157,7 @@ struct chx_px { /* inherits PQ */
};
struct chx_thread { /* inherits PQ */
struct chx_pq *next, *prev;
struct chx_qh q;
uint32_t state : 4;
uint32_t flag_detached : 1;
uint32_t flag_got_cancel : 1;
@@ -180,63 +183,69 @@ struct chx_thread { /* inherits PQ */
static int
ll_empty (struct chx_qh *q)
{
return q == (struct chx_qh *)q->next;
return q == q->next;
}
static struct chx_pq *
ll_dequeue (struct chx_pq *pq)
{
pq->next->prev = pq->prev;
pq->prev->next = pq->next;
pq->prev = pq->next = pq;
pq->q.next->prev = pq->q.prev;
pq->q.prev->next = pq->q.next;
pq->q.prev = pq->q.next = &pq->q;
return pq;
}
static void
ll_insert (struct chx_pq *pq0, struct chx_qh *q)
ll_insert (struct chx_qh *q0, struct chx_qh *q)
{
struct chx_pq *pq = (struct chx_pq *)q;
pq0->next = (struct chx_pq *)pq;
pq0->prev = pq->prev;
pq->prev->next = (struct chx_pq *)pq0;
pq->prev = pq0;
q0->next = q;
q0->prev = q->prev;
q->prev->next = q0;
q->prev = q0;
}
static struct chx_pq *
ll_pop (struct chx_qh *q)
{
if (q == (struct chx_qh *)q->next)
if (q == q->next)
return NULL;
return ll_dequeue (q->next);
return ll_dequeue ((struct chx_pq *)q->next);
}
static void
ll_prio_push (struct chx_pq *pq0, struct chx_qh *q0)
{
struct chx_pq *p;
struct chx_qh *q;
for (p = q0->next; p != (struct chx_pq *)q0; p = p->next)
if (p->prio <= pq0->prio)
break;
for (q = q0->next; q != q0; q = q->next)
{
struct chx_pq *p = (struct chx_pq *)q;
if (p->prio <= pq0->prio)
break;
}
pq0->parent = q0;
ll_insert (pq0, (struct chx_qh *)p);
ll_insert (&pq0->q, q);
}
static void
ll_prio_enqueue (struct chx_pq *pq0, struct chx_qh *q0)
{
struct chx_pq *p;
struct chx_qh *q;
for (p = q0->next; p != (struct chx_pq *)q0; p = p->next)
if (p->prio < pq0->prio)
break;
for (q = q0->next; q != q0; q = q->next)
{
struct chx_pq *p = (struct chx_pq *)q;
if (p->prio < pq0->prio)
break;
}
pq0->parent = q0;
ll_insert (pq0, (struct chx_qh *)p);
ll_insert (&pq0->q, q);
}
@@ -308,29 +317,35 @@ chx_ready_enqueue (struct chx_thread *tp)
#endif
static void
chx_set_timer (struct chx_thread *tp, uint32_t ticks)
chx_set_timer (struct chx_qh *q, uint32_t ticks)
{
if (tp == (struct chx_thread *)&q_timer.q)
if (q == &q_timer.q)
chx_systick_reload (ticks);
else
tp->v = ticks;
{
struct chx_thread *tp = (struct chx_thread *)q;
tp->v = ticks;
}
}
static struct chx_thread *
chx_timer_insert (struct chx_thread *tp, uint32_t usec)
{
struct chx_pq *p;
struct chx_qh *q;
uint32_t ticks = usec_to_ticks (usec);
uint32_t next_ticks = chx_systick_get ();
for (p = q_timer.q.next; p != (struct chx_pq *)&q_timer.q; p = p->next)
for (q = q_timer.q.next; q != &q_timer.q; q = q->next)
{
struct chx_pq *p = (struct chx_pq *)q;
if (ticks < next_ticks)
{
tp->parent = &q_timer.q;
ll_insert ((struct chx_pq *)tp, (struct chx_qh *)p);
chx_set_timer ((struct chx_thread *)tp->prev, ticks);
chx_set_timer (tp, (next_ticks - ticks));
ll_insert (&tp->q, q);
chx_set_timer (tp->q.prev, ticks);
chx_set_timer (&tp->q, (next_ticks - ticks));
break;
}
else
@@ -340,12 +355,12 @@ chx_timer_insert (struct chx_thread *tp, uint32_t usec)
}
}
if (p == (struct chx_pq *)&q_timer.q)
if (q == &q_timer.q)
{
tp->parent = &q_timer.q;
ll_insert ((struct chx_pq *)tp, (struct chx_qh *)p);
chx_set_timer ((struct chx_thread *)tp->prev, ticks);
chx_set_timer (tp, 1); /* Non-zero for the last entry. */
ll_insert (&tp->q, q);
chx_set_timer (tp->q.prev, ticks);
chx_set_timer (&tp->q, 1); /* Non-zero for the last entry. */
}
return tp;
@@ -355,25 +370,30 @@ chx_timer_insert (struct chx_thread *tp, uint32_t usec)
static uint32_t
chx_timer_dequeue (struct chx_thread *tp)
{
struct chx_thread *tp_prev;
struct chx_qh *q_prev;
uint32_t ticks_remained;
chx_spin_lock (&q_timer.lock);
ticks_remained = chx_systick_get ();
tp_prev = (struct chx_thread *)tp->prev;
if (tp_prev == (struct chx_thread *)&q_timer.q)
q_prev = tp->q.prev;
if (q_prev == &q_timer.q)
{
if (tp->next == (struct chx_pq *)&q_timer.q)
if (tp->q.next == &q_timer.q)
chx_systick_reload (0); /* Cancel timer. */
else
chx_systick_reload (ticks_remained + tp->v); /* Update timer. */
}
else
{
struct chx_pq *p;
struct chx_thread *tp_prev = (struct chx_thread *)q_prev;
struct chx_qh *q;
for (p = q_timer.q.next; p != (struct chx_pq *)tp; p = p->next)
ticks_remained += p->v;
for (q = q_timer.q.next; q != &q_timer.q; q = q->next)
{
struct chx_pq *p = (struct chx_pq *)q;
ticks_remained += p->v;
}
tp_prev->v += tp->v;
}
@@ -406,15 +426,17 @@ chx_timer_expired (void)
if (!ll_empty (&q_timer.q))
{
struct chx_thread *tp_next;
struct chx_qh *q, *q_next;
for (tp = (struct chx_thread *)q_timer.q.next;
tp != (struct chx_thread *)&q_timer.q && next_tick == 0;
tp = tp_next)
for (q = q_timer.q.next;
q != &q_timer.q && next_tick == 0;
q = q_next)
{
tp = (struct chx_thread *)q;
next_tick = tp->v;
tp->v = (uintptr_t)0;
tp_next = (struct chx_thread *)tp->next;
q_next = tp->q.next;
ll_dequeue ((struct chx_pq *)tp);
chx_ready_enqueue (tp);
if (tp == running)
@@ -425,7 +447,7 @@ chx_timer_expired (void)
}
if (!ll_empty (&q_timer.q))
chx_set_timer ((struct chx_thread *)&q_timer.q, next_tick);
chx_set_timer (&q_timer.q, next_tick);
}
}
@@ -460,15 +482,15 @@ chx_init (struct chx_thread *tp)
chx_init_arch (tp);
chx_spin_init (&chx_enable_sleep_lock);
q_ready.q.next = q_ready.q.prev = (struct chx_pq *)&q_ready.q;
q_ready.q.next = q_ready.q.prev = &q_ready.q;
chx_spin_init (&q_ready.lock);
q_timer.q.next = q_timer.q.prev = (struct chx_pq *)&q_timer.q;
q_timer.q.next = q_timer.q.prev = &q_timer.q;
chx_spin_init (&q_timer.lock);
q_join.q.next = q_join.q.prev = (struct chx_pq *)&q_join.q;
q_join.q.next = q_join.q.prev = &q_join.q;
chx_spin_init (&q_join.lock);
q_intr.q.next = q_intr.q.prev = (struct chx_pq *)&q_intr.q;
q_intr.q.next = q_intr.q.prev = &q_intr.q;
chx_spin_init (&q_intr.lock);
tp->next = tp->prev = (struct chx_pq *)tp;
tp->q.next = tp->q.prev = &tp->q;
tp->mutex_list = NULL;
tp->clp = NULL;
tp->state = THREAD_RUNNING;
@@ -542,20 +564,24 @@ chx_wakeup (struct chx_pq *pq)
static void __attribute__((noreturn))
chx_exit (void *retval)
{
struct chx_pq *p;
struct chx_qh *q;
struct chx_thread *running = chx_running ();
chx_cpu_sched_lock ();
if (running->flag_join_req)
{ /* wake up a thread which requests to join */
chx_spin_lock (&q_join.lock);
for (p = q_join.q.next; p != (struct chx_pq *)&q_join.q; p = p->next)
if (p->v == (uintptr_t)running)
{ /* should be one at most. */
ll_dequeue (p);
chx_wakeup (p);
break;
}
for (q = q_join.q.next; q != &q_join.q; q = q->next)
{
struct chx_pq *p = (struct chx_pq *)q;
if (p->v == (uintptr_t)running)
{ /* should be one at most. */
ll_dequeue (p);
chx_wakeup (p);
break;
}
}
chx_spin_unlock (&q_join.lock);
}
@@ -599,9 +625,14 @@ chx_mutex_unlock (chopstx_mutex_t *mutex)
/* Examine mutexes we hold, and determine new priority for running. */
for (m = running->mutex_list; m; m = m->list)
if (!ll_empty (&m->q)
&& ((struct chx_thread *)(m->q.next))->prio > newprio)
newprio = ((struct chx_thread *)m->q.next)->prio;
if (!ll_empty (&m->q))
{
struct chx_thread *tp_m = (struct chx_thread *)m->q.next;
uint16_t prio_m = tp_m->prio;
if (prio_m > newprio)
newprio = prio_m;
}
/* Then, assign it. */
running->prio = newprio;
@@ -632,7 +663,7 @@ chopstx_create (uint32_t flags_and_prio,
tp = chopstx_create_arch (stack_addr, stack_size, thread_entry,
arg);
tp->next = tp->prev = (struct chx_pq *)tp;
tp->q.next = tp->q.prev = &tp->q;
tp->mutex_list = NULL;
tp->clp = NULL;
tp->state = THREAD_EXITED;
@@ -744,7 +775,7 @@ void
chopstx_mutex_init (chopstx_mutex_t *mutex)
{
chx_spin_init (&mutex->lock);
mutex->q.next = mutex->q.prev = (struct chx_pq *)&mutex->q;
mutex->q.next = mutex->q.prev = &mutex->q;
mutex->list = NULL;
mutex->owner = NULL;
}
@@ -880,7 +911,7 @@ void
chopstx_cond_init (chopstx_cond_t *cond)
{
chx_spin_init (&cond->lock);
cond->q.next = cond->q.prev = (struct chx_pq *)&cond->q;
cond->q.next = cond->q.prev = &cond->q;
}
@@ -1372,7 +1403,7 @@ chx_proxy_init (struct chx_px *px, uint32_t *cp)
{
struct chx_thread *running = chx_running ();
px->next = px->prev = (struct chx_pq *)px;
px->q.next = px->q.prev = &px->q;
px->flag_is_proxy = 1;
px->prio = running->prio;
px->parent = NULL;

View File

@@ -27,7 +27,7 @@
*/
struct chx_qh {
struct chx_pq *next, *prev;
struct chx_qh *next, *prev;
};
typedef uintptr_t chopstx_t;

View File

@@ -66,6 +66,15 @@ ackbtn_init (chopstx_intr_t *intr)
pin_config |= PINCFG_EDGE_RISING;
break;
case BOARD_ID_ST_DONGLE:
/* PA5 is connected to a switch */
afio_exticr_index = 0;
afio_exticr_extiX_pY = AFIO_EXTICR2_EXTI5_PA;
irq_num = EXTI9_5_IRQ;
pin_config = 0x0020; /* EXTI_PR_PR5 == EXTI_IMR_MR5 == EXTI_RTSR_TR5 */
pin_config |= PINCFG_EDGE_RISING;
break;
case BOARD_ID_FST_01SZ:
default:
/* PA3 is connected to a hall sensor DRV5032FA */

View File

@@ -1,7 +1,7 @@
\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename chopstx.info
@set VERSION 1.20
@set VERSION 1.21
@settitle Chopstx Reference Manual
@c Unify some of the indices.
@syncodeindex tp fn