update.
[chise/xemacs-chise.git.1] / src / 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 XEmacs.
5
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING.  If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21 /* Synched up with: FSF 19.30. */
22
23 #ifdef emacs
24 #include <config.h>
25 #include "lisp.h"
26 #endif
27
28 #include <stddef.h>
29 #ifndef emacs
30 typedef size_t SIZE;
31 typedef void *POINTER;
32 #define EXCEEDS_LISP_PTR(x) 0
33 #endif
34
35 #include "mem-limits.h"
36
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
52 static void
53 check_memory_limits (void)
54 {
55   extern POINTER (*__morecore) (ptrdiff_t size);
56
57   POINTER cp;
58   unsigned long five_percent;
59   unsigned long data_size;
60   void (*save_warn_fun) (const char *);
61
62   if (lim_data == 0)
63     get_lim_data ();
64   five_percent = lim_data / 20;
65
66   /* Find current end of memory and issue warning if getting near max */
67   cp = (char *) (*__morecore) (0);
68   data_size = (char *) cp - (char *) data_space_start;
69
70   if (warn_function)
71     {
72       /* temporarily reset the warn_function to 0 or we will get infinite
73          looping. */
74       save_warn_fun = warn_function;
75       warn_function = 0;
76       switch (warnlevel)
77         {
78         case 0:
79           if (data_size > five_percent * 15)
80             {
81               warnlevel++;
82               (*save_warn_fun) ("Warning: past 75% of memory limit");
83             }
84           break;
85
86         case 1:
87           if (data_size > five_percent * 17)
88             {
89               warnlevel++;
90               (*save_warn_fun) ("Warning: past 85% of memory limit");
91             }
92           break;
93
94         case 2:
95           if (data_size > five_percent * 19)
96             {
97               warnlevel++;
98               (*save_warn_fun) ("Warning: past 95% of memory limit");
99             }
100           break;
101
102         default:
103           (*save_warn_fun) ("Warning: past acceptable memory limits");
104           break;
105         }
106       warn_function = save_warn_fun;
107     }
108
109   /* If we go down below 70% full, issue another 75% warning
110      when we go up again.  */
111   if (data_size < five_percent * 14)
112     warnlevel = 0;
113   /* If we go down below 80% full, issue another 85% warning
114      when we go up again.  */
115   else if (warnlevel > 1 && data_size < five_percent * 16)
116     warnlevel = 1;
117   /* If we go down below 90% full, issue another 95% warning
118      when we go up again.  */
119   else if (warnlevel > 2 && data_size < five_percent * 18)
120     warnlevel = 2;
121
122   if (EXCEEDS_LISP_PTR (cp))
123     {
124       if (warn_function)
125         {
126           /* temporarily reset the warn_function to 0 or we will get infinite
127              looping. */
128           save_warn_fun = warn_function;
129           warn_function = 0;
130           (*save_warn_fun)
131             ("Warning: memory in use exceeds lisp pointer size");
132           warn_function = save_warn_fun;
133         }
134     }
135 }
136
137 /* Cause reinitialization based on job parameters;
138    also declare where the end of pure storage is. */
139
140 void
141 memory_warnings (void *start, void (*warnfun) (const char *))
142 {
143   extern void (* __after_morecore_hook) (void); /* From gmalloc.c */
144
145   if (start)
146     data_space_start = (char*) start;
147   else
148     data_space_start = start_of_data ();
149
150 #ifndef _NO_MALLOC_WARNING_
151   warn_function = warnfun;
152   __after_morecore_hook = check_memory_limits;
153 #endif
154 }