18 #include "DynArr256.hpp" 
   50 #define require(x) require_exit_or_core_with_printer((x), 0, ndbout_printer) 
   53 #define DA256_EXTRA_SAFE 
   58 #include <valgrind/callgrind.h> 
   60 #define CALLGRIND_TOGGLE_COLLECT() 
   62 Uint32 allocatedpages = 0;
 
   63 Uint32 allocatednodes = 0;
 
   64 Uint32 releasednodes = 0;
 
   69 require_impl(
bool x, 
int line)
 
   73     ndbout_c(
"LINE: %d", line);
 
   78 DynArr256Pool::DynArr256Pool()
 
   86 DynArr256Pool::init(Uint32 type_id, 
const Pool_context & pc)
 
   92 DynArr256Pool::init(NdbMutex* m, Uint32 type_id, 
const Pool_context & pc)
 
  100 static const Uint32 g_max_sizes[5] = { 0, 256, 65536, 16777216, ~0 };
 
  112   Uint32 sz = m_head.m_sz;
 
  113   Uint32 ptrI = m_head.m_ptr_i;
 
  115   Uint32 type_id = (~m_pool.m_type_id) & 0xFFFF;
 
  117   if (unlikely(pos >= g_max_sizes[sz]))
 
  123   Uint32 px[4] = { (pos >> 24) & 255, 
 
  129   Uint32* retVal = &m_head.m_ptr_i;
 
  132     if (unlikely(ptrI == RNIL))
 
  139     Uint32 shr = sz << 3;
 
  140     Uint32 p0 = (pos >> shr) & 255;
 
  142     Uint32 page_no = ptrI >> DA256_BITS;
 
  143     Uint32 page_idx = ptrI & DA256_MASK;
 
  146     Uint32 *magic_ptr, p;
 
  149       Uint32 line = ((p0 << 8) + (p0 << 4) + p0 + 255) >> 12;
 
  150       Uint32 * ptr = (Uint32*)(page->m_nodes + page_idx);
 
  153       retVal = (ptr + 1 + p0 + line);
 
  154       magic_ptr =(ptr + (p0 & ~15));
 
  158       Uint32 b = (page_idx + 1) >> 4;
 
  159       Uint32 * ptr = (Uint32*)(page->m_header+b);
 
  161       p = page_idx - (b << 4) + b;
 
  162       retVal = (ptr + 1 + p);
 
  167     Uint32 magic = *magic_ptr;
 
  169     if (unlikely(! ((magic & (1 << p)) && (magic >> 16) == type_id)))
 
  180 DynArr256::set(Uint32 pos)
 
  182   Uint32 sz = m_head.m_sz;
 
  183   Uint32 type_id = (~m_pool.m_type_id) & 0xFFFF;  
 
  186   if (unlikely(pos >= g_max_sizes[sz]))
 
  188     if (unlikely(!expand(pos)))
 
  196   Uint32 px[4] = { (pos >> 24) & 255, 
 
  202   Uint32 ptrI = m_head.m_ptr_i;
 
  203   Uint32 *retVal = &m_head.m_ptr_i;
 
  209     Uint32 shr = sz << 3;
 
  210     Uint32 p0 = (pos >> shr) & 255;
 
  214       if (unlikely((ptrI = m_pool.seize()) == RNIL))
 
  221     Uint32 page_no = ptrI >> DA256_BITS;
 
  222     Uint32 page_idx = ptrI & DA256_MASK;
 
  225     Uint32 *magic_ptr, p;
 
  228       Uint32 line = ((p0 << 8) + (p0 << 4) + p0 + 255) >> 12;
 
  229       Uint32 * ptr = (Uint32*)(page->m_nodes + page_idx);
 
  232       magic_ptr = (ptr + (p0 & ~15));
 
  233       retVal = (ptr + 1 + p0 + line);
 
  237       Uint32 b = (page_idx + 1) >> 4;
 
  238       Uint32 * ptr = (Uint32*)(page->m_header+b);
 
  240       p = page_idx - (b << 4) + b;
 
  242       retVal = (ptr + 1 + p);
 
  246     Uint32 magic = *magic_ptr;
 
  248     if (unlikely(! ((magic & (1 << p)) && (magic >> 16) == type_id)))
 
  262 initpage(
DA256Page* p, Uint32 page_no, Uint32 type_id)
 
  265 #ifdef DA256_USE_PREFETCH 
  266 #if defined(__GNUC__) && !(__GNUC__ == 2 && __GNUC_MINOR__ < 96) 
  267 #ifdef DA256_EXTRA_SAFE 
  268   for (i = 0; i<(30 * 17 + 2); i++)
 
  270     __builtin_prefetch (p->m_header + i, 1);    
 
  274     __builtin_prefetch (p->m_header + 0, 1);    
 
  275     __builtin_prefetch (p->m_header + 1, 1);    
 
  276     for (i = 0; i<30; i++)
 
  278       __builtin_prefetch (p->m_nodes + i, 1);
 
  285   for  (i = 0; i<2; i++)
 
  287     cl = p->m_header + 
i;
 
  288     cl->m_magic = (~type_id << 16);
 
  293   for (i = 0; i<30; i++)
 
  296     free->m_magic = type_id;
 
  297     free->m_next_free = (page_no << DA256_BITS) + (i + 1);
 
  298 #ifdef DA256_EXTRA_SAFE 
  300     for (j = 0; j<17; j++)
 
  301       node->m_lines[j].m_magic = type_id;
 
  306   free->m_next_free = RNIL;
 
  310 DynArr256::expand(Uint32 pos)
 
  315   Uint32 sz = m_head.m_sz;
 
  317   for (; pos >= g_max_sizes[sz]; sz++);
 
  319   if (m_head.m_sz == 0)
 
  326   for (; pos >= g_max_sizes[sz]; sz++)
 
  328     Uint32 ptrI = m_pool.seize();
 
  329     if (unlikely(ptrI == RNIL))
 
  334   alloc[idx] = m_head.m_ptr_i;
 
  336   for (i = 0; i<idx; i++)
 
  338     m_head.m_ptr_i = alloc[
i];
 
  339     Uint32 * ptr = 
get(0);
 
  340     * ptr = alloc[i + 1];
 
  344   m_head.m_ptr_i = alloc[0];
 
  349   for (i = 0; i<idx; i++)
 
  350     m_pool.release(alloc[i]);
 
  355 DynArr256::init(ReleaseIterator &iter)
 
  359   iter.m_ptr_i[0] = RNIL;
 
  360   iter.m_ptr_i[1] = m_head.m_ptr_i;
 
  361   iter.m_ptr_i[2] = RNIL;
 
  362   iter.m_ptr_i[3] = RNIL;
 
  363   iter.m_ptr_i[4] = RNIL;
 
  376   Uint32 sz = iter.m_sz;
 
  377   Uint32 ptrI = iter.m_ptr_i[sz];
 
  378   Uint32 page_no = ptrI >> DA256_BITS;
 
  379   Uint32 page_idx = ptrI & DA256_MASK;
 
  380   Uint32 type_id = (~m_pool.m_type_id) & 0xFFFF;
 
  386     Uint32 p0 = iter.m_pos & 255;
 
  389       Uint32 *retVal, *magic_ptr, p;
 
  392         Uint32 line = ((p0 << 8) + (p0 << 4) + p0 + 255) >> 12;
 
  393         Uint32 * ptr = (Uint32*)(page->m_nodes + page_idx);
 
  396         retVal = (ptr + 1 + p0 + line);
 
  397         magic_ptr =(ptr + (p0 & ~15));
 
  401         Uint32 b = (page_idx + 1) >> 4;
 
  402         Uint32 * ptr = (Uint32*)(page->m_header+b);
 
  404         p = page_idx - (b << 4) + b;
 
  405         retVal = (ptr + 1 + p);
 
  409       Uint32 magic = *magic_ptr;
 
  410       Uint32 val = *retVal;
 
  411       if (unlikely(! ((magic & (1 << p)) && (magic >> 16) == type_id)))
 
  414       if (sz == m_head.m_sz)
 
  423           iter.m_pos &= ~(Uint32)255;
 
  431           m_pool.release(ptrI);
 
  437       else if (val != RNIL)
 
  440         iter.m_ptr_i[iter.m_sz] = val;
 
  441         iter.m_pos = (p0 << 8);
 
  448     m_pool.release(ptrI);
 
  454   new (&m_head) 
Head();
 
  465 seizenode(
DA256Page* page, Uint32 idx, Uint32 type_id)
 
  468   Uint32 b = (idx + 1) >> 4;
 
  469   Uint32 p = idx - (b << 4) + b;
 
  473 #ifdef DA256_USE_PREFETCH 
  474 #if defined(__GNUC__) && !(__GNUC__ == 2 && __GNUC_MINOR__ < 96) 
  475   __builtin_prefetch (page->m_header + b, 1); 
 
  476   for (i = 0; i<17; i++)
 
  478     __builtin_prefetch (ptr->m_lines+i, 1);    
 
  483 #ifdef DA256_EXTRA_SAFE 
  484   Uint32 check = type_id;
 
  486   type_id = ((~type_id) << 16) | 0xFFFF;
 
  488 #ifdef DA256_EXTRA_SAFE 
  489   if (unlikely(((page->m_header + b)->m_magic & (1 << p)) != 0))
 
  495   (page->m_header + b)->m_magic |= (1 << p);
 
  496   (page->m_header + b)->m_data[p] = RNIL;
 
  497   for (i = 0; i<17; i++)
 
  500 #ifdef DA256_EXTRA_SAFE 
  501     if (unlikely(line->m_magic != check))
 
  506     line->m_magic = type_id;
 
  507     for (Uint32 j = 0; j<15; j++)
 
  508       line->m_data[j] = RNIL;
 
  519 releasenode(
DA256Page* page, Uint32 idx, Uint32 type_id)
 
  522   Uint32 b = (idx + 1) >> 4;
 
  523   Uint32 p = idx - (b << 4) + b;
 
  527 #ifdef DA256_USE_PREFETCH 
  528 #if defined(__GNUC__) && !(__GNUC__ == 2 && __GNUC_MINOR__ < 96) 
  529   __builtin_prefetch (page->m_header + b, 1); 
 
  530   for (i = 0; i<17; i++)
 
  532     __builtin_prefetch (ptr->m_lines+i, 1);    
 
  537 #ifdef DA256_EXTRA_SAFE 
  538   Uint32 check = ((~type_id) << 16) | 0xFFFF;
 
  541 #ifdef DA256_EXTRA_SAFE 
  542   if (unlikely((((page->m_header + b)->m_magic & (1 << p)) == 0)))
 
  548   (page->m_header + b)->m_magic ^= (1 << p);
 
  549   for (i = 0; i<17; i++)
 
  552 #ifdef DA256_EXTRA_SAFE 
  553     if (unlikely(line->m_magic != check))
 
  558     line->m_magic = type_id;
 
  569 DynArr256Pool::seize()
 
  571   Uint32 type_id = m_type_id;
 
  576   Uint32 ff = m_first_free;
 
  582       initpage(page, page_no, type_id);
 
  591     ff = (page_no << DA256_BITS);
 
  595     page = memroot + (ff >> DA256_BITS);
 
  598   Uint32 idx = ff & DA256_MASK;
 
  600   if (likely(ptr->m_magic == type_id))
 
  602     Uint32 next = ptr->m_next_free;
 
  603     if (likely(seizenode(page, idx, type_id)))
 
  616 DynArr256Pool::release(Uint32 ptrI)
 
  618   Uint32 type_id = m_type_id;
 
  620   Uint32 page_no = ptrI >> DA256_BITS;
 
  621   Uint32 page_idx = ptrI & DA256_MASK;
 
  626   if (likely(releasenode(page, page_idx, type_id)))
 
  628     ptr->m_magic = type_id;
 
  630     Uint32 ff = m_first_free;
 
  631     ptr->m_next_free = ff;
 
  641 #include "ndbd_malloc_impl.hpp" 
  642 #include "SimulatedBlock.hpp" 
  656 simple(
DynArr256 & arr, 
int argc, 
char* argv[])
 
  658   ndbout_c(
"argc: %d", argc);
 
  659   for (Uint32 i = 1; i<(Uint32)argc; i++)
 
  661     Uint32 * s = arr.set(atoi(argv[i]));
 
  664       for (Uint32 j = 1; j<
i; j++)
 
  666         if (atoi(argv[i]) == atoi(argv[j]))
 
  676     Uint32 * g = arr.
get(atoi(argv[i]));
 
  677     Uint32 v = g ? *g : ~0;
 
  678     ndbout_c(
"p: %p %p %d", s, g, v);
 
  684 basic(
DynArr256& arr, 
int argc, 
char* argv[])
 
  689   Uint32 save[2*MAXLEN];
 
  690   for (Uint32 i = 0; i<MAXLEN; i++)
 
  692     int op = (rand() % 100) > 50;
 
  699       Uint32 item = (rand() % len) << 1;
 
  700       Uint32 idx = save[item];
 
  701       Uint32 val = save[item+1];
 
  703       Uint32 *p = arr.
get(idx);
 
  709       Uint32 item = len << 1;
 
  713       for(Uint32 j = 0; j < item; j += 2)
 
  723       Uint32 *p = arr.set(idx);
 
  725       if (item == (len << 1))
 
  732         assert(* p == save[item+1]);
 
  746   gettimeofday(&tv, 0);
 
  747   unsigned long long ret = tv.tv_sec;
 
  755 read(
DynArr256& arr, 
int argc, 
char ** argv)
 
  758   Uint64 mbytes = 16*1024;
 
  759   Uint32 seed = time(0);
 
  760   Uint32 seq = 0, seqmask = 0;
 
  762   for (Uint32 i = 2; i<argc; i++)
 
  764     if (strncmp(argv[i], 
"--mbytes=", 
sizeof(
"--mbytes=")-1) == 0)
 
  766       mbytes = atoi(argv[i]+
sizeof(
"--mbytes=")-1);
 
  767       if (argv[i][strlen(argv[i])-1] == 
'g' ||
 
  768           argv[i][strlen(argv[i])-1] == 
'G')
 
  771     else if (strncmp(argv[i], 
"--cnt=", 
sizeof(
"--cnt=")-1) == 0)
 
  773       cnt = atoi(argv[i]+
sizeof(
"--cnt=")-1);
 
  775     else if (strncmp(argv[i], 
"--seq", 
sizeof(
"--seq")-1) == 0)
 
  784   Uint32 maxidx = (1024*mbytes+31) / 32;
 
  785   Uint32 nodes = (maxidx+255) / 256;
 
  786   Uint32 pages = (nodes + 29)/ 30;
 
  787   ndbout_c(
"%lldmb data -> %d entries (%dkb)",
 
  788            mbytes, maxidx, 32*pages);
 
  790   for (Uint32 i = 0; i<maxidx; i++)
 
  792     Uint32 *ptr = arr.set(i);
 
  802     seqmask = ~(Uint32)0;
 
  805   ndbout_c(
"Timing %d %s reads (seed: %u)", cnt, 
 
  806            seq ? 
"sequential" : 
"random", seed);
 
  808   for (Uint32 i = 0; i<10; i++)
 
  810     Uint32 sum0 = 0, sum1 = 0;
 
  811     Uint64 start = micro();
 
  812     for (Uint32 i = 0; i<cnt; i++)
 
  814       Uint32 idx = ((rand() & (~seqmask)) + ((i + seq) & seqmask)) % maxidx;
 
  815       Uint32 *ptr = arr.
get(idx);
 
  819     start = micro() - start;
 
  820     float uspg = start; uspg /= cnt;
 
  821     ndbout_c(
"Elapsed %lldus diff: %d -> %f us/get", start, sum0 - sum1, uspg);
 
  827 write(
DynArr256& arr, 
int argc, 
char ** argv)
 
  829   Uint32 seq = 0, seqmask = 0;
 
  831   Uint64 mbytes = 16*1024;
 
  832   Uint32 seed = time(0);
 
  834   for (Uint32 i = 2; i<argc; i++)
 
  836     if (strncmp(argv[i], 
"--mbytes=", 
sizeof(
"--mbytes=")-1) == 0)
 
  838       mbytes = atoi(argv[i]+
sizeof(
"--mbytes=")-1);
 
  839       if (argv[i][strlen(argv[i])-1] == 
'g' ||
 
  840           argv[i][strlen(argv[i])-1] == 
'G')
 
  843     else if (strncmp(argv[i], 
"--cnt=", 
sizeof(
"--cnt=")-1) == 0)
 
  845       cnt = atoi(argv[i]+
sizeof(
"--cnt=")-1);
 
  847     else if (strncmp(argv[i], 
"--seq", 
sizeof(
"--seq")-1) == 0)
 
  856   Uint32 maxidx = (1024*mbytes+31) / 32;
 
  857   Uint32 nodes = (maxidx+255) / 256;
 
  858   Uint32 pages = (nodes + 29)/ 30;
 
  859   ndbout_c(
"%lldmb data -> %d entries (%dkb)",
 
  860            mbytes, maxidx, 32*pages);
 
  867     seqmask = ~(Uint32)0;
 
  870   ndbout_c(
"Timing %d %s writes (seed: %u)", cnt, 
 
  871            seq ? 
"sequential" : 
"random", seed);
 
  872   for (Uint32 i = 0; i<10; i++)
 
  874     Uint64 start = micro();
 
  875     for (Uint32 i = 0; i<cnt; i++)
 
  877       Uint32 idx = ((rand() & (~seqmask)) + ((i + seq) & seqmask)) % maxidx;
 
  878       Uint32 *ptr = arr.set(idx);
 
  881     start = micro() - start;
 
  882     float uspg = start; uspg /= cnt;
 
  883     ndbout_c(
"Elapsed %lldus -> %f us/set", start, uspg);
 
  887     while(arr.
release(iter, &val));
 
  892 main(
int argc, 
char** argv)
 
  896     for (Uint32 i = 0; i<30; i++)
 
  898       Uint32 b = (i + 1) >> 4;
 
  899       Uint32 p = i - (b << 4) + b;
 
  900       printf(
"[ %d %d %d ]\n", i, b, p);
 
  911   rl.m_resource_id = 0;
 
  919   pool.init(0x2001, pc);
 
  924   if (strcmp(argv[1], 
"--simple") == 0)
 
  925     simple(arr, argc, argv);
 
  926   else if (strcmp(argv[1], 
"--basic") == 0)
 
  927     basic(arr, argc, argv);
 
  928   else if (strcmp(argv[1], 
"--read") == 0)
 
  929     read(arr, argc, argv);
 
  930   else if (strcmp(argv[1], 
"--write") == 0)
 
  931     write(arr, argc, argv);
 
  936   while (arr.
release(iter, &val)) cnt++;
 
  938   ndbout_c(
"allocatedpages: %d allocatednodes: %d releasednodes: %d" 
  947   printf(
"sizeof(DA256Page): %d\n", 
sizeof(
DA256Page));
 
  951   for (Uint32 i = 0; i<10000; i++)
 
  953     Uint32 arg = rand() & 255;
 
  955     Uint32 idx = arg & 256;
 
  962       Uint32 b = (base + 1) >> 4;
 
  963       Uint32 p = base - (b << 4) + b;
 
  964       Uint32 magic = page.m_header[b].m_magic;
 
  965       Uint32 retVal = page.m_header[b].m_data[p];
 
  967       require(magic & (1 << p));
 
  973       Uint32 line = idx / 15;
 
  974       Uint32 off = idx % 15;
 
  977         Uint32 pos = 1 + idx + line;
 
  978         Uint32 magic = pos & ~15;
 
  980         Uint32 * ptr = (Uint32*)&page.m_nodes[base];
 
  981         assert((ptr + pos) == &page.m_nodes[base].m_lines[line].m_data[off]);
 
  982         assert((ptr + magic) == &page.m_nodes[base].m_lines[line].m_magic);
 
  989 Uint32 g_currentStartPhase;
 
  994 UpgradeStartup::sendCmAppChg(
Ndbcntr& cntr, 
Signal* signal, Uint32 startLevel){
 
 1002 UpgradeStartup::sendCntrMasterReq(
Ndbcntr& cntr, 
Signal* signal, Uint32 
n){
 
 1009 #include <SimBlockList.hpp> 
 1012 SimBlockList::unload()