phys.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /* $Id$ */
  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 "phys.h"
  10. /* Physical manipulations.
  11. The blocks concerned are not in any logical chain.
  12. */
  13. public mallink *
  14. create_chunk(p, n)
  15. char *p;
  16. unsigned int n;
  17. {
  18. /* The newly acquired piece of memory at p, of length n,
  19. is turned into a free chunk, properly chained in the
  20. physical chain.
  21. The address of the chunk is returned.
  22. */
  23. register mallink *ml;
  24. /* All of malloc memory is followed by a virtual chunk, the
  25. mallink of which starts mallink_size() bytes past the last
  26. byte in memory.
  27. Its use is prevented by testing for ml == ml_last first.
  28. */
  29. register mallink *last = ml_last;
  30. assert(!last || p == (char *)phys_next_of(last) - mallink_size());
  31. ml = (mallink *)(p + mallink_size()); /* bump ml */
  32. new_mallink(ml);
  33. started_working_on(ml);
  34. set_free(ml, 1);
  35. set_phys_prev(ml, last);
  36. ml_last = ml;
  37. set_phys_next(ml, (mallink *)((char *)ml + n));
  38. calc_checksum(ml);
  39. assert(size_of(ml) + mallink_size() == n);
  40. if (last && free_of(last)) {
  41. coalesce_backw(ml, last);
  42. ml = last;
  43. }
  44. check_mallinks("create_chunk, phys. linked");
  45. return ml;
  46. }
  47. public
  48. truncate(ml, size)
  49. register mallink *ml;
  50. unsigned int size;
  51. {
  52. /* The chunk ml is truncated.
  53. The chunk at ml is split in two.
  54. The remaining part is then freed.
  55. */
  56. register mallink *new = (mallink *)((char *)ml + size);
  57. register mallink *ph_next = phys_next_of(ml);
  58. new_mallink(new);
  59. set_free(new, 1);
  60. set_phys_prev(new, ml);
  61. set_phys_next(new, ph_next);
  62. calc_checksum(new);
  63. if (! last_mallink(ml)) {
  64. set_phys_prev(ph_next, new);
  65. calc_checksum(ph_next);
  66. if (free_of(ph_next)) coalesce_forw(new, ph_next);
  67. }
  68. else ml_last = new;
  69. set_phys_next(ml, new);
  70. calc_checksum(ml);
  71. started_working_on(new);
  72. link_free_chunk(new);
  73. stopped_working_on(new);
  74. check_mallinks("truncate");
  75. }
  76. public
  77. combine_chunks(ml1, ml2)
  78. register mallink *ml1, *ml2;
  79. {
  80. /* The chunks ml1 and ml2 are combined.
  81. */
  82. register mallink *ml3 = phys_next_of(ml2);
  83. set_phys_next(ml1, ml3);
  84. calc_checksum(ml1);
  85. if (!last_mallink(ml2)) {
  86. set_phys_prev(ml3, ml1);
  87. calc_checksum(ml3);
  88. }
  89. if (ml_last == ml2)
  90. ml_last = ml1;
  91. }