Hi! On Mon, 22 Sep 2014 19:21:33 +0000, "Tannenbaum, Barry M" <barry.m.tannenb...@intel.com> wrote: > That's exactly correct. > > There are two ways to implement a work-stealing scheduler. We refer to them > as: [...]
Thanks for the explanation. > Cilk implements Parent Stealing. Since you're running with 1 worker, there's > no other worker to steal the continuation. So steal_flag will never be set to > 1 and you'll never break out of the loop. Remains the question about how to address that in the testsuite: > -----Original Message----- > From: Thomas Schwinge [mailto:tho...@codesourcery.com] > Sent: Monday, September 22, 2014 9:56 AM > To: Iyer, Balaji V > Cc: gcc-patches@gcc.gnu.org > Subject: Re: FW: [PATCH] Cilk Keywords (_Cilk_spawn and _Cilk_sync) for C > > Hi! > > On Tue, 27 Aug 2013 21:30:49 +0000, "Iyer, Balaji V" > <balaji.v.i...@intel.com> wrote: > > --- /dev/null > > +++ gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c > > @@ -0,0 +1,37 @@ > > +/* { dg-do run { target { i?86-*-* x86_64-*-* arm*-*-* } } } */ > > +/* { dg-options "-fcilkplus" } */ > > +/* { dg-options "-lcilkrts" { target { i?86-*-* x86_64-*-* arm*-*-* } > > +} } */ > > + > > +void f0(volatile int *steal_flag) > > +{ > > + int i = 0; > > + /* Wait for steal_flag to be set */ > > + while (!*steal_flag) > > + ; > > +} > > + > > +int f1() > > +{ > > + > > + volatile int steal_flag = 0; > > + _Cilk_spawn f0(&steal_flag); > > + steal_flag = 1; // Indicate stolen > > + _Cilk_sync; > > + return 0; > > +} > > + > > +void f2(int q) > > +{ > > + q = 5; > > +} > > + > > +void f3() > > +{ > > + _Cilk_spawn f2(f1()); > > +} > > + > > +int main() > > +{ > > + f3(); > > + return 0; > > +} > > Is this really well-formed Cilk Plus code? Running with CILK_NWORKERS=1, or > -- the equivalent -- in a system with just one CPU (as per > libcilkrts/runtime/os-unix.c:__cilkrts_hardware_cpu_count returning 1), I see > this test busy-loop as follows: > > Breakpoint 1, __cilkrts_hardware_cpu_count () at > ../../../source/libcilkrts/runtime/os-unix.c:358 > 358 { > (gdb) return 1 > Make __cilkrts_hardware_cpu_count return now? (y or n) y > #0 cilkg_get_user_settable_values () at > ../../../source/libcilkrts/runtime/global_state.cpp:385 > 385 CILK_ASSERT(hardware_cpu_count > 0); > (gdb) c > Continuing. > ^C > Program received signal SIGINT, Interrupt. > f0 (steal_flag=steal_flag@entry=0x7fffffffd03c) at > [...]/source/gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c:9 > 9 while (!*steal_flag) > (gdb) info threads > Id Target Id Frame > * 1 Thread 0x7ffff7fcd780 (LWP 30816) "spawning_arg.ex" f0 > (steal_flag=steal_flag@entry=0x7fffffffd03c) at > [...]/source/gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c:9 > (gdb) list > 4 > 5 void f0(volatile int *steal_flag) > 6 { > 7 int i = 0; > 8 /* Wait for steal_flag to be set */ > 9 while (!*steal_flag) > 10 ; > 11 } > 12 > 13 int f1() > (gdb) bt > #0 f0 (steal_flag=steal_flag@entry=0x7fffffffd03c) at > [...]/source/gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c:9 > #1 0x00000000004009c8 in _cilk_spn_0 () at > [...]/source/gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c:17 > #2 0x0000000000400a4b in f1 () at > [...]/source/gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c:17 > #3 0x0000000000400d0e in _cilk_spn_1 () at > [...]/source/gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c:30 > #4 0x0000000000400d7a in f3 () at > [...]/source/gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c:30 > #5 0x0000000000400e33 in main () at > [...]/source/gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c:35 > > No additional thread has been spawned by libcilkrts, and the one initial > thread is stuck in f0, without being able to make progress. Should in f0's > while loop, some function be called to "yield to libcilkrts scheduler", or > should libcilkrts have spawned an additional thread, or is the test case just > not valid Cilk Plus code? Assuming the test cases are considered well-formed Cilk Plus code, I understand there is then a hard requirement to run them with more than one worker. OK to fix as follows? commit ee7138e451d1f3284d6fa0f61fe517c82db94060 Author: Thomas Schwinge <tho...@codesourcery.com> Date: Mon Sep 29 12:47:34 2014 +0200 Audit Cilk Plus tests for CILK_NWORKERS=1. gcc/testsuite/ * c-c++-common/cilk-plus/CK/spawning_arg.c (main): Call __cilkrts_set_param to set two workers. * c-c++-common/cilk-plus/CK/steal_check.c (main): Likewise. * g++.dg/cilk-plus/CK/catch_exc.cc (main): Likewise. --- gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c | 15 +++++++++++++++ gcc/testsuite/c-c++-common/cilk-plus/CK/steal_check.c | 17 ++++++++++++++--- gcc/testsuite/g++.dg/cilk-plus/CK/catch_exc.cc | 14 ++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c index 95e6cab..138b82c 100644 --- gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c +++ gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c @@ -2,6 +2,17 @@ /* { dg-options "-fcilkplus" } */ /* { dg-additional-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */ +#ifdef __cplusplus +extern "C" { +#endif + +extern int __cilkrts_set_param (const char *, const char *); + +#ifdef __cplusplus +} +#endif + + void f0(volatile int *steal_flag) { int i = 0; @@ -32,6 +43,10 @@ void f3() int main() { + /* Ensure more than one worker. */ + if (__cilkrts_set_param("nworkers", "2") != 0) + __builtin_abort(); + f3(); return 0; } diff --git gcc/testsuite/c-c++-common/cilk-plus/CK/steal_check.c gcc/testsuite/c-c++-common/cilk-plus/CK/steal_check.c index 6e28765..6b41c7f 100644 --- gcc/testsuite/c-c++-common/cilk-plus/CK/steal_check.c +++ gcc/testsuite/c-c++-common/cilk-plus/CK/steal_check.c @@ -2,8 +2,16 @@ /* { dg-options "-fcilkplus" } */ /* { dg-additional-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */ -// #include <cilk/cilk_api.h> -extern void __cilkrts_set_param (char *, char *); +#ifdef __cplusplus +extern "C" { +#endif + +extern int __cilkrts_set_param (const char *, const char *); + +#ifdef __cplusplus +} +#endif + void foo(volatile int *); @@ -11,7 +19,10 @@ void main2(void); int main(void) { - // __cilkrts_set_param ((char *)"nworkers", (char *)"2"); + /* Ensure more than one worker. */ + if (__cilkrts_set_param("nworkers", "2") != 0) + __builtin_abort(); + main2(); return 0; } diff --git gcc/testsuite/g++.dg/cilk-plus/CK/catch_exc.cc gcc/testsuite/g++.dg/cilk-plus/CK/catch_exc.cc index 0633d19..09ddf8b 100644 --- gcc/testsuite/g++.dg/cilk-plus/CK/catch_exc.cc +++ gcc/testsuite/g++.dg/cilk-plus/CK/catch_exc.cc @@ -10,6 +10,16 @@ #endif #include <cstdlib> +#ifdef __cplusplus +extern "C" { +#endif + +extern int __cilkrts_set_param (const char *, const char *); + +#ifdef __cplusplus +} +#endif + void func(int volatile* steal_me) { @@ -59,6 +69,10 @@ void my_test() int main() { + /* Ensure more than one worker. */ + if (__cilkrts_set_param("nworkers", "2") != 0) + __builtin_abort(); + my_test(); #if HAVE_IO printf("PASSED\n"); Grüße, Thomas
pgp0lJdaoaACC.pgp
Description: PGP signature