log.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /* $Header$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. */
  6. #include "param.h"
  7. #include "impl.h"
  8. #include "check.h"
  9. #include "log.h"
  10. /* Logical manipulations.
  11. The chunks are properly chained in the physical chain.
  12. */
  13. privatedata mallink *free_list[MAX_FLIST];
  14. public
  15. link_free_chunk(ml)
  16. register mallink *ml;
  17. {
  18. /* The free chunk ml is inserted in its proper logical
  19. chain.
  20. */
  21. register mallink **mlp = &free_list[-1];
  22. register size_type n = size_of(ml);
  23. register mallink *ml1;
  24. assert(n < (1L << LOG_MAX_SIZE));
  25. do {
  26. n >>= 1;
  27. mlp++;
  28. }
  29. while (n >= MIN_SIZE);
  30. ml1 = *mlp;
  31. set_log_prev(ml, MAL_NULL);
  32. set_log_next(ml, ml1);
  33. calc_checksum(ml);
  34. if (ml1) {
  35. /* link backwards
  36. */
  37. set_log_prev(ml1, ml);
  38. calc_checksum(ml1);
  39. }
  40. *mlp = ml;
  41. }
  42. public
  43. unlink_free_chunk(ml)
  44. register mallink *ml;
  45. {
  46. /* Unlinks a free chunk from (the middle of) the
  47. logical chain.
  48. */
  49. register mallink *next = log_next_of(ml);
  50. register mallink *prev = log_prev_of(ml);
  51. if (!prev) {
  52. /* it is the first in the chain */
  53. register mallink **mlp = &free_list[-1];
  54. register size_type n = size_of(ml);
  55. assert(n < (1L << LOG_MAX_SIZE));
  56. do {
  57. n >>= 1;
  58. mlp++;
  59. }
  60. while (n >= MIN_SIZE);
  61. *mlp = next;
  62. }
  63. else {
  64. set_log_next(prev, next);
  65. calc_checksum(prev);
  66. }
  67. if (next) {
  68. set_log_prev(next, prev);
  69. calc_checksum(next);
  70. }
  71. }
  72. public mallink *
  73. search_free_list(class, n)
  74. unsigned int n;
  75. {
  76. /* Searches the free_list[class] for a chunk of at least size n;
  77. since it is searching a slightly undersized list,
  78. such a block may not be there.
  79. */
  80. register mallink *ml;
  81. for (ml = free_list[class]; ml; ml = log_next_of(ml))
  82. if (size_of(ml) >= n)
  83. return ml;
  84. return MAL_NULL; /* nothing found */
  85. }
  86. public mallink *
  87. first_present(class)
  88. int class;
  89. {
  90. /* Find the index i in free_list[] such that:
  91. i >= class && free_list[i] != MAL_NULL.
  92. Return MAL_NULL if no such i exists;
  93. Otherwise, return the first block of this list, after
  94. unlinking it.
  95. */
  96. register mallink **mlp, *ml;
  97. for (mlp = &free_list[class]; mlp < &free_list[MAX_FLIST]; mlp++) {
  98. if ((ml = *mlp) != MAL_NULL) {
  99. *mlp = log_next_of(ml); /* may be MAL_NULL */
  100. if (*mlp) {
  101. /* unhook backward link
  102. */
  103. set_log_prev(*mlp, MAL_NULL);
  104. calc_checksum(*mlp);
  105. }
  106. return ml;
  107. }
  108. }
  109. return MAL_NULL;
  110. }
  111. #ifdef CHECK
  112. public mallink *
  113. free_list_entry(i) {
  114. /* To allow maldump.c access to log.c's private data.
  115. */
  116. return free_list[i];
  117. }
  118. #endif /* CHECK */