Merge the change for GNU/Linux from riscv branch.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
2019-11-25 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* chopstx-gnu-linux.c (chx_idle): Synchronous IDLE.
|
||||
(chx_idle, idle_stack): Remove.
|
||||
(chx_init_arch): Don't makecontext for IDLE.
|
||||
(preempted_context_switch): Simplify, because no case for
|
||||
interrupting IDLE.
|
||||
(voluntary_context_switch): Simply call chx_idle to get tp_next.
|
||||
|
||||
2019-11-22 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* chopstx-gnu-linux.c (preempted_context_switch): Rename.
|
||||
|
||||
@@ -146,11 +146,28 @@ chx_cpu_sched_unlock (void)
|
||||
pthread_sigmask (SIG_SETMASK, &ss_cur, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
/* NOTE: Called holding the cpu_sched_lock. */
|
||||
static struct chx_thread *
|
||||
chx_idle (void)
|
||||
{
|
||||
for (;;)
|
||||
pause ();
|
||||
struct chx_thread *tp_next = NULL;
|
||||
|
||||
while (tp_next == NULL)
|
||||
{
|
||||
int sig;
|
||||
sigset_t set;
|
||||
|
||||
sigfillset (&set);
|
||||
if (sigwait (&set, &sig))
|
||||
continue;
|
||||
|
||||
if (sig == SIGALRM)
|
||||
tp_next = chx_timer_expired ();
|
||||
else
|
||||
tp_next = chx_recv_irq (sig);
|
||||
}
|
||||
|
||||
return tp_next;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -167,9 +184,6 @@ chx_handle_intr (uint32_t irq_num)
|
||||
}
|
||||
|
||||
|
||||
static ucontext_t idle_tc;
|
||||
static char idle_stack[4096];
|
||||
|
||||
struct chx_thread main_thread;
|
||||
|
||||
void
|
||||
@@ -213,12 +227,6 @@ chx_init_arch (struct chx_thread *tp)
|
||||
sa.sa_flags = SA_SIGINFO|SA_RESTART;
|
||||
sigaction (SIGALRM, &sa, NULL);
|
||||
|
||||
getcontext (&idle_tc);
|
||||
idle_tc.uc_stack.ss_sp = idle_stack;
|
||||
idle_tc.uc_stack.ss_size = sizeof (idle_stack);
|
||||
idle_tc.uc_link = NULL;
|
||||
makecontext (&idle_tc, chx_idle, 0);
|
||||
|
||||
getcontext (&tp->tc);
|
||||
chx_set_running (tp);
|
||||
}
|
||||
@@ -227,31 +235,25 @@ static void
|
||||
preempted_context_switch (struct chx_thread *tp_next)
|
||||
{
|
||||
struct chx_thread *tp_prev = chx_running ();
|
||||
|
||||
/*
|
||||
* The swapcontext implementation may reset sigmask in the
|
||||
* middle of its execution, unfortunately. It is best if
|
||||
* sigmask restore is done at the end of the routine, but we
|
||||
* can't assume that.
|
||||
*
|
||||
* Thus, there might be a race condition with regards to the
|
||||
* user context TCP, if signal mask is cleared and signal comes
|
||||
* in. To avoid this situation, we block signals.
|
||||
*
|
||||
* We don't need to fill the mask here. It keeps the condition
|
||||
* of blocking signals before&after swapcontext call. It is
|
||||
* done by the signal mask for sigaction, the initial creation
|
||||
* of the thread, and the condition of chx_sched function which
|
||||
* mandates holding cpu_sched_lock.
|
||||
*/
|
||||
chx_set_running (tp_next);
|
||||
if (tp_prev)
|
||||
{
|
||||
/*
|
||||
* The swapcontext implementation may reset sigmask in the
|
||||
* middle of its execution, unfortunately. It is best if
|
||||
* sigmask restore is done at the end of the routine, but we
|
||||
* can't assume that.
|
||||
*
|
||||
* Thus, there might be a race condition with regards to the
|
||||
* user context TCP, if signal mask is cleared and signal comes
|
||||
* in. To avoid this situation, we block signals.
|
||||
*
|
||||
* We don't need to fill the mask here. It keeps the condition
|
||||
* of blocking signals before&after swapcontext call. It is
|
||||
* done by the signal mask for sigaction, the initial creation
|
||||
* of the thread, and the condition of chx_sched function which
|
||||
* mandates holding cpu_sched_lock.
|
||||
*/
|
||||
swapcontext (&tp_prev->tc, &tp_next->tc);
|
||||
}
|
||||
else
|
||||
{
|
||||
setcontext (&tp_next->tc);
|
||||
}
|
||||
swapcontext (&tp_prev->tc, &tp_next->tc);
|
||||
}
|
||||
|
||||
|
||||
@@ -259,16 +261,13 @@ static uintptr_t
|
||||
voluntary_context_switch (struct chx_thread *tp_next)
|
||||
{
|
||||
struct chx_thread *tp, *tp_prev;
|
||||
ucontext_t *tcp;
|
||||
|
||||
if (!tp_next)
|
||||
tp_next = chx_idle ();
|
||||
|
||||
tp_prev = chx_running ();
|
||||
if (tp_next)
|
||||
tcp = &tp_next->tc;
|
||||
else
|
||||
tcp = &idle_tc;
|
||||
|
||||
chx_set_running (tp_next);
|
||||
swapcontext (&tp_prev->tc, tcp);
|
||||
swapcontext (&tp_prev->tc, &tp_next->tc);
|
||||
chx_cpu_sched_unlock ();
|
||||
|
||||
tp = chx_running ();
|
||||
|
||||
Reference in New Issue
Block a user