FW: [PATCH] Cilk Keywords (_Cilk_spawn and _Cilk_sync) for C

Thomas Schwinge thomas@codesourcery.com
Mon Sep 29 10:54:00 GMT 2014


Hi!

On Mon, 22 Sep 2014 19:21:33 +0000, "Tannenbaum, Barry M" <barry.m.tannenbaum@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:thomas@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.iyer@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 <thomas@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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 472 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20140929/243aad71/attachment.sig>


More information about the Gcc-patches mailing list