Revision: emacs@sv.gnu.org/emacs--devo--0--patch-106
[emacs.git] / src / vm-limit.c
blob48d13c323ae247959a7fedf04a74bf699dc29aea
1 /* Functions for memory limit warnings.
2 Copyright (C) 1990, 1992, 2002, 2003, 2004,
3 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 #ifdef emacs
23 #include <config.h>
24 #include "lisp.h"
25 #endif
27 #ifndef emacs
28 #include <stddef.h>
29 typedef size_t SIZE;
30 typedef void *POINTER;
31 #define EXCEEDS_LISP_PTR(x) 0
32 #endif
34 #include "mem-limits.h"
36 #ifdef HAVE_GETRLIMIT
37 #include <sys/resource.h>
38 #endif
41 Level number of warnings already issued.
42 0 -- no warnings issued.
43 1 -- 75% warning already issued.
44 2 -- 85% warning already issued.
45 3 -- 95% warning issued; keep warning frequently.
47 static int warnlevel;
49 /* Function to call to issue a warning;
50 0 means don't issue them. */
51 static void (*warn_function) ();
53 /* Get more memory space, complaining if we're near the end. */
55 static void
56 check_memory_limits ()
58 #ifdef REL_ALLOC
59 extern POINTER (*real_morecore) ();
60 #endif
61 extern POINTER (*__morecore) ();
64 register POINTER cp;
65 unsigned long five_percent;
66 unsigned long data_size;
68 #ifdef HAVE_GETRLIMIT
69 struct rlimit {
70 rlim_t rlim_cur;
71 rlim_t rlim_max;
72 } rlimit;
74 getrlimit (RLIMIT_DATA, &rlimit);
76 five_percent = rlimit.rlim_max / 20;
77 data_size = rlimit.rlim_cur;
79 #else /* not HAVE_GETRLIMIT */
81 if (lim_data == 0)
82 get_lim_data ();
83 five_percent = lim_data / 20;
85 /* Find current end of memory and issue warning if getting near max */
86 #ifdef REL_ALLOC
87 if (real_morecore)
88 cp = (char *) (*real_morecore) (0);
89 else
90 #endif
91 cp = (char *) (*__morecore) (0);
92 data_size = (char *) cp - (char *) data_space_start;
94 #endif /* not HAVE_GETRLIMIT */
96 if (warn_function)
97 switch (warnlevel)
99 case 0:
100 if (data_size > five_percent * 15)
102 warnlevel++;
103 (*warn_function) ("Warning: past 75% of memory limit");
105 break;
107 case 1:
108 if (data_size > five_percent * 17)
110 warnlevel++;
111 (*warn_function) ("Warning: past 85% of memory limit");
113 break;
115 case 2:
116 if (data_size > five_percent * 19)
118 warnlevel++;
119 (*warn_function) ("Warning: past 95% of memory limit");
121 break;
123 default:
124 (*warn_function) ("Warning: past acceptable memory limits");
125 break;
128 /* If we go down below 70% full, issue another 75% warning
129 when we go up again. */
130 if (data_size < five_percent * 14)
131 warnlevel = 0;
132 /* If we go down below 80% full, issue another 85% warning
133 when we go up again. */
134 else if (warnlevel > 1 && data_size < five_percent * 16)
135 warnlevel = 1;
136 /* If we go down below 90% full, issue another 95% warning
137 when we go up again. */
138 else if (warnlevel > 2 && data_size < five_percent * 18)
139 warnlevel = 2;
141 if (EXCEEDS_LISP_PTR (cp))
142 (*warn_function) ("Warning: memory in use exceeds lisp pointer size");
145 /* Cause reinitialization based on job parameters;
146 also declare where the end of pure storage is. */
148 void
149 memory_warnings (start, warnfun)
150 POINTER start;
151 void (*warnfun) ();
153 extern void (* __after_morecore_hook) (); /* From gmalloc.c */
155 if (start)
156 data_space_start = start;
157 else
158 data_space_start = start_of_data ();
160 warn_function = warnfun;
161 __after_morecore_hook = check_memory_limits;
163 #ifdef WINDOWSNT
164 /* Force data limit to be recalculated on each run. */
165 lim_data = 0;
166 #endif
169 /* arch-tag: eab04eda-1f69-447a-8d9f-95f0a3983ca5
170 (do not change this comment) */