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.

Reply via email to