tl_mem.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. /***** tl_spin: tl_mem.c *****/
  10. /* Copyright (c) 1995-2003 by Lucent Technologies, Bell Laboratories. */
  11. /* All Rights Reserved. This software is for educational purposes only. */
  12. /* No guarantee whatsoever is expressed or implied by the distribution of */
  13. /* this code. Permission is given to distribute this code provided that */
  14. /* this introductory message is not removed and no monies are exchanged. */
  15. /* Software written by Gerard J. Holzmann. For tool documentation see: */
  16. /* http://spinroot.com/ */
  17. /* Send all bug-reports and/or questions to: bugs@spinroot.com */
  18. /* Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, */
  19. /* presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. */
  20. #include "tl.h"
  21. #if 1
  22. #define log(e, u, d) event[e][(int) u] += (int32_t) d;
  23. #else
  24. #define log(e, u, d)
  25. #endif
  26. #define A_LARGE 80
  27. #define A_USER 0x55000000
  28. #define NOTOOBIG 32768
  29. #define POOL 0
  30. #define ALLOC 1
  31. #define FREE 2
  32. #define NREVENT 3
  33. extern unsigned long All_Mem;
  34. extern int tl_verbose;
  35. union M {
  36. int32_t size;
  37. union M *link;
  38. };
  39. static union M *freelist[A_LARGE];
  40. static int32_t req[A_LARGE];
  41. static int32_t event[NREVENT][A_LARGE];
  42. void *
  43. tl_emalloc(int U)
  44. { union M *m;
  45. int32_t r, u;
  46. void *rp;
  47. u = (int32_t) ((U-1)/sizeof(union M) + 2);
  48. if (u >= A_LARGE)
  49. { log(ALLOC, 0, 1);
  50. if (tl_verbose)
  51. printf("tl_spin: memalloc %ld bytes\n", u);
  52. m = (union M *) emalloc((int) u*sizeof(union M));
  53. All_Mem += (unsigned long) u*sizeof(union M);
  54. } else
  55. { if (!freelist[u])
  56. { r = req[u] += req[u] ? req[u] : 1;
  57. if (r >= NOTOOBIG)
  58. r = req[u] = NOTOOBIG;
  59. log(POOL, u, r);
  60. freelist[u] = (union M *)
  61. emalloc((int) r*u*sizeof(union M));
  62. All_Mem += (unsigned long) r*u*sizeof(union M);
  63. m = freelist[u] + (r-2)*u;
  64. for ( ; m >= freelist[u]; m -= u)
  65. m->link = m+u;
  66. }
  67. log(ALLOC, u, 1);
  68. m = freelist[u];
  69. freelist[u] = m->link;
  70. }
  71. m->size = (u|A_USER);
  72. for (r = 1; r < u; )
  73. (&m->size)[r++] = 0;
  74. rp = (void *) (m+1);
  75. memset(rp, 0, U);
  76. return rp;
  77. }
  78. void
  79. tfree(void *v)
  80. { union M *m = (union M *) v;
  81. int32_t u;
  82. --m;
  83. if ((m->size&0xFF000000) != A_USER)
  84. Fatal("releasing a free block", (char *)0);
  85. u = (m->size &= 0xFFFFFF);
  86. if (u >= A_LARGE)
  87. { log(FREE, 0, 1);
  88. /* free(m); */
  89. } else
  90. { log(FREE, u, 1);
  91. m->link = freelist[u];
  92. freelist[u] = m;
  93. }
  94. }
  95. void
  96. a_stats(void)
  97. { int32_t p, a, f;
  98. int i;
  99. printf(" size\t pool\tallocs\t frees\n");
  100. for (i = 0; i < A_LARGE; i++)
  101. { p = event[POOL][i];
  102. a = event[ALLOC][i];
  103. f = event[FREE][i];
  104. if(p|a|f)
  105. printf("%5d\t%6ld\t%6ld\t%6ld\n",
  106. i, p, a, f);
  107. }
  108. }