[e70e45] | 1 | /******************************************************************* |
---|
| 2 | * File: omBin.c |
---|
| 3 | * Purpose: definitions of routines for working with bins |
---|
| 4 | * Author: obachman (Olaf Bachmann) |
---|
| 5 | * Created: 11/99 |
---|
| 6 | *******************************************************************/ |
---|
| 7 | |
---|
[f769719] | 8 | #include <omalloc/omalloc.h> |
---|
[e70e45] | 9 | /* this should go away */ |
---|
| 10 | |
---|
| 11 | #ifdef OM_INTERNAL_DEBUG |
---|
| 12 | size_t omSizeOfBinAddr(void* addr) |
---|
| 13 | { |
---|
| 14 | return _omSizeOfBinAddr(addr); |
---|
| 15 | } |
---|
| 16 | #endif |
---|
| 17 | |
---|
| 18 | /***************************************************************** |
---|
| 19 | * |
---|
| 20 | * SpecBin business |
---|
| 21 | * |
---|
| 22 | *****************************************************************/ |
---|
| 23 | #define om_LargeBin ((omBin) 1) |
---|
| 24 | omBin _omGetSpecBin(size_t size, int align, int track) |
---|
| 25 | |
---|
| 26 | { |
---|
| 27 | omBin om_new_specBin; |
---|
| 28 | long max_blocks; |
---|
| 29 | long sizeW; |
---|
| 30 | |
---|
| 31 | |
---|
| 32 | size = OM_ALIGN_SIZE(size); |
---|
| 33 | #ifdef OM_ALIGNMENT_NEEDS_WORK |
---|
| 34 | if (align || size >= OM_SIZEOF_UNIQUE_MAX_BLOCK_THRESHOLD) |
---|
| 35 | { |
---|
| 36 | align = 1; |
---|
| 37 | size = OM_STRICT_ALIGN_SIZE(size); |
---|
| 38 | } |
---|
| 39 | #else |
---|
| 40 | align = 0; |
---|
[13fe1b] | 41 | #endif |
---|
| 42 | |
---|
[e70e45] | 43 | if (size > SIZEOF_OM_BIN_PAGE) |
---|
| 44 | { |
---|
| 45 | /* need page header */ |
---|
[13fe1b] | 46 | max_blocks = - (long) |
---|
[e70e45] | 47 | ((size+(SIZEOF_SYSTEM_PAGE-SIZEOF_OM_BIN_PAGE))+SIZEOF_SYSTEM_PAGE-1) |
---|
| 48 | / SIZEOF_SYSTEM_PAGE; |
---|
[13fe1b] | 49 | sizeW = ((-max_blocks*SIZEOF_SYSTEM_PAGE) - |
---|
[e70e45] | 50 | (SIZEOF_SYSTEM_PAGE - SIZEOF_OM_BIN_PAGE)) / SIZEOF_LONG; |
---|
| 51 | om_new_specBin = om_LargeBin; |
---|
| 52 | } |
---|
| 53 | else |
---|
| 54 | { |
---|
| 55 | /* SIZEOF_OM_BIN_PAGE == max_blocks*size + r1; r1 < size */ |
---|
| 56 | /* r1 = max_blocks*(size_padding) + r2; r2 < max_blocks */ |
---|
| 57 | max_blocks = SIZEOF_OM_BIN_PAGE / size; |
---|
| 58 | sizeW = (SIZEOF_OM_BIN_PAGE % size) / max_blocks; |
---|
| 59 | #ifdef OM_ALIGNMENT_NEEDS_WORK |
---|
| 60 | if (align) |
---|
| 61 | sizeW = ((size + sizeW) & ~ (SIZEOF_STRICT_ALIGNMENT - 1)); |
---|
| 62 | else |
---|
| 63 | #endif |
---|
| 64 | sizeW = ((size + sizeW) & ~ (SIZEOF_OM_ALIGNMENT - 1)); |
---|
[13fe1b] | 65 | |
---|
[e70e45] | 66 | omAssume(sizeW >= size); |
---|
| 67 | omAssume(max_blocks*sizeW <= SIZEOF_OM_BIN_PAGE); |
---|
| 68 | omAssume((max_blocks+1)*sizeW > SIZEOF_OM_BIN_PAGE || |
---|
| 69 | max_blocks*(sizeW + SIZEOF_STRICT_ALIGNMENT) > SIZEOF_OM_BIN_PAGE); |
---|
| 70 | |
---|
| 71 | sizeW = sizeW >> LOG_SIZEOF_LONG; |
---|
| 72 | if (size > OM_MAX_BLOCK_SIZE) |
---|
| 73 | { |
---|
| 74 | om_new_specBin = om_LargeBin; |
---|
| 75 | } |
---|
| 76 | #ifdef OM_ALIGNMENT_NEEDS_WORK |
---|
| 77 | else if (align) |
---|
| 78 | { |
---|
| 79 | om_new_specBin = omSmallSize2AlignedBin( size ); |
---|
| 80 | } |
---|
| 81 | #endif |
---|
| 82 | #ifdef OM_HAVE_TRACK |
---|
| 83 | else if (track) |
---|
| 84 | { |
---|
| 85 | om_new_specBin = omSmallSize2TrackBin( size ); |
---|
| 86 | } |
---|
| 87 | #endif |
---|
[13fe1b] | 88 | else |
---|
[e70e45] | 89 | { |
---|
| 90 | om_new_specBin = omSmallSize2Bin( size ); |
---|
| 91 | } |
---|
| 92 | } |
---|
| 93 | |
---|
| 94 | if (om_new_specBin == om_LargeBin || |
---|
| 95 | om_new_specBin->max_blocks < max_blocks) |
---|
| 96 | { |
---|
| 97 | omSpecBin s_bin; |
---|
| 98 | #ifdef OM_HAVE_TRACK |
---|
| 99 | if (track) |
---|
| 100 | s_bin = omFindInSortedGList(om_SpecTrackBin, next, max_blocks, max_blocks); |
---|
| 101 | else |
---|
| 102 | #endif |
---|
| 103 | s_bin = omFindInSortedGList(om_SpecBin, next, max_blocks, max_blocks); |
---|
| 104 | |
---|
[13fe1b] | 105 | if (s_bin != NULL) |
---|
[e70e45] | 106 | { |
---|
| 107 | (s_bin->ref)++; |
---|
[13fe1b] | 108 | omAssume(s_bin->bin != NULL && |
---|
[e70e45] | 109 | s_bin->bin->max_blocks == s_bin->max_blocks && |
---|
| 110 | s_bin->bin->sizeW == sizeW); |
---|
| 111 | return s_bin->bin; |
---|
| 112 | } |
---|
| 113 | s_bin = (omSpecBin) omAlloc(sizeof(omSpecBin_t)); |
---|
| 114 | s_bin->ref = 1; |
---|
| 115 | s_bin->next = NULL; |
---|
| 116 | s_bin->max_blocks = max_blocks; |
---|
| 117 | s_bin->bin = (omBin) omAlloc(sizeof(omBin_t)); |
---|
| 118 | s_bin->bin->current_page = om_ZeroPage; |
---|
| 119 | s_bin->bin->last_page = NULL; |
---|
| 120 | s_bin->bin->next = NULL; |
---|
| 121 | s_bin->bin->sizeW = sizeW; |
---|
| 122 | s_bin->bin->max_blocks = max_blocks; |
---|
| 123 | s_bin->bin->sticky = 0; |
---|
| 124 | #ifdef OM_HAVE_TRACK |
---|
| 125 | if (track) |
---|
| 126 | { |
---|
| 127 | om_SpecTrackBin = omInsertInSortedGList(om_SpecTrackBin, next, max_blocks, s_bin); |
---|
| 128 | } |
---|
| 129 | else |
---|
| 130 | #endif |
---|
| 131 | om_SpecBin = omInsertInSortedGList(om_SpecBin, next, max_blocks, s_bin); |
---|
| 132 | return s_bin->bin; |
---|
| 133 | } |
---|
| 134 | else |
---|
| 135 | { |
---|
| 136 | return om_new_specBin; |
---|
| 137 | } |
---|
| 138 | } |
---|
| 139 | |
---|
| 140 | void _omUnGetSpecBin(omBin *bin_p, int force) |
---|
| 141 | { |
---|
| 142 | omBin bin = *bin_p; |
---|
| 143 | if (! omIsStaticBin(bin)) |
---|
| 144 | { |
---|
[13fe1b] | 145 | #ifdef OM_HAVE_TRACK |
---|
[e70e45] | 146 | int track_bin = 0; |
---|
[13fe1b] | 147 | #endif |
---|
[e70e45] | 148 | omSpecBin s_bin; |
---|
| 149 | |
---|
| 150 | #ifdef OM_HAVE_TRACK |
---|
| 151 | s_bin = omFindInGList(om_SpecTrackBin, next, bin, bin); |
---|
| 152 | if (s_bin != NULL) |
---|
| 153 | track_bin = 1; |
---|
| 154 | else |
---|
| 155 | #endif |
---|
| 156 | s_bin = omFindInSortedGList(om_SpecBin, next, max_blocks, bin->max_blocks); |
---|
[13fe1b] | 157 | |
---|
[f103fb] | 158 | omAssume(s_bin != NULL && bin == s_bin->bin); |
---|
[e70e45] | 159 | if (s_bin != NULL) |
---|
| 160 | { |
---|
| 161 | (s_bin->ref)--; |
---|
| 162 | if (s_bin->ref == 0 || force) |
---|
| 163 | { |
---|
[f103fb] | 164 | #ifdef OM_HAVE_TRACK |
---|
[13fe1b] | 165 | if (! track_bin) |
---|
[f103fb] | 166 | #endif |
---|
| 167 | omFreeKeptAddrFromBin(s_bin->bin); |
---|
[e70e45] | 168 | if(s_bin->bin->last_page == NULL || force) |
---|
| 169 | { |
---|
| 170 | #ifdef OM_HAVE_TRACK |
---|
| 171 | if (track_bin) |
---|
| 172 | om_SpecTrackBin = omRemoveFromSortedGList(om_SpecTrackBin, next, max_blocks, s_bin); |
---|
| 173 | else |
---|
| 174 | #endif |
---|
| 175 | om_SpecBin = omRemoveFromSortedGList(om_SpecBin, next, max_blocks, s_bin); |
---|
| 176 | omFreeSize(s_bin->bin, sizeof(omBin_t)); |
---|
| 177 | omFreeSize(s_bin, sizeof(omSpecBin_t)); |
---|
| 178 | } |
---|
| 179 | } |
---|
| 180 | } |
---|
| 181 | } |
---|
| 182 | *bin_p = NULL; |
---|
| 183 | } |
---|
| 184 | |
---|
| 185 | |
---|
| 186 | /***************************************************************** |
---|
| 187 | * |
---|
| 188 | * Sticky business |
---|
| 189 | * |
---|
| 190 | *****************************************************************/ |
---|
| 191 | #define omGetStickyBin(bin, sticky_tag) \ |
---|
| 192 | omFindInGList(bin, next, sticky, sticky_tag) |
---|
| 193 | |
---|
| 194 | static omBin omCreateStickyBin(omBin bin, unsigned long sticky) |
---|
| 195 | { |
---|
| 196 | omBin s_bin = (omBin) omAlloc(sizeof(omBin_t)); |
---|
| 197 | s_bin->sticky = sticky; |
---|
| 198 | s_bin->current_page = om_ZeroPage; |
---|
| 199 | s_bin->last_page = NULL; |
---|
| 200 | s_bin->max_blocks = bin->max_blocks; |
---|
| 201 | s_bin->sizeW = bin->sizeW; |
---|
| 202 | s_bin->next = bin->next; |
---|
| 203 | bin->next = s_bin; |
---|
| 204 | return s_bin; |
---|
| 205 | } |
---|
| 206 | |
---|
| 207 | unsigned long omGetMaxStickyBinTag(omBin bin) |
---|
| 208 | { |
---|
| 209 | unsigned long sticky = 0; |
---|
| 210 | do |
---|
| 211 | { |
---|
| 212 | if (bin->sticky > sticky) sticky = bin->sticky; |
---|
| 213 | bin = bin->next; |
---|
| 214 | } |
---|
| 215 | while (bin != NULL); |
---|
| 216 | return sticky; |
---|
| 217 | } |
---|
| 218 | |
---|
| 219 | unsigned long omGetNewStickyBinTag(omBin bin) |
---|
| 220 | { |
---|
| 221 | unsigned long sticky = omGetMaxStickyBinTag(bin); |
---|
| 222 | if (sticky < BIT_SIZEOF_LONG - 2) |
---|
| 223 | { |
---|
| 224 | sticky++; |
---|
| 225 | omCreateStickyBin(bin, sticky); |
---|
| 226 | return sticky; |
---|
| 227 | } |
---|
| 228 | else |
---|
| 229 | { |
---|
| 230 | omAssume(sticky == BIT_SIZEOF_LONG - 1); |
---|
| 231 | } |
---|
| 232 | return sticky; |
---|
| 233 | } |
---|
| 234 | |
---|
| 235 | void omSetStickyBinTag(omBin bin, unsigned long sticky_tag) |
---|
| 236 | { |
---|
| 237 | omBin s_bin; |
---|
| 238 | s_bin = omGetStickyBin(bin, sticky_tag); |
---|
[13fe1b] | 239 | |
---|
[e70e45] | 240 | if (s_bin != bin) |
---|
| 241 | { |
---|
| 242 | omBinPage tc, tl; |
---|
| 243 | unsigned long ts; |
---|
[13fe1b] | 244 | |
---|
[e70e45] | 245 | if (s_bin == NULL) s_bin = omCreateStickyBin(bin, sticky_tag); |
---|
| 246 | ts = bin->sticky; |
---|
| 247 | tl = bin->last_page; |
---|
| 248 | tc = bin->current_page; |
---|
| 249 | bin->sticky = s_bin->sticky; |
---|
| 250 | bin->current_page = s_bin->current_page; |
---|
| 251 | bin->last_page = s_bin->last_page; |
---|
| 252 | s_bin->sticky = ts; |
---|
| 253 | s_bin->last_page = tl; |
---|
| 254 | s_bin->current_page = tc; |
---|
| 255 | } |
---|
| 256 | } |
---|
| 257 | |
---|
| 258 | void omUnSetStickyBinTag(omBin bin, unsigned long sticky) |
---|
| 259 | { |
---|
| 260 | omAssume(omGetStickyBin(bin, 0) != NULL); |
---|
| 261 | if (bin->sticky == sticky) |
---|
| 262 | omSetStickyBinTag(bin, 0); |
---|
| 263 | } |
---|
| 264 | |
---|
| 265 | static void omMergeStickyPages(omBin to_bin, omBin from_bin) |
---|
| 266 | { |
---|
| 267 | #ifdef HAVE_OM_ASSUME |
---|
| 268 | int length = omGListLength(to_bin->last_page, prev) + |
---|
| 269 | omGListLength(from_bin->last_page, prev); |
---|
[13fe1b] | 270 | #endif |
---|
| 271 | |
---|
[e70e45] | 272 | omBinPage page = from_bin->last_page; |
---|
| 273 | omAssume(to_bin->sizeW == from_bin->sizeW); |
---|
| 274 | omAssume(to_bin != from_bin); |
---|
| 275 | |
---|
| 276 | if (page == NULL) return; |
---|
| 277 | do |
---|
| 278 | { |
---|
[f103fb] | 279 | omSetTopBinAndStickyOfPage(page, to_bin, to_bin->sticky); |
---|
[e70e45] | 280 | if (page->prev == NULL) break; |
---|
| 281 | page = page->prev; |
---|
| 282 | } |
---|
| 283 | while(1); |
---|
| 284 | |
---|
| 285 | if (to_bin->last_page == NULL) |
---|
| 286 | { |
---|
| 287 | omAssume(to_bin->current_page == om_ZeroPage); |
---|
| 288 | to_bin->last_page = from_bin->last_page; |
---|
| 289 | to_bin->current_page = from_bin->current_page; |
---|
| 290 | return; |
---|
| 291 | } |
---|
[13fe1b] | 292 | |
---|
| 293 | omAssume(to_bin->current_page != om_ZeroPage && |
---|
[e70e45] | 294 | to_bin->current_page != NULL); |
---|
| 295 | |
---|
| 296 | if (to_bin->current_page->current != NULL) |
---|
| 297 | { |
---|
| 298 | if (to_bin->current_page->prev == NULL) |
---|
| 299 | { |
---|
| 300 | from_bin->last_page->next = to_bin->current_page; |
---|
| 301 | to_bin->current_page->prev = from_bin->last_page; |
---|
| 302 | to_bin->current_page = from_bin->current_page; |
---|
| 303 | return; |
---|
| 304 | } |
---|
| 305 | to_bin->current_page = to_bin->current_page->prev; |
---|
| 306 | } |
---|
| 307 | else |
---|
| 308 | { |
---|
| 309 | /* need to reset this here, since new current_page is going to be |
---|
[13fe1b] | 310 | from_bin->current_page, and only for current_page may we have |
---|
[e70e45] | 311 | used_blocks != 0 && current == NULL */ |
---|
| 312 | to_bin->current_page->used_blocks = 0; |
---|
| 313 | } |
---|
| 314 | |
---|
[13fe1b] | 315 | |
---|
| 316 | omAssume(to_bin->current_page != NULL && |
---|
[e70e45] | 317 | to_bin->current_page->current == NULL && |
---|
| 318 | to_bin->current_page->used_blocks == 0); |
---|
| 319 | |
---|
| 320 | from_bin->last_page->next = to_bin->current_page->next; |
---|
[13fe1b] | 321 | if (to_bin->current_page->next != NULL) |
---|
[e70e45] | 322 | to_bin->current_page->next->prev = from_bin->last_page; |
---|
| 323 | else |
---|
| 324 | { |
---|
| 325 | omAssume(to_bin->current_page == to_bin->last_page); |
---|
| 326 | to_bin->last_page = from_bin->last_page; |
---|
| 327 | } |
---|
| 328 | to_bin->current_page->next = page; |
---|
| 329 | page->prev = to_bin->current_page; |
---|
| 330 | to_bin->current_page = from_bin->current_page; |
---|
[13fe1b] | 331 | |
---|
[e70e45] | 332 | #ifdef HAVE_OM_ASSUME |
---|
| 333 | omAssume(omGListLength(to_bin->last_page, prev) == length); |
---|
| 334 | #endif |
---|
| 335 | } |
---|
| 336 | |
---|
| 337 | void omDeleteStickyBinTag(omBin bin, unsigned long sticky) |
---|
| 338 | { |
---|
| 339 | omBin no_sticky_bin = NULL; |
---|
| 340 | omBin sticky_bin = NULL; |
---|
| 341 | |
---|
| 342 | if (sticky == 0) |
---|
| 343 | { |
---|
| 344 | omAssume(0); |
---|
| 345 | return; |
---|
| 346 | } |
---|
[13fe1b] | 347 | |
---|
[e70e45] | 348 | sticky_bin = omGetStickyBin(bin, sticky); |
---|
| 349 | if (sticky_bin != NULL) |
---|
| 350 | { |
---|
| 351 | no_sticky_bin = omGetStickyBin(bin, 0); |
---|
| 352 | omAssume(no_sticky_bin != NULL && sticky_bin != no_sticky_bin); |
---|
| 353 | |
---|
| 354 | omMergeStickyPages(no_sticky_bin, sticky_bin); |
---|
| 355 | |
---|
[13fe1b] | 356 | if (bin == sticky_bin) |
---|
[e70e45] | 357 | { |
---|
| 358 | sticky_bin = no_sticky_bin; |
---|
| 359 | omSetStickyBinTag(bin, 0); |
---|
| 360 | } |
---|
| 361 | bin->next = omRemoveFromGList(bin->next, next, sticky_bin); |
---|
| 362 | omFreeSize(sticky_bin, sizeof(omBin_t)); |
---|
| 363 | } |
---|
| 364 | } |
---|
| 365 | |
---|
| 366 | |
---|
[f103fb] | 367 | /***************************************************************** |
---|
| 368 | * |
---|
| 369 | * Sticky bins |
---|
| 370 | * |
---|
| 371 | *****************************************************************/ |
---|
| 372 | omBin om_StickyBins = NULL; |
---|
| 373 | omBin omGetStickyBinOfBin(omBin bin) |
---|
| 374 | { |
---|
| 375 | omBin new_bin = omAlloc(sizeof(omBin_t)); |
---|
| 376 | omAssume(omIsKnownTopBin(bin, 1) && ! omIsStickyBin(bin)); |
---|
| 377 | new_bin->sticky = SIZEOF_VOIDP; |
---|
| 378 | new_bin->max_blocks = bin->max_blocks; |
---|
| 379 | new_bin->sizeW = bin->sizeW; |
---|
| 380 | new_bin->next = om_StickyBins; |
---|
| 381 | om_StickyBins = new_bin; |
---|
| 382 | new_bin->last_page = NULL; |
---|
| 383 | new_bin->current_page = om_ZeroPage; |
---|
| 384 | #if 0 |
---|
| 385 | if (omIsSpecBin(bin)) |
---|
| 386 | { |
---|
| 387 | omSpecBin s_bin = omFindInSortedGList(om_SpecBin, next, max_blocks, bin->max_blocks); |
---|
| 388 | omAssume(s_bin != NULL); |
---|
| 389 | if (s_bin != NULL) |
---|
| 390 | s_bin->ref++; |
---|
| 391 | } |
---|
| 392 | #endif |
---|
| 393 | return new_bin; |
---|
| 394 | } |
---|
| 395 | |
---|
| 396 | void omMergeStickyBinIntoBin(omBin sticky_bin, omBin into_bin) |
---|
| 397 | { |
---|
[13fe1b] | 398 | if (! omIsOnGList(om_StickyBins, next, sticky_bin) || |
---|
[f103fb] | 399 | !sticky_bin->sticky || |
---|
| 400 | sticky_bin->max_blocks != into_bin->max_blocks || |
---|
| 401 | sticky_bin == into_bin || |
---|
| 402 | !omIsKnownTopBin(into_bin, 1) || |
---|
| 403 | omIsStickyBin(into_bin)) |
---|
| 404 | { |
---|
| 405 | #ifndef OM_NDEBUG |
---|
[13fe1b] | 406 | omReportError(omError_StickyBin, omError_NoError, OM_FLR, |
---|
[f103fb] | 407 | (! omIsOnGList(om_StickyBins, next, sticky_bin) ? "unknown sticky_bin" : |
---|
[13fe1b] | 408 | (!sticky_bin->sticky ? "sticky_bin is not sticky" : |
---|
[f103fb] | 409 | (sticky_bin->max_blocks != into_bin->max_blocks ? "sticky_bin and into_bin have different block sizes" : |
---|
[13fe1b] | 410 | (sticky_bin == into_bin ? "sticky_bin == into_bin" : |
---|
[f103fb] | 411 | (!omIsKnownTopBin(into_bin, 1) ? "unknown into_bin" : |
---|
| 412 | (omIsStickyBin(into_bin) ? "into_bin is sticky" : |
---|
| 413 | "unknown sticky_bin error"))))))); |
---|
| 414 | #endif |
---|
| 415 | return; |
---|
| 416 | } |
---|
| 417 | omFreeKeptAddrFromBin(sticky_bin); |
---|
| 418 | om_StickyBins = omRemoveFromGList(om_StickyBins, next, sticky_bin); |
---|
| 419 | omMergeStickyPages(into_bin, sticky_bin); |
---|
| 420 | |
---|
| 421 | #if 0 |
---|
| 422 | if (! omIsStaticBin(into_bin)) |
---|
| 423 | { |
---|
| 424 | omBin _ibin = into_bin; |
---|
| 425 | omUnGetSpecBin(&_ibin); |
---|
| 426 | } |
---|
| 427 | #endif |
---|
| 428 | omFreeSize(sticky_bin, sizeof(omBin_t)); |
---|
| 429 | #if defined(OM_INTERNAL_DEBUG) && !defined(OM_NDEBUG) |
---|
| 430 | omTestBin(into_bin, 2); |
---|
[13fe1b] | 431 | #endif |
---|
[f103fb] | 432 | } |
---|
[13fe1b] | 433 | |
---|
[e70e45] | 434 | /***************************************************************** |
---|
| 435 | * |
---|
| 436 | * AllBin business |
---|
| 437 | * |
---|
| 438 | *****************************************************************/ |
---|
[f103fb] | 439 | #ifndef OM_NDEBUG |
---|
| 440 | int omIsKnownTopBin(omBin bin, int normal_bin) |
---|
| 441 | { |
---|
| 442 | omBin to_check; |
---|
| 443 | omSpecBin s_bin; |
---|
| 444 | int i; |
---|
[13fe1b] | 445 | |
---|
[f103fb] | 446 | omAssume(normal_bin == 1 || normal_bin == 0); |
---|
[13fe1b] | 447 | |
---|
[f103fb] | 448 | #ifdef OM_HAVE_TRACK |
---|
[13fe1b] | 449 | if (! normal_bin) |
---|
[f103fb] | 450 | { |
---|
| 451 | to_check = om_StaticTrackBin; |
---|
| 452 | s_bin = om_SpecTrackBin; |
---|
| 453 | } |
---|
[13fe1b] | 454 | else |
---|
[f103fb] | 455 | #endif |
---|
| 456 | { |
---|
| 457 | omAssume(normal_bin); |
---|
| 458 | to_check = om_StaticBin; |
---|
| 459 | s_bin = om_SpecBin; |
---|
| 460 | } |
---|
| 461 | |
---|
| 462 | for (i=0; i<= OM_MAX_BIN_INDEX; i++) |
---|
| 463 | { |
---|
[13fe1b] | 464 | if (bin == &(to_check[i])) |
---|
[f103fb] | 465 | return 1; |
---|
| 466 | } |
---|
[13fe1b] | 467 | |
---|
[f103fb] | 468 | while (s_bin != NULL) |
---|
| 469 | { |
---|
| 470 | if (bin == s_bin->bin) return 1; |
---|
| 471 | s_bin = s_bin->next; |
---|
| 472 | } |
---|
| 473 | to_check = om_StickyBins; |
---|
| 474 | |
---|
| 475 | while (to_check != NULL) |
---|
| 476 | { |
---|
| 477 | if (bin == to_check) return 1; |
---|
| 478 | to_check = to_check->next; |
---|
| 479 | } |
---|
| 480 | return 0; |
---|
| 481 | } |
---|
| 482 | #endif |
---|
| 483 | |
---|
[e70e45] | 484 | unsigned long omGetNewStickyAllBinTag() |
---|
| 485 | { |
---|
| 486 | unsigned long sticky = 0, new_sticky; |
---|
| 487 | int i; |
---|
| 488 | omSpecBin s_bin; |
---|
| 489 | // first, find new sticky tag |
---|
| 490 | for (i=0; i<=OM_MAX_BIN_INDEX; i++) |
---|
| 491 | { |
---|
| 492 | new_sticky = omGetMaxStickyBinTag(&(om_StaticBin[i])); |
---|
| 493 | if (new_sticky > sticky) sticky = new_sticky; |
---|
| 494 | } |
---|
| 495 | s_bin = om_SpecBin; |
---|
[13fe1b] | 496 | while (s_bin != NULL) |
---|
[e70e45] | 497 | { |
---|
| 498 | new_sticky = omGetMaxStickyBinTag(s_bin->bin); |
---|
| 499 | if (new_sticky > sticky) sticky = new_sticky; |
---|
| 500 | s_bin = s_bin->next; |
---|
| 501 | } |
---|
[13fe1b] | 502 | if (sticky < BIT_SIZEOF_LONG - 2) |
---|
[e70e45] | 503 | { |
---|
| 504 | sticky++; |
---|
| 505 | for (i=0; i<=OM_MAX_BIN_INDEX; i++) |
---|
| 506 | { |
---|
| 507 | omCreateStickyBin(&(om_StaticBin[i]), sticky); |
---|
| 508 | } |
---|
| 509 | s_bin = om_SpecBin; |
---|
[13fe1b] | 510 | while (s_bin != NULL) |
---|
[e70e45] | 511 | { |
---|
| 512 | omCreateStickyBin(s_bin->bin, sticky); |
---|
| 513 | s_bin = s_bin->next; |
---|
| 514 | } |
---|
| 515 | return sticky; |
---|
| 516 | } |
---|
| 517 | else |
---|
| 518 | { |
---|
| 519 | omBin bin; |
---|
| 520 | omAssume(sticky == BIT_SIZEOF_LONG - 1); |
---|
| 521 | for (i=0; i<=OM_MAX_BIN_INDEX; i++) |
---|
| 522 | { |
---|
| 523 | bin = &om_StaticBin[i]; |
---|
| 524 | if (omGetStickyBin(bin, BIT_SIZEOF_LONG -1) == NULL) |
---|
| 525 | omCreateStickyBin(bin, BIT_SIZEOF_LONG -1); |
---|
| 526 | } |
---|
| 527 | s_bin = om_SpecBin; |
---|
[13fe1b] | 528 | while (s_bin != NULL) |
---|
[e70e45] | 529 | { |
---|
| 530 | if (omGetStickyBin(s_bin->bin, BIT_SIZEOF_LONG -1) == NULL) |
---|
| 531 | omCreateStickyBin(s_bin->bin, BIT_SIZEOF_LONG -1); |
---|
| 532 | s_bin = s_bin->next; |
---|
| 533 | } |
---|
| 534 | return BIT_SIZEOF_LONG - 1; |
---|
| 535 | } |
---|
| 536 | } |
---|
| 537 | |
---|
| 538 | void omSetStickyAllBinTag(unsigned long sticky) |
---|
| 539 | { |
---|
| 540 | omSpecBin s_bin = om_SpecBin; |
---|
| 541 | int i; |
---|
| 542 | for (i=0; i<=OM_MAX_BIN_INDEX; i++) |
---|
| 543 | { |
---|
| 544 | omSetStickyBinTag(&(om_StaticBin[i]), sticky); |
---|
| 545 | } |
---|
[13fe1b] | 546 | while (s_bin != NULL) |
---|
[e70e45] | 547 | { |
---|
| 548 | omSetStickyBinTag(s_bin->bin, sticky); |
---|
| 549 | s_bin = s_bin->next; |
---|
| 550 | } |
---|
| 551 | } |
---|
| 552 | |
---|
| 553 | void omUnSetStickyAllBinTag(unsigned long sticky) |
---|
| 554 | { |
---|
| 555 | omSpecBin s_bin = om_SpecBin; |
---|
| 556 | int i; |
---|
| 557 | for (i=0; i<=OM_MAX_BIN_INDEX; i++) |
---|
| 558 | { |
---|
| 559 | omUnSetStickyBinTag(&(om_StaticBin[i]), sticky); |
---|
| 560 | } |
---|
[13fe1b] | 561 | while (s_bin != NULL) |
---|
[e70e45] | 562 | { |
---|
| 563 | omUnSetStickyBinTag(s_bin->bin, sticky); |
---|
| 564 | s_bin = s_bin->next; |
---|
| 565 | } |
---|
| 566 | } |
---|
| 567 | |
---|
| 568 | void omDeleteStickyAllBinTag(unsigned long sticky) |
---|
| 569 | { |
---|
| 570 | omSpecBin s_bin = om_SpecBin; |
---|
| 571 | int i; |
---|
| 572 | for (i=0; i<=OM_MAX_BIN_INDEX; i++) |
---|
| 573 | { |
---|
| 574 | omDeleteStickyBinTag(&(om_StaticBin[i]), sticky); |
---|
| 575 | } |
---|
[13fe1b] | 576 | while (s_bin != NULL) |
---|
[e70e45] | 577 | { |
---|
| 578 | omDeleteStickyBinTag(s_bin->bin, sticky); |
---|
| 579 | s_bin = s_bin->next; |
---|
| 580 | } |
---|
| 581 | } |
---|
| 582 | |
---|
| 583 | #if 0 |
---|
| 584 | void omPrintMissing(omBin bin) |
---|
| 585 | { |
---|
| 586 | omBinPage page = bin->last_page; |
---|
[13fe1b] | 587 | |
---|
[e70e45] | 588 | while (page != NULL) |
---|
| 589 | { |
---|
| 590 | void* addr = (void*) page + SIZEOF_OM_BIN_PAGE_HEADER; |
---|
| 591 | int i; |
---|
[13fe1b] | 592 | |
---|
[e70e45] | 593 | for (i=0; i<bin->max_blocks; i++) |
---|
| 594 | { |
---|
| 595 | if (! omIsOnList(page->current, addr)) |
---|
| 596 | printf("%d:%p\n", i, addr); |
---|
| 597 | addr += bin->sizeW*SIZEOF_LONG; |
---|
| 598 | } |
---|
| 599 | page = page->prev; |
---|
| 600 | } |
---|
| 601 | } |
---|
| 602 | #endif |
---|
| 603 | |
---|
[f103fb] | 604 | /***************************************************************** |
---|
| 605 | * |
---|
| 606 | * Statistics |
---|
| 607 | * |
---|
| 608 | *****************************************************************/ |
---|
[13fe1b] | 609 | static void omGetBinStat(omBin bin, int *pages_p, int *used_blocks_p, |
---|
[f103fb] | 610 | int *free_blocks_p) |
---|
| 611 | { |
---|
| 612 | int pages = 0, used_blocks = 0, free_blocks = 0; |
---|
| 613 | int where = 1; |
---|
[13fe1b] | 614 | |
---|
[f103fb] | 615 | omBinPage page = bin->last_page; |
---|
| 616 | while (page != NULL) |
---|
| 617 | { |
---|
[13fe1b] | 618 | pages++; if (where == 1) |
---|
[f103fb] | 619 | { |
---|
| 620 | used_blocks += omGetUsedBlocksOfPage(page) + 1; |
---|
| 621 | if (bin->max_blocks > 0) |
---|
| 622 | free_blocks += bin->max_blocks - omGetUsedBlocksOfPage(page) -1; |
---|
| 623 | } |
---|
[13fe1b] | 624 | else |
---|
[f103fb] | 625 | { |
---|
| 626 | if (bin->max_blocks > 1) |
---|
| 627 | used_blocks += bin->max_blocks; |
---|
| 628 | else |
---|
| 629 | used_blocks++; |
---|
| 630 | } |
---|
| 631 | if (page == bin->current_page) where = -1; |
---|
| 632 | page = page->prev; |
---|
| 633 | } |
---|
| 634 | *pages_p = pages; |
---|
| 635 | *used_blocks_p = used_blocks; |
---|
| 636 | *free_blocks_p = free_blocks; |
---|
| 637 | } |
---|
| 638 | |
---|
[13fe1b] | 639 | static void omGetTotalBinStat(omBin bin, int *pages_p, int *used_blocks_p, |
---|
[f103fb] | 640 | int *free_blocks_p) |
---|
| 641 | { |
---|
| 642 | int t_pages = 0, t_used_blocks = 0, t_free_blocks = 0; |
---|
| 643 | int pages = 0, used_blocks = 0, free_blocks = 0; |
---|
[13fe1b] | 644 | |
---|
[f103fb] | 645 | while (bin != NULL) |
---|
| 646 | { |
---|
| 647 | omGetBinStat(bin, &pages, &used_blocks, &free_blocks); |
---|
| 648 | t_pages += pages; |
---|
| 649 | t_used_blocks += used_blocks; |
---|
| 650 | t_free_blocks += free_blocks; |
---|
| 651 | if (!omIsStickyBin(bin)) |
---|
| 652 | bin = bin->next; |
---|
[13fe1b] | 653 | else |
---|
[f103fb] | 654 | bin = NULL; |
---|
| 655 | } |
---|
| 656 | *pages_p = t_pages; |
---|
| 657 | *used_blocks_p = t_used_blocks; |
---|
| 658 | *free_blocks_p = t_free_blocks; |
---|
| 659 | } |
---|
| 660 | |
---|
| 661 | static void omPrintBinStat(FILE * fd, omBin bin, int track, int* pages, int* used_blocks, int* free_blocks) |
---|
| 662 | { |
---|
| 663 | if (track) |
---|
| 664 | { |
---|
| 665 | fprintf(fd, "T \t \t"); |
---|
| 666 | } |
---|
| 667 | else |
---|
| 668 | { |
---|
[13fe1b] | 669 | fprintf(fd, "%s%ld\t%ld\t", (omIsStaticNormalBin(bin) ? " " : |
---|
| 670 | (omIsStickyBin(bin) ? "S" : |
---|
[f103fb] | 671 | (omIsTrackBin(bin) ? "T" : "*"))), |
---|
[657747] | 672 | (long)bin->sizeW, bin->max_blocks); |
---|
[f103fb] | 673 | } |
---|
| 674 | omGetTotalBinStat(bin, pages, used_blocks, free_blocks); |
---|
| 675 | fprintf(fd, "%d\t%d\t%d\n", *pages, *free_blocks, *used_blocks); |
---|
| 676 | if (bin->next != NULL && !omIsStickyBin(bin)) |
---|
| 677 | { |
---|
| 678 | int s_pages, s_free_blocks, s_used_blocks; |
---|
| 679 | while (bin != NULL) |
---|
| 680 | { |
---|
| 681 | omGetBinStat(bin, &s_pages, &s_used_blocks, &s_free_blocks); |
---|
[13fe1b] | 682 | fprintf(fd, " \t \t%d\t%d\t%d\t%d\n", s_pages, s_free_blocks, s_used_blocks, |
---|
[f103fb] | 683 | (int) bin->sticky); |
---|
| 684 | bin = bin->next; |
---|
| 685 | *pages += s_pages; |
---|
| 686 | *used_blocks += s_used_blocks; |
---|
| 687 | *free_blocks += s_free_blocks; |
---|
| 688 | } |
---|
| 689 | } |
---|
| 690 | } |
---|
[13fe1b] | 691 | |
---|
[f103fb] | 692 | void omPrintBinStats(FILE* fd) |
---|
| 693 | { |
---|
| 694 | int i = OM_MAX_BIN_INDEX, pages=0, used_blocks=0, free_blocks=0; |
---|
| 695 | int pages_p, used_blocks_p, free_blocks_p; |
---|
| 696 | omSpecBin s_bin = om_SpecBin; |
---|
| 697 | omBin sticky; |
---|
[13fe1b] | 698 | |
---|
[f103fb] | 699 | fprintf(fd, " SizeW\tBlocks\tUPages\tFBlocks\tUBlocks\tSticky\n"); |
---|
| 700 | fflush(fd); |
---|
| 701 | while (s_bin != NULL || i >= 0) |
---|
| 702 | { |
---|
| 703 | if (s_bin == NULL || (i >= 0 && (unsigned long) om_StaticBin[i].max_blocks < (unsigned long) s_bin->bin->max_blocks)) |
---|
| 704 | { |
---|
| 705 | omPrintBinStat(fd, &om_StaticBin[i], 0, &pages_p, &used_blocks_p, &free_blocks_p); |
---|
| 706 | pages += pages_p; |
---|
| 707 | used_blocks += used_blocks_p; |
---|
| 708 | free_blocks += free_blocks_p; |
---|
| 709 | #ifdef OM_HAVE_TRACK |
---|
[13fe1b] | 710 | if (om_StaticTrackBin[i].current_page != om_ZeroPage) |
---|
[f103fb] | 711 | { |
---|
| 712 | omPrintBinStat(fd, &om_StaticTrackBin[i], 1, &pages_p, &used_blocks_p, &free_blocks_p); |
---|
| 713 | pages += pages_p; |
---|
| 714 | used_blocks += used_blocks_p; |
---|
| 715 | free_blocks += free_blocks_p; |
---|
| 716 | } |
---|
[13fe1b] | 717 | #endif |
---|
[f103fb] | 718 | i--; |
---|
| 719 | } |
---|
| 720 | else |
---|
| 721 | { |
---|
| 722 | omPrintBinStat(fd, s_bin->bin,0, &pages_p, &used_blocks_p, &free_blocks_p); |
---|
| 723 | pages += pages_p; |
---|
| 724 | used_blocks += used_blocks_p; |
---|
| 725 | free_blocks += free_blocks_p; |
---|
| 726 | s_bin = s_bin->next; |
---|
| 727 | } |
---|
| 728 | } |
---|
| 729 | #ifdef OM_HAVE_TRACK |
---|
| 730 | s_bin = om_SpecTrackBin; |
---|
| 731 | while (s_bin != NULL) |
---|
| 732 | { |
---|
| 733 | omPrintBinStat(fd, s_bin->bin, 0, &pages_p, &used_blocks_p, &free_blocks_p); |
---|
| 734 | s_bin = s_bin->next; |
---|
| 735 | pages += pages_p; |
---|
| 736 | used_blocks += used_blocks_p; |
---|
| 737 | free_blocks += free_blocks_p; |
---|
| 738 | } |
---|
| 739 | #endif |
---|
| 740 | sticky = om_StickyBins; |
---|
| 741 | while (sticky != NULL) |
---|
| 742 | { |
---|
| 743 | omPrintBinStat(fd, sticky, 0, &pages_p, &used_blocks_p, &free_blocks_p); |
---|
| 744 | sticky = sticky->next; |
---|
| 745 | pages += pages_p; |
---|
| 746 | used_blocks += used_blocks_p; |
---|
| 747 | free_blocks += free_blocks_p; |
---|
| 748 | } |
---|
| 749 | fprintf(fd, "----------------------------------------\n"); |
---|
| 750 | fprintf(fd, " \t \t%d\t%d\t%d\n", pages, free_blocks, used_blocks); |
---|
| 751 | } |
---|
[13fe1b] | 752 | |
---|
[979bd0f] | 753 | static long omGetUsedBytesOfBin(omBin bin) |
---|
[e70e45] | 754 | { |
---|
| 755 | int pages = 0, used_blocks = 0, free_blocks = 0; |
---|
| 756 | omGetTotalBinStat(bin, &pages, &used_blocks, &free_blocks); |
---|
[979bd0f] | 757 | return ((long)used_blocks)*((long)bin->sizeW)*SIZEOF_LONG; |
---|
[e70e45] | 758 | } |
---|
| 759 | |
---|
[979bd0f] | 760 | long omGetUsedBinBytes() |
---|
[e70e45] | 761 | { |
---|
| 762 | int i = OM_MAX_BIN_INDEX; |
---|
| 763 | omSpecBin s_bin = om_SpecBin; |
---|
[979bd0f] | 764 | long used = 0; |
---|
[f103fb] | 765 | omBin sticky; |
---|
[13fe1b] | 766 | |
---|
[e70e45] | 767 | for (; i>=0; i--) |
---|
| 768 | { |
---|
| 769 | used += omGetUsedBytesOfBin(&om_StaticBin[i]); |
---|
| 770 | } |
---|
| 771 | while (s_bin != NULL) |
---|
| 772 | { |
---|
| 773 | used += omGetUsedBytesOfBin(s_bin->bin); |
---|
| 774 | s_bin = s_bin->next; |
---|
| 775 | } |
---|
| 776 | #ifdef OM_HAVE_TRACK |
---|
| 777 | for (i=OM_MAX_BIN_INDEX; i>=0; i--) |
---|
| 778 | { |
---|
| 779 | used += omGetUsedBytesOfBin(&om_StaticTrackBin[i]); |
---|
| 780 | } |
---|
| 781 | s_bin = om_SpecTrackBin; |
---|
| 782 | while (s_bin != NULL) |
---|
| 783 | { |
---|
| 784 | used += omGetUsedBytesOfBin(s_bin->bin); |
---|
| 785 | s_bin = s_bin->next; |
---|
| 786 | } |
---|
| 787 | #endif |
---|
| 788 | |
---|
[f103fb] | 789 | sticky = om_StickyBins; |
---|
| 790 | while (sticky != NULL) |
---|
| 791 | { |
---|
| 792 | used += omGetUsedBytesOfBin(sticky); |
---|
| 793 | sticky = sticky->next; |
---|
| 794 | } |
---|
[e70e45] | 795 | return used; |
---|
| 796 | } |
---|