annotate src/malloc.c @ 665:fdefd0186b75

[xemacs-hg @ 2001-09-20 06:28:42 by ben] The great integral types renaming. The purpose of this is to rationalize the names used for various integral types, so that they match their intended uses and follow consist conventions, and eliminate types that were not semantically different from each other. The conventions are: -- All integral types that measure quantities of anything are signed. Some people disagree vociferously with this, but their arguments are mostly theoretical, and are vastly outweighed by the practical headaches of mixing signed and unsigned values, and more importantly by the far increased likelihood of inadvertent bugs: Because of the broken "viral" nature of unsigned quantities in C (operations involving mixed signed/unsigned are done unsigned, when exactly the opposite is nearly always wanted), even a single error in declaring a quantity unsigned that should be signed, or even the even more subtle error of comparing signed and unsigned values and forgetting the necessary cast, can be catastrophic, as comparisons will yield wrong results. -Wsign-compare is turned on specifically to catch this, but this tends to result in a great number of warnings when mixing signed and unsigned, and the casts are annoying. More has been written on this elsewhere. -- All such quantity types just mentioned boil down to EMACS_INT, which is 32 bits on 32-bit machines and 64 bits on 64-bit machines. This is guaranteed to be the same size as Lisp objects of type `int', and (as far as I can tell) of size_t (unsigned!) and ssize_t. The only type below that is not an EMACS_INT is Hashcode, which is an unsigned value of the same size as EMACS_INT. -- Type names should be relatively short (no more than 10 characters or so), with the first letter capitalized and no underscores if they can at all be avoided. -- "count" == a zero-based measurement of some quantity. Includes sizes, offsets, and indexes. -- "bpos" == a one-based measurement of a position in a buffer. "Charbpos" and "Bytebpos" count text in the buffer, rather than bytes in memory; thus Bytebpos does not directly correspond to the memory representation. Use "Membpos" for this. -- "Char" refers to internal-format characters, not to the C type "char", which is really a byte. -- For the actual name changes, see the script below. I ran the following script to do the conversion. (NOTE: This script is idempotent. You can safely run it multiple times and it will not screw up previous results -- in fact, it will do nothing if nothing has changed. Thus, it can be run repeatedly as necessary to handle patches coming in from old workspaces, or old branches.) There are two tags, just before and just after the change: `pre-integral-type-rename' and `post-integral-type-rename'. When merging code from the main trunk into a branch, the best thing to do is first merge up to `pre-integral-type-rename', then apply the script and associated changes, then merge from `post-integral-type-change' to the present. (Alternatively, just do the merging in one operation; but you may then have a lot of conflicts needing to be resolved by hand.) Script `fixtypes.sh' follows: ----------------------------------- cut ------------------------------------ files="*.[ch] s/*.h m/*.h config.h.in ../configure.in Makefile.in.in ../lib-src/*.[ch] ../lwlib/*.[ch]" gr Memory_Count Bytecount $files gr Lstream_Data_Count Bytecount $files gr Element_Count Elemcount $files gr Hash_Code Hashcode $files gr extcount bytecount $files gr bufpos charbpos $files gr bytind bytebpos $files gr memind membpos $files gr bufbyte intbyte $files gr Extcount Bytecount $files gr Bufpos Charbpos $files gr Bytind Bytebpos $files gr Memind Membpos $files gr Bufbyte Intbyte $files gr EXTCOUNT BYTECOUNT $files gr BUFPOS CHARBPOS $files gr BYTIND BYTEBPOS $files gr MEMIND MEMBPOS $files gr BUFBYTE INTBYTE $files gr MEMORY_COUNT BYTECOUNT $files gr LSTREAM_DATA_COUNT BYTECOUNT $files gr ELEMENT_COUNT ELEMCOUNT $files gr HASH_CODE HASHCODE $files ----------------------------------- cut ------------------------------------ `fixtypes.sh' is a Bourne-shell script; it uses 'gr': ----------------------------------- cut ------------------------------------ #!/bin/sh # Usage is like this: # gr FROM TO FILES ... # globally replace FROM with TO in FILES. FROM and TO are regular expressions. # backup files are stored in the `backup' directory. from="$1" to="$2" shift 2 echo ${1+"$@"} | xargs global-replace "s/$from/$to/g" ----------------------------------- cut ------------------------------------ `gr' in turn uses a Perl script to do its real work, `global-replace', which follows: ----------------------------------- cut ------------------------------------ : #-*- Perl -*- ### global-modify --- modify the contents of a file by a Perl expression ## Copyright (C) 1999 Martin Buchholz. ## Copyright (C) 2001 Ben Wing. ## Authors: Martin Buchholz <martin@xemacs.org>, Ben Wing <ben@xemacs.org> ## Maintainer: Ben Wing <ben@xemacs.org> ## Current Version: 1.0, May 5, 2001 # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with XEmacs; see the file COPYING. If not, write to the Free # Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. eval 'exec perl -w -S $0 ${1+"$@"}' if 0; use strict; use FileHandle; use Carp; use Getopt::Long; use File::Basename; (my $myName = $0) =~ s@.*/@@; my $usage=" Usage: $myName [--help] [--backup-dir=DIR] [--line-mode] [--hunk-mode] PERLEXPR FILE ... Globally modify a file, either line by line or in one big hunk. Typical usage is like this: [with GNU print, GNU xargs: guaranteed to handle spaces, quotes, etc. in file names] find . -name '*.[ch]' -print0 | xargs -0 $0 's/\bCONST\b/const/g'\n [with non-GNU print, xargs] find . -name '*.[ch]' -print | xargs $0 's/\bCONST\b/const/g'\n The file is read in, either line by line (with --line-mode specified) or in one big hunk (with --hunk-mode specified; it's the default), and the Perl expression is then evalled with \$_ set to the line or hunk of text, including the terminating newline if there is one. It should destructively modify the value there, storing the changed result in \$_. Files in which any modifications are made are backed up to the directory specified using --backup-dir, or to `backup' by default. To disable this, use --backup-dir= with no argument. Hunk mode is the default because it is MUCH MUCH faster than line-by-line. Use line-by-line only when it matters, e.g. you want to do a replacement only once per line (the default without the `g' argument). Conversely, when using hunk mode, *ALWAYS* use `g'; otherwise, you will only make one replacement in the entire file! "; my %options = (); $Getopt::Long::ignorecase = 0; &GetOptions ( \%options, 'help', 'backup-dir=s', 'line-mode', 'hunk-mode', ); die $usage if $options{"help"} or @ARGV <= 1; my $code = shift; die $usage if grep (-d || ! -w, @ARGV); sub SafeOpen { open ((my $fh = new FileHandle), $_[0]); confess "Can't open $_[0]: $!" if ! defined $fh; return $fh; } sub SafeClose { close $_[0] or confess "Can't close $_[0]: $!"; } sub FileContents { my $fh = SafeOpen ("< $_[0]"); my $olddollarslash = $/; local $/ = undef; my $contents = <$fh>; $/ = $olddollarslash; return $contents; } sub WriteStringToFile { my $fh = SafeOpen ("> $_[0]"); binmode $fh; print $fh $_[1] or confess "$_[0]: $!\n"; SafeClose $fh; } foreach my $file (@ARGV) { my $changed_p = 0; my $new_contents = ""; if ($options{"line-mode"}) { my $fh = SafeOpen $file; while (<$fh>) { my $save_line = $_; eval $code; $changed_p = 1 if $save_line ne $_; $new_contents .= $_; } } else { my $orig_contents = $_ = FileContents $file; eval $code; if ($_ ne $orig_contents) { $changed_p = 1; $new_contents = $_; } } if ($changed_p) { my $backdir = $options{"backup-dir"}; $backdir = "backup" if !defined ($backdir); if ($backdir) { my ($name, $path, $suffix) = fileparse ($file, ""); my $backfulldir = $path . $backdir; my $backfile = "$backfulldir/$name"; mkdir $backfulldir, 0755 unless -d $backfulldir; print "modifying $file (original saved in $backfile)\n"; rename $file, $backfile; } WriteStringToFile ($file, $new_contents); } } ----------------------------------- cut ------------------------------------ In addition to those programs, I needed to fix up a few other things, particularly relating to the duplicate definitions of types, now that some types merged with others. Specifically: 1. in lisp.h, removed duplicate declarations of Bytecount. The changed code should now look like this: (In each code snippet below, the first and last lines are the same as the original, as are all lines outside of those lines. That allows you to locate the section to be replaced, and replace the stuff in that section, verifying that there isn't anything new added that would need to be kept.) --------------------------------- snip ------------------------------------- /* Counts of bytes or chars */ typedef EMACS_INT Bytecount; typedef EMACS_INT Charcount; /* Counts of elements */ typedef EMACS_INT Elemcount; /* Hash codes */ typedef unsigned long Hashcode; /* ------------------------ dynamic arrays ------------------- */ --------------------------------- snip ------------------------------------- 2. in lstream.h, removed duplicate declaration of Bytecount. Rewrote the comment about this type. The changed code should now look like this: --------------------------------- snip ------------------------------------- #endif /* The have been some arguments over the what the type should be that specifies a count of bytes in a data block to be written out or read in, using Lstream_read(), Lstream_write(), and related functions. Originally it was long, which worked fine; Martin "corrected" these to size_t and ssize_t on the grounds that this is theoretically cleaner and is in keeping with the C standards. Unfortunately, this practice is horribly error-prone due to design flaws in the way that mixed signed/unsigned arithmetic happens. In fact, by doing this change, Martin introduced a subtle but fatal error that caused the operation of sending large mail messages to the SMTP server under Windows to fail. By putting all values back to be signed, avoiding any signed/unsigned mixing, the bug immediately went away. The type then in use was Lstream_Data_Count, so that it be reverted cleanly if a vote came to that. Now it is Bytecount. Some earlier comments about why the type must be signed: This MUST BE SIGNED, since it also is used in functions that return the number of bytes actually read to or written from in an operation, and these functions can return -1 to signal error. Note that the standard Unix read() and write() functions define the count going in as a size_t, which is UNSIGNED, and the count going out as an ssize_t, which is SIGNED. This is a horrible design flaw. Not only is it highly likely to lead to logic errors when a -1 gets interpreted as a large positive number, but operations are bound to fail in all sorts of horrible ways when a number in the upper-half of the size_t range is passed in -- this number is unrepresentable as an ssize_t, so code that checks to see how many bytes are actually written (which is mandatory if you are dealing with certain types of devices) will get completely screwed up. --ben */ typedef enum lstream_buffering --------------------------------- snip ------------------------------------- 3. in dumper.c, there are four places, all inside of switch() statements, where XD_BYTECOUNT appears twice as a case tag. In each case, the two case blocks contain identical code, and you should *REMOVE THE SECOND* and leave the first.
author ben
date Thu, 20 Sep 2001 06:31:11 +0000
parents b39c14581166
children 13e47461d509
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 /* dynamic memory allocation for GNU.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2 Copyright (C) 1985, 1987 Free Software Foundation, Inc.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4 NO WARRANTY
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
6 BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
7 NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8 WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
9 RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10 WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12 FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14 DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15 CORRECTION.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18 STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19 WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20 LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21 OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22 USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
23 DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24 A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25 PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26 DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
27
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
28 GENERAL PUBLIC LICENSE TO COPY
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
29
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
30 1. You may copy and distribute verbatim copies of this source file
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31 as you receive it, in any medium, provided that you conspicuously and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32 appropriately publish on each copy a valid copyright notice "Copyright
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33 (C) 1985 Free Software Foundation, Inc."; and include following the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34 copyright notice a verbatim copy of the above disclaimer of warranty
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35 and of this License. You may charge a distribution fee for the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36 physical act of transferring a copy.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
37
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38 2. You may modify your copy or copies of this source file or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39 any portion of it, and copy and distribute such modifications under
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40 the terms of Paragraph 1 above, provided that you also do the following:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42 a) cause the modified files to carry prominent notices stating
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
43 that you changed the files and the date of any change; and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 b) cause the whole of any work that you distribute or publish,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46 that in whole or in part contains or is a derivative of this
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47 program or any part thereof, to be licensed at no charge to all
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 third parties on terms identical to those contained in this
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49 License Agreement (except that you may choose to grant more extensive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50 warranty protection to some or all third parties, at your option).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52 c) You may charge a distribution fee for the physical act of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
53 transferring a copy, and you may at your option offer warranty
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
54 protection in exchange for a fee.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56 Mere aggregation of another unrelated program with this program (or its
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
57 derivative) on a volume of a storage or distribution medium does not bring
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58 the other program under the scope of these terms.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
59
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60 3. You may copy and distribute this program (or a portion or derivative
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
61 of it, under Paragraph 2) in object code or executable form under the terms
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
62 of Paragraphs 1 and 2 above provided that you also do one of the following:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
63
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 a) accompany it with the complete corresponding machine-readable
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 source code, which must be distributed under the terms of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66 Paragraphs 1 and 2 above; or,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68 b) accompany it with a written offer, valid for at least three
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69 years, to give any third party free (except for a nominal
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
70 shipping charge) a complete machine-readable copy of the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
71 corresponding source code, to be distributed under the terms of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 Paragraphs 1 and 2 above; or,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74 c) accompany it with the information you received as to where the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75 corresponding source code may be obtained. (This alternative is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76 allowed only for noncommercial distribution and only if you
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77 received the program in object code or executable form alone.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79 For an executable file, complete source code means all the source code for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80 all modules it contains; but, as a special exception, it need not include
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81 source code for modules which are standard libraries that accompany the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82 operating system on which the executable file runs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 4. You may not copy, sublicense, distribute or transfer this program
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85 except as expressly provided under this License Agreement. Any attempt
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86 otherwise to copy, sublicense, distribute or transfer this program is void and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
87 your rights to use the program under this License agreement shall be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 automatically terminated. However, parties who have received computer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
89 software programs from you with this License Agreement will not have
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
90 their licenses terminated so long as such parties remain in full compliance.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 5. If you wish to incorporate parts of this program into other free
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93 programs whose distribution conditions are different, write to the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 MA 02111-1307, USA.. We have not yet worked out a simple rule that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 can be stated here, but we will often permit this. We will be guided
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 by the two goals of preserving the free status of all derivatives of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98 our free software and of promoting the sharing and reuse of software.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101 In other words, you are welcome to use, share and improve this program.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102 You are forbidden to forbid anyone else to use, share and improve
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103 what you give them. Help stamp out software-hoarding! */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105 /* Synched up with: Not synched with FSF. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109 * @(#)nmalloc.c 1 (Caltech) 2/21/82
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 * U of M Modified: 20 Jun 1983 ACT: strange hacks for Emacs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 * Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115 * This is a very fast storage allocator. It allocates blocks of a small
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116 * number of different sizes, and keeps free lists of each size. Blocks
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117 * that don't exactly fit are passed up to the next larger size. In this
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 * implementation, the available sizes are (2^n)-4 (or -16) bytes long.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 * This is designed for use in a program that uses vast quantities of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 * memory, but bombs when it runs out. To make it a little better, it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 * warns the user when he starts to get near the end.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123 * June 84, ACT: modified rcheck code to check the range given to malloc,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 * rather than the range determined by the 2-power used.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 * Jan 85, RMS: calls malloc_warning to issue warning on nearly full.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 * No longer Emacs-specific; can serve as all-purpose malloc for GNU.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 * You should call malloc_init to reinitialize after loading dumped Emacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 * Call malloc_stats to get info on memory stats if MSTATS turned on.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 * realloc knows how to return same block given, just changing its size,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 * if the power of 2 is correct.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 * nextf[i] is the pointer to the next free block of size 2^(i+3). The
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136 * smallest allocatable block is 8 bytes. The overhead information will
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 * go in the first int of the block, and the returned pointer will point
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 * to the second.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 #ifdef MSTATS
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 * nmalloc[i] is the difference between the number of mallocs and frees
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 * for a given block size.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 #endif MSTATS
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 #ifdef emacs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 /* config.h specifies which kind of system this is. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 #include <config.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 #else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151 /* Determine which kind of system this is. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152 #include <signal.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 #ifndef SIGTSTP
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 #ifndef USG
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 #define USG
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 #else /* SIGTSTP */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 #ifdef SIGIO
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 #define BSD4_2
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 #endif /* SIGIO */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 #endif /* SIGTSTP */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163 #if defined(hpux)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 #define USG
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 #endif /* not emacs */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 #include <stddef.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 /* Define getpagesize () if the system does not. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 #include "getpagesize.h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 #ifdef HAVE_ULIMIT_H
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175 #include <ulimit.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 #ifndef BSD4_2
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 #ifndef USG
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 #include <sys/vlimit.h> /* warn the user when near the end */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 #endif /* not USG */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182 #else /* if BSD4_2 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183 #include <sys/time.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 #include <sys/resource.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 #endif /* BSD4_2 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 #ifdef __STDC__
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 #ifndef HPUX
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 /* not sure where this for NetBSD should really go
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 and it probably applies to other systems */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 #if !defined(__NetBSD__) && !defined(__bsdi__) && !defined(__OpenBSD__)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 extern void *sbrk (ptrdiff_t);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 #else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194 extern char *sbrk ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195 #endif /* __NetBSD__ or __OpenBSD__ */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196 #endif /* HPUX */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197 #else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 extern void *sbrk ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199 #endif /* __STDC__ */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 extern char *start_of_data (void);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 #ifdef BSD
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204 #define start_of_data() &etext
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207 #ifndef emacs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 #define start_of_data() &etext
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 #define ISALLOC ((char) 0xf7) /* magic byte that implies allocation */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 #define ISFREE ((char) 0x54) /* magic byte that implies free block */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213 /* this is for error checking only */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214 #define ISMEMALIGN ((char) 0xd6) /* Stored before the value returned by
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215 memalign, with the rest of the word
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 being the distance to the true
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217 beginning of the block. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219 extern char etext;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 /* These two are for user programs to look at, when they are interested. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
223 Bytecount malloc_sbrk_used; /* amount of data space used now */
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
224 Bytecount malloc_sbrk_unused; /* amount more we can have */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 /* start of data space; can be changed by calling init_malloc */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227 static char *data_space_start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229 #ifdef MSTATS
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230 static int nmalloc[30];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 static int nmal, nfre;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232 #endif /* MSTATS */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
234 /* If range checking is not turned on, all we have is a flag indicating
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
235 whether memory is allocated, an index in nextf[], and a size field; to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
236 realloc() memory we copy either size bytes or 1<<(index+3) bytes depending
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
237 on whether the former can hold the exact size (given the value of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
238 'index'). If range checking is on, we always need to know how much space
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239 is allocated, so the 'size' field is never used. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
241 struct mhead {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
242 char mh_alloc; /* ISALLOC or ISFREE */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
243 char mh_index; /* index in nextf[] */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244 /* Remainder are valid only when block is allocated */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
245 unsigned short mh_size; /* size, if < 0x10000 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246 #ifdef rcheck
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247 unsigned mh_nbytes; /* number of bytes allocated */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
248 int mh_magic4; /* should be == MAGIC4 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
249 #endif /* rcheck */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
250 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252 /* Access free-list pointer of a block.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253 It is stored at block + 4.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
254 This is not a field in the mhead structure
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
255 because we want sizeof (struct mhead)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 to describe the overhead for when the block is in use,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
257 and we do not want the free-list pointer to count in that. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
258
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259 #define CHAIN(a) \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 (*(struct mhead **) (sizeof (char *) + (char *) (a)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262 #ifdef rcheck
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264 /* To implement range checking, we write magic values in at the beginning and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 end of each allocated block, and make sure they are undisturbed whenever a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 free or a realloc occurs. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267 /* Written in each of the 4 bytes following the block's real space */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 #define MAGIC1 0x55
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
269 /* Written in the 4 bytes before the block's real space */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270 #define MAGIC4 0x55555555
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271 #define ASSERT(p) if (!(p)) botch("p"); else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272 #define EXTRA 4 /* 4 bytes extra for MAGIC1s */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273 #else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274 #define ASSERT(p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275 #define EXTRA 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276 #endif /* rcheck */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279 /* nextf[i] is free list of blocks of size 2**(i + 3) */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
280
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
281 static struct mhead *nextf[30];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
282
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283 /* busy[i] is nonzero while allocation of block size i is in progress. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285 static char busy[30];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
287 /* Number of bytes of writable memory we can expect to be able to get */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
288 extern unsigned int lim_data;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290 /* Level number of warnings already issued.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
291 0 -- no warnings issued.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292 1 -- 75% warning already issued.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293 2 -- 85% warning already issued.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 static int warnlevel;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 /* Function to call to issue a warning;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298 0 means don't issue them. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299 static void (*warnfunction) ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 /* nonzero once initial bunch of free blocks made */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302 static int gotpool;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
304 char *_malloc_base;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 static void getpool (void);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
308 /* Cause reinitialization based on job parameters;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
309 also declare where the end of pure storage is. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
310 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311 malloc_init (start, warnfun)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312 char *start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313 void (*warnfun) ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
315 if (start)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
316 data_space_start = start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
317 lim_data = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
318 warnlevel = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
319 warnfunction = warnfun;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
320 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
321
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
322 /* Return the maximum size to which MEM can be realloc'd
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
323 without actually requiring copying. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
324
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
325 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
326 malloc_usable_size (mem)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
327 char *mem;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
328 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
329 int blocksize = 8 << (((struct mhead *) mem) - 1) -> mh_index;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
330
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
331 return blocksize - sizeof (struct mhead) - EXTRA;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
332 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
334 static void get_lim_data ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
335
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
336 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
337 morecore (nu) /* ask system for more memory */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
338 int nu; /* size index to get more of */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
339 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340 char *cp;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 int nblks;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
342 unsigned int siz;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
343 int oldmask;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
344
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345 #ifdef BSD
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 #ifndef BSD4_1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
347 /* ?? There was a suggestion not to block SIGILL, somehow for GDB's sake. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
348 oldmask = sigsetmask (-1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
349 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
350 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
351
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352 if (!data_space_start)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354 data_space_start = start_of_data ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 if (lim_data == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 get_lim_data ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360 /* On initial startup, get two blocks of each size up to 1k bytes */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361 if (!gotpool)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362 { getpool (); getpool (); gotpool = 1; }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 /* Find current end of memory and issue warning if getting near max */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366 cp = sbrk (0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 siz = cp - data_space_start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
368
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369 if (warnfunction)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
370 switch (warnlevel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
371 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
372 case 0:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373 if (siz > (lim_data / 4) * 3)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
375 warnlevel++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376 (*warnfunction) ("Warning: past 75% of memory limit");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
378 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
379 case 1:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380 if (siz > (lim_data / 20) * 17)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382 warnlevel++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383 (*warnfunction) ("Warning: past 85% of memory limit");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386 case 2:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387 if (siz > (lim_data / 20) * 19)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389 warnlevel++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 (*warnfunction) ("Warning: past 95% of memory limit");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395 if ((int) cp & 0x3ff) /* land on 1K boundaries */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396 sbrk (1024 - ((int) cp & 0x3ff));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
397
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
398 /* Take at least 2k, and figure out how many blocks of the desired size
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
399 we're about to get */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
400 nblks = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 if ((siz = nu) < 8)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
402 nblks = 1 << ((siz = 8) - nu);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
403
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
404 if ((cp = sbrk (1 << (siz + 3))) == (char *) -1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
405 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
406 #ifdef BSD
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
407 #ifndef BSD4_1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
408 sigsetmask (oldmask);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
409 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
410 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
411 return; /* no more room! */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
412 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
413 malloc_sbrk_used = siz;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
414 malloc_sbrk_unused = lim_data - siz;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
415
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
416 if ((int) cp & 7)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
417 { /* shouldn't happen, but just in case */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
418 cp = (char *) (((int) cp + 8) & ~7);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
419 nblks--;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
420 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
421
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
422 /* save new header and link the nblks blocks together */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
423 nextf[nu] = (struct mhead *) cp;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
424 siz = 1 << (nu + 3);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
425 while (1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
426 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
427 ((struct mhead *) cp) -> mh_alloc = ISFREE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
428 ((struct mhead *) cp) -> mh_index = nu;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
429 if (--nblks <= 0) break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
430 CHAIN ((struct mhead *) cp) = (struct mhead *) (cp + siz);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
431 cp += siz;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
432 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
433 CHAIN ((struct mhead *) cp) = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
434
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
435 #ifdef BSD
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
436 #ifndef BSD4_1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
437 sigsetmask (oldmask);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
438 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
439 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
440 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
441
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
442 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
443 getpool (void)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
444 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
445 int nu;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
446 char *cp = sbrk (0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
447
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
448 if ((int) cp & 0x3ff) /* land on 1K boundaries */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
449 sbrk (1024 - ((int) cp & 0x3ff));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
450
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
451 /* Record address of start of space allocated by malloc. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
452 if (_malloc_base == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
453 _malloc_base = cp;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
454
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
455 /* Get 2k of storage */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
456
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
457 cp = sbrk (04000);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
458 if (cp == (char *) -1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
459 return;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 /* Divide it into an initial 8-word block
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462 plus one block of size 2**nu for nu = 3 ... 10. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
463
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
464 CHAIN (cp) = nextf[0];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
465 nextf[0] = (struct mhead *) cp;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
466 ((struct mhead *) cp) -> mh_alloc = ISFREE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
467 ((struct mhead *) cp) -> mh_index = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
468 cp += 8;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
469
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
470 for (nu = 0; nu < 7; nu++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
472 CHAIN (cp) = nextf[nu];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
473 nextf[nu] = (struct mhead *) cp;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
474 ((struct mhead *) cp) -> mh_alloc = ISFREE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475 ((struct mhead *) cp) -> mh_index = nu;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
476 cp += 8 << nu;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
477 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
478 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
479
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
480 char *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
481 malloc (n) /* get a block */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
482 unsigned n;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
483 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
484 struct mhead *p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
485 unsigned int nbytes;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
486 int nunits = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
487
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
488 /* Figure out how many bytes are required, rounding up to the nearest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
489 multiple of 8, then figure out which nestf[] area to use.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
490 Both the beginning of the header and the beginning of the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
491 block should be on an eight byte boundary. */
647
b39c14581166 [xemacs-hg @ 2001-08-13 04:45:47 by ben]
ben
parents: 442
diff changeset
492 nbytes = (n + ((sizeof (*p) + 7) & ~7) + EXTRA + 7) & ~7;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
493 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
494 unsigned int shiftr = (nbytes - 1) >> 2;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
495
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
496 while (shiftr >>= 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
497 nunits++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
498 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
499
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
500 /* In case this is reentrant use of malloc from signal handler,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
501 pick a block size that no other malloc level is currently
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
502 trying to allocate. That's the easiest harmless way not to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
503 interfere with the other level of execution. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
504 while (busy[nunits]) nunits++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
505 busy[nunits] = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
506
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
507 /* If there are no blocks of the appropriate size, go get some */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
508 /* COULD SPLIT UP A LARGER BLOCK HERE ... ACT */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
509 if (nextf[nunits] == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
510 morecore (nunits);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
511
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
512 /* Get one block off the list, and set the new list head */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
513 if ((p = nextf[nunits]) == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
514 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
515 busy[nunits] = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
516 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
517 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
518 nextf[nunits] = CHAIN (p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
519 busy[nunits] = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
520
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
521 /* Check for free block clobbered */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
522 /* If not for this check, we would gobble a clobbered free chain ptr */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
523 /* and bomb out on the NEXT allocate of this size block */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
524 if (p -> mh_alloc != ISFREE || p -> mh_index != nunits)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
525 #ifdef rcheck
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
526 botch ("block on free list clobbered");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
527 #else /* not rcheck */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
528 abort ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
529 #endif /* not rcheck */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
530
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
531 /* Fill in the info, and if range checking, set up the magic numbers */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
532 p -> mh_alloc = ISALLOC;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533 #ifdef rcheck
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
534 p -> mh_nbytes = n;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
535 p -> mh_magic4 = MAGIC4;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
536 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
537 /* Get the location n after the beginning of the user's space. */
647
b39c14581166 [xemacs-hg @ 2001-08-13 04:45:47 by ben]
ben
parents: 442
diff changeset
538 char *m = (char *) p + ((sizeof (*p) + 7) & ~7) + n;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
539
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
540 *m++ = MAGIC1, *m++ = MAGIC1, *m++ = MAGIC1, *m = MAGIC1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
541 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
542 #else /* not rcheck */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
543 p -> mh_size = n;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
544 #endif /* not rcheck */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
545 #ifdef MSTATS
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
546 nmalloc[nunits]++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
547 nmal++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
548 #endif /* MSTATS */
647
b39c14581166 [xemacs-hg @ 2001-08-13 04:45:47 by ben]
ben
parents: 442
diff changeset
549 return (char *) p + ((sizeof (*p) + 7) & ~7);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
550 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
551
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
552 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
553 free (mem)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
554 char *mem;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
555 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
556 struct mhead *p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
557 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
558 char *ap = mem;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
559
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
560 if (ap == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
561 return;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
562
647
b39c14581166 [xemacs-hg @ 2001-08-13 04:45:47 by ben]
ben
parents: 442
diff changeset
563 p = (struct mhead *) (ap - ((sizeof (*p) + 7) & ~7));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
564 if (p -> mh_alloc == ISMEMALIGN)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
565 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
566 ap -= p->mh_size;
647
b39c14581166 [xemacs-hg @ 2001-08-13 04:45:47 by ben]
ben
parents: 442
diff changeset
567 p = (struct mhead *) (ap - ((sizeof (*p) + 7) & ~7));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
568 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
569
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
570 #ifndef rcheck
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
571 if (p -> mh_alloc != ISALLOC)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
572 abort ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
573
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
574 #else /* rcheck */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
575 if (p -> mh_alloc != ISALLOC)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
576 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
577 if (p -> mh_alloc == ISFREE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
578 botch ("free: Called with already freed block argument\n");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
579 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
580 botch ("free: Called with bad argument\n");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
581 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
582
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
583 ASSERT (p -> mh_magic4 == MAGIC4);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
584 ap += p -> mh_nbytes;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
585 ASSERT (*ap++ == MAGIC1); ASSERT (*ap++ == MAGIC1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
586 ASSERT (*ap++ == MAGIC1); ASSERT (*ap == MAGIC1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
587 #endif /* rcheck */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
588 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
589 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
590 int nunits = p -> mh_index;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
591
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
592 ASSERT (nunits <= 29);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
593 p -> mh_alloc = ISFREE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
594
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
595 /* Protect against signal handlers calling malloc. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
596 busy[nunits] = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
597 /* Put this block on the free list. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
598 CHAIN (p) = nextf[nunits];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
599 nextf[nunits] = p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
600 busy[nunits] = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
601
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
602 #ifdef MSTATS
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
603 nmalloc[nunits]--;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
604 nfre++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
605 #endif /* MSTATS */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
606 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
607 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
608
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
609 char *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
610 realloc (mem, n)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
611 char *mem;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
612 unsigned n;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
613 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
614 struct mhead *p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
615 unsigned int tocopy;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
616 unsigned int nbytes;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
617 int nunits;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
618
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
619 if (mem == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
620 return malloc (n);
647
b39c14581166 [xemacs-hg @ 2001-08-13 04:45:47 by ben]
ben
parents: 442
diff changeset
621 p = (struct mhead *) (mem - ((sizeof (*p) + 7) & ~7));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
622 nunits = p -> mh_index;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
623 ASSERT (p -> mh_alloc == ISALLOC);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
624 #ifdef rcheck
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
625 ASSERT (p -> mh_magic4 == MAGIC4);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
626 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
627 char *m = mem + (tocopy = p -> mh_nbytes);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
628 ASSERT (*m++ == MAGIC1); ASSERT (*m++ == MAGIC1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
629 ASSERT (*m++ == MAGIC1); ASSERT (*m == MAGIC1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
630 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
631 #else /* not rcheck */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
632 if (p -> mh_index >= 13)
647
b39c14581166 [xemacs-hg @ 2001-08-13 04:45:47 by ben]
ben
parents: 442
diff changeset
633 tocopy = (1 << (p -> mh_index + 3)) - ((sizeof (*p) + 7) & ~7);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
634 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
635 tocopy = p -> mh_size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
636 #endif /* not rcheck */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
637
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
638 /* See if desired size rounds to same power of 2 as actual size. */
647
b39c14581166 [xemacs-hg @ 2001-08-13 04:45:47 by ben]
ben
parents: 442
diff changeset
639 nbytes = (n + ((sizeof (*p) + 7) & ~7) + EXTRA + 7) & ~7;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
640
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
641 /* If ok, use the same block, just marking its size as changed. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
642 if (nbytes > (4 << nunits) && nbytes <= (8 << nunits))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
643 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
644 #ifdef rcheck
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
645 char *m = mem + tocopy;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
646 *m++ = 0; *m++ = 0; *m++ = 0; *m++ = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
647 p-> mh_nbytes = n;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
648 m = mem + n;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
649 *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
650 #else /* not rcheck */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
651 p -> mh_size = n;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
652 #endif /* not rcheck */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
653 return mem;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
654 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
655
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
656 if (n < tocopy)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
657 tocopy = n;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
658 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
659 char *new;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
660
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
661 if ((new = malloc (n)) == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
662 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
663 memcpy (new, mem, tocopy);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
664 free (mem);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
665 return new;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
666 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
667 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
668
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
669
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
670 char *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
671 memalign (alignment, size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
672 unsigned alignment, size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
673 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
674 char *ptr = malloc (size + alignment);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
675 char *aligned;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
676 struct mhead *p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
677
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
678 if (ptr == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
679 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
680 /* If entire block has the desired alignment, just accept it. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
681 if (((int) ptr & (alignment - 1)) == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
682 return ptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
683 /* Otherwise, get address of byte in the block that has that alignment. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
684 aligned = (char *) (((int) ptr + alignment - 1) & -alignment);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
685
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
686 /* Store a suitable indication of how to free the block,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
687 so that free can find the true beginning of it. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
688 p = (struct mhead *) aligned - 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
689 p -> mh_size = aligned - ptr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
690 p -> mh_alloc = ISMEMALIGN;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
691 return aligned;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
692 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
693
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
694 #ifndef __hpux
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
695 /* This runs into trouble with getpagesize on HPUX.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
696 Patching out seems cleaner than the ugly fix needed. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
697 char *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
698 valloc (size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
699 unsigned size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
700 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
701 return memalign (getpagesize (), size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
702 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
703 #endif /* not __hpux */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
704
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
705 #ifdef MSTATS
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
706 /* Return statistics describing allocation of blocks of size 2**n. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
707
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
708 struct mstats_value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
709 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
710 int blocksize;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
711 int nfree;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
712 int nused;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
713 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
714
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
715 struct mstats_value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
716 malloc_stats (size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
717 int size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
718 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
719 struct mstats_value v;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
720 int i;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
721 struct mhead *p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
722
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
723 v.nfree = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
724
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
725 if (size < 0 || size >= 30)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
726 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
727 v.blocksize = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
728 v.nused = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
729 return v;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
730 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
731
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
732 v.blocksize = 1 << (size + 3);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
733 v.nused = nmalloc[size];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
734
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
735 for (p = nextf[size]; p; p = CHAIN (p))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
736 v.nfree++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
737
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
738 return v;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
739 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
740 int
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
741 malloc_mem_used (void)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
742 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
743 int i;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
744 int size_used;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
745
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
746 size_used = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
747
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
748 for (i = 0; i < 30; i++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
749 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
750 int allocation_size = 1 << (i + 3);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
751 struct mhead *p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
752
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
753 size_used += nmalloc[i] * allocation_size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
754 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
755
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
756 return size_used;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
757 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
758
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
759 int
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
760 malloc_mem_free (void)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
761 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
762 int i;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
763 int size_unused;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
764
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
765 size_unused = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
766
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
767 for (i = 0; i < 30; i++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
768 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
769 int allocation_size = 1 << (i + 3);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
770 struct mhead *p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
771
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
772 for (p = nextf[i]; p ; p = CHAIN (p))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
773 size_unused += allocation_size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
774 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
775
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
776 return size_unused;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
777 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
778 #endif /* MSTATS */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
779
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
780 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
781 * This function returns the total number of bytes that the process
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
782 * will be allowed to allocate via the sbrk(2) system call. On
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
783 * BSD systems this is the total space allocatable to stack and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
784 * data. On USG systems this is the data space only.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
785 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
786
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
787 #ifdef USG
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
788
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
789 static void
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
790 get_lim_data (void)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
791 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
792 #ifdef ULIMIT_BREAK_VALUE
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
793 lim_data = ULIMIT_BREAK_VALUE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
794 #else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
795 lim_data = ulimit (3, 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
796 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
797
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
798 lim_data -= (long) data_space_start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
799 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
800
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
801 #else /* not USG */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
802 #ifndef BSD4_2
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
803
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
804 static void
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
805 get_lim_data (void)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
806 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
807 lim_data = vlimit (LIM_DATA, -1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
808 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
809
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
810 #else /* BSD4_2 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
811
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
812 static void
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
813 get_lim_data (void)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
814 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
815 struct rlimit XXrlimit;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
816
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
817 getrlimit (RLIMIT_DATA, &XXrlimit);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
818 #ifdef RLIM_INFINITY
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
819 lim_data = XXrlimit.rlim_cur & RLIM_INFINITY; /* soft limit */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
820 #else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
821 lim_data = XXrlimit.rlim_cur; /* soft limit */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
822 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
823 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
824
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
825 #endif /* BSD4_2 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
826 #endif /* not USG */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
827