aboutsummaryrefslogtreecommitdiff
path: root/unix/os/zawset.c
diff options
context:
space:
mode:
authorJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
committerJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
commit40e5a5811c6ffce9b0974e93cdd927cbcf60c157 (patch)
tree4464880c571602d54f6ae114729bf62a89518057 /unix/os/zawset.c
downloadiraf-osx-40e5a5811c6ffce9b0974e93cdd927cbcf60c157.tar.gz
Repatch (from linux) of OSX IRAF
Diffstat (limited to 'unix/os/zawset.c')
-rw-r--r--unix/os/zawset.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/unix/os/zawset.c b/unix/os/zawset.c
new file mode 100644
index 00000000..62b0ef6b
--- /dev/null
+++ b/unix/os/zawset.c
@@ -0,0 +1,154 @@
+/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+ */
+
+#ifdef SYSV
+#define NORLIMIT
+#endif
+
+#ifndef CYGWIN
+#ifdef LINUX
+#undef NORLIMIT
+#endif
+#endif
+
+#ifdef SOLARIS
+#define RLIMIT_RSS RLIMIT_VMEM
+#undef NORLIMIT
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#ifndef NORLIMIT
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+
+#define import_kernel
+#define import_knames
+#define import_spp
+#include <iraf.h>
+
+#define PCT_RESERVE 10 /* percent */
+#define MIN_RESERVE 50 /* megabytes */
+#define MIN_WORKSET 32 /* megabytes */
+
+#define ENV_DEBUG "ZAWSET_DEBUG"
+#define MB (1024*1024)
+#define KB 1024
+
+/* Kernel default working set values in bytes. */
+unsigned int defworkset = SZ_DEFWORKSET;
+unsigned int maxworkset = SZ_MAXWORKSET;
+static unsigned int max_wss = 0;
+extern char *getenv();
+
+
+/* ZAWSET -- Adjust or query the "working set", i.e., the maximum amount of
+ * physical memory allocated to the process.
+ */
+int
+ZAWSET (
+ XINT *best_size, /* requested working set size, bytes. */
+ XINT *new_size,
+ XINT *old_size, /* actual new and old sizes, bytes. */
+ XINT *max_size /* max working set size, bytes */
+)
+{
+ int physmem=0, kb_page;
+ int debug = (getenv(ENV_DEBUG) != NULL);
+ char *s, *getenv();
+
+#ifndef NORLIMIT
+ unsigned int working_set_size;
+ struct rlimit rlp;
+#endif
+
+
+ /* Get the page size in kilobytes. */
+ kb_page = getpagesize() / KB;
+
+#ifdef _SC_PHYS_PAGES
+ /* On recent POSIX systems (including Solaris, Linux, and maybe
+ * others) we can use sysconf to get the actual system memory size.
+ * The computation is done in KB to avoid integer overflow.
+ */
+ physmem = sysconf(_SC_PHYS_PAGES) * kb_page;
+ if (physmem > 0) {
+ maxworkset = min (MAX_LONG / KB, physmem);
+
+ /* Don't try to use all of physical memory. */
+ if (maxworkset == physmem) {
+ maxworkset -= (max ((MIN_RESERVE*MB)/KB,
+ physmem * PCT_RESERVE / 100));
+ if (maxworkset <= 0)
+ maxworkset = (MIN_WORKSET * MB) / KB;
+ }
+
+ /* Now convert back to bytes. */
+ maxworkset *= 1024;
+ }
+#endif
+
+ /* The hard upper limit on memory utilization defined by the unix
+ * kernel can be limited either by the value compiled into the IRAF
+ * kernel, or by the value set in the user environment variable
+ * MAXWORKSET, given in units of Mb.
+ */
+ if (!max_wss) {
+ if ( (s = getenv ("MAXWORKSET")) ) {
+ max_wss = atoi(s) * 1024*1024;
+ if (max_wss < 1024*1024)
+ max_wss = maxworkset;
+ } else
+ max_wss = maxworkset;
+ }
+
+ if (debug)
+ fprintf(stderr,"zawset: physmem=%dm, maxworkset=%dm max_wss=%dm\n",
+ physmem / KB, maxworkset / MB, max_wss / MB);
+
+#ifdef NORLIMIT
+ if (*best_size == 0)
+ *old_size = *new_size = defworkset;
+ else
+ *new_size = *old_size = min (max_wss, *best_size);
+ *max_size = max_wss;
+#else
+ getrlimit (RLIMIT_RSS, &rlp);
+ if (debug)
+ fprintf (stderr, "zawset: starting rlimit cur=%ldm, max=%ldm\n",
+ (long)(rlp.rlim_cur == RLIM_INFINITY ? 0 : rlp.rlim_cur) / MB,
+ (long)(rlp.rlim_max == RLIM_INFINITY ? 0 : rlp.rlim_max) / MB);
+
+ working_set_size = min (max_wss,
+ rlp.rlim_cur == RLIM_INFINITY ? max_wss : rlp.rlim_cur);
+
+ /* Now try to set the size requested by our caller. If bestsize was
+ * given as zero, merely return the status values.
+ */
+ (*max_size) = min (max_wss,
+ rlp.rlim_max == RLIM_INFINITY ? max_wss : rlp.rlim_max);
+
+ if (*best_size <= 0)
+ *new_size = *old_size = working_set_size;
+ else {
+ rlp.rlim_cur = min (*best_size, *max_size);
+ if (rlp.rlim_cur > working_set_size)
+ setrlimit (RLIMIT_RSS, &rlp);
+ getrlimit (RLIMIT_RSS, &rlp);
+ *old_size = working_set_size;
+ *new_size = min(*best_size, min(max_wss,
+ rlp.rlim_cur == RLIM_INFINITY ? max_wss : rlp.rlim_cur));
+ }
+ if (debug)
+ fprintf (stderr, "zawset: adjusted rlimit cur=%ldm, max=%ldm\n",
+ (long)(rlp.rlim_cur == RLIM_INFINITY ? 0 : rlp.rlim_cur) / MB,
+ (long)(rlp.rlim_max == RLIM_INFINITY ? 0 : rlp.rlim_max) / MB);
+#endif
+ if (debug)
+ fprintf (stderr, "zawset: best=%ldm old=%ldm new=%ldm max=%ldm\n",
+ (long)*best_size/MB, (long)*old_size/MB,
+ (long)*new_size/MB, (long)*max_size/MB);
+
+ return (XOK);
+}