/* Copyright (C) 2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "ArrayPool.hpp" #include "WOPool.hpp" #include "RWPool.hpp" #include #include "ndbd_malloc_impl.hpp" #include "SimulatedBlock.hpp" #ifdef USE_CALLGRIND #include #else #define CALLGRIND_TOGGLE_COLLECT() #endif #define T_TEST_AP (1 << 0) #define T_TEST_WO (1 << 1) #define T_TEST_RW (1 << 2) #define T_SEIZE (1 << 0) #define T_RELEASE (1 << 1) #define T_G_RELEASE (1 << 2) #define T_R_RELEASE (1 << 3) #define T_R_G_RELEASE (1 << 4) #define T_MIX (1 << 5) #define T_GETPTR (1 << 6) #define T_FIFO (1 << 7) const char *test_names[] = { "seize", "release", "get+rel", "r-rel", "r-get+rel", "mix", "getptr", "fifo", 0 }; Uint32 pools = ~0; Uint32 tests = ~0; Uint32 records = ~0; Uint32 sizes = 7; unsigned int seed; Ndbd_mem_manager mm; Configuration cfg; Block_context ctx(cfg, mm); struct BB : public SimulatedBlock { BB(int no, Block_context& ctx) : SimulatedBlock(no, ctx) {} }; BB block(DBACC, ctx); template void init(ArrayPool & pool, Uint32 cnt) { pool.setSize(cnt + 1, true); } template void init(RecordPool & pool, Uint32 cnt) { Pool_context pc; pc.m_block = █ pool.wo_pool_init(0x2001, pc); } template void init(RecordPool & pool, Uint32 cnt) { Pool_context pc; pc.m_block = █ pool.init(0x2001, pc); } template void test_pool(R& pool, Uint32 cnt, Uint32 loops) { Ptr ptr; Uint32 *arr = (Uint32*)alloca(cnt * sizeof(Uint32)); bzero(arr, cnt * sizeof(Uint32)); if (tests & T_SEIZE) { Uint64 sum = 0; for(Uint32 i = 0; ido_stuff(); assert(b); } CALLGRIND_TOGGLE_COLLECT(); Uint64 stop = NdbTick_CurrentMillisecond(); for(Uint32 j = 0; jdo_stuff(); pool.release(ptr.i); arr[j] = RNIL; } sum += (stop - start); } printf(" ; %lld", sum); fflush(stdout); } if (tests & T_RELEASE) { // release Uint64 sum = 0; for(Uint32 i = 0; ido_stuff(); } Uint64 start = NdbTick_CurrentMillisecond(); CALLGRIND_TOGGLE_COLLECT(); for(Uint32 j = 0; jdo_stuff(); } Uint64 start = NdbTick_CurrentMillisecond(); CALLGRIND_TOGGLE_COLLECT(); for(Uint32 j = 0; jdo_stuff(); pool.release(ptr); arr[j] = RNIL; } CALLGRIND_TOGGLE_COLLECT(); Uint64 stop = NdbTick_CurrentMillisecond(); sum += (stop - start); } printf(" ; %lld", sum); fflush(stdout); } if (tests & T_R_RELEASE) { // release reverse Uint64 sum = 0; for(Uint32 i = 0; ido_stuff(); } Uint64 start = NdbTick_CurrentMillisecond(); CALLGRIND_TOGGLE_COLLECT(); for(Uint32 j = 0; jdo_stuff(); } Uint64 start = NdbTick_CurrentMillisecond(); CALLGRIND_TOGGLE_COLLECT(); for(Uint32 j = 0; jdo_stuff(); pool.release(ptr); arr[cnt - j - 1] = RNIL; } CALLGRIND_TOGGLE_COLLECT(); Uint64 stop = NdbTick_CurrentMillisecond(); sum += (stop - start); } printf(" ; %lld", sum); fflush(stdout); } if (tests & T_MIX) { Uint64 sum = 0; Uint64 start = NdbTick_CurrentMillisecond(); Uint32 lseed = seed; CALLGRIND_TOGGLE_COLLECT(); for(Uint32 i = 0; ido_stuff(); } else { pool.getPtr(ptr); ptr.p->do_stuff(); pool.release(ptr); arr[pos] = RNIL; } } CALLGRIND_TOGGLE_COLLECT(); Uint64 stop = NdbTick_CurrentMillisecond(); for(Uint32 j = 0; jdo_stuff(); assert(b); } Uint64 sum = 0; Uint64 start = NdbTick_CurrentMillisecond(); CALLGRIND_TOGGLE_COLLECT(); for(Uint32 i = 0; ido_stuff(); } CALLGRIND_TOGGLE_COLLECT(); Uint64 stop = NdbTick_CurrentMillisecond(); for(Uint32 j = 0; jdo_stuff(); pool.release(ptr.i); arr[j] = RNIL; } sum += (stop - start); printf(" ; %lld", sum); fflush(stdout); } if (tests & T_FIFO) { // fifo Uint64 sum = 0; Uint64 start = NdbTick_CurrentMillisecond(); CALLGRIND_TOGGLE_COLLECT(); for(Uint32 i = 0; ido_stuff(); ptr.p->m_nextList = RNIL; if (head == RNIL) { head = ptr.i; } else { T* t = pool.getPtr(last); t->m_nextList = ptr.i; } last = ptr.i; } while (head != RNIL) { pool.getPtr(ptr, head); ptr.p->do_stuff(); head = ptr.p->m_nextList; pool.release(ptr); } } CALLGRIND_TOGGLE_COLLECT(); Uint64 stop = NdbTick_CurrentMillisecond(); sum += (stop - start); printf(" ; %lld", sum); fflush(stdout); } ndbout_c(""); } template struct Rec { Uint32 m_data; Uint32 m_magic; Uint32 nextPool; Uint32 m_nextList; char m_cdata[sz-16]; void do_stuff() { Uint32 sum = 0; Uint32 *ptr = (Uint32*)this; for(Uint32 i = 0; i<(sz >> 2); i++) sum += * ptr ++; m_data = sum; } }; typedef Rec<32> Rec32; typedef Rec<36> Rec36; typedef Rec<56> Rec56; typedef Rec<224> Rec224; template void test_ap(Uint32 cnt, Uint32 loop) { printf("AP ; %d ; %d", sizeof(T), (cnt * sizeof(T))>>10); fflush(stdout); ArrayPool pool; init(pool, cnt); test_pool >(pool, cnt, loop); } template void test_rw(Uint32 cnt, Uint32 loop) { printf("RW ; %d ; %d", sizeof(T), (cnt * sizeof(T))>>10); fflush(stdout); RecordPool pool; init(pool, cnt); test_pool >(pool, cnt, loop); } template void test_wo(Uint32 cnt, Uint32 loop) { printf("WO ; %d ; %d", sizeof(T), (cnt * sizeof(T))>>10); fflush(stdout); RecordPool pool; init(pool, cnt); test_pool >(pool, cnt, loop); } #include extern EventLogger g_eventLogger; int main(int argc, char **argv) { Uint32 loops = 300000; for (Uint32 i = 1 ; i i+1 && strcmp(argv[i], "-pools") == 0) { pools = 0; for (Uint32 j = 0; j= '0' && c <= '9') pools |= 1 << (c - '0'); else pools |= 1 << (10 + (c - 'a')); } } else if (argc > i+1 && strcmp(argv[i], "-tests") == 0) { tests = 0; for (Uint32 j = 0; j= '0' && c <= '9') tests |= 1 << (c - '0'); else tests |= 1 << (10 + (c - 'a')); } } else if (argc > i+1 && strcmp(argv[i], "-sizes") == 0) { sizes = 0; for (Uint32 j = 0; j= '0' && c <= '9') sizes |= 1 << (c - '0'); else sizes |= 1 << (10 + (c - 'a')); } } else if (argc > i+1 && strcmp(argv[i], "-records") == 0) { records = 0; for (Uint32 j = 0; j= '0' && c <= '9') records |= 1 << (c - '0'); else records |= 1 << (10 + (c - 'a')); } } else if (argc > i+1 && strcmp(argv[i], "-loop") == 0) { loops = atoi(argv[i+1]); } } Resource_limit rl; rl.m_min = 0; rl.m_max = 10000; rl.m_resource_id = 0; mm.set_resource_limit(rl); if(!mm.init()) { abort(); } seed = time(0); Uint32 sz = 0; Uint32 cnt = 256; printf("pool ; rs ; ws"); for (Uint32 i = 0; test_names[i] && i<31; i++) if (tests & (1 << i)) printf(" ; %s", test_names[i]); ndbout_c(""); while(cnt <= 1000000) { Uint32 loop = 768 * loops / cnt; if (sizes & (1 << sz)) { if (records & 1) { if (pools & T_TEST_AP) test_ap(cnt, loop); if (pools & T_TEST_WO) test_wo(cnt, loop); if (pools & T_TEST_RW) test_rw(cnt, loop); } if (records & 2) { if (pools & T_TEST_AP) test_ap(cnt, loop); if (pools & T_TEST_WO) test_wo(cnt, loop); if (pools & T_TEST_RW) test_rw(cnt, loop); } if (records & 4) { if (pools & T_TEST_AP) test_ap(cnt, loop); if (pools & T_TEST_WO) test_wo(cnt, loop); if (pools & T_TEST_RW) test_rw(cnt, loop); } if (records & 8) { if (pools & T_TEST_AP) test_ap(cnt, loop); if (pools & T_TEST_WO) test_wo(cnt, loop); if (pools & T_TEST_RW) test_rw(cnt, loop); } } cnt += (512 << sz); sz++; } } Uint32 g_currentStartPhase; Uint32 g_start_type; NdbNodeBitmask g_nowait_nodes; void childExit(int code, Uint32 currentStartPhase) { abort(); } void childAbort(int code, Uint32 currentStartPhase) { abort(); } void childReportError(int error) { abort(); } void UpgradeStartup::sendCmAppChg(Ndbcntr& cntr, Signal* signal, Uint32 startLevel){ } void UpgradeStartup::execCM_APPCHG(SimulatedBlock & block, Signal* signal){ } void UpgradeStartup::sendCntrMasterReq(Ndbcntr& cntr, Signal* signal, Uint32 n){ } void UpgradeStartup::execCNTR_MASTER_REPLY(SimulatedBlock & block, Signal* signal){ } #include void SimBlockList::unload() { } #define INSTANCE(X) \ template void test_ap(unsigned, unsigned);\ template void test_wo(unsigned, unsigned);\ template void test_rw(unsigned, unsigned);\ template void test_pool >(ArrayPool&, unsigned, unsigned);\ template void test_pool >(RecordPool&, unsigned, unsigned); \ template void test_pool >(RecordPool&, unsigned, unsigned);\ template void init(ArrayPool&, unsigned);\ template void init(RecordPool&, unsigned);\ template void init(RecordPool&, unsigned) INSTANCE(Rec32); INSTANCE(Rec36); INSTANCE(Rec56); INSTANCE(Rec224);