aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code/boot.c
diff options
context:
space:
mode:
authorNick Barnes2001-10-31 14:40:56 +0000
committerNick Barnes2001-10-31 14:40:56 +0000
commit7acfca905d76140f4cc0b09c9a12de237de364cd (patch)
tree3ed8babfa3a73d30f29e08ca5d5adcda4ca4e826 /mps/code/boot.c
parentb7ce4893f9902d57cd67ac9a92fa6c3d5a8fc833 (diff)
downloademacs-7acfca905d76140f4cc0b09c9a12de237de364cd.tar.gz
emacs-7acfca905d76140f4cc0b09c9a12de237de364cd.zip
Branch imports for masters.
Copied from Perforce Change: 23678 ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code/boot.c')
-rw-r--r--mps/code/boot.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/mps/code/boot.c b/mps/code/boot.c
new file mode 100644
index 00000000000..7888c8e381e
--- /dev/null
+++ b/mps/code/boot.c
@@ -0,0 +1,125 @@
1/* impl.c.boot: BOOTSTRAP ALLOCATOR
2 *
3 * $HopeName: MMsrc!boot.c(MMdevel_pekka_locus.2) $
4 * Copyright (C) 1999 Harlequin Limited. All rights reserved.
5 *
6 * .overview: A structure and protocols for allocating memory from a
7 * given block. Very simple, it basically just increments a pointer.
8 *
9 * .boot.c: The Bootstrap Allocator is used to allocate C structures
10 * for use in the implementation, not client objects. Therefore,
11 * we use "C types" (void *, size_t) not "client types" (Addr, Size).
12 */
13
14#include "boot.h"
15#include "mpm.h"
16
17SRCID(boot, "$HopeName: MMsrc!boot.c(MMdevel_pekka_locus.2) $");
18
19
20#define BootBlockSig ((Sig)0x519B002B) /* SIGnature BOOT Block */
21
22
23/* BootBlockCheck -- check a BootBlock structure */
24
25Bool BootBlockCheck(BootBlock boot)
26{
27 CHECKS(BootBlock, boot);
28 CHECKL(boot->base != NULL);
29 CHECKL(boot->alloc != NULL);
30 CHECKL(boot->limit != NULL);
31 CHECKL(boot->base <= boot->alloc);
32 CHECKL(boot->alloc <= boot->limit);
33 CHECKL(boot->alloc < boot->limit);
34
35 return TRUE;
36}
37
38
39/* BootBlockInit -- initialize a BootBlock
40 *
41 * boot: a pointer to the structure to be initialized
42 * (must have been allocated by the caller, probably on the stack).
43 * base: a pointer to the base of the memory to be allocated from
44 * from (the memory need not be committed)
45 * limit: a pointer to the limit of the memory to be allocated from
46 */
47
48Res BootBlockInit(BootBlockStruct *boot, void *base, void *limit)
49{
50 /* Can't check boot as we are supposed to be initializing it */
51 AVER(boot != NULL);
52 AVER(base != NULL);
53 AVER(limit != NULL);
54 AVER(base < limit);
55
56 boot->base = base;
57 boot->alloc = base;
58 boot->limit = limit;
59 boot->sig = BootBlockSig;
60
61 AVERT(BootBlock, boot);
62 return ResOK;
63}
64
65
66/* BootBlockFinish -- finish a BootBlock structure */
67
68void BootBlockFinish(BootBlock boot)
69{
70 AVERT(BootBlock, boot);
71
72 boot->base = boot->alloc = boot->limit = NULL;
73 boot->sig = SigInvalid;
74}
75
76
77/* BootAllocated
78 *
79 * Returns the total amount allocated using this descriptor
80 */
81size_t BootAllocated(BootBlock boot)
82{
83 AVERT(BootBlock, boot);
84
85 return PointerOffset(boot->base, boot->alloc);
86}
87
88
89/* BootAlloc -- allocate from BootBlock structure
90 *
91 * preturn: The returned pointer, see .boot.c.
92 * boot: must have been initialized with BootBlockInit().
93 * size: size of requested object, see .boot.c.
94 * align: required alignment of object, see .boot.c.
95 */
96
97Res BootAlloc(void **pReturn, BootBlock boot, size_t size, size_t align)
98{
99 void *blockBase, *blockLimit; /* base, limit of candidate block */
100
101 AVER(pReturn != NULL);
102 AVERT(BootBlock, boot);
103 AVER(size > 0);
104 AVER(AlignCheck((Align)align));
105
106 /* Align alloc pointer up and bounds check. */
107 blockBase = PointerAlignUp(boot->alloc, align);
108 if(boot->limit <= blockBase || blockBase < boot->alloc) {
109 return ResMEMORY;
110 }
111 blockLimit = PointerAdd(blockBase, size);
112 /* Following checks that the ordering constraint holds: */
113 /* boot->alloc <= blockBase < blockLimit <= boot->limit */
114 /* (if it doesn't hold then something overallocated/wrapped round) */
115 if(blockBase < boot->alloc ||
116 blockLimit <= blockBase ||
117 boot->limit < blockLimit) {
118 return ResMEMORY;
119 }
120
121 /* Fits! So allocate it */
122 boot->alloc = blockLimit;
123 *pReturn = blockBase;
124 return ResOK;
125}