freelist.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #include "precomp_wasabi_bfc.h"
  2. #include "freelist.h"
  3. // define this to turn off freelist behavior
  4. //#define FREELIST_FUCT
  5. FreelistPriv::FreelistPriv() {
  6. total_allocated = 0;
  7. }
  8. FreelistPriv::~FreelistPriv() {
  9. #ifdef ASSERTS_ENABLED
  10. // ASSERTPR(total_allocated == 0, "didn't free entire freelist!(1)");
  11. // ASSERTPR(blocks.getNumItems() == 0, "didn't free entire freelist!(2)");
  12. if (total_allocated != 0) DebugStringW(L"didn't free entire freelist!(1)\n");
  13. if (blocks.getNumItems() != 0) DebugStringW(L"didn't free entire freelist!(2)\n");
  14. #endif
  15. }
  16. void *FreelistPriv::getRecord(int typesize, int blocksize, int initialblocksize) {
  17. #ifdef FREELIST_FUCT
  18. return MALLOC(typesize);
  19. #else
  20. ASSERT(typesize >= sizeof(void *));
  21. FLMemBlock *mem = NULL;
  22. for (int i = 0; i < blocks.getNumItems(); i++) {
  23. mem = blocks[i];
  24. if (mem->freelist != NULL) break;
  25. mem = NULL;
  26. }
  27. if (mem == NULL) {
  28. // figure record count for this new block
  29. int siz = (blocks.getNumItems() ? blocksize : initialblocksize);
  30. // allocate another block of memory
  31. mem = new FLMemBlock(siz*typesize);
  32. // prelink it into a freelist
  33. char *record = static_cast<char *>(mem->freelist);
  34. void **ptr;
  35. for (int i = 0; i < siz-1; i++) {
  36. ptr = reinterpret_cast<void **>(record);
  37. record += typesize;
  38. *ptr = static_cast<void *>(record);
  39. }
  40. // terminate newly made freelist
  41. ptr = reinterpret_cast<void **>(record);
  42. *ptr = NULL;
  43. blocks.addItem(mem);
  44. }
  45. // get first free record
  46. void *ret = mem->freelist;
  47. // advance freelist *
  48. mem->freelist = *(static_cast<void **>(mem->freelist));
  49. mem->nallocated++;
  50. total_allocated++;
  51. return ret;
  52. #endif
  53. }
  54. void FreelistPriv::freeRecord(void *record) {
  55. #ifdef FREELIST_FUCT
  56. FREE(record);
  57. #else
  58. FLMemBlock *mem=NULL;
  59. for (int i = 0; i < blocks.getNumItems(); i++) {
  60. mem = blocks[i];
  61. if (mem->isMine(reinterpret_cast<MBT*>(record))) break;
  62. mem = NULL;
  63. }
  64. ASSERTPR(mem != NULL, "attempted to free record with no block");
  65. // stash it back on the block's freelist
  66. *reinterpret_cast<void **>(record) = mem->freelist;
  67. mem->freelist = record;
  68. ASSERT(mem->nallocated > 0);
  69. mem->nallocated--;
  70. if (mem->nallocated == 0) {
  71. blocks.delItem(mem);
  72. }
  73. total_allocated--;
  74. #endif
  75. }