Skip to content
Snippets Groups Projects
Commit e5c98d46 authored by Nadav Har'El's avatar Nadav Har'El
Browse files

We had a bug where we forgot to zero the .tbss section (the zero part of

the TLS), which led to preempt_counter not being intialized to zero and
therefore preemption not being enabled for new threads.

Such non-preemptable threads can monopolize their CPU and cause other
threads with the misfortune of being assigned to this CPU to never run.

This patch adds a simple test reproducing this bug. Because we don't have
an implementation of __tls_get_addr(), we can't "extern" a TLS symbol
(here sched::preempt_counter) from the test, and so I had to create a
new sched::get_preempt_counter() function which I can "extern" from the
test.
parent 60985e55
No related branches found
No related tags found
No related merge requests found
......@@ -69,6 +69,7 @@
/tests/tst-bsd-netdriver.so: ./tests/tst-bsd-netdriver.so
/tests/tst-virtionet.so: ./tests/tst-virtionet.so
/tests/tst-fpu.so: ./tests/tst-fpu.so
/tests/tst-preempt.so: ./tests/tst-preempt.so
/tests/tst-tracepoint.so: ./tests/tst-tracepoint.so
/tests/tst-leak.so: ./tests/tst-leak.so
/tests/tst-mmap.so: ./tests/tst-mmap.so
......
......@@ -87,6 +87,7 @@ tests += tests/tst-vblk.so tests/tst-fat.so tests/tst-romfs.so tests/bench/bench
tests += tests/tst-bsd-evh.so tests/tst-bsd-callout.so tests/tst-bsd-netisr.so \
tests/tst-bsd-netdriver.so tests/tst-virtionet.so
tests += tests/tst-fpu.so
tests += tests/tst-preempt.so
tests += tests/tst-tracepoint.so
tests += tests/tst-hub.so
tests += tests/tst-leak.so tests/tst-mmap.so
......
......@@ -424,6 +424,11 @@ void preempt_enable()
// FIXME: may need to schedule() here if a high prio thread is waiting
}
unsigned int get_preempt_counter()
{
return preempt_counter;
}
void preempt()
{
if (!preempt_counter) {
......
#include "sched.hh"
#include "debug.hh"
namespace sched {
// For this to work, we need to implement __tls_get_addr()
//extern unsigned int __thread preempt_counter;
// It's much easier, to expose the TLS variable via a function:
extern unsigned int get_preempt_counter();
}
int main(int argc, char **argv)
{
debug("Running preemption tests\n");
// Test 1: check that new threads start preemptable, i.e., with
// preempt_counter==0. We had a bug where we didn't zero the .tbss
// section, leading to non-zero preempt_counter initialization.
assert(sched::get_preempt_counter() == 0);
auto t1 = new sched::thread([] {
assert(sched::get_preempt_counter() == 0);
});
t1->start();
delete t1;
debug("Preemption tests succeeded\n");
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment