Take memory from envirnoment variables; document those.
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index a54153b..6c5ed84 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -608,6 +608,8 @@
 * GFORTRAN_ERROR_BACKTRACE:: Show backtrace on run-time errors
 * GFORTRAN_FORMATTED_BUFFER_SIZE:: Buffer size for formatted files
 * GFORTRAN_UNFORMATTED_BUFFER_SIZE:: Buffer size for unformatted files
+* GFORTRAN_NUM_IMAGES:: Number of images to for -fcoarray=shared
+* GFORTRAN_SHARED_MEMORY_SIZE::  Memory for shared-memory coarrays
 @end menu
 
 @node TMPDIR
@@ -793,6 +795,35 @@
 specifies buffer size in bytes to be used for unformatted output.
 The default value is 131072.
 
+@node GFORTRAN_NUM_IMAGES
+@section @env{GFORTRAN_NUM_IMAGES}---Set number of images for shared-memory coarrays
+
+The @env{GFORTRAN_NUM_IMAGES} environment variable specifies the number
+of images to be run for shared-memory coarrays, as an integer.  The default
+value is the number of CPUs on the system.
+
+@node GFORTRAN_SHARED_MEMORY_SIZE
+@section @env{GFORTRAN_SHARED_MEMORY_SIZE}---Set size for shared-memory coarrays
+
+The @env{GFORTRAN_SHARED_MEMORY_SIZE} environment variable specifies
+the size of the shared memory block to be allocated for shared
+coarrays. It is safe on Linux and Darwin to make this larger than
+needed.  When specifying this value, keep in mind that part of the space
+will not be available to the user program because of overhead.
+
+The format is an integer, optionally followed by @code{k} or @code{K}
+for a unit of kilobytes, @code{m} or @code{M} for a unit of megabytes
+and @code{g} or @code{G} for a unit of gitabytes.
+
+For example, if the size of all coarrays is known to be smaller than
+50 megabyte, the syntax could be
+@smallexample
+$ GFORTRAN_SHARED_MEMORY_SIZE=80M ./a.out
+@end smallexample
+
+The default is 256 kilobyte for 32-bit systems and 256 gigabyte for
+64-bit systems.
+
 @c =====================================================================
 @c PART II: LANGUAGE REFERENCE
 @c =====================================================================
diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi
index 0fb7e1a..e9f89cb 100644
--- a/gcc/fortran/invoke.texi
+++ b/gcc/fortran/invoke.texi
@@ -188,7 +188,7 @@
 -fbounds-check -ftail-call-workaround -ftail-call-workaround=@var{n} @gol
 -fcheck-array-temporaries @gol
 -fcheck=@var{<all|array-temps|bits|bounds|do|mem|pointer|recursion>} @gol
--fcoarray=@var{<none|single|lib>} -fexternal-blas -ff2c @gol
+-fcoarray=@var{<none|single|lib|shared>} -fexternal-blas -ff2c @gol
 -ffrontend-loop-interchange -ffrontend-optimize @gol
 -finit-character=@var{n} -finit-integer=@var{n} -finit-local-zero @gol
 -finit-derived -finit-logical=@var{<true|false>} @gol
@@ -1607,6 +1607,13 @@
 @item @samp{lib}
 Library-based coarray parallelization; a suitable GNU Fortran coarray
 library needs to be linked.
+
+@item @samp{shared}
+This enables an experimental shared-memory implementation of
+coarrays. Expect bugs and incomplete implementation.  Currently,
+this depends on POSIX shared mutexes, so this option is not supported
+on systems which do not have them. There is no Windows implementation
+at the moment.
 @end table
 
 
diff --git a/libgfortran/caf_shared/coarraynative.c b/libgfortran/caf_shared/coarraynative.c
index 1ae0c40..cf72433 100644
--- a/libgfortran/caf_shared/coarraynative.c
+++ b/libgfortran/caf_shared/coarraynative.c
@@ -35,6 +35,7 @@
 #include <string.h>
 
 #define GFORTRAN_ENV_NUM_IMAGES "GFORTRAN_NUM_IMAGES"
+#define GFORTRAN_ENV_SHARED_MEMORY_SIZE "GFORTRAN_SHARED_MEMORY_SIZE"
 
 nca_local_data *local = NULL;
 
@@ -55,6 +56,54 @@
   return nimages;
 }
 
+/* Get the amount of memory for the shared memory block.  This is picked from
+   an environment variable.  If that is not there, pick a reasonable default.
+   Note that on a 64-bit system which allows overcommit, there is no penalty in
+   reserving a large space and then not using it.  */
+
+static size_t
+get_memory_size (void)
+{
+  char *e;
+  size_t sz = 0;
+  e = getenv (GFORTRAN_ENV_SHARED_MEMORY_SIZE);
+  if (e)
+    {
+      char *num, suffix;
+      int rv;
+      rv = sscanf (e, "%zu%1s",&sz, &suffix);
+      if (rv == 2)
+	{
+	  switch (suffix)
+	    {
+	    case 'k':
+	    case 'K':
+	      sz *= ((size_t) 1) << 10;
+	      break;
+	    case 'm':
+	    case 'M':
+	      sz *= ((size_t) 1) << 20;
+	      break;
+	    case 'g':
+	    case 'G':
+	      sz *= ((size_t) 1) << 30;
+	      break;
+	    default:
+	      sz = 0;
+	    }
+	}
+    }
+  if (sz == 0)
+    {
+      /* Use 256 MB for 32-bit systems and 256 GB for 64-bit systems.  */
+      if (sizeof (size_t) == 4)
+	sz = ((size_t) 1) << 28;
+      else
+	sz = ((size_t) 1) << 38;
+    }
+  return sz;
+}
+
 /* Get a master.  */
 
 static master *
@@ -79,6 +128,8 @@
 void
 ensure_initialization (void)
 {
+  size_t shmem_size;
+
   if (local)
     return;
 
@@ -86,8 +137,9 @@
 					    // that point? Maybe use
 					    // mmap(MAP_ANON) instead
   pagesize = sysconf (_SC_PAGE_SIZE);
+  shmem_size = round_to_pagesize (get_memory_size());
   local->total_num_images = get_environ_image_num ();
-  shared_memory_init (&local->sm);
+  shared_memory_init (&local->sm, shmem_size);
   shared_memory_prepare (&local->sm);
   if (this_image.m == NULL) /* A bit of a hack, but we
 			       need the master early.  */
diff --git a/libgfortran/caf_shared/shared_memory.c b/libgfortran/caf_shared/shared_memory.c
index 0c0b36c..bc1a2e9 100644
--- a/libgfortran/caf_shared/shared_memory.c
+++ b/libgfortran/caf_shared/shared_memory.c
@@ -186,21 +186,11 @@
    shared memory is stored at the beginning.  */
 
 void
-shared_memory_init (shared_memory_act **pmem)
+shared_memory_init (shared_memory_act **pmem, size_t initial_size)
 {
   shared_memory_act *mem;
   int fd;
 
-  /* Darwin does not appear to be able to grow shared memory segments.  Choose
-     256 GB; that will likely be enough.  If not, the ftruncate will fail
-     noisily.  */
-
-#ifdef __APPLE__
-  size_t initial_size = ((size_t) 1) << 38;
-#else
-  size_t initial_size = round_to_pagesize (sizeof (global_shared_memory_meta));
-#endif
-
   mem = malloc (get_shared_memory_act_size (1));
   fd = get_shmem_fd ();
 
diff --git a/libgfortran/caf_shared/shared_memory.h b/libgfortran/caf_shared/shared_memory.h
index 09692fc..dd03227 100644
--- a/libgfortran/caf_shared/shared_memory.h
+++ b/libgfortran/caf_shared/shared_memory.h
@@ -53,7 +53,7 @@
   ssize_t offset;
 } shared_mem_ptr;
 
-void shared_memory_init (shared_memory *);
+void shared_memory_init (shared_memory *, size_t);
 internal_proto (shared_memory_init);
 
 void shared_memory_prepare (shared_memory *);