Merged to master at 3b8664e0dfbd..842b684f2a64 (from, to] You can see the entire diff with 'git diff' or at https://github.com/brho/akaros/compare/3b8664e0dfbd...842b684f2a64
On 2016-05-04 at 10:06 Barret Rhoden <[email protected]> wrote: > We had an extension to pthreads: pthread_can_vcore_request(). It was > a way for an application to tell the 2LS to not request vcores or to > yield vcores. The problem with making it a pthread extension is that > it is 2LS specific: an app needs to know/care about it's 2LS, and > every 2LS needed to reimplement the same logic. > > By pushing it into parlib, we avoid all of that. The app also gets > finer-grained control over what it needs (i.e., there's a minor > difference between not yielding and not requesting more cores). > > Be careful using this new variable. It'll prevent *any* vcores from > being requested, so you want to use it after the app requests > whatever vcores it wants (not including the one VC you get from being > an MCP). This variable is a minor pain, and might not be worth > keeping around. We'll see. > > This is actually a problem of having 2LSs that aren't app-specific > enough. The app knows what it wants, but the 2LS doesn't. We're > trying to find a way to deal with that in a way that doesn't > duplicate too much code. > > Signed-off-by: Barret Rhoden <[email protected]> > --- > tests/lock_test.c | 3 ++- > tests/old/condvar_test.c | 6 ++++-- > tests/old/fpperf.cc | 3 ++- > tests/pthread_barrier_test.c | 3 ++- > tests/pthread_switch.c | 3 ++- > tests/pthread_test.c | 3 ++- > user/parlib/include/parlib/parlib.h | 1 + > user/parlib/parlib.c | 1 + > user/parlib/vcore.c | 2 ++ > user/pthread/pthread.c | 29 > ++++------------------------- user/pthread/pthread.h | > 2 +- user/utest/pvcalarm.c | 6 ++++-- > 12 files changed, 27 insertions(+), 35 deletions(-) > > diff --git a/tests/lock_test.c b/tests/lock_test.c > index 80e2a2a365d9..4b8a5db2aaac 100644 > --- a/tests/lock_test.c > +++ b/tests/lock_test.c > @@ -732,7 +732,7 @@ static void os_prep_work(pthread_t > *worker_threads, int nr_threads) atomic_init(&indir_idx, 0); > atomic_init(&preempt_cnt, 0); > atomic_init(&indir_cnt, 0); > - pthread_can_vcore_request(FALSE); /* 2LS won't manage > vcores */ > + parlib_never_yield = TRUE; > pthread_need_tls(FALSE); > pthread_mcp_init(); /* > gives us one vcore */ register_ev_handler(EV_VCORE_PREEMPT, > trace_preempt, 0); @@ -744,6 +744,7 @@ static void > os_prep_work(pthread_t *worker_threads, int nr_threads) > clear_kevent_q(EV_CHECK_MSGS); } > vcore_request_total(nr_threads); > + parlib_never_vc_request = TRUE; > for (int i = 0; i < nr_threads; i++) { > printd("Vcore %d mapped to pcore %d\n", i, > __procinfo.vcoremap[i].pcoreid); > diff --git a/tests/old/condvar_test.c b/tests/old/condvar_test.c > index d7397a49598c..927338dcc384 100644 > --- a/tests/old/condvar_test.c > +++ b/tests/old/condvar_test.c > @@ -122,9 +122,10 @@ int main(void) > * > * Need to make sure we are running in parallel here. Temp > turned off the > * 2LSs VC management and got up to 2 VC. Assuming no > preemption. */ > - pthread_can_vcore_request(FALSE); /* 2LS won't manage > vcores */ > + parlib_never_yield = TRUE; > while (num_vcores() < 2) > vcore_request_more(1); > + parlib_never_vc_request = TRUE; > for (long i = 0; i < 1000; i++) { > for (int j = 0; j < 10; j++) { /* some extra > chances at each point */ state = FALSE; > @@ -147,6 +148,7 @@ int main(void) > pthread_join(my_threads[0], my_retvals[0]); > } > } > - pthread_can_vcore_request(TRUE); /* 2LS controls VCs > again */ > + parlib_never_yield = FALSE; > + parlib_never_vc_request = FALSE; > printf("test_cv: single sender/receiver complete\n"); > } > diff --git a/tests/old/fpperf.cc b/tests/old/fpperf.cc > index 55b0f290e4b3..6363f1f7d43f 100644 > --- a/tests/old/fpperf.cc > +++ b/tests/old/fpperf.cc > @@ -72,7 +72,8 @@ int main(int argc, char **argv) > #if 1 > # ifdef __ros__ > if (argc == 4) { > - pthread_can_vcore_request(FALSE); > + parlib_never_yield = TRUE; > + parlib_never_vc_request = TRUE; > pthread_mcp_init(); > printf("Vcore %d mapped to pcore %d\n", 0, > __procinfo.vcoremap[0].pcoreid); } > diff --git a/tests/pthread_barrier_test.c > b/tests/pthread_barrier_test.c index 1ab1fc6b6ea4..76abc045bcff 100644 > --- a/tests/pthread_barrier_test.c > +++ b/tests/pthread_barrier_test.c > @@ -46,9 +46,10 @@ int main(int argc, char** argv) > perror("Init threads/malloc"); > if (nr_vcores) { > /* Only do the vcore trickery if requested */ > - pthread_can_vcore_request(FALSE); /* 2LS > won't manage vcores */ > + parlib_never_yield = TRUE; > pthread_mcp_init(); /* > gives us one vcore */ vcore_request_total(nr_vcores); > + parlib_never_vc_request = TRUE; > for (int i = 0; i < nr_vcores; i++) { > printd("Vcore %d mapped to pcore %d\n", i, > __procinfo.vcoremap[i].pcoreid); > diff --git a/tests/pthread_switch.c b/tests/pthread_switch.c > index 3093c7920baa..70df52ecafb1 100644 > --- a/tests/pthread_switch.c > +++ b/tests/pthread_switch.c > @@ -68,7 +68,8 @@ int main(int argc, char** argv) > nr_switch_loops = strtol(argv[1], 0, 10); > printf("Making 2 threads of %d switches each\n", > nr_switch_loops); > - pthread_can_vcore_request(FALSE); /* 2LS won't manage > vcores */ > + parlib_never_yield = TRUE; > + parlib_never_vc_request = TRUE; > pthread_need_tls(FALSE); > pthread_mcp_init(); /* > gives us one vcore */ > diff --git a/tests/pthread_test.c b/tests/pthread_test.c > index e0c77093a581..bfd703798fe0 100644 > --- a/tests/pthread_test.c > +++ b/tests/pthread_test.c > @@ -82,10 +82,11 @@ int main(int argc, char** argv) > #ifdef __ros__ > if (nr_vcores) { > /* Only do the vcore trickery if requested */ > - pthread_can_vcore_request(FALSE); /* 2LS > won't manage vcores */ > + parlib_never_yield = TRUE; > pthread_need_tls(FALSE); > pthread_mcp_init(); /* > gives us one vcore */ vcore_request_total(nr_vcores); > + parlib_never_vc_request = TRUE; > for (int i = 0; i < nr_vcores; i++) { > printf_safe("Vcore %d mapped to pcore %d\n", > i, __procinfo.vcoremap[i].pcoreid); > diff --git a/user/parlib/include/parlib/parlib.h > b/user/parlib/include/parlib/parlib.h index > 4bca2db25f95..891f6831d1f0 100644 --- > a/user/parlib/include/parlib/parlib.h +++ > b/user/parlib/include/parlib/parlib.h @@ -60,6 +60,7 @@ > void syscall_async(struct syscall *sysc, unsigned long > num, ...); /* Control variables */ extern bool > parlib_wants_to_be_mcp; /* instructs the 2LS to be an MCP */ > extern bool parlib_never_yield; /* instructs the 2LS > to not yield vcores */ +extern bool parlib_never_vc_request;/* 2LS: > do not request vcores */ __END_DECLS > > diff --git a/user/parlib/parlib.c b/user/parlib/parlib.c > index cc558502dbbe..a6caa0073668 100644 > --- a/user/parlib/parlib.c > +++ b/user/parlib/parlib.c > @@ -7,3 +7,4 @@ > /* Control variables */ > bool parlib_wants_to_be_mcp = TRUE; > bool parlib_never_yield = FALSE; > +bool parlib_never_vc_request = FALSE; > diff --git a/user/parlib/vcore.c b/user/parlib/vcore.c > index fd22f8677efa..ae76bcc12355 100644 > --- a/user/parlib/vcore.c > +++ b/user/parlib/vcore.c > @@ -253,6 +253,8 @@ void vcore_request_total(long nr_vcores_wanted) > { > static long nr_vc_wanted; > > + if (parlib_never_vc_request) > + return; > if (nr_vcores_wanted == > __procdata.res_req[RES_CORES].amt_wanted) return; > > diff --git a/user/pthread/pthread.c b/user/pthread/pthread.c > index e089ff938ea0..9a6691ec9b33 100644 > --- a/user/pthread/pthread.c > +++ b/user/pthread/pthread.c > @@ -24,7 +24,6 @@ struct mcs_pdr_lock queue_lock; > int threads_ready = 0; > int threads_active = 0; > atomic_t threads_total; > -bool can_adjust_vcores = TRUE; > bool need_tls = TRUE; > > /* Array of per-vcore structs to manage waiting on syscalls and > handling @@ -107,11 +106,8 @@ static void __attribute__((noreturn)) > pth_sched_entry(void) /* no new thread, try to yield */ > printd("[P] No threads, vcore %d is yielding\n", > vcore_id()); /* TODO: you can imagine having something smarter here, > like spin for a > - * bit before yielding (or not at all if you want to > be greedy). */ > - if (can_adjust_vcores) > - vcore_yield(FALSE); > - if (!parlib_wants_to_be_mcp) > - sys_yield(FALSE); > + * bit before yielding. */ > + vcore_yield(FALSE); > } while (1); > /* Prep the pthread to run any pending posix signal handlers > registered > * via pthread_kill once it is restored. */ > @@ -160,8 +156,7 @@ static void pth_thread_runnable(struct uthread > *uthread) mcs_pdr_unlock(&queue_lock); > /* Smarter schedulers should look at the num_vcores() and > how much work is > * going on to make a decision about how many vcores to > request. */ > - if (can_adjust_vcores) > - vcore_request_more(threads_ready); > + vcore_request_more(threads_ready); > } > > /* For some reason not under its control, the uthread stopped > running (compared @@ -339,14 +334,6 @@ static void > pth_thread_refl_fault(struct uthread *uth, > /* Akaros pthread extensions / hacks */ > > -/* Tells the pthread 2LS to not change the number of vcores. This > means it will > - * neither request vcores nor yield vcores. Only used for testing. > */ -void pthread_can_vcore_request(bool can) > -{ > - /* checked when we would request or yield */ > - can_adjust_vcores = can; > -} > - > void pthread_need_tls(bool need) > { > need_tls = need; > @@ -541,13 +528,6 @@ void pthread_mcp_init() > /* Prevent this from happening more than once. */ > init_once_racy(return); > > - if (!parlib_wants_to_be_mcp) { > - /* sign to whether or not we ask for more vcores. > actually, if we're > - * an SCP, the current kernel will ignore our > requests, but best to not > - * rely on that. */ > - can_adjust_vcores = FALSE; > - return; > - } > uthread_mcp_init(); > /* From here forward we are an MCP running on vcore 0. Could > consider doing > * other pthread specific initialization based on knowing we > are an mcp @@ -923,8 +903,7 @@ static void wake_slist(struct > pthread_list *to_wake) } > threads_ready += nr_woken; > mcs_pdr_unlock(&queue_lock); > - if (can_adjust_vcores) > - vcore_request_more(threads_ready); > + vcore_request_more(threads_ready); > } > > int pthread_cond_broadcast(pthread_cond_t *c) > diff --git a/user/pthread/pthread.h b/user/pthread/pthread.h > index a98df07c8dd1..ca5a3cc65b8c 100644 > --- a/user/pthread/pthread.h > +++ b/user/pthread/pthread.h > @@ -8,6 +8,7 @@ > #include <parlib/dtls.h> > #include <parlib/spinlock.h> > #include <parlib/signal.h> > +#include <parlib/parlib.h> > /* GNU / POSIX scheduling crap */ > #include <sched.h> > > @@ -152,7 +153,6 @@ typedef int pthread_once_t; > typedef dtls_key_t pthread_key_t; > > /* Akaros pthread extensions / hacks */ > -void pthread_can_vcore_request(bool can); /* default is TRUE > */ void pthread_need_tls(bool need); /* > default is TRUE */ void pthread_lib_init(void); > void pthread_mcp_init(void); > diff --git a/user/utest/pvcalarm.c b/user/utest/pvcalarm.c > index 8cb8ec20d768..cb9f55477d80 100644 > --- a/user/utest/pvcalarm.c > +++ b/user/utest/pvcalarm.c > @@ -14,9 +14,10 @@ bool test_pvcalarms(void) { > __sync_fetch_and_add(&count[vcore_id()], 1); > } > > - pthread_can_vcore_request(FALSE); > + parlib_never_yield = TRUE; > pthread_mcp_init(); > vcore_request_total(max_vcores()); > + parlib_never_vc_request = TRUE; > for (int i=0; i<max_vcores(); i++) > count[i] = 0; > > @@ -65,7 +66,8 @@ bool test_sigperf(void) > } > > pthread_lib_init(); > - pthread_can_vcore_request(TRUE); > + parlib_never_yield = FALSE; > + parlib_never_vc_request = FALSE; > > sigset_t s; > sigemptyset(&s); -- You received this message because you are subscribed to the Google Groups "Akaros" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. For more options, visit https://groups.google.com/d/optout.
