00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 #include <memory.h>
00084 #include <malloc.h>
00085 #include <unistd.h>
00086
00087 #define NEWALLOC
00088 #include "udanax.h"
00089
00090 typecorecrum *grimreaper;
00091 int ingrimreaper = false;
00092 int reaplevel = 0;
00093 int timesaroundreaper = 0;
00094 int crumnumber = 0;
00095 int reapnumber = 0;
00096 int nreapings = 0;
00097 int reservnumber = 0;
00098
00099 #define MAXALLOCQUEUEARRAY 500
00100 struct queue allocqueuearray[MAXALLOCQUEUEARRAY];
00101
00102 static bool isreapable(int *fuckinap, typecorecrum *localreaper);
00103 static void reap(typecorecrum *localreaper);
00104
00112 void
00113 initqueues()
00114 {
00115 for (int i = 0; i < MAXALLOCQUEUEARRAY; i++)
00116 qinit(&allocqueuearray[i]);
00117
00118 #ifdef NEWALLOC
00119 int num = allocsize / 3;
00120 #else
00121 int num = 0;
00122 #endif
00123
00124 for (int j = 0; j < num; j += sizeof(typecuc) + sizeof(typecbc) + sizeof(type2dcbc) + 3 * sizeof(tagtype)) {
00125 qpush(&allocqueuearray[(sizeof(typecuc) + sizeof(tagtype) + sizeof(HEADER) - 1) / sizeof(HEADER)],
00126 (queue *) falloc(sizeof(typecuc) + sizeof(tagtype)));
00127 qpush(&allocqueuearray[(sizeof(typecbc) + sizeof(tagtype) + sizeof(HEADER) - 1) / sizeof(HEADER)],
00128 (queue *) falloc(sizeof(typecbc) + sizeof(tagtype)));
00129 qpush(&allocqueuearray[(sizeof(type2dcbc) + sizeof(tagtype) + sizeof(HEADER) - 1) / sizeof(HEADER)],
00130 (queue *) falloc(sizeof(type2dcbc) + sizeof(tagtype)));
00131 }
00132 }
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00152 static char *
00153 allocfromqueue(
00154 int n)
00155 {
00156 return (char *) qremove(&allocqueuearray[((n + sizeof(HEADER) - 1) / sizeof(HEADER))]);
00157 }
00158
00166 static void
00167 freetoqueue(
00168 char *ptr)
00169 {
00170
00171
00172
00173
00174
00175 int n = ((HEADER *) (ptr - sizeof(HEADER)))->s.size - 1;
00176 qpush(&allocqueuearray[n], (queue *) ptr);
00177
00178
00179 }
00180
00181 static typecorecrum *
00182 createcruminternal(
00183 int crumheight,
00184 int enftype,
00185 typecorecrum *allocated)
00186 {
00187 unsigned crumsize = 0;
00188
00189 if (crumheight == 0) {
00190 switch (enftype) {
00191 case GRAN:
00192 crumsize = sizeof(typecbc);
00193 break;
00194 case SPAN:
00195 case POOM:
00196 crumsize = sizeof( type2dcbc);
00197 break;
00198 default:
00199 L(" enftype = %d\n", enftype);
00200 assert(0);
00201 }
00202 } else
00203 crumsize = sizeof(typecuc);
00204
00205 typecorecrum *ptr;
00206 if (!allocated)
00207 ptr = (typecorecrum *) eallocwithtag(crumsize, (tagtype) (crumheight > 0 ? CUCTAG : CBCTAG));
00208 else
00209 ptr = allocated;
00210
00211 ptr->height = crumheight;
00212 ptr->isapex = false;
00213 ptr->cenftype = enftype;
00214 ptr->modified = true ;
00215 ptr->isleftmost = false;
00216 ptr->age = NEW;
00217 ptr->leftbroorfather = NULL;
00218 ptr->rightbro = NULL;
00219
00220 clear(&ptr->cdsp, sizeof(ptr->cdsp));
00221 clear(&ptr->cwid, sizeof(ptr->cwid));
00222
00223 if (crumheight > 0) {
00224 ((typecuc *) ptr)->numberofsons = 0;
00225 ((typecuc *) ptr)->leftson = NULL;
00226 ((typecuc *) ptr)->sonorigin.diskblocknumber = DISKPTRNULL;
00227
00228 } else {
00229 if (enftype == GRAN) {
00230 clear(&((typecbc *) ptr)->cinfo, sizeof(((typecbc *) ptr)->cinfo));
00231 ((typecbc *) ptr)->cinfo.infotype = GRANCLEARLYILLEGALINFO;
00232 } else
00233 clear(&((type2dcbc *) ptr)->c2dinfo, sizeof(((type2dcbc *) ptr)->c2dinfo));
00234 }
00235 ++crumnumber;
00236
00237 return ptr;
00238 }
00239
00247 void
00248 initcrum(
00249 int crumheight,
00250 int enftype,
00251 typecorecrum *ptr)
00252 {
00253 createcruminternal(crumheight, enftype, ptr);
00254 }
00255
00263 static void
00264 xgrabmorecore()
00265 {
00266 char *tmp = (char *) sbrk(incrementalallocsize);
00267 if (!tmp)
00268 assert(0);
00269
00270 ((HEADER *) tmp)->s.size = (incrementalallocsize + sizeof(HEADER) - 1) / sizeof(HEADER);
00271 ffree(tmp + sizeof(HEADER));
00272
00273 L("xgrabmorecore got another %d\n", incrementalallocsize);
00274 }
00275
00283 static void
00284 grimlyreap()
00285 {
00286 typecorecrum *ptr;
00287 int eh;
00288
00289 ingrimreaper = true;
00290 if (reaplevel++)
00291 #ifndef DISTRIBUTION
00292 if (reaplevel == 1)
00293 L("Recursive grimreaper call.\n");
00294 #endif
00295
00296 if (!grimreaper)
00297 assert(0);
00298
00299 reapnumber = 0;
00300 timesaroundreaper = 0;
00301 for (ptr = grimreaper; grimreaper; grimreaper = (typecorecrum *) grimreaper->nextcrum) {
00302 if (grimreaper == ptr) {
00303 ++timesaroundreaper;
00304 }
00305 if (timesaroundreaper > 10) {
00306 L("urk in grimlyreap\n");
00307
00308 xgrabmorecore();
00309 break;
00311
00312
00313 }
00314
00315 if (grimreaper->age == RESERVED)
00316 continue;
00317
00318 if (isreapable(&eh, grimreaper)) {
00319 reap(grimreaper);
00320 reapnumber = 0;
00321 timesaroundreaper = 0;
00322 --reaplevel;
00323 break;
00324 } else {
00325 if (eh) {
00326
00327 }
00328 }
00329
00330 ++reapnumber;
00331 grimreaper->age++;
00332 }
00333
00334 ingrimreaper = false;
00335 }
00336
00344 static int *
00345 ealloc(
00346 unsigned nbytes)
00347 {
00348
00349
00350 for (;;) {
00351 char *ret;
00352
00353 if ((ret = allocfromqueue(nbytes + sizeof(tagtype))) != 0) {
00354 ret += sizeof(tagtype);
00355 return (int *) ret;
00356 }
00357 ret = (char *)falloc(nbytes + sizeof(tagtype));
00358
00359 if (ret) {
00360
00361 *(tagtype *) ret = false;
00362 return (int *) (ret + sizeof(tagtype));
00363 }
00364 if (grimreaper == NULL) {
00365 xgrabmorecore();
00366
00367
00368
00369 }
00370 grimlyreap();
00371 }
00372 }
00373
00381 void
00382 efree(
00383 char *ptr)
00384 {
00385
00386 if (*(ptr - sizeof(tagtype)) == CBCTAG || *(ptr - sizeof(tagtype)) == CUCTAG) {
00387 #ifdef NEWALLOC
00388 freetoqueue(ptr - sizeof(tagtype));
00389 #else
00390 ffree(ptr - sizeof(tagtype));
00391 #endif
00392 } else {
00393 free(ptr - sizeof(tagtype));
00394 }
00395 }
00396
00397
00398
00399
00400
00408 int *
00409 eallocwithtag(
00410 unsigned nbytes,
00411 tagtype tag)
00412 {
00413 char *ret = NULL;
00414
00415 if (tag == CBCTAG || tag == CUCTAG) {
00416 ret = (char *) ealloc(nbytes);
00417
00418 } else {
00419 ret = (char *) malloc(nbytes + sizeof(tagtype));
00420 ret += sizeof(tagtype);
00421 }
00422
00423
00424
00425 *(ret - sizeof(tagtype)) = tag;
00426 return (int *) ret;
00427 }
00428
00436 static bool
00437 isreapable(
00438 int *fuckinap,
00439 typecorecrum *localreaper)
00440 {
00441 register typecorecrum *p;
00442 typecuc *father;
00443
00444 *fuckinap = 0;
00445 if (!localreaper)
00446 assert(0);
00447
00448 if (localreaper->age < OLD || localreaper->age == RESERVED) {
00449 *fuckinap = 1;
00450 return false;
00451 }
00452
00453 if (localreaper->isapex) {
00454 if (localreaper->cenftype != POOM)
00455 return false;
00456
00457 if (localreaper->modified) {
00458 if (!((typecuc *) localreaper)->leftson) {
00459 #ifndef DISTRIBUTION
00460 dump(localreaper);
00461 L("in isreapable modified and no son in apex");
00462 #endif
00463 return false;
00464 }
00465
00466 for (p = ((typecuc *) localreaper)->leftson; p; p = p->rightbro) {
00467 if (p->modified)
00468 return false;
00469
00470 if (p->age < OLD || p->age == RESERVED)
00471 return false;
00472
00473 if (p->height > 0 && ((typecuc *) p)->leftson)
00474 return false;
00475
00476 if (p->height == 0 && p->cenftype == GRAN && ((typecbc *) p)->cinfo.infotype == GRANORGL && ((typecbc *) p)->cinfo.granstuff.orglstuff.orglincore)
00477 return false;
00478 }
00479 return true;
00480
00481 } else {
00482 for (p = ((typecuc *) localreaper)->leftson; p; p = p->rightbro) {
00483 if (p->modified)
00484 return false;
00485
00486 if (p->age < OLD || p->age == RESERVED)
00487 return false;
00488
00489 if (p->height > 0 && ((typecuc *) p)->leftson)
00490 return false;
00491
00492 if (p->height == 0 && p->cenftype == GRAN && ((typecbc *) p)->cinfo.infotype == GRANORGL && ((typecbc *) p)->cinfo.granstuff.orglstuff.orglincore)
00493 return false;
00494 }
00495 return true;
00496 }
00497 }
00498
00499
00500 if (!localreaper)
00501 assert(0);
00502
00503 father = weakfindfather((typecorecrum *) localreaper);
00504 if (!father) {
00505 L("in isreapable no father !! \n");
00506 return false;
00507 }
00508
00509 if (localreaper->height == 0) {
00510 if (localreaper->cenftype == GRAN) {
00511 if (((typecbc *) localreaper)->cinfo.infotype == GRANORGL) {
00512 if (((typecbc *) localreaper)->cinfo.granstuff.orglstuff.orglincore)
00513 return false;
00514 }
00515 }
00516
00517 for (p = weakfindleftmostbro(localreaper); p; p = p->rightbro) {
00518 if (p->age < OLD || p->age == RESERVED)
00519 return false;
00520
00521 if (p->height == 0 && p->cenftype == GRAN && ((typecbc *) p)->cinfo.infotype == GRANORGL && ((typecbc *) p)->cinfo.granstuff.orglstuff.orglincore)
00522 return false;
00523 }
00524 return true;
00525
00526 } else {
00527 if (father->modified) {
00528 for (p = weakfindleftmostbro(localreaper); p; p = p->rightbro) {
00529 if (p->modified)
00530 return false;
00531
00532 if (p->age < OLD || p->age == RESERVED)
00533 return false;
00534
00535 if (p->height > 0 && ((typecuc *) p)->leftson)
00536 return false;
00537 }
00538 return true;
00539
00540 } else {
00541 for (p = weakfindleftmostbro(localreaper); p; p = p->rightbro) {
00542 if (p->modified)
00543 return false;
00544
00545 if (p->age < OLD || p->age == RESERVED)
00546 return false;
00547
00548 if (p->height > 0 && ((typecuc *) p)->leftson)
00549 return false;
00550 }
00551 return true;
00552 }
00553 }
00554 }
00555
00563 static void
00564 reap(
00565 typecorecrum *localreaper)
00566 {
00567 typecuc *temp;
00568
00569 if (!localreaper)
00570 assert(0);
00571
00572 ++nreapings;
00573 if (localreaper->isapex) {
00574 temp = (typecuc *) localreaper->leftbroorfather;
00575 grimreaper = grimreaper->nextcrum;
00576 if (!temp)
00577 return;
00578
00579 orglwrite((typecbc *) temp);
00580 if (!localreaper)
00581 assert(0);
00582
00583 return;
00584 }
00585
00586 temp = weakfindfather((typecorecrum *) localreaper);
00587 if (!temp)
00588 assert(0);
00589
00590 if (!temp->leftson) {
00591 grimreaper = grimreaper->nextcrum;
00592 return;
00593 }
00594
00595 subtreewrite(temp);
00596 }
00597
00605
00606
00607 void
00608 initgrimreaper()
00609 {
00610 grimreaper = NULL;
00611 }
00612
00620 int
00621 testforrejuvinate(
00622 typecorecrum *ptr)
00623 {
00624 if (ptr->age == RESERVED) {
00625 if (!reservnumber)
00626 assert(0);
00627
00628 --reservnumber;
00629 }
00630 return 0;
00631 }
00632
00640 void
00641 funcrejuvinate(
00642 typecorecrum *ptr)
00643 {
00644 if (ptr->age == RESERVED) {
00645 if (!reservnumber) {
00646 #ifndef DISTRIBUTION
00647 dump(ptr);
00648 assert(0);
00649 #else
00650 assert(0);
00651 #endif
00652 }
00653 --reservnumber;
00654 }
00655 ptr->age = NEW;
00656 }
00657
00665
00666 void
00667 reserve(
00668 typecorecrum *ptr)
00669 {
00670 #ifndef DISTRIBUTION
00671 foohex("reserve\n", (int) ptr);
00672 #endif
00673 if (ptr->age != RESERVED) {
00674 ++reservnumber;
00675 } else {
00676 #ifndef DISTRIBUTION
00677 assert(0);
00678 #else
00679 assert(0);
00680 #endif
00681 }
00682 ptr->age = RESERVED;
00683 }
00684
00692 void
00693 testforreservedness(
00694 char *msg)
00695 {
00696
00697 int numreserved = 0;
00698 bool first;
00699
00700 typecorecrum *ptr;
00701 for (ptr = grimreaper, first = true; ptr && (first ? true : ptr != grimreaper); ptr = ptr->nextcrum, first = false)
00702 if (ptr->age == RESERVED) {
00703 ++numreserved;
00704 if (true || debug)
00705 dump(ptr);
00706 }
00707
00708 if (numreserved) {
00709 L("numreserved = %s: There are %d reserved crums. (reservnumber = %d)\n", msg, numreserved, reservnumber);
00710 assert(0);
00711 }
00712
00713 if (reservnumber) {
00714 L("reservnumber = %d\n", reservnumber);
00715 assert(0);
00716 }
00717 }
00718
00726
00727 void
00728 subtreefree(
00729 typecorecrum *ptr)
00730 {
00731 if (!ptr)
00732 assert(0);
00733
00734 if (ptr->height > 0) {
00735 typecorecrum *p, *right;
00736
00737 for (p = ((typecuc *) ptr)->leftson; p; p = right) {
00738 right = p->rightbro;
00739 disown(p);
00740 subtreefree(p);
00741 }
00742
00743 } else if (ptr->cenftype == GRAN
00744 && ((typecbc *) ptr)->cinfo.infotype == GRANORGL
00745 && ((typecbc *) ptr)->cinfo.granstuff.orglstuff.orglincore)
00746 orglfree(((typecbc *) ptr)->cinfo.granstuff.orglstuff.orglptr);
00747
00748 freecrum(ptr);
00749 }
00750
00758 void
00759 freecrum(
00760 typecorecrum *ptr)
00761 {
00762 if (ptr->age == RESERVED)
00763 assert(0);
00764
00765 if (grimreaper == ptr)
00766 grimreaper = grimreaper->nextcrum;
00767
00768 if (grimreaper == ptr)
00769 grimreaper = NULL;
00770
00771 ptr->nextcrum->prevcrum = ptr->prevcrum;
00772 ptr->prevcrum->nextcrum = ptr->nextcrum;
00773
00774
00775
00776 --crumnumber;
00777 efree((char *)ptr);
00778 }
00779
00787 void
00788 loaffree(
00789 typecuc *father)
00790 {
00791 if (father->height <= 0 )
00792 assert(0);
00793
00794 typecorecrum *ptr, *next;
00795 for (ptr = father->leftson; ptr; ptr = next) {
00796 next = ptr->rightbro;
00797 disownnomodify(ptr);
00798 subtreefree(ptr);
00799 }
00800
00801 father->modified = false;
00802 }
00803
00811 void
00812 orglfree(
00813 typecuc *ptr)
00814 {
00815 assert(ptr);
00816 assert(ptr->isapex);
00817 assert(((typecbc *) ptr->leftbroorfather)->cinfo.granstuff.orglstuff.diskorglptr.diskblocknumber != DISKPTRNULL);
00818
00819 ((typecbc *) ptr->leftbroorfather)->cinfo.granstuff.orglstuff.orglincore = false;
00820 ((typecbc *) ptr->leftbroorfather)->cinfo.granstuff.orglstuff.orglptr = NULL;
00821
00822 subtreefree((typecorecrum *) ptr);
00823 }
00824
00832 typecuc *
00833 createenf(
00834 int enftype)
00835 {
00836 typecuc *fullcrumptr = (typecuc *) createcrum(1, enftype);
00837
00838 fullcrumptr->cenftype = enftype;
00839 fullcrumptr->isapex = true;
00840 fullcrumptr->isleftmost = true;
00841
00842 typecorecrum *ptr = createcrum(0, enftype);
00843
00844 adopt(ptr, SON, (typecorecrum *) fullcrumptr);
00845 if (enftype == GRAN)
00846 ((typecbc *) ptr)->cinfo.infotype = GRANNULL;
00847
00848 ivemodified(ptr);
00849
00850
00851
00852
00853
00854 return fullcrumptr;
00855 }
00856
00864 typecorecrum *
00865 createcrum(
00866 int crumheight,
00867 int enftype)
00868 {
00869 typecorecrum *ptr = createcruminternal(crumheight, enftype, (typecorecrum *) NULL);
00870
00871 if (grimreaper) {
00872 ptr->nextcrum = grimreaper;
00873 ptr->prevcrum = grimreaper->prevcrum;
00874 grimreaper->prevcrum->nextcrum = ptr;
00875 grimreaper->prevcrum = ptr;
00876 } else
00877 grimreaper = ptr->nextcrum = ptr->prevcrum = ptr;
00878
00879 return ptr;
00880 }