00001
00002
00003
00004
00005
00006
00007
00008 #include "config.h"
00009
00010 #ifndef lint
00011 static const char revid[] = "$Id: db__salloc_8c-source.html,v 1.1 2008/06/08 10:18:16 sebdiaz Exp $";
00012 #endif
00013
00014 #ifndef NO_SYSTEM_INCLUDES
00015 #include <sys/types.h>
00016
00017 #include <errno.h>
00018 #include <stdlib.h>
00019 #include <string.h>
00020 #endif
00021
00022 #include "db_int.h"
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 SH_LIST_HEAD(__head);
00035 struct __data {
00036 size_t len;
00037 SH_LIST_ENTRY links;
00038 };
00039
00040
00041
00042
00043
00044
00045
00046 void
00047 CDB___db_shalloc_init(area, size)
00048 void *area;
00049 size_t size;
00050 {
00051 struct __data *elp;
00052 struct __head *hp;
00053
00054 hp = area;
00055 SH_LIST_INIT(hp);
00056
00057 elp = (struct __data *)(hp + 1);
00058 elp->len = size - sizeof(struct __head) - sizeof(elp->len);
00059 SH_LIST_INSERT_HEAD(hp, elp, links, __data);
00060 }
00061
00062
00063
00064
00065
00066
00067
00068 int
00069 CDB___db_shalloc(p, len, align, retp)
00070 void *p, *retp;
00071 size_t len, align;
00072 {
00073 struct __data *elp;
00074 size_t *sp;
00075 void *rp;
00076
00077
00078 if (len < sizeof(struct __data))
00079 len = sizeof(struct __data);
00080
00081 #ifdef DIAGNOSTIC
00082
00083 ++len;
00084 #endif
00085
00086
00087 if (align <= sizeof(db_align_t))
00088 align = sizeof(db_align_t);
00089
00090
00091 for (elp = SH_LIST_FIRST((struct __head *)p, __data);
00092 elp != NULL;
00093 elp = SH_LIST_NEXT(elp, links, __data)) {
00094
00095
00096
00097
00098
00099
00100
00101 rp = (u_int8_t *)elp + sizeof(size_t) + elp->len;
00102 rp = (u_int8_t *)rp - len;
00103 rp = (u_int8_t *)((db_alignp_t)rp & ~(align - 1));
00104
00105
00106
00107
00108
00109 if ((u_int8_t *)rp < (u_int8_t *)&elp->links)
00110 continue;
00111
00112 *(void **)retp = rp;
00113 #ifdef DIAGNOSTIC
00114
00115
00116
00117
00118
00119
00120
00121 *((u_int8_t *)elp + sizeof(size_t) + elp->len - 1) = GUARD_BYTE;
00122 #endif
00123
00124 #define SHALLOC_FRAGMENT 32
00125
00126
00127
00128
00129 if ((u_int8_t *)rp >=
00130 (u_int8_t *)&elp->links + SHALLOC_FRAGMENT) {
00131 sp = rp;
00132 *--sp = elp->len -
00133 ((u_int8_t *)rp - (u_int8_t *)&elp->links);
00134 elp->len -= *sp + sizeof(size_t);
00135 return (0);
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 #define ILLEGAL_SIZE 1
00147 SH_LIST_REMOVE(elp, links, __data);
00148 for (sp = rp; (u_int8_t *)--sp >= (u_int8_t *)&elp->links;)
00149 *sp = ILLEGAL_SIZE;
00150 return (0);
00151 }
00152
00153 return (ENOMEM);
00154 }
00155
00156
00157
00158
00159
00160
00161
00162 void
00163 CDB___db_shalloc_free(regionp, ptr)
00164 void *regionp, *ptr;
00165 {
00166 struct __data *elp, *lastp, *newp;
00167 struct __head *hp;
00168 size_t free_size, *sp;
00169 int merged;
00170
00171
00172
00173
00174
00175 for (sp = (size_t *)ptr; sp[-1] == ILLEGAL_SIZE; --sp)
00176 ;
00177 ptr = sp;
00178
00179 newp = (struct __data *)((u_int8_t *)ptr - sizeof(size_t));
00180 free_size = newp->len;
00181
00182 #ifdef DIAGNOSTIC
00183
00184
00185
00186
00187
00188
00189 if (*((u_int8_t *)ptr + free_size - 1) != GUARD_BYTE) {
00190
00191
00192
00193
00194 fprintf(stderr,
00195 "Guard byte incorrect during shared memory free.\n");
00196 abort();
00197
00198 }
00199
00200
00201 memset(ptr, CLEAR_BYTE, free_size);
00202 #endif
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 hp = (struct __head *)regionp;
00214 for (elp = SH_LIST_FIRST(hp, __data), lastp = NULL;
00215 elp != NULL && (void *)elp < (void *)ptr;
00216 lastp = elp, elp = SH_LIST_NEXT(elp, links, __data))
00217 ;
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 merged = 0;
00228 if ((u_int8_t *)ptr + free_size == (u_int8_t *)elp) {
00229 newp->len += elp->len + sizeof(size_t);
00230 SH_LIST_REMOVE(elp, links, __data);
00231 if (lastp != NULL)
00232 SH_LIST_INSERT_AFTER(lastp, newp, links, __data);
00233 else
00234 SH_LIST_INSERT_HEAD(hp, newp, links, __data);
00235 merged = 1;
00236 }
00237
00238
00239 if (lastp != NULL && (u_int8_t *)lastp +
00240 lastp->len + sizeof(size_t) == (u_int8_t *)newp) {
00241 lastp->len += newp->len + sizeof(size_t);
00242
00243
00244
00245
00246
00247
00248 if (merged)
00249 SH_LIST_REMOVE(newp, links, __data);
00250 merged = 1;
00251 }
00252
00253 if (!merged) {
00254 if (lastp == NULL)
00255 SH_LIST_INSERT_HEAD(hp, newp, links, __data);
00256 else
00257 SH_LIST_INSERT_AFTER(lastp, newp, links, __data);
00258 }
00259 }
00260
00261
00262
00263
00264
00265
00266
00267 size_t
00268 CDB___db_shalloc_count(addr)
00269 void *addr;
00270 {
00271 struct __data *elp;
00272 size_t count;
00273
00274 count = 0;
00275 for (elp = SH_LIST_FIRST((struct __head *)addr, __data);
00276 elp != NULL;
00277 elp = SH_LIST_NEXT(elp, links, __data))
00278 count += elp->len;
00279
00280 return (count);
00281 }
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 size_t
00295 CDB___db_shsizeof(ptr)
00296 void *ptr;
00297 {
00298 struct __data *elp;
00299 size_t *sp;
00300
00301
00302
00303
00304
00305 for (sp = (size_t *)ptr; sp[-1] == ILLEGAL_SIZE; --sp)
00306 ;
00307
00308 elp = (struct __data *)((u_int8_t *)sp - sizeof(size_t));
00309 return (elp->len);
00310 }
00311
00312
00313
00314
00315
00316
00317 void
00318 CDB___db_shalloc_dump(addr, fp)
00319 void *addr;
00320 FILE *fp;
00321 {
00322 struct __data *elp;
00323
00324
00325 if (fp == NULL)
00326 fp = stderr;
00327
00328 fprintf(fp, "%s\nMemory free list\n", DB_LINE);
00329
00330 for (elp = SH_LIST_FIRST((struct __head *)addr, __data);
00331 elp != NULL;
00332 elp = SH_LIST_NEXT(elp, links, __data))
00333 fprintf(fp, "%#lx: %lu\t", (u_long)elp, (u_long)elp->len);
00334 fprintf(fp, "\n");
00335 }