talloc.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include <stdlib.h>
  2. #include "talloc.h"
  3. struct trec {
  4. struct trec* parent;
  5. struct trec* child;
  6. struct trec* sibling;
  7. };
  8. void* talloc(void* parent, size_t size) {
  9. struct trec* c = malloc(size + sizeof(struct trec));
  10. if(parent) {
  11. struct trec* p = &((struct trec*)parent)[-1];
  12. c->sibling = p->child;
  13. p->child = c;
  14. c->parent = p;
  15. }
  16. else {
  17. c->sibling = NULL;
  18. c->parent = NULL;
  19. }
  20. c->child = NULL;
  21. return &c[1];
  22. }
  23. void* trealloc(void* old, size_t size) {
  24. struct trec* o = &((struct trec*)old)[-1];
  25. struct trec* n;
  26. n = realloc(o, size + sizeof(struct trec));
  27. if(n == o) return n;
  28. // fix parent
  29. struct trec* p = n->parent;
  30. if(p->child == o) {
  31. p->child = n;
  32. }
  33. else {
  34. struct trec* z = p->child;
  35. while(z->sibling != o) z = z->sibling;
  36. z->sibling = n;
  37. }
  38. // fix children
  39. struct trec* z = n->child;
  40. while(z) {
  41. z->parent = n;
  42. z = z->sibling;
  43. }
  44. return n;
  45. }
  46. // designed for cascading frees, no parent list fixing
  47. static void tfree_fast(struct trec* p) {
  48. struct trec* c = p->child;
  49. struct trec* o;
  50. // free all children
  51. while(c) {
  52. o = c;
  53. c = c->sibling;
  54. tfree_fast(o);
  55. }
  56. free(p);
  57. }
  58. void tfree(void* m) {
  59. // parent is being deleted
  60. struct trec* p = &((struct trec*)m)[-1];
  61. struct trec* c = p->child;
  62. struct trec* o;
  63. // free all children
  64. while(c) {
  65. o = c;
  66. c = c->sibling;
  67. tfree_fast(o);
  68. }
  69. // fix the grandparent's linked list
  70. struct trec* g = p->parent;
  71. if(g) {
  72. struct trec* n = g->child;
  73. if(n == p) {
  74. g->child = p->sibling;
  75. }
  76. else {
  77. while(n->sibling != p) n = n->sibling;
  78. n->sibling = p->sibling;
  79. }
  80. }
  81. free(p);
  82. }