Partially sync files.el from XEmacs 21.5 for wildcard support.
[sxemacs] / src / mem / vm-limit.c
1 /* Functions for memory limit warnings.
2    Copyright (C) 1990, 1992 Free Software Foundation, Inc.
3
4 This file is part of SXEmacs
5
6 SXEmacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 SXEmacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
18
19
20 /* Synched up with: FSF 19.30. */
21
22 #ifdef emacs
23 #include <config.h>
24 #include "lisp.h"
25 #endif
26
27 #include <stddef.h>
28 #ifndef emacs
29 typedef size_t SIZE;
30 typedef void *POINTER;
31 #define EXCEEDS_LISP_PTR(x) 0
32 #endif
33
34 #include "mem-limits.h"
35
36 #if !defined _NO_MALLOC_WARNING_
37 /*
38   Level number of warnings already issued.
39   0 -- no warnings issued.
40   1 -- 75% warning already issued.
41   2 -- 85% warning already issued.
42   3 -- 95% warning issued; keep warning frequently.
43 */
44 static int warnlevel;
45
46 /* Function to call to issue a warning;
47    0 means don't issue them.  */
48 static void (*warn_function) (const char *);
49
50 /* Get more memory space, complaining if we're near the end. */
51 static void check_memory_limits(void)
52 {
53         extern POINTER(*__morecore) (ptrdiff_t size);
54
55         POINTER cp;
56         unsigned long five_percent;
57         unsigned long data_size;
58         void (*save_warn_fun) (const char *);
59
60         if (lim_data == 0)
61                 get_lim_data();
62         five_percent = lim_data / 20;
63
64         /* Find current end of memory and issue warning if getting near max */
65         cp = (char *)(*__morecore) (0);
66         data_size = (char *)cp - (char *)data_space_start;
67
68         if (warn_function) {
69                 /* temporarily reset the warn_function to 0 or we will get infinite
70                    looping. */
71                 save_warn_fun = warn_function;
72                 warn_function = 0;
73                 switch (warnlevel) {
74                 case 0:
75                         if (data_size > five_percent * 15) {
76                                 warnlevel++;
77                                 (*save_warn_fun)
78                                     ("Warning: past 75% of memory limit");
79                         }
80                         break;
81
82                 case 1:
83                         if (data_size > five_percent * 17) {
84                                 warnlevel++;
85                                 (*save_warn_fun)
86                                     ("Warning: past 85% of memory limit");
87                         }
88                         break;
89
90                 case 2:
91                         if (data_size > five_percent * 19) {
92                                 warnlevel++;
93                                 (*save_warn_fun)
94                                     ("Warning: past 95% of memory limit");
95                         }
96                         break;
97
98                 default:
99                         (*save_warn_fun)
100                             ("Warning: past acceptable memory limits");
101                         break;
102                 }
103                 warn_function = save_warn_fun;
104         }
105
106         /* If we go down below 70% full, issue another 75% warning
107            when we go up again.  */
108         if (data_size < five_percent * 14)
109                 warnlevel = 0;
110         /* If we go down below 80% full, issue another 85% warning
111            when we go up again.  */
112         else if (warnlevel > 1 && data_size < five_percent * 16)
113                 warnlevel = 1;
114         /* If we go down below 90% full, issue another 95% warning
115            when we go up again.  */
116         else if (warnlevel > 2 && data_size < five_percent * 18)
117                 warnlevel = 2;
118
119         if (EXCEEDS_LISP_PTR(cp)) {
120                 if (warn_function) {
121                         /* temporarily reset the warn_function to 0 or we will get infinite
122                            looping. */
123                         save_warn_fun = warn_function;
124                         warn_function = 0;
125                         (*save_warn_fun)
126                             ("Warning: memory in use exceeds lisp pointer size");
127                         warn_function = save_warn_fun;
128                 }
129         }
130 }
131 #endif  /* !_NO_MALLOC_WARNING_ */
132
133 /* Cause reinitialization based on job parameters;
134    also declare where the end of pure storage is. */
135
136 void memory_warnings(void *start, void (*warnfun) (const char *))
137 {
138 #ifndef _NO_MALLOC_WARNING_
139         extern void (*__after_morecore_hook) (void);    /* From gmalloc.c */
140 #endif
141
142         if (start)
143                 data_space_start = (char *)start;
144         else
145                 data_space_start = start_of_data();
146
147 #if !defined _NO_MALLOC_WARNING_
148         warn_function = warnfun;
149         __after_morecore_hook = check_memory_limits;
150 #endif
151 }