tl_mem.c 2.5 KB

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