Ejemplo n.º 1
0
END_TEST


START_TEST(updateLogEntryAllocNoExtras)
{
  Tinit();

  recordid rid = { 3 , 4, sizeof(int)*3 };

  stasis_log_t *l = (stasis_log_t *)stasis_log();
  LogEntry * log = allocUpdateLogEntry(l, 200, 1, OPERATION_SET,
                                       rid.page, 0);
  assert(log->prevLSN == 200);
  assert(log->xid == 1);
  assert(log->type == UPDATELOG);

  assert(log->update.funcID    == OPERATION_SET);
  assert(log->update.page   == 3);
  assert(log->update.arg_size    == 0);

  assert(stasis_log_entry_update_args_ptr(log) == NULL);

  assert(sizeofLogEntry(0, log) == (sizeof(struct __raw_log_entry) + sizeof(UpdateLogEntry) + 0 * (sizeof(int)+sizeof(char))));

  l->write_entry(l, log);
  l->write_entry_done(l, log);

  Tdeinit();
}
Ejemplo n.º 2
0
int main(int argc, char * argv[]) {
  if(argc != 3) { printf(usage, argv[0]); abort(); }
  char * endptr;
  numthreads = strtoul(argv[1], &endptr, 10);
  if(*endptr != 0) { printf(usage, argv[0]); abort(); }
  numops= strtoul(argv[2], &endptr, 10) / numthreads;
  if(*endptr != 0) { printf(usage, argv[0]); abort(); }

  pthread_t workers[numthreads];

  Page * p;
  Tinit();

  dpt = stasis_runtime_dirty_page_table();

  p = loadPage(-1,0);

  for(int i = 0; i < numthreads; i++) {
    pthread_create(&workers[i], 0, worker, p);
  }
  for(int i = 0; i < numthreads; i++) {
    pthread_join(workers[i], 0);
  }

  releasePage(p);

  Tdeinit();
}
Ejemplo n.º 3
0
int main(int argc, char** argv) {

  assert(argc == 3);

  int xact_count = atoi(argv[1]);
  int count = atoi(argv[2]);

  /*  unlink("storefile.txt");
  unlink("logfile.txt");
  unlink("blob0_file.txt");
  unlink("blob1_file.txt");*/

  Tinit();
  
  int xid = Tbegin();

  recordid hash = TnaiveHashCreate(xid, sizeof(int), sizeof(int));

  Tcommit(xid);

  int i = 0;
  int k;
  for(k = 0; k < xact_count; k++) {
    xid = Tbegin();
    for(; i < (count*(k+1)) ; i++) {
      TnaiveHashInsert(xid, hash, &i, sizeof(int), &i, sizeof(int));
    }
    Tcommit(xid);

  }
  

  Tdeinit();

}
Ejemplo n.º 4
0
JNIEXPORT void JNICALL Java_stasis_jni_Stasis_deinit
  (JNIEnv *e, jclass c) {
  initted--;
  if(!initted) {
    Tdeinit();
  }
}
Ejemplo n.º 5
0
}END_TEST

/** @test  More complicated case of log w/ hard bound; many xacts at a time.
*/
START_TEST(boundedLogConcurrentTest) {
  stasis_log_type = LOG_TO_MEMORY;
  stasis_log_in_memory_max_entries = 1000;
  stasis_log_softcommit = 1;
  Tinit();
  int xid = Tbegin();
  pageid_t region_start = TregionAlloc(xid, NUM_XACTS, 0);
  Tcommit(xid);

  for(int64_t i = 0; i < NUM_XACTS; i++) {
    int xids[NUM_CONCURRENT_XACTS];
    for(int j = 0; j < NUM_CONCURRENT_XACTS; j++) {
      xids[j] = Tbegin();
    }
    for(int j = 0; j < NUM_CONCURRENT_XACTS; j++) {
      TinitializeFixedPage(xids[j], region_start + i, sizeof(uint64_t));
      recordid rid = {region_start + i, 0, sizeof(uint64_t)};
      Tset(xids[j], rid, &i);
      i++;
    }
    for(int j = 0; j < NUM_CONCURRENT_XACTS; j++) {
      Tcommit(xids[j]);
    }
  }

  Tdeinit();

}END_TEST
Ejemplo n.º 6
0
} END_TEST

START_TEST(regions_lockSmokeTest) {
  Tinit();
  int xid = Tbegin();
  pageid_t pageid = TregionAlloc(xid, 100,0);
  fsckRegions(xid);
  Tcommit(xid);


  xid = Tbegin();
  int xid2 = Tbegin();

  TregionDealloc(xid, pageid);

  for(int i = 0; i < 50; i++) {
    TregionAlloc(xid2, 1, 0);
  }

  fsckRegions(xid);
  Tabort(xid);
  fsckRegions(xid2);
  Tcommit(xid2);
  Tdeinit();
} END_TEST
Ejemplo n.º 7
0
int main(int argc, char * argv[]) {

  Tinit();
  ReferentialAlgebra_init();

  recordid rootEntry;
  recordid hash;
  int xid = Tbegin();
  if(TrecordType(xid, ROOT_RECORD) == INVALID_SLOT) {
    printf("Creating new store\n");

    rootEntry = Talloc(xid, sizeof(recordid));
    assert(rootEntry.page == ROOT_RECORD.page);
    assert(rootEntry.slot == ROOT_RECORD.slot);

    hash = ReferentialAlgebra_allocContext(xid);

    Tset(xid, rootEntry, &hash);

  } else {
    printf("Opened existing store\n");
    rootEntry.page = ROOT_RECORD.page;
    rootEntry.slot = ROOT_RECORD.slot;
    rootEntry.size = sizeof(recordid);

    Tread(xid, rootEntry, &hash);

  }

  context = ReferentialAlgebra_openContext(xid,hash);

  Tcommit(xid);

  FILE * in;
  if(argc == 3) { // listen on socket
    if(strcmp("--socket", argv[1])) {
      printf("usage:\n\n%s\n%s <filename>\n%s --socket addr:port\n",
	     argv[0],argv[0],argv[0]);
    } else {
      startServer(argv[2], hash);
    }

    printf("Shutting down...\n");
  } else {
    if(argc == 2) {
      in = fopen(argv[1], "r");
      if(!in) {
	printf("Couldn't open input file.\n");
	return 1;
      }
    } else {
      in = stdin;
    }
    openInterpreter(in, stdout, hash);
  }
  Tdeinit();
}
Ejemplo n.º 8
0
} END_TEST

START_TEST(regions_recoveryTest) {

  Tinit();

  pageid_t pages[50];
  int xid1 = Tbegin();
  int xid2 = Tbegin();
  for(int i = 0; i < 50; i+=2) {
    pages[i] = TregionAlloc(xid1, stasis_util_random64(4)+1, 0);
    pages[i+1] = TregionAlloc(xid2, stasis_util_random64(2)+1, 0);
  }

  fsckRegions(xid1);

  Tcommit(xid1);

  Tdeinit();

  if(TdurabilityLevel() == VOLATILE) { return; }

  Tinit();

  int xid = Tbegin();
  fsckRegions(xid);

  for(int i = 0; i < 50; i+=2) {
    TregionDealloc(xid, pages[i]);
  }

  fsckRegions(xid);
  Tabort(xid);
  fsckRegions(Tbegin());
  Tdeinit();

  Tinit();
  fsckRegions(Tbegin());
  Tdeinit();

} END_TEST
Ejemplo n.º 9
0
int main(int argc, char** argv) {

  assert(argc == 3 || argc == 4);

  int thread_count = atoi(argv[1]);
  count = atoi(argv[2]);

  alwaysCommit = (argc==4);

  unlink("storefile.txt");
  unlink("logfile.txt");
  unlink("blob0_file.txt");
  unlink("blob1_file.txt");

  pthread_t * workers = stasis_malloc(thread_count, pthread_t);

  Tinit();
  int xid = Tbegin();
  //  hash = ThashCreate(xid, sizeof(int), sizeof(int));
  hash = ThashCreate(xid, VARIABLE_LENGTH, VARIABLE_LENGTH);
  
  Tcommit(xid);

  int k;

  /* threads have static thread sizes.  Ughh. */
  pthread_attr_t attr;
  pthread_attr_init(&attr);

  pthread_mutex_init(&mutex, NULL);

  pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
  //  pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
  pthread_mutex_lock(&mutex);


  for(k = 0; k < thread_count; k++) {
    int * k_copy = stasis_alloc(int);
    *k_copy = k ;
    pthread_create(&workers[k], &attr, go, k_copy);

  }

  pthread_mutex_unlock(&mutex);

  for(k = 0; k < thread_count; k++) {
    pthread_join(workers[k],NULL);
  }

  Tdeinit();

  printf("Committed %d times, put %d times.\n", commitCount, putCount);
}
Ejemplo n.º 10
0
void insertProbeIter(lsmkey_t NUM_ENTRIES) {
  int intcmp = 0;
  lsmTreeRegisterComparator(intcmp,cmp);
  TlsmRegionAllocConf_t alloc_conf = LSM_REGION_ALLOC_STATIC_INITIALIZER;

  stasis_page_impl_register(lsmRootImpl());
  Tinit();
  int xid = Tbegin();
  recordid tree = TlsmCreate(xid, intcmp,
			     TlsmRegionAlloc, &alloc_conf,
			     sizeof(lsmkey_t));
  long oldpagenum = -1;
  for(lsmkey_t i = 0; i < NUM_ENTRIES; i++) {
    long pagenum = TlsmFindPage(xid, tree, (byte*)&i);
    assert(pagenum == -1 || pagenum == oldpagenum || oldpagenum == -1);
    DEBUG("TlsmAppendPage %d\n",i);
    TlsmAppendPage(xid, tree, (const byte*)&i, TlsmRegionAlloc, &alloc_conf, i + OFFSET);
    pagenum = TlsmFindPage(xid, tree, (byte*)&i);
    oldpagenum = pagenum;
    assert(pagenum == i + OFFSET);
  }

  for(lsmkey_t i = 0; i < NUM_ENTRIES; i++) {
    long pagenum = TlsmFindPage(xid, tree, (byte*)&i);
    assert(pagenum == i + OFFSET);
  }

  int64_t count = 0;

  lladdIterator_t * it = lsmTreeIterator_open(xid, tree);

  while(lsmTreeIterator_next(xid, it)) {
    lsmkey_t * key;
    lsmkey_t **key_ptr = &key;
    int size = lsmTreeIterator_key(xid, it, (byte**)key_ptr);
    assert(size == sizeof(lsmkey_t));
    long *value;
    long **value_ptr = &value;
    size = lsmTreeIterator_value(xid, it, (byte**)value_ptr);
    assert(size == sizeof(pageid_t));
    assert(*key + OFFSET == *value);
    assert(*key == count);
    count++;
  }
  assert(count == NUM_ENTRIES);

  lsmTreeIterator_close(xid, it);

  Tcommit(xid);
  Tdeinit();
}
Ejemplo n.º 11
0
END_TEST

/** @test

    Quick test of allocUpdateLogEntry

    @todo  It would be nice if this test used actual operatations table instead of making up values.*/

START_TEST(updateLogEntryAlloc)
{

  char args[] = {'a', 'b', 'c'};
  recordid rid = { 3 , 4, sizeof(int)*3 };

  LogEntry * log;

  Tinit();  /* Needed because it sets up the operations table. */
  stasis_log_t *l = (stasis_log_t *)stasis_log();

  log = allocUpdateLogEntry(l, 200, 1, OPERATION_SET,
                            rid.page, 3*sizeof(char));
  memcpy(stasis_log_entry_update_args_ptr(log), args, 3*sizeof(char));
  assert(log->prevLSN == 200);
  assert(log->xid == 1);
  assert(log->type == UPDATELOG);

  assert(log->update.funcID    == OPERATION_SET);
  assert(log->update.page   == 3);
  assert(log->update.arg_size   == 3*sizeof(char));

  assert(stasis_log_entry_update_args_ptr(log) != NULL);
  assert(args[0] == ((char*)stasis_log_entry_update_args_ptr(log))[0]);
  assert(args[1] == ((char*)stasis_log_entry_update_args_ptr(log))[1]);
  assert(args[2] == ((char*)stasis_log_entry_update_args_ptr(log))[2]);

  //  printf("sizes %d %d\n",sizeofLogEntry(log),(sizeof(struct __raw_log_entry) + sizeof(UpdateLogEntry) + (sizeof(char))));

  assert(sizeofLogEntry(0, log) == (sizeof(struct __raw_log_entry) + sizeof(UpdateLogEntry) + 3 * (sizeof(char))));

  l->write_entry(l, log);
  l->write_entry_done(l, log);
  Tdeinit();
}
Ejemplo n.º 12
0
int main(int argc, char * argv[]) {
  if(argc != 3) { printf(usage, argv[0]); abort(); }
  char * endptr;
  unsigned long numthreads = strtoul(argv[1], &endptr, 10);
  if(*endptr != 0) { printf(usage, argv[0]); abort(); }
  unsigned long numops= strtoul(argv[2], &endptr, 10) / numthreads;
  if(*endptr != 0) { printf(usage, argv[0]); abort(); }

  pthread_t workers[numthreads];

  Tinit();

  for(int i = 0; i < numthreads; i++) {
    pthread_create(&workers[i], 0, noopWorker, &numops);
  }
  for(int i = 0; i < numthreads; i++) {
    pthread_join(workers[i], 0);
  }

  Tdeinit();
}
Ejemplo n.º 13
0
int
runSubject(void) {
  pthread_t* threads;
  pthread_attr_t attr;
  intptr_t k;
  int xid, fd;

  /* Need the following sleep call for debugging. */
  //sleep(45);

  printf("\tRunning Subject Process\n"); fflush(stdout);

  readGlobalsFromSharedBuffer();

  initHashTable = 1;

  Tinit();
  
  if (iteration == 0) {
    /* Create the transactional hash table data structure. */
    xid = Tbegin();
    hashTable = ThashCreate(xid, sizeof(int), sizeof(int));
    Tcommit(xid);

    /* Write the hash table recordid to a file, so it can be 
     * reloaded during subsequent iterations.
     */
    fd = open("recordid.txt", O_CREAT | O_WRONLY | O_SYNC, 0777);
    write(fd, (char*) &hashTable, sizeof(recordid));
    close(fd);
  }
  else {
    /* Otherwise, read in the hash table from disk. */
    fd = open("recordid.txt", O_RDONLY, 0777);
    read(fd, (char*) &hashTable, sizeof(recordid));
    close(fd);
  }

  initHashTable = 0;
  
  /* Open the insert and commit log files. The insert-log keeps track of all insertions
   * that were made to the hash-table, not all of which may have been committed.  The
   * commit-log keeps track of all insertions that were definitely committed.
   */
  insertLog = open("inserts.txt", O_CREAT | O_RDWR | O_APPEND, 0777);
  commitLog = open("commits.txt", O_CREAT | O_RDWR | O_APPEND, 0777);

  /* Allocate the worker threads. */
  threads = stasis_malloc(numThreads, pthread_t);
  
  pthread_attr_init(&attr);
  pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);

  pthread_mutex_init(&hashTableMutex, NULL);

  for (k = 0; k < numThreads; k++) {
    pthread_create(&threads[k], &attr, threadFunc, (void*) k);
  }
  
  for (k = 0; k < numThreads; k++) {
    pthread_join(threads[k], NULL);
  }

  /* Close the insert and commit log files. */
  close(insertLog);
  close(commitLog);
  
  Tdeinit();

  printf("\t\tSubject Process Exiting Normally\n"); fflush(stdout);

  return 0;
}
Ejemplo n.º 14
0
} END_TEST

START_TEST(regions_lockRandomizedTest) {
  Tinit();

  const int NUM_XACTS = 100;
  const int NUM_OPS   = 10000;
  const int FUDGE = 10;
  int xids[NUM_XACTS];

  pageid_t * xidRegions[NUM_XACTS + FUDGE];
  int xidRegionCounts[NUM_XACTS + FUDGE];

  int longXid = Tbegin();

  time_t seed = time(0);
  printf("\nSeed = %ld\n", seed);
  srandom(seed);

  for(int i = 0; i < NUM_XACTS; i++) {
    xids[i] = Tbegin();
    assert(xids[i] < NUM_XACTS + FUDGE);
    xidRegions[xids[i]] = stasis_malloc(NUM_OPS, pageid_t);
    xidRegionCounts[xids[i]] = 0;
  }
  int activeXacts = NUM_XACTS;

  for(int i = 0; i < NUM_OPS; i++) {
    pageid_t j;
    if(!(i % (NUM_OPS/NUM_XACTS))) {
      // abort or commit one transaction randomly.
      activeXacts --;
      j = stasis_util_random64(activeXacts);

      if(stasis_util_random64(2)) {
	Tcommit(xids[j]);
      } else {
	Tabort(xids[j]);
      }

      if(activeXacts == 0) {
	break;
      }
      for(; j < activeXacts; j++) {
	xids[j] = xids[j+1];
      }
      fsckRegions(longXid);
    }

    j = stasis_util_random64(activeXacts);

    if(stasis_util_random64(2)) {
      // alloc
      xidRegions[xids[j]][xidRegionCounts[xids[j]]] = TregionAlloc(xids[j], stasis_util_random64(100), 0);
	xidRegionCounts[xids[j]]++;
    } else {
      // free
      if(xidRegionCounts[xids[j]]) {
	pageid_t k = stasis_util_random64(xidRegionCounts[xids[j]]);

	TregionDealloc(xids[j], xidRegions[xids[j]][k]);

	xidRegionCounts[xids[j]]--;

	for(; k < xidRegionCounts[xids[j]]; k++) {
	  xidRegions[xids[j]][k] = xidRegions[xids[j]][k+1];
	}
      }
    }
  }

  for(int i = 0; i < activeXacts; i++) {
    Tabort(i);
    fsckRegions(longXid);
  }

  Tcommit(longXid);

  Tdeinit();
} END_TEST
Ejemplo n.º 15
0
END_TEST

START_TEST(regions_randomizedTest) {
  Tinit();
  time_t seed = time(0);
  printf("Seed = %ld: ", seed);
  srandom(seed);
  int xid = Tbegin();
  pageid_t pagesAlloced = 0;
  pageid_t regionsAlloced = 0;
  double max_blowup = 0;
  pageid_t max_region_count = 0;
  pageid_t max_waste = 0;
  pageid_t max_size = 0;
  pageid_t max_ideal_size = 0;
  for(int i = 0; i < 10000; i++) {
    if(!(i % 100)) {
      Tcommit(xid);
      xid = Tbegin();
    }
    if(!(i % 100)) {
      fsckRegions(xid);
    }

    if(stasis_util_random64(2)) {
      unsigned int size = stasis_util_random64(100);
      TregionAlloc(xid, size, 0);
      pagesAlloced += size;
      regionsAlloced ++;
    } else {
      if(regionsAlloced) {
	pageid_t victim = stasis_util_random64(regionsAlloced);
	pageid_t victimSize;
	pageid_t victimPage;
	TregionFindNthActive(xid, victim, &victimPage, &victimSize);
	TregionDealloc(xid, victimPage);
	pagesAlloced -= victimSize;
	regionsAlloced --;
      } else {
	i--;
      }
    }

    if(regionsAlloced) {
      pageid_t lastRegionStart;
      pageid_t lastRegionSize;

      TregionFindNthActive(xid, regionsAlloced-1, &lastRegionStart, &lastRegionSize);
      pageid_t length = lastRegionStart + lastRegionSize+1;
      pageid_t ideal  = pagesAlloced + regionsAlloced + 1;
      double blowup = (double)length/(double)ideal;
      unsigned long long bytes_wasted = length - ideal;
      // printf("Region count = %d, blowup = %d / %d = %5.2f\n", regionsAlloced, length, ideal, blowup);
      if(max_blowup < blowup) {
	max_blowup = blowup;
      }
      if(max_waste < bytes_wasted) {
	max_waste = bytes_wasted;
      }
      if(max_size < length) {
	max_size = length;
      }
      if(max_ideal_size < ideal) {
	max_ideal_size = ideal;
      }
      if(max_region_count < regionsAlloced) {
	max_region_count = regionsAlloced;
      }
    }
  }
  fsckRegions(xid);
  Tcommit(xid);

  Tdeinit();
  printf("Max # of regions = %lld, page file size = %5.2fM, ideal page file size = %5.2fM, (blowup = %5.2f)\n",
	 //peak bytes wasted = %5.2fM, blowup = %3.2f\n",
	 max_region_count,
	 ((double)max_size * PAGE_SIZE)/(1024.0*1024.0),
	 ((double)max_ideal_size * PAGE_SIZE)/(1024.0*1024.0),
	 (double)max_size/(double)max_ideal_size);
  //	 ((double)max_waste * PAGE_SIZE)/(1024.0*1024.0),
  //	 max_blowup);
  if((double)max_size/(double)max_ideal_size > 5) {
    // max_blowup isn't what we want here; it measures the peak
    // percentage of the file that is unused.  Instead, we want to
    // measure the actual and ideal page file sizes for this run.
    printf("ERROR: Excessive blowup (max allowable is 5)\n");
    abort();
  }

} END_TEST
Ejemplo n.º 16
0
void bLSM::deinit_stasis() { Tdeinit(); }
Ejemplo n.º 17
0
} END_TEST

START_TEST(pagedListCheck) {
  Tinit();

  int xid = Tbegin();

  recordid list = TpagedListAlloc(xid);

  int a;
  recordid b;
  int i;

  printf("\n");
  for(i = 0; i < NUM_ENTRIES; i++) {

    if(!(i % (NUM_ENTRIES/10))) {
      printf("."); fflush(stdout);
    }

    a = i;
    b.page = i+1;
    b.slot = i+2;
    b.size = i+3;

    int ret;

    {
      byte * t;

      ret = TpagedListFind(xid, list, (byte*)&a, sizeof(int), &t);
      assert(-1 == ret);
    }
    ret = TpagedListInsert(xid, list, (byte*)&a, sizeof(int), (byte*)&b, sizeof(recordid));

    assert(!ret);

    recordid * bb;
    recordid ** bbb = &bb;
    ret = TpagedListFind(xid, list, (byte*)&a, sizeof(int), (byte**)bbb);

    assert(ret == sizeof(recordid));
    assert(!memcmp(bb, &b, sizeof(recordid)));
  }
  Tcommit(xid);
  printf("\n");
  xid = Tbegin();
  for(i = 0; i < NUM_ENTRIES; i++ ) {

    if(!(i % (NUM_ENTRIES/10))) {
      printf("."); fflush(stdout);
    }

    a = i;
    b.page = i+1;
    b.slot = i+2;
    b.size = i+3;

    recordid * bb;
    recordid ** bbb = &bb;
    int ret = TpagedListFind(xid, list, (byte*)&a, sizeof(int), (byte**)bbb);

    assert(ret == sizeof(recordid));
    assert(!memcmp(bb, &b, sizeof(recordid)));


    if(!(i % 10)) {

      ret = TpagedListRemove(xid, list, (byte*)&a, sizeof(int));

      assert(ret);

      free(bb);
      bb = 0;

      ret = TpagedListFind(xid, list, (byte*)&a, sizeof(int), (byte**)bbb);

      assert(-1==ret);
      assert(!bb);
    }
  }
  Tabort(xid);

  xid = Tbegin();
  printf("\n");
  for(i = 0; i < NUM_ENTRIES; i++) {

    if(!(i % (NUM_ENTRIES/10))) {
      printf("."); fflush(stdout);
    }

    a = i;
    b.page = i+1;
    b.slot = i+2;
    b.size = i+3;

    recordid * bb;
    recordid ** bbb = &bb;
    int ret = TpagedListFind(xid, list, (byte*)&a, sizeof(int), (byte**)bbb);

    assert(ret == sizeof(recordid));
    assert(!memcmp(bb, &b, sizeof(recordid)));
  }

  byte * seen = stasis_calloc(NUM_ENTRIES, byte);

  lladd_pagedList_iterator * it = TpagedListIterator(xid, list);

  int keySize;
  int valueSize;
  int * key = 0;
  int ** bkey = &key;
  recordid * value = 0;
  recordid ** bvalue = &value;

  while(TpagedListNext(xid, it, (byte**)bkey, &keySize, (byte**)bvalue, &valueSize)) {
    assert(!seen[*key]);
    seen[*key] = 1;

    assert(value->page == *key+1);
    assert(value->slot == *key+2);
    assert(value->size == *key+3);


    free(key);
    free(value);
    key = 0;
    value = 0;
  }

  for(i = 0; i < NUM_ENTRIES; i++) {
    assert(seen[i] == 1);
  }

  Tcommit(xid);
  Tdeinit();

} END_TEST
int main(int argc, char** argv) {

  assert(argc == 4);

  int thread_count = atoi(argv[1]) ;
  //  count = atoi(argv[2]);
  thread_requests_per_sec = (double)(atoi(argv[2]));
  count = 10.0 * thread_requests_per_sec;
  alwaysCommit = atoi(argv[3]);
  

  printf("%d %f\n", thread_count, thread_requests_per_sec);

  /*  unlink("storefile.txt");
  unlink("logfile.txt");
  unlink("blob0_file.txt");
  unlink("blob1_file.txt"); */

  int l;

  for(l = 0; l < COUNTER_RESOLUTION; l++) {
    buckets[l] = 0;
  }

  pthread_t * workers = stasis_malloc(thread_count, pthread_t);

  Tinit();
  int xid = Tbegin();
  hash = ThashCreate(xid, sizeof(int), sizeof(int));
  
  Tcommit(xid);

  int k;

  /* threads have static thread sizes.  Ughh. */
  pthread_attr_t attr;
  pthread_attr_init(&attr);

  pthread_mutex_init(&mutex, NULL);
  pthread_cond_init(&never, NULL);

  pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
  //  pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
  pthread_mutex_lock(&mutex);


  for(k = 0; k < thread_count; k++) {
    int * k_copy = stasis_alloc(int);
    *k_copy = k ;
    pthread_create(&workers[k], &attr, go, k_copy);

  }

  pthread_mutex_unlock(&mutex);

  for(k = 0; k < thread_count; k++) {
    pthread_join(workers[k],NULL);
  }

  double log_multiplier = (COUNTER_RESOLUTION / log(MAX_SECONDS * 1000000000.0));

  int total = 0;

  for(k = 0; k < COUNTER_RESOLUTION; k++) {
    printf("%3.4f\t%d\n", exp(((double)k)/log_multiplier)/1000000000.0, buckets[k]);
    total += buckets[k];
  }
  
  printf("Total requests %d\n", total);
  /*  printf("mean:     (max, avg)  %f, %f\n", max_mean, avg_mean / (double)thread_count);

  printf("variance: (max, avg)  %f, %f\n", max_var, avg_var / (double)thread_count); */

  Tdeinit();
}