Merge the change for GNU/Linux from riscv branch.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka
2019-11-25 09:53:50 +09:00
parent 823ebe222c
commit de301bf025
2 changed files with 51 additions and 43 deletions

View File

@@ -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.

View File

@@ -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 ();