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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
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);
}
|