tl_mem.c 2.6 KB

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