aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman2006-03-11 15:24:02 +0000
committerRichard M. Stallman2006-03-11 15:24:02 +0000
commit395d3972b1ffbcbe1a81052163be27345d0ca8fb (patch)
tree156d82ccf671edfe2884ca5b931c8ac3585ed691
parent02b370adb2780a76ef926b7a8f394fe32a72b7ee (diff)
downloademacs-395d3972b1ffbcbe1a81052163be27345d0ca8fb.tar.gz
emacs-395d3972b1ffbcbe1a81052163be27345d0ca8fb.zip
(get_lim_data, lim_data, data_space_start): Moved from mem-limits.h.
(enum warnlevel): New data type. (check_memory_limits): Rewrite the logic about warnings. Use standard `struct rlimit'. Check return values for nonsense. (memory_warnings): Always clear lim_data.
-rw-r--r--src/ChangeLog18
-rw-r--r--src/vm-limit.c211
2 files changed, 173 insertions, 56 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 6d7ef065cf8..e83940cecd6 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,21 @@
12006-03-11 Richard Stallman <rms@gnu.org>
2
3 * vm-limit.c (get_lim_data, lim_data, data_space_start):
4 Moved from mem-limits.h.
5 (enum warnlevel): New data type.
6 (check_memory_limits): Rewrite the logic about warnings.
7 Use standard `struct rlimit'. Check return values for nonsense.
8 (memory_warnings): Always clear lim_data.
9
10 * mem-limits.h (get_lim_data, lim_data, data_space_start):
11 Moved to vm-limit.c.
12
13 * xterm.c (x_fully_uncatch_errors, x_catching_errors): New functions.
14
15 * eval.c (unwind_to_catch): Call x_fully_uncatch_errors.
16 (internal_condition_case_1, internal_condition_case_2):
17 Abort if within unclosed x_catch_errors.
18
12006-03-11 Romain Francoise <romain@orebokech.com> 192006-03-11 Romain Francoise <romain@orebokech.com>
2 20
3 * process.c (Vprocess_adaptive_read_buffering): Doc fix. 21 * process.c (Vprocess_adaptive_read_buffering): Doc fix.
diff --git a/src/vm-limit.c b/src/vm-limit.c
index 48d13c323ae..de31eda0cec 100644
--- a/src/vm-limit.c
+++ b/src/vm-limit.c
@@ -32,6 +32,9 @@ typedef void *POINTER;
32#endif 32#endif
33 33
34#include "mem-limits.h" 34#include "mem-limits.h"
35#include <sys/resource.h>
36
37#define HAVE_GETRLIMIT
35 38
36#ifdef HAVE_GETRLIMIT 39#ifdef HAVE_GETRLIMIT
37#include <sys/resource.h> 40#include <sys/resource.h>
@@ -44,13 +47,102 @@ typedef void *POINTER;
44 2 -- 85% warning already issued. 47 2 -- 85% warning already issued.
45 3 -- 95% warning issued; keep warning frequently. 48 3 -- 95% warning issued; keep warning frequently.
46*/ 49*/
47static int warnlevel; 50enum warnlevel { not_warned, warned_75, warned_85, warned_95 };
51
52static enum warnlevel warnlevel;
48 53
49/* Function to call to issue a warning; 54/* Function to call to issue a warning;
50 0 means don't issue them. */ 55 0 means don't issue them. */
51static void (*warn_function) (); 56static void (*warn_function) ();
52 57
53/* Get more memory space, complaining if we're near the end. */ 58/* Start of data space; can be changed by calling malloc_init. */
59static POINTER data_space_start;
60
61/* Number of bytes of writable memory we can expect to be able to get. */
62static unsigned long lim_data;
63
64
65#ifdef NO_LIM_DATA
66static void
67get_lim_data ()
68{
69 lim_data = -1;
70}
71#else /* not NO_LIM_DATA */
72
73#ifdef USG
74
75static void
76get_lim_data ()
77{
78 extern long ulimit ();
79
80 lim_data = -1;
81
82 /* Use the ulimit call, if we seem to have it. */
83#if !defined (ULIMIT_BREAK_VALUE) || defined (GNU_LINUX)
84 lim_data = ulimit (3, 0);
85#endif
86
87 /* If that didn't work, just use the macro's value. */
88#ifdef ULIMIT_BREAK_VALUE
89 if (lim_data == -1)
90 lim_data = ULIMIT_BREAK_VALUE;
91#endif
92
93 lim_data -= (long) data_space_start;
94}
95
96#else /* not USG */
97#ifdef WINDOWSNT
98
99static void
100get_lim_data ()
101{
102 extern unsigned long reserved_heap_size;
103 lim_data = reserved_heap_size;
104}
105
106#else
107#if !defined (BSD4_2) && !defined (__osf__)
108
109#ifdef MSDOS
110void
111get_lim_data ()
112{
113 _go32_dpmi_meminfo info;
114
115 _go32_dpmi_get_free_memory_information (&info);
116 lim_data = info.available_memory;
117}
118#else /* not MSDOS */
119static void
120get_lim_data ()
121{
122 lim_data = vlimit (LIM_DATA, -1);
123}
124#endif /* not MSDOS */
125
126#else /* BSD4_2 */
127
128static void
129get_lim_data ()
130{
131 struct rlimit XXrlimit;
132
133 getrlimit (RLIMIT_DATA, &XXrlimit);
134#ifdef RLIM_INFINITY
135 lim_data = XXrlimit.rlim_cur & RLIM_INFINITY; /* soft limit */
136#else
137 lim_data = XXrlimit.rlim_cur; /* soft limit */
138#endif
139}
140#endif /* BSD4_2 */
141#endif /* not WINDOWSNT */
142#endif /* not USG */
143#endif /* not NO_LIM_DATA */
144
145/* Verify amount of memory available, complaining if we're near the end. */
54 146
55static void 147static void
56check_memory_limits () 148check_memory_limits ()
@@ -64,14 +156,19 @@ check_memory_limits ()
64 register POINTER cp; 156 register POINTER cp;
65 unsigned long five_percent; 157 unsigned long five_percent;
66 unsigned long data_size; 158 unsigned long data_size;
159 enum warnlevel new_warnlevel;
67 160
68#ifdef HAVE_GETRLIMIT 161#ifdef HAVE_GETRLIMIT
69 struct rlimit { 162 struct rlimit rlimit;
70 rlim_t rlim_cur; 163
71 rlim_t rlim_max; 164 getrlimit (RLIMIT_AS, &rlimit);
72 } rlimit; 165
166 if (RLIM_INFINITY == rlimit.rlim_max)
167 return;
73 168
74 getrlimit (RLIMIT_DATA, &rlimit); 169 /* This is a nonsensical case, but it happens -- rms. */
170 if (rlimit.rlim_cur > rlimit.rlim_max)
171 return;
75 172
76 five_percent = rlimit.rlim_max / 20; 173 five_percent = rlimit.rlim_max / 20;
77 data_size = rlimit.rlim_cur; 174 data_size = rlimit.rlim_cur;
@@ -93,57 +190,61 @@ check_memory_limits ()
93 190
94#endif /* not HAVE_GETRLIMIT */ 191#endif /* not HAVE_GETRLIMIT */
95 192
96 if (warn_function) 193 if (!warn_function)
97 switch (warnlevel) 194 return;
98 { 195
99 case 0: 196 /* What level of warning does current memory usage demand? */
100 if (data_size > five_percent * 15) 197 if (data_size > five_percent * 19)
101 { 198 new_warnlevel = warned_95;
102 warnlevel++; 199 else if (data_size > five_percent * 17)
103 (*warn_function) ("Warning: past 75% of memory limit"); 200 new_warnlevel = warned_85;
104 } 201 else if (data_size > five_percent * 15)
105 break; 202 new_warnlevel = warned_75;
106 203 else
107 case 1: 204 new_warnlevel = not_warned;
108 if (data_size > five_percent * 17) 205
109 { 206 /* If we have gone up a level, give the appropriate warning. */
110 warnlevel++; 207 if (new_warnlevel > warnlevel || new_warnlevel == warned_95)
111 (*warn_function) ("Warning: past 85% of memory limit"); 208 {
112 } 209 warnlevel = new_warnlevel;
113 break; 210 switch (warnlevel)
114 211 {
115 case 2: 212 case warned_75:
116 if (data_size > five_percent * 19) 213 (*warn_function) ("Warning: past 75% of memory limit");
117 { 214 break;
118 warnlevel++; 215
119 (*warn_function) ("Warning: past 95% of memory limit"); 216 case warned_85:
120 } 217 (*warn_function) ("Warning: past 85% of memory limit");
121 break; 218 break;
122 219
123 default: 220 case warned_95:
124 (*warn_function) ("Warning: past acceptable memory limits"); 221 (*warn_function) ("Warning: past 95% of memory limit");
125 break; 222 }
126 } 223 }
127 224 /* Handle going down in usage levels, with some hysteresis. */
128 /* If we go down below 70% full, issue another 75% warning 225 else
129 when we go up again. */ 226 {
130 if (data_size < five_percent * 14) 227 /* If we go down below 70% full, issue another 75% warning
131 warnlevel = 0; 228 when we go up again. */
132 /* If we go down below 80% full, issue another 85% warning 229 if (data_size < five_percent * 14)
133 when we go up again. */ 230 warnlevel = not_warned;
134 else if (warnlevel > 1 && data_size < five_percent * 16) 231 /* If we go down below 80% full, issue another 85% warning
135 warnlevel = 1; 232 when we go up again. */
136 /* If we go down below 90% full, issue another 95% warning 233 else if (warnlevel > warned_75 && data_size < five_percent * 16)
137 when we go up again. */ 234 warnlevel = warned_75;
138 else if (warnlevel > 2 && data_size < five_percent * 18) 235 /* If we go down below 90% full, issue another 95% warning
139 warnlevel = 2; 236 when we go up again. */
237 else if (warnlevel > warned_85 && data_size < five_percent * 18)
238 warnlevel = warned_85;
239 }
140 240
141 if (EXCEEDS_LISP_PTR (cp)) 241 if (EXCEEDS_LISP_PTR (cp))
142 (*warn_function) ("Warning: memory in use exceeds lisp pointer size"); 242 (*warn_function) ("Warning: memory in use exceeds lisp pointer size");
143} 243}
144 244
145/* Cause reinitialization based on job parameters; 245/* Enable memory usage warnings.
146 also declare where the end of pure storage is. */ 246 START says where the end of pure storage is.
247 WARNFUN specifies the function to call to issue a warning. */
147 248
148void 249void
149memory_warnings (start, warnfun) 250memory_warnings (start, warnfun)
@@ -160,10 +261,8 @@ memory_warnings (start, warnfun)
160 warn_function = warnfun; 261 warn_function = warnfun;
161 __after_morecore_hook = check_memory_limits; 262 __after_morecore_hook = check_memory_limits;
162 263
163#ifdef WINDOWSNT
164 /* Force data limit to be recalculated on each run. */ 264 /* Force data limit to be recalculated on each run. */
165 lim_data = 0; 265 lim_data = 0;
166#endif
167} 266}
168 267
169/* arch-tag: eab04eda-1f69-447a-8d9f-95f0a3983ca5 268/* arch-tag: eab04eda-1f69-447a-8d9f-95f0a3983ca5