20 #include "ndbd_malloc_impl.hpp"
21 #include <ndb_global.h>
22 #include <EventLogger.hpp>
23 #include <portlib/NdbMem.h>
26 void *sbrk(
int increment)
34 static int f_method_idx = 0;
35 #ifdef NDBD_MALLOC_METHOD_SBRK
36 static const char * f_method =
"SMsm";
38 static const char * f_method =
"MSms";
43 #ifndef NDBD_RANDOM_START_PAGE
44 #define NDBD_RANDOM_START_PAGE
48 #ifdef NDBD_RANDOM_START_PAGE
49 static Uint32 g_random_start_page_id = 0;
59 extern void mt_mem_manager_init();
60 extern void mt_mem_manager_lock();
61 extern void mt_mem_manager_unlock();
69 #define ZONE_LO_BOUND (1u << 19)
73 extern void ndbd_alloc_touch_mem(
void * p,
size_t sz,
volatile Uint32 * watchCounter);
77 do_malloc(Uint32 pages,
90 char method = f_method[f_method_idx];
105 if (ptr == (
void*)-1)
114 sz = 1 + (9 * sz) / 10;
115 if (pages >= 32 && sz < 32)
122 else if (UintPtr(ptr) < UintPtr(baseaddress))
127 ndbout_c(
"sbrk(%lluMb) => %p which is less than baseaddress!!",
128 Uint64((
sizeof(
Alloc_page) * sz) >> 20), ptr);
145 if (UintPtr(ptr) < UintPtr(baseaddress))
147 ndbout_c(
"malloc(%lluMb) => %p which is less than baseaddress!!",
148 Uint64((
sizeof(
Alloc_page) * sz) >> 20), ptr);
161 sz = 1 + (9 * sz) / 10;
162 if (pages >= 32 && sz < 32)
178 if (UintPtr(ptr) & align)
181 chunk->m_ptr = (
Alloc_page*)((UintPtr(ptr) + align) & ~align);
185 ndbout_c(
"do_malloc(%d) -> %p %d", pages, ptr, chunk->m_cnt);
190 for (Uint32
i = 0;
i<chunk->m_cnt;
i++, page++)
192 page->m_data[0*1024] = 0;
193 page->m_data[1*1024] = 0;
194 page->m_data[2*1024] = 0;
195 page->m_data[3*1024] = 0;
196 page->m_data[4*1024] = 0;
197 page->m_data[5*1024] = 0;
198 page->m_data[6*1024] = 0;
199 page->m_data[7*1024] = 0;
212 input = input | (input >> 8);
213 input = input | (input >> 4);
214 input = input | (input >> 2);
215 input = input | (input >> 1);
216 Uint32 output = (input & 0x5555) + ((input >> 1) & 0x5555);
217 output = (output & 0x3333) + ((output >> 2) & 0x3333);
218 output = output + (output >> 4);
219 output = (output & 0xf) + ((output >> 8) & 0xf);
223 Ndbd_mem_manager::Ndbd_mem_manager()
226 memset(m_buddy_lists, 0,
sizeof(m_buddy_lists));
227 memset(m_resource_limit, 0,
sizeof(m_resource_limit));
231 g_eventLogger->
error(
"Invalid build, ndbd_malloc_impl.cpp:%d", __LINE__);
234 mt_mem_manager_init();
238 Ndbd_mem_manager::get_memroot()
const
240 #ifdef NDBD_RANDOM_START_PAGE
241 return (
void*)(m_base_page - g_random_start_page_id);
243 return (
void*)m_base_page;
265 Uint32
id = rl.m_resource_id;
266 assert(
id < XX_RL_COUNT);
268 Uint32 reserve =
id ? rl.m_min : 0;
269 mt_mem_manager_lock();
270 Uint32 current_reserved = m_resource_limit[0].m_min;
272 m_resource_limit[
id] = rl;
273 m_resource_limit[
id].m_curr = 0;
274 m_resource_limit[0].m_min = current_reserved + reserve;
275 mt_mem_manager_unlock();
279 Ndbd_mem_manager::get_resource_limit(Uint32
id,
Resource_limit& rl)
const
281 if (
id < XX_RL_COUNT)
283 mt_mem_manager_lock();
284 rl = m_resource_limit[
id];
285 mt_mem_manager_unlock();
298 Uint32 res_alloc = 0;
299 Uint32 shared_alloc = 0;
301 for (Uint32
i = 1;
i<XX_RL_COUNT;
i++)
303 curr += rl[
i].m_curr;
304 sumres += rl[
i].m_min;
305 assert(rl[
i].m_max == 0 || rl[
i].m_curr <= rl[
i].m_max);
306 if (rl[
i].m_curr > rl[
i].m_min)
308 shared_alloc += rl[
i].m_curr - rl[
i].m_min;
309 res_alloc += rl[
i].m_min;
313 res_alloc += rl[
i].m_curr;
316 assert(curr == rl[0].m_curr);
317 assert(res_alloc + shared_alloc == curr);
318 assert(res_alloc <= sumres);
319 assert(sumres == res_alloc + rl[0].m_min);
320 assert(rl[0].m_curr <= rl[0].m_max);
325 cmp_chunk(
const void * chunk_vptr_1,
const void * chunk_vptr_2)
329 if (ptr1->m_ptr < ptr2->m_ptr)
331 if (ptr1->m_ptr > ptr2->m_ptr)
340 assert(m_base_page == 0);
347 Uint32 reserved = m_resource_limit[0].m_min;
348 if (m_resource_limit[0].m_max)
350 pages = m_resource_limit[0].m_max;
354 pages = m_resource_limit[0].m_min;
357 if (m_resource_limit[0].m_min == 0)
359 m_resource_limit[0].m_min = pages;
363 g_eventLogger->
info(
"Ndbd_mem_manager::init(%d) min: %lluMb initial: %lluMb",
365 (pg*m_resource_limit[0].m_min)>>20,
373 #if SIZEOF_CHARP == 4
374 Uint64 sum = (pg*pages);
375 if (sum >= (Uint64(1) << 32))
377 g_eventLogger->
error(
"Trying to allocate more that 4Gb with 32-bit binary!!");
382 #ifdef NDBD_RANDOM_START_PAGE
389 Uint32 max_rand_start = ZONE_LO_BOUND - 1;
390 if (max_rand_start > pages)
392 max_rand_start -= pages;
393 if (max_rand_start > 0x10000)
394 g_random_start_page_id = 0x10000 + (rand() % (max_rand_start - 0x10000));
395 else if (max_rand_start)
396 g_random_start_page_id = rand() % max_rand_start;
398 assert(Uint64(pages) + Uint64(g_random_start_page_id) <= 0xFFFFFFFF);
400 ndbout_c(
"using g_random_start_page_id: %u (%.8x)",
401 g_random_start_page_id, g_random_start_page_id);
408 Uint32 allocated = 0;
409 while (m_unmapped_chunks.size() < MAX_CHUNKS && allocated < pages)
412 memset(&chunk, 0,
sizeof(chunk));
414 if (do_malloc(pages - allocated, &chunk, watchCounter, m_base_page))
419 m_unmapped_chunks.push_back(chunk);
420 allocated += chunk.m_cnt;
428 if (allocated < m_resource_limit[0].m_min)
431 error(
"Unable to alloc min memory from OS: min: %lldMb "
432 " allocated: %lldMb",
433 (Uint64)(
sizeof(
Alloc_page)*m_resource_limit[0].m_min) >> 20,
434 (Uint64)(
sizeof(
Alloc_page)*allocated) >> 20);
437 else if (allocated < pages)
440 warning(
"Unable to alloc requested memory from OS: min: %lldMb"
441 " requested: %lldMb allocated: %lldMb",
442 (Uint64)(
sizeof(
Alloc_page)*m_resource_limit[0].m_min)>>20,
443 (Uint64)(
sizeof(
Alloc_page)*m_resource_limit[0].m_max)>>20,
445 if (!alloc_less_memory)
452 qsort(m_unmapped_chunks.getBase(), m_unmapped_chunks.size(),
455 m_base_page = m_unmapped_chunks[0].m_ptr;
457 for (Uint32
i = 0;
i<m_unmapped_chunks.size();
i++)
459 UintPtr start = UintPtr(m_unmapped_chunks[
i].m_ptr) - UintPtr(m_base_page);
460 start >>= (2 + BMW_2LOG);
461 assert((Uint64(start) >> 32) == 0);
462 m_unmapped_chunks[
i].m_start = Uint32(start);
463 Uint64 last64 = start + m_unmapped_chunks[
i].m_cnt;
464 assert((last64 >> 32) == 0);
465 Uint32 last = Uint32(last64);
471 m_resource_limit[0].m_resource_id = max_page;
472 m_resource_limit[0].m_min = reserved;
473 m_resource_limit[0].m_max = 0;
481 Uint32
limit = ~(Uint32)0;
487 for (Uint32
i = 0; resources[
i] ;
i++)
489 limit += m_resource_limit[resources[
i]].m_min;
493 while (m_unmapped_chunks.size() && sofar <
limit)
495 Uint32 remain = limit - sofar;
497 unsigned idx = m_unmapped_chunks.size() - 1;
498 InitChunk * chunk = &m_unmapped_chunks[idx];
502 if (chunk->m_cnt > remain)
507 Uint32
extra = chunk->m_cnt - remain;
508 chunk->m_cnt = remain;
511 newchunk.m_start = chunk->m_start + remain;
512 newchunk.m_ptr = m_base_page + newchunk.m_start;
513 newchunk.m_cnt = extra;
514 m_unmapped_chunks.push_back(newchunk);
517 chunk = &m_unmapped_chunks[idx];
520 ndbd_alloc_touch_mem(chunk->m_ptr,
537 Uint32 cnt = chunk->m_cnt;
543 NdbMem_MemLock(start, 32768 *
sizeof(
Alloc_page));
550 NdbMem_MemLock(start, cnt *
sizeof(
Alloc_page));
553 grow(chunk->m_start, chunk->m_cnt);
554 sofar += chunk->m_cnt;
556 m_unmapped_chunks.erase(idx);
559 mt_mem_manager_lock();
560 check_resource_limits(m_resource_limit);
561 mt_mem_manager_unlock();
563 if (resources == 0 && memlock)
565 NdbMem_MemLockAll(1);
569 #include <NdbOut.hpp>
572 Ndbd_mem_manager::grow(Uint32 start, Uint32 cnt)
575 Uint32 start_bmp = start >> BPP_2LOG;
576 Uint32 last_bmp = (start + cnt - 1) >> BPP_2LOG;
578 #if SIZEOF_CHARP == 4
579 assert(start_bmp == 0 && last_bmp == 0);
582 if (start_bmp != last_bmp)
584 Uint32 tmp = ((start_bmp + 1) << BPP_2LOG) - start;
586 grow((start_bmp + 1) << BPP_2LOG, cnt - tmp);
590 if ((start + cnt) == ((start_bmp + 1) << BPP_2LOG))
595 for (Uint32
i = 0;
i<m_used_bitmap_pages.size();
i++)
596 if (m_used_bitmap_pages[
i] == start_bmp)
599 if (start != (start_bmp << BPP_2LOG))
602 ndbout_c(
"ndbd_malloc_impl.cpp:%d:grow(%d, %d) %d!=%d not using %uMb"
603 " - Unable to use due to bitmap pages missaligned!!",
604 __LINE__, start, cnt, start, (start_bmp << BPP_2LOG),
606 g_eventLogger->
error(
"ndbd_malloc_impl.cpp:%d:grow(%d, %d) not using %uMb"
607 " - Unable to use due to bitmap pages missaligned!!",
608 __LINE__, start, cnt,
616 ndbout_c(
"creating bitmap page %d", start_bmp);
625 m_used_bitmap_pages.push_back(start_bmp);
630 mt_mem_manager_lock();
631 m_resource_limit[0].m_curr += cnt;
632 m_resource_limit[0].m_max += cnt;
633 if (start >= ZONE_LO_BOUND)
635 Uint64 mbytes = ((Uint64(cnt) * 32) + 1023) / 1024;
636 ndbout_c(
"Adding %uMb to ZONE_HI (%u,%u)", (Uint32)mbytes, start, cnt);
639 else if (start + cnt <= ZONE_LO_BOUND)
641 Uint64 mbytes = ((Uint64(cnt)*32) + 1023) / 1024;
642 ndbout_c(
"Adding %uMb to ZONE_LO (%u,%u)", (Uint32)mbytes, start, cnt);
647 Uint32 cnt0 = ZONE_LO_BOUND - start;
648 Uint32 cnt1 = start + cnt - ZONE_LO_BOUND;
649 Uint64 mbytes0 = ((Uint64(cnt0)*32) + 1023) / 1024;
650 Uint64 mbytes1 = ((Uint64(cnt1)*32) + 1023) / 1024;
651 ndbout_c(
"Adding %uMb to ZONE_LO (split %u,%u)", (Uint32)mbytes0,
653 ndbout_c(
"Adding %uMb to ZONE_HI (split %u,%u)", (Uint32)mbytes1,
654 ZONE_LO_BOUND, cnt1);
655 release(start, cnt0);
656 release(ZONE_LO_BOUND, cnt1);
658 mt_mem_manager_unlock();
663 Ndbd_mem_manager::release(Uint32 start, Uint32 cnt)
665 assert(m_resource_limit[0].m_curr >= cnt);
667 m_resource_limit[0].m_curr -= cnt;
669 set(start, start+cnt-1);
671 Uint32 zone = start < ZONE_LO_BOUND ? 0 : 1;
672 release_impl(zone, start, cnt);
676 Ndbd_mem_manager::release_impl(Uint32 zone, Uint32 start, Uint32 cnt)
680 Uint32
test = check(start-1, start+cnt);
681 if (start != ZONE_LO_BOUND && test & 1)
685 Uint32 sz = fd->m_size;
686 Uint32 left = start - sz;
687 remove_free_list(zone, left, fd->m_list);
692 Uint32 right = start + cnt;
693 if (right != ZONE_LO_BOUND && test & 2)
695 Free_page_data *fd = get_free_page_data(m_base_page+right, right);
696 Uint32 sz = fd->m_size;
697 remove_free_list(zone, right, fd->m_list);
701 insert_free_list(zone, start, cnt);
705 Ndbd_mem_manager::alloc(AllocZone zone,
706 Uint32*
ret, Uint32 *pages, Uint32 min)
708 if (zone == NDB_ZONE_ANY)
710 Uint32 save = * pages;
711 alloc_impl(ZONE_HI, ret, pages, min);
717 alloc_impl(ZONE_LO, ret, pages, min);
721 Ndbd_mem_manager::alloc_impl(Uint32 zone,
722 Uint32* ret, Uint32 *pages, Uint32 min)
726 Uint32 cnt = * pages;
732 for (i = list; i < 16; i++)
734 if ((start = m_buddy_lists[zone][i]))
741 Uint32 sz = remove_free_list(zone, start, i);
742 Uint32
extra = sz - cnt;
746 insert_free_list(zone, start + cnt, extra);
747 clear_and_set(start, start+cnt-1);
751 clear(start, start+cnt-1);
754 assert(m_resource_limit[0].m_curr + cnt <= m_resource_limit[0].m_max);
765 assert((Int32)list >= min_list);
766 for (i = list - 1; i >= min_list; i--)
768 if ((start = m_buddy_lists[zone][i]))
770 Uint32 sz = remove_free_list(zone, start, i);
771 Uint32
extra = sz - cnt;
774 insert_free_list(zone, start + cnt, extra);
776 clear_and_set(start, start+sz-1);
780 clear(start, start+sz-1);
785 assert(m_resource_limit[0].m_curr + sz <= m_resource_limit[0].m_max);
793 Ndbd_mem_manager::insert_free_list(Uint32 zone, Uint32 start, Uint32
size)
796 Uint32 last = start + size - 1;
798 Uint32 head = m_buddy_lists[zone][list];
801 fd_first->m_list = list;
802 fd_first->m_next = head;
803 fd_first->m_prev = 0;
804 fd_first->m_size =
size;
806 Free_page_data* fd_last = get_free_page_data(m_base_page+last, last);
807 fd_last->m_list = list;
808 fd_last->m_next = head;
810 fd_last->m_size =
size;
815 assert(fd->m_prev == 0);
816 assert(fd->m_list == list);
820 m_buddy_lists[zone][list] = start;
824 Ndbd_mem_manager::remove_free_list(Uint32 zone, Uint32 start, Uint32 list)
826 Free_page_data* fd = get_free_page_data(m_base_page+start, start);
827 Uint32 size = fd->m_size;
828 Uint32 next = fd->m_next;
829 Uint32 prev = fd->m_prev;
830 assert(fd->m_list == list);
834 assert(m_buddy_lists[zone][list] != start);
835 fd = get_free_page_data(m_base_page+prev, prev);
836 assert(fd->m_next == start);
837 assert(fd->m_list == list);
842 assert(m_buddy_lists[zone][list] == start);
843 m_buddy_lists[zone][list] = next;
848 fd = get_free_page_data(m_base_page+next, next);
849 assert(fd->m_list == list);
850 assert(fd->m_prev == start);
858 Ndbd_mem_manager::dump()
const
860 mt_mem_manager_lock();
861 for (Uint32 zone = 0; zone < 2; zone ++)
863 for (Uint32 i = 0; i<16; i++)
865 printf(
" list: %d - ", i);
866 Uint32 head = m_buddy_lists[zone][
i];
870 printf(
"[ i: %d prev %d next %d list %d size %d ] ",
871 head, fd->m_prev, fd->m_next, fd->m_list, fd->m_size);
877 for (Uint32 i = 0; i<XX_RL_COUNT; i++)
879 printf(
"ri: %d min: %d curr: %d max: %d\n",
881 m_resource_limit[i].m_min,
882 m_resource_limit[i].m_curr,
883 m_resource_limit[i].m_max);
886 mt_mem_manager_unlock();
890 Ndbd_mem_manager::alloc_page(Uint32
type, Uint32* i, AllocZone zone)
892 Uint32 idx = type & RG_MASK;
893 assert(idx && idx < XX_RL_COUNT);
894 mt_mem_manager_lock();
899 Uint32 res0 = (rl.m_curr < rl.m_min) ? 1 : 0;
900 Uint32
limit = (rl.m_max == 0 || rl.m_curr < rl.m_max) ? 0 : 1;
901 Uint32 free = (tot.m_min + tot.m_curr < tot.m_max) ? 1 : 0;
903 assert(tot.m_min >= res0);
905 if (likely(res0 == 1 || (limit == 0 && free == 1)))
907 alloc(zone, i, &cnt, 1);
910 m_resource_limit[0].m_curr = tot.m_curr + cnt;
911 m_resource_limit[0].m_min = tot.m_min - res0;
912 m_resource_limit[idx].m_curr = rl.m_curr + cnt;
914 check_resource_limits(m_resource_limit);
915 mt_mem_manager_unlock();
916 #ifdef NDBD_RANDOM_START_PAGE
917 *i += g_random_start_page_id;
918 return m_base_page + *i - g_random_start_page_id;
920 return m_base_page + *
i;
924 mt_mem_manager_unlock();
929 Ndbd_mem_manager::release_page(Uint32 type, Uint32 i)
931 Uint32 idx = type & RG_MASK;
932 assert(idx && idx < XX_RL_COUNT);
933 mt_mem_manager_lock();
937 #ifdef NDBD_RANDOM_START_PAGE
938 i -= g_random_start_page_id;
941 Uint32 sub = (rl.m_curr <= rl.m_min) ? 1 : 0;
943 m_resource_limit[0].m_curr = tot.m_curr - 1;
944 m_resource_limit[0].m_min = tot.m_min + sub;
945 m_resource_limit[idx].m_curr = rl.m_curr - 1;
947 check_resource_limits(m_resource_limit);
948 mt_mem_manager_unlock();
952 Ndbd_mem_manager::alloc_pages(Uint32 type, Uint32* i, Uint32 *cnt, Uint32 min)
954 Uint32 idx = type & RG_MASK;
955 assert(idx && idx < XX_RL_COUNT);
956 mt_mem_manager_lock();
962 Uint32 max = rl.m_max - rl.m_curr;
963 Uint32 res0 = rl.m_min - rl.m_curr;
964 Uint32 free_shared = tot.m_max - (tot.m_min + tot.m_curr);
967 if (rl.m_curr + req <= rl.m_min)
975 req = rl.m_max ? max : req;
976 res0 = (rl.m_curr > rl.m_min) ? 0 : res0;
979 if (unlikely(res1 > free_shared))
989 assert (res0 + res1 == req);
990 assert (tot.m_min >= res0);
995 alloc(NDB_ZONE_ANY, i, &req, min);
997 if (unlikely(req < res0))
1001 assert(tot.m_min >= res0);
1002 assert(tot.m_curr + req <= tot.m_max);
1004 m_resource_limit[0].m_curr = tot.m_curr + req;
1005 m_resource_limit[0].m_min = tot.m_min - res0;
1006 m_resource_limit[idx].m_curr = rl.m_curr + req;
1007 check_resource_limits(m_resource_limit);
1008 mt_mem_manager_unlock();
1009 #ifdef NDBD_RANDOM_START_PAGE
1010 *i += g_random_start_page_id;
1014 mt_mem_manager_unlock();
1016 #ifdef NDBD_RANDOM_START_PAGE
1017 *i += g_random_start_page_id;
1023 Ndbd_mem_manager::release_pages(Uint32 type, Uint32 i, Uint32 cnt)
1025 Uint32 idx = type & RG_MASK;
1026 assert(idx && idx < XX_RL_COUNT);
1027 mt_mem_manager_lock();
1031 #ifdef NDBD_RANDOM_START_PAGE
1032 i -= g_random_start_page_id;
1037 Uint32 currnew = rl.m_curr - cnt;
1038 if (rl.m_curr > rl.m_min)
1040 if (currnew < rl.m_min)
1042 m_resource_limit[0].m_min = tot.m_min + (rl.m_min - currnew);
1047 m_resource_limit[0].m_min = tot.m_min + cnt;
1049 m_resource_limit[0].m_curr = tot.m_curr - cnt;
1050 m_resource_limit[idx].m_curr = currnew;
1051 check_resource_limits(m_resource_limit);
1052 mt_mem_manager_unlock();
1057 #include <Vector.hpp>
1058 #include <NdbTick.h>
1070 Timer() { sum = cnt = 0;}
1075 gettimeofday(&st, 0);
1078 Uint64 calc_diff() {
1080 gettimeofday(&st2, 0);
1081 Uint64 diff = st2.tv_sec;
1084 diff += st2.tv_usec;
1093 void add(Uint64 diff) { sum += diff; cnt++;}
1095 void print(
const char * title)
const {
1098 printf(
"%s %fus/call %lld %d\n", title, ps, sum, cnt);
1103 main(
int argc,
char** argv)
1108 sz = 32*atoi(argv[1]);
1111 run_time = atoi(argv[2]);
1115 printf(
"Startar modul test av Page Manager %dMb %ds\n",
1116 (sz >> 5), run_time);
1119 g_eventLogger->
enable(Logger::LL_ON, Logger::LL_INFO);
1120 g_eventLogger->
enable(Logger::LL_ON, Logger::LL_CRITICAL);
1121 g_eventLogger->
enable(Logger::LL_ON, Logger::LL_ERROR);
1122 g_eventLogger->
enable(Logger::LL_ON, Logger::LL_WARNING);
1131 rl.m_resource_id = 0;
1133 rl.m_min = sz < 16384 ? sz : 16384;
1135 rl.m_resource_id = 1;
1140 printf(
"pid: %d press enter to continue\n", getpid());
1141 fgets(buf,
sizeof(buf), stdin);
1143 time_t stop = time(0) + run_time;
1144 for(Uint32 i = 0; time(0) < stop; i++){
1148 Uint32 c = (rand() % 100);
1162 Uint32 alloc = 1 + rand() % 3200;
1164 if(chunks.size() == 0 && c == 0)
1170 printf(
"loop=%d ", i);
1173 const int ch = rand() % chunks.size();
1174 Chunk chunk = chunks[ch];
1177 Uint64 start = NdbTick_CurrentMillisecond();
1178 mem.release(chunk.pageId, chunk.pageCount);
1181 printf(
" release %d %d\n", chunk.pageId, chunk.pageCount);
1190 chunk.pageCount = alloc;
1193 printf(
" alloc %d -> ", alloc); fflush(stdout);
1196 mem.alloc(&chunk.pageId, &chunk.pageCount, 1);
1197 Uint64 diff = timer[0].calc_diff();
1200 printf(
"%d %d", chunk.pageId, chunk.pageCount);
1201 assert(chunk.pageCount <= alloc);
1202 if(chunk.pageCount != 0){
1203 chunks.push_back(chunk);
1204 if(chunk.pageCount != alloc) {
1207 printf(
" - Tried to allocate %d - only allocated %d - free: %d",
1208 alloc, chunk.pageCount, 0);
1217 printf(
" Failed to alloc %d pages with %d pages free",
1227 while(chunks.size() > 0){
1228 Chunk chunk = chunks.back();
1229 mem.release(chunk.pageId, chunk.pageCount);
1230 chunks.erase(chunks.size() - 1);
1233 const char *title[] = {
1239 for(Uint32 i = 0; i<4; i++)
1240 timer[i].print(title[i]);