Pristine Ack-5.5
[Ack-5.5.git] / lang / cem / libcc.ansi / stdlib / malloc / phys.c
1 /* $Id: phys.c,v 1.2 1994/06/24 11:55:35 ceriel Exp $ */
2 /*
3  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4  * See the copyright notice in the ACK home directory, in the file "Copyright".
5  */
6 #include        <stdlib.h>
7 #include        "param.h"
8 #include        "impl.h"
9 #include        "check.h"
10 #include        "phys.h"
11
12 /*      Physical manipulations.
13         The blocks concerned are not in any logical chain.
14 */
15
16 public mallink *
17 create_chunk(void *p, size_t n)
18 {
19         /*      The newly acquired piece of memory at p, of length n,
20                 is turned into a free chunk, properly chained in the
21                 physical chain.
22                 The address of the chunk is returned.
23         */
24         register mallink *ml;
25         /*      All of malloc memory is followed by a virtual chunk, the
26                 mallink of which starts mallink_size() bytes past the last
27                 byte in memory.
28                 Its use is prevented by testing for ml == ml_last first.
29         */
30         register mallink *last = ml_last;
31         
32         assert(!last || p == (char *)phys_next_of(last) - mallink_size());
33         ml = (mallink *)((char *)p + mallink_size());   /* bump ml */
34         new_mallink(ml);
35         started_working_on(ml);
36         set_free(ml, 1);
37         set_phys_prev(ml, last);
38         ml_last = ml;
39
40         set_phys_next(ml, (mallink *)((char *)ml + n));
41         calc_checksum(ml);
42         assert(size_of(ml) + mallink_size() == n);
43         if (last && free_of(last)) {
44                 coalesce_backw(ml, last);
45                 ml = last;
46         }
47         check_mallinks("create_chunk, phys. linked");
48         return ml;
49 }
50
51 public
52 truncate(register mallink *ml, size_t size)
53 {
54         /*      The chunk ml is truncated.
55                 The chunk at ml is split in two.
56                 The remaining part is then freed.
57         */
58         register mallink *new = (mallink *)((char *)ml + size);
59         register mallink *ph_next = phys_next_of(ml);
60
61         new_mallink(new);
62         set_free(new, 1);
63         set_phys_prev(new, ml);
64         set_phys_next(new, ph_next);
65         calc_checksum(new);
66         if (! last_mallink(ml)) {
67                 set_phys_prev(ph_next, new);
68                 calc_checksum(ph_next);
69                 if (free_of(ph_next)) coalesce_forw(new, ph_next);
70         }
71         else    ml_last = new;
72         set_phys_next(ml, new);
73         calc_checksum(ml);
74
75         started_working_on(new);
76         link_free_chunk(new);
77         stopped_working_on(new);
78         check_mallinks("truncate");
79 }
80
81 public
82 combine_chunks(register mallink *ml1, register mallink *ml2)
83 {
84         /*      The chunks ml1 and ml2 are combined.
85         */
86         register mallink *ml3 = phys_next_of(ml2);
87
88         set_phys_next(ml1, ml3);
89         calc_checksum(ml1);
90         if (!last_mallink(ml2)) {
91                 set_phys_prev(ml3, ml1);
92                 calc_checksum(ml3);
93         }
94         if (ml_last == ml2)
95                 ml_last = ml1;
96 }