File: zawset.c

package info (click to toggle)
iraf 2.17-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 95,288 kB
  • sloc: ansic: 228,894; fortran: 75,606; lisp: 18,369; xml: 8,401; sh: 6,111; yacc: 5,648; lex: 596; makefile: 575; asm: 153; csh: 95; sed: 4
file content (127 lines) | stat: -rw-r--r-- 3,733 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>

#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;


/* 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;

	unsigned int working_set_size;
	struct rlimit rlp;


	/* 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);

	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);
	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);
}