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