source: branches/libc-0.6/src/emx/src/lib/malloc/imisc.c@ 2685

Last change on this file since 2685 was 2685, checked in by bird, 20 years ago

Inlined _um_find_bucket.

  • Property cvs2svn:cvs-rev set to 1.5
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 4.1 KB
Line 
1/* imisc.c (emx+gcc) -- Copyright (c) 1996 by Eberhard Mattes */
2
3#include "libc-alias.h"
4#include <stdlib.h>
5#include <stddef.h>
6#include <assert.h>
7#include <umalloc.h>
8#include <sys/builtin.h> /* For <sys/fmutex.h> */
9#include <sys/fmutex.h>
10#include <emx/umalloc.h>
11
12
13static __inline__ void _um_lump_link_bucket (struct _um_bucket *bucket,
14 struct _um_lump *lump)
15{
16 lump->x.free.prev = NULL;
17 if (bucket->head != NULL)
18 bucket->head->x.free.prev = lump;
19 else
20 bucket->tail = lump;
21 lump->x.free.next = bucket->head;
22 bucket->head = lump;
23}
24
25
26void _um_lump_unlink_bucket (struct _um_bucket *bucket, struct _um_lump *lump)
27{
28 if (lump->x.free.prev == NULL)
29 bucket->head = lump->x.free.next;
30 else
31 lump->x.free.prev->x.free.next = lump->x.free.next;
32 if (lump->x.free.next == NULL)
33 bucket->tail = lump->x.free.prev;
34 else
35 lump->x.free.next->x.free.prev = lump->x.free.prev;
36}
37
38
39void _um_lump_unlink_heap (Heap_t h, struct _um_lump *lump)
40{
41 size_t rsize;
42 int bucket;
43
44 rsize = _UM_ROUND_LUMP (lump->size);
45 bucket = _um_find_bucket (rsize);
46 _um_lump_unlink_bucket (&h->buckets[bucket], lump);
47}
48
49
50void _um_lump_link_heap (Heap_t h, struct _um_lump *lump)
51{
52 size_t rsize;
53 int bucket_number;
54
55 rsize = _UM_ROUND_LUMP (lump->size);
56 bucket_number = _um_find_bucket (rsize);
57 _um_lump_link_bucket (&h->buckets[bucket_number], lump);
58}
59
60
61/* Turn uninitialized memory into a free lump. RSIZE is the rounded
62 total size, including `struct _um_lump' and the size word at the
63 end. This function does not coalesce the new lump with neighboring
64 free lumps, therefore the segment need not be in a consistent
65 state. */
66
67void _um_lump_make_free (Heap_t h, struct _um_lump *lump,
68 struct _um_seg *seg, size_t rsize)
69{
70 int bucket_number;
71
72 assert (_UM_IS_ALIGNED (seg, _UM_PARENT_ALIGN));
73 assert (rsize % _UM_PAGE_SIZE == 0);
74 lump->parent_seg = _UMINT_FROM_PTR (seg) | _UMS_FREE;
75 _um_lump_set_size (lump, rsize - _UM_LUMP_OVERHEAD);
76
77 bucket_number = _um_find_bucket (rsize);
78 _um_lump_link_bucket (&h->buckets[bucket_number], lump);
79}
80
81
82/* Turn uninitialized memory into a free lump. RSIZE is the rounded
83 total size, including `struct _um_lump' and the size word at the
84 end. This function attempts to coalesce the new lump with
85 neighboring free lumps. Note that the segment must be in a
86 consistent state (except for the free lump to be created). */
87
88void _um_lump_coalesce_free (Heap_t h, struct _um_lump *lump,
89 struct _um_seg *seg, size_t rsize)
90{
91 assert (_UM_IS_ALIGNED (seg, _UM_PARENT_ALIGN));
92 assert (rsize % _UM_PAGE_SIZE == 0);
93 lump->parent_seg = _UMINT_FROM_PTR (seg) | _UMS_FREE;
94 _um_lump_set_size (lump, rsize - _UM_LUMP_OVERHEAD);
95
96 /* Coalesce with preceding free lump, if possible. */
97
98 if (!_UM_FIRST_LUMP (seg, lump))
99 {
100 struct _um_lump *prev = _UM_PREV_LUMP (lump);
101 if (_UM_LUMP_STATUS (prev) == _UMS_FREE)
102 {
103 _um_lump_unlink_heap (h, prev);
104 assert (_UM_IS_ALIGNED (seg, _UM_PARENT_ALIGN));
105 prev->parent_seg = _UMINT_FROM_PTR (seg) | _UMS_FREE;
106
107 /* It's important to round at least one of the sizes,
108 otherwise the sum might become too short. */
109
110 _um_lump_set_size (prev, (_UM_ROUND_LUMP (lump->size)
111 + _UM_ROUND_LUMP (prev->size)
112 - _UM_LUMP_OVERHEAD));
113 lump = prev;
114 }
115 }
116
117 /* Coalesce with succeeding free lump, if possible. */
118
119 if (!_UM_LAST_LUMP (seg, lump))
120 {
121 struct _um_lump *next = _UM_NEXT_LUMP (lump);
122 if (_UM_LUMP_STATUS (next) == _UMS_FREE)
123 {
124 _um_lump_unlink_heap (h, next);
125
126 /* It's important to round at least one of the sizes,
127 otherwise the sum might become too short. */
128
129 _um_lump_set_size (lump, (_UM_ROUND_LUMP (lump->size)
130 + _UM_ROUND_LUMP (next->size)
131 - _UM_LUMP_OVERHEAD));
132 }
133 }
134
135 _um_lump_link_heap (h, lump);
136}
137
Note: See TracBrowser for help on using the repository browser.