This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gomp] OMP_STACKSIZE env variable


Asher Langton reported in private mail that they have programs
that can't run in the default thread stack size.  I believe one
solution for glibc is to use ulimit -s, which sets the default
thread stack size.  But he also mentions that another openmp
implementation provides OMP_STACKSIZE; it seems reasonable to
allow that as well.

The following has been lightly tested.  I *think* this should
Just Compile on other systems, but I'm not sure what sort of
brokenness wrt missing symbols I'm likely to encounter.  I'll
check this in shortly, and endevour to fix problems as they
are reported.


r~


	* env.c (gomp_nthreads_var): Change to unsigned long.
	(gomp_run_sched_chunk): Likewise.
	(parse_unsigned_long): Rename from parse_num_threads and generalize.
	(initialize_env): Initialize gomp_thread_attr.
	* libgomp.h (gomp_nthreads_var): Update decl.
	(gomp_run_sched_chunk): Likewise.
	(gomp_thread_attr): Declare.
	* team.c (gomp_thread_attr): Export.
	(initialize_team): Don't initialize it.

=== env.c
==================================================================
--- env.c	(revision 114503)
+++ env.c	(local)
@@ -32,13 +32,15 @@
 #include "libgomp_f.h"
 #include <stdlib.h>
 #include <string.h>
+#include <limits.h>
+#include <errno.h>
 
 
-unsigned gomp_nthreads_var = 1;
+unsigned long gomp_nthreads_var = 1;
 bool gomp_dyn_var = false;
 bool gomp_nest_var = false;
 enum gomp_schedule_type gomp_run_sched_var = GFS_DYNAMIC;
-unsigned gomp_run_sched_chunk = 1;
+unsigned long gomp_run_sched_chunk = 1;
 
 /* Parse the OMP_SCHEDULE environment variable.  */
 
@@ -98,33 +100,35 @@
   return;
 }
 
-/* Parse the OMP_NUM_THREADS environment varible.  Return true if one was
+/* Parse an unsigned long environment varible.  Return true if one was
    present and it was successfully parsed.  */
 
 static bool
-parse_num_threads (void)
+parse_unsigned_long (const char *name, unsigned long *pvalue)
 {
   char *env, *end;
+  unsigned long value;
 
-  env = getenv ("OMP_NUM_THREADS");
+  env = getenv (name);
   if (env == NULL)
     return false;
 
   if (*env == '\0')
     goto invalid;
 
-  gomp_nthreads_var = strtoul (env, &end, 10);
+  value = strtoul (env, &end, 10);
   if (*end != '\0')
     goto invalid;
+
+  *pvalue = value;
   return true;
 
  invalid:
-  gomp_error ("Invalid value for enviroment variable OMP_NUM_THREADS");
-  gomp_nthreads_var = 1;
+  gomp_error ("Invalid value for environment variable %s", name);
   return false;
 }
 
-/* Parse a boolean value for environement variable NAME and store the 
+/* Parse a boolean value for environment variable NAME and store the 
    result in VALUE.  */
 
 static void
@@ -141,20 +145,43 @@
   else if (strcmp (env, "false") == 0)
     *value = false;
   else
-    gomp_error ("Invalid value for environement variable %s", name);
+    gomp_error ("Invalid value for environment variable %s", name);
 }
 
 static void __attribute__((constructor))
 initialize_env (void)
 {
+  unsigned long stacksize;
+
   /* Do a compile time check that mkomp_h.pl did good job.  */
   omp_check_defines ();
 
   parse_schedule ();
   parse_boolean ("OMP_DYNAMIC", &gomp_dyn_var);
   parse_boolean ("OMP_NESTED", &gomp_nest_var);
-  if (!parse_num_threads ())
+  if (!parse_unsigned_long ("OMP_NUM_THREADS", &gomp_nthreads_var))
     gomp_init_num_threads ();
+
+  /* Not strictly environment related, but ordering constructors is tricky.  */
+  pthread_attr_init (&gomp_thread_attr);
+  pthread_attr_setdetachstate (&gomp_thread_attr, PTHREAD_CREATE_DETACHED);
+
+  if (parse_unsigned_long ("OMP_STACKSIZE", &stacksize))
+    {
+      stacksize *= 1024;
+      if (stacksize < PTHREAD_STACK_MIN)
+	gomp_error ("Stack size less than minimum of %luk",
+		    PTHREAD_STACK_MIN / 1024ul
+		    + (PTHREAD_STACK_MIN % 1024 != 0));
+      else
+	{
+	  int err = pthread_attr_setstacksize (&gomp_thread_attr, stacksize);
+	  if (err == EINVAL)
+	    gomp_error ("Stack size larger than system limit");
+	  else if (err != 0)
+	    gomp_error ("Stack size change failed: %s", strerror (err));
+	}
+    }
 }
 
 
=== libgomp.h
==================================================================
--- libgomp.h	(revision 114503)
+++ libgomp.h	(local)
@@ -237,12 +237,15 @@
 /* These are the OpenMP 2.5 internal control variables described in
    section 2.3.  At least those that correspond to environment variables.  */
 
-extern unsigned gomp_nthreads_var;
+extern unsigned long gomp_nthreads_var;
 extern bool gomp_dyn_var;
 extern bool gomp_nest_var;
 extern enum gomp_schedule_type gomp_run_sched_var;
-extern unsigned gomp_run_sched_chunk;
+extern unsigned long gomp_run_sched_chunk;
 
+/* The attributes to be used during thread creation.  */
+extern pthread_attr_t gomp_thread_attr;
+
 /* Function prototypes.  */
 
 /* alloc.c */
=== team.c
==================================================================
--- team.c	(revision 114503)
+++ team.c	(local)
@@ -39,7 +39,7 @@
 static unsigned gomp_threads_used;
 
 /* This attribute contains PTHREAD_CREATE_DETACHED.  */
-static pthread_attr_t gomp_thread_attr;
+pthread_attr_t gomp_thread_attr;
 
 /* This barrier holds and releases threads waiting in gomp_threads.  */
 static gomp_barrier_t gomp_threads_dock;
@@ -338,7 +338,4 @@
   thr = &initial_thread_tls_data;
 #endif
   gomp_sem_init (&thr->release, 0);
-
-  pthread_attr_init (&gomp_thread_attr);
-  pthread_attr_setdetachstate (&gomp_thread_attr, PTHREAD_CREATE_DETACHED);
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]