1 | /* Record manager routines */ |
---|
2 | |
---|
3 | |
---|
4 | #include "memint.h" |
---|
5 | |
---|
6 | |
---|
7 | #define ALLOC_SIZE NICE_BLOCK_SIZE |
---|
8 | |
---|
9 | |
---|
10 | /* #define DEBUG_MEM */ |
---|
11 | #define MAGIC_COOKIE 0x34f21ab3l |
---|
12 | #define MAGIC_COOKIE1 0x432fa13bl |
---|
13 | |
---|
14 | |
---|
15 | struct list_ |
---|
16 | { |
---|
17 | struct list_ *next; |
---|
18 | }; |
---|
19 | |
---|
20 | typedef struct list_ *list; |
---|
21 | |
---|
22 | |
---|
23 | struct rec_mgr_ |
---|
24 | { |
---|
25 | int size; |
---|
26 | int recs_per_block; |
---|
27 | list free; |
---|
28 | list blocks; |
---|
29 | }; |
---|
30 | |
---|
31 | |
---|
32 | /* mem_new_rec(mgr) allocates a record from the specified record */ |
---|
33 | /* manager. */ |
---|
34 | |
---|
35 | pointer |
---|
36 | #if defined(__STDC__) |
---|
37 | mem_new_rec(rec_mgr mgr) |
---|
38 | #else |
---|
39 | mem_new_rec(mgr) |
---|
40 | rec_mgr mgr; |
---|
41 | #endif |
---|
42 | { |
---|
43 | int i; |
---|
44 | pointer p; |
---|
45 | list new_; |
---|
46 | |
---|
47 | if (!mgr->free) |
---|
48 | { |
---|
49 | /* Allocate a new block. */ |
---|
50 | new_=(list)mem_get_block(ALLOC_SIZE); |
---|
51 | new_->next=mgr->blocks; |
---|
52 | mgr->blocks=new_; |
---|
53 | mgr->free=(list)((INT_PTR)new_+ROUNDUP(sizeof(struct list_))); |
---|
54 | p=(pointer)(mgr->free); |
---|
55 | /* Carve the block into pieces. */ |
---|
56 | for (i=1; i < mgr->recs_per_block; ++i) |
---|
57 | { |
---|
58 | ((list)p)->next=(list)((INT_PTR)p+mgr->size); |
---|
59 | #if defined(DEBUG_MEM) |
---|
60 | if (mgr->size >= sizeof(long)+sizeof(struct list_)) |
---|
61 | *(long *)(sizeof(struct list_)+(INT_PTR)p)=MAGIC_COOKIE; |
---|
62 | #endif |
---|
63 | p=(pointer)((INT_PTR)p+mgr->size); |
---|
64 | } |
---|
65 | ((list)p)->next=0; |
---|
66 | #if defined(DEBUG_MEM) |
---|
67 | if (mgr->size >= sizeof(long)+sizeof(struct list_)) |
---|
68 | *(long *)(sizeof(struct list_)+(INT_PTR)p)=MAGIC_COOKIE; |
---|
69 | #endif |
---|
70 | } |
---|
71 | new_=mgr->free; |
---|
72 | #if defined(DEBUG_MEM) |
---|
73 | if (mgr->size >= sizeof(long)+sizeof(struct list_)) |
---|
74 | if (*(long *)(sizeof(struct list_)+(INT_PTR)new_) != MAGIC_COOKIE) |
---|
75 | fprintf(stderr, "record at 0x%lx may be in use\n", (INT_PTR)new_); |
---|
76 | else |
---|
77 | *(long *)(sizeof(struct list_)+(INT_PTR)new_)=MAGIC_COOKIE1; |
---|
78 | #endif |
---|
79 | mgr->free=mgr->free->next; |
---|
80 | return ((pointer)new_); |
---|
81 | } |
---|
82 | |
---|
83 | |
---|
84 | /* mem_free_rec(mgr, rec) frees a record managed by the indicated */ |
---|
85 | /* record manager. */ |
---|
86 | |
---|
87 | void |
---|
88 | #if defined(__STDC__) |
---|
89 | mem_free_rec(rec_mgr mgr, pointer rec) |
---|
90 | #else |
---|
91 | mem_free_rec(mgr, rec) |
---|
92 | rec_mgr mgr; |
---|
93 | pointer rec; |
---|
94 | #endif |
---|
95 | { |
---|
96 | #if defined(DEBUG_MEM) |
---|
97 | if (mgr->size >= sizeof(long)+sizeof(struct list_)) |
---|
98 | if (*(long *)(sizeof(struct list_)+(INT_PTR)rec) == MAGIC_COOKIE) |
---|
99 | fprintf(stderr, "record at 0x%lx may already be freed\n", (INT_PTR)rec); |
---|
100 | #endif |
---|
101 | ((list)rec)->next=mgr->free; |
---|
102 | #if defined(DEBUG_MEM) |
---|
103 | if (mgr->size >= sizeof(long)+sizeof(struct list_)) |
---|
104 | *(long *)(sizeof(struct list_)+(INT_PTR)rec)=MAGIC_COOKIE; |
---|
105 | #endif |
---|
106 | mgr->free=(list)rec; |
---|
107 | } |
---|
108 | |
---|
109 | |
---|
110 | /* mem_new_rec_mgr(size) creates a new record manager with the given */ |
---|
111 | /* record size. */ |
---|
112 | |
---|
113 | rec_mgr |
---|
114 | #if defined(__STDC__) |
---|
115 | mem_new_rec_mgr(int size) |
---|
116 | #else |
---|
117 | mem_new_rec_mgr(size) |
---|
118 | int size; |
---|
119 | #endif |
---|
120 | { |
---|
121 | rec_mgr mgr; |
---|
122 | |
---|
123 | if (size < sizeof(struct list_)) |
---|
124 | size=sizeof(struct list_); |
---|
125 | size=ROUNDUP(size); |
---|
126 | if (size > ALLOC_SIZE-ROUNDUP(sizeof(struct list_))) |
---|
127 | mem_fatal("mem_new_rec_mgr: record size too large"); |
---|
128 | mgr=(rec_mgr)mem_get_block((SIZE_T)sizeof(struct rec_mgr_)); |
---|
129 | mgr->size=size; |
---|
130 | mgr->recs_per_block=(ALLOC_SIZE-ROUNDUP(sizeof(struct list_)))/size; |
---|
131 | mgr->free=0; |
---|
132 | mgr->blocks=0; |
---|
133 | return (mgr); |
---|
134 | } |
---|
135 | |
---|
136 | |
---|
137 | /* mem_free_rec_mgr(mgr) frees all the storage associated with the */ |
---|
138 | /* specified record manager. */ |
---|
139 | |
---|
140 | void |
---|
141 | #if defined(__STDC__) |
---|
142 | mem_free_rec_mgr(rec_mgr mgr) |
---|
143 | #else |
---|
144 | mem_free_rec_mgr(mgr) |
---|
145 | rec_mgr mgr; |
---|
146 | #endif |
---|
147 | { |
---|
148 | list p, q; |
---|
149 | |
---|
150 | for (p=mgr->blocks; p; p=q) |
---|
151 | { |
---|
152 | q=p->next; |
---|
153 | mem_free_block((pointer)p); |
---|
154 | } |
---|
155 | mem_free_block((pointer)mgr); |
---|
156 | } |
---|