int main(void)
{
  int n;
  usCount start;
  pthread_permit1_t permit1;

  printf("Press key to continue ...\n");
  getchar();
  printf("Wait ...\n");
  start=GetUsCount();
  while(GetUsCount()-start<3000000000000ULL);
  printf("Calculating timing overhead ...\n");
  for(n=0; n<5000000; n++)
  {
    start=GetUsCount();
    timingoverhead+=GetUsCount()-start;
  }
  timingoverhead/=5000000;
  printf("Timing overhead on this machine is %u us. Go!\n", (size_t) timingoverhead);

  pthread_permit1_init(&permit1, 1);
  permitaddr=&permit1;
  for(n=0; n<THREADS; n++)
  {
    thrd_create(&threads[n], (thrd_start_t) threadfunc<pthread_permit1_t, pthread_permit1_grant, pthread_permit1_revoke, pthread_permit1_wait>, (void *)(size_t)n);
  }
  printf("Press key to kill all\n");
  getchar();
  done=1;
  mssleep(2000);
  printf("Press key to exit\n");
  getchar();
  return 0;
}
template<typename permit_t, int (*permit_grant)(pthread_permitX_t), void (*permit_revoke)(permit_t *), int(*permit_wait)(permit_t *, mtx_t *mtx)> int threadfunc(void *mynum)
{
  size_t mythread=(size_t) mynum;
  permit_t *permit=(permit_t *)permitaddr;
  usCount start, end;
  size_t count=0;
#ifdef UNCONTENDED
  if(UNCONTENDED==mythread) return 0;
#endif
  if(!mynum)
  {
    usCount revoketotal=0, granttotal=0;
    while(!done)
    {
#if DONTCONSUME
      // Revoke permit
      start=GetUsCount();
      permit_revoke(permit);
      end=GetUsCount();
      revoketotal+=end-start-timingoverhead;
      //printf("Thread %u revoked permit\n", mythread);
#endif
      //mssleep(1000);
      //printf("\nThread %u granting permit\n", mythread);
      start=GetUsCount();
      permit_grant(permit);
      end=GetUsCount();
      granttotal+=end-start-timingoverhead;
      //mssleep(1);
      count++;
    }
    printf("Thread %u, average revoke/grant time was %u/%u cycles\n", mythread, (size_t)((double)revoketotal/count*CYCLESPERMICROSECOND), (size_t)((double)granttotal/count*CYCLESPERMICROSECOND));
    permit_grant(permit);
  }
  else
  {
    usCount waittotal=0;
    mtx_t mtx;
    mtx_init(&mtx, mtx_plain);
    mtx_lock(&mtx);
    while(!done)
    {
      // Wait on permit
      start=GetUsCount();
      permit_wait(permit, &mtx);
      end=GetUsCount();
      waittotal+=end-start-timingoverhead;
      count++;
      //printf("%u", mythread);
#if defined(UNCONTENDED) && 0==DONTCONSUME
      if(UNCONTENDED==0 && 1==mythread)
      {
        permit_grant(permit);
      }
#endif
    }
    printf("Thread %u, average wait time was %u cycles\n", mythread, (size_t)((double)waittotal/count*CYCLESPERMICROSECOND));
  }
  return 0;
}
Ejemplo n.º 3
0
int main(void)
{
	double std=0, ned=0;

#if 0
	{
		usCount start, end;
		start=GetUsCount();
		THREADSLEEP(5000);
		end=GetUsCount();
		printf("Wait was %lf\n", (end-start)/1000000000000.0);
	}
#endif
#ifdef WIN32
	{	/* Force load of user32.dll so we can debug */
		BOOL v;
		SystemParametersInfo(SPI_GETBEEP, 0, &v, 0);
	}
#endif

	if(0)
	{
		printf("\nTesting standard allocator with %d threads ...\n", THREADS);
		std=runtest();
	}
	if(1)
	{
		printf("\nTesting nedmalloc with %d threads ...\n", THREADS);
		whichmalloc=1;
		ned=runtest();
	}
#ifdef WIN32
	if(0)
	{
		ULONG data=2;
		win32heap=HeapCreate(0, 0, 0);
		HeapSetInformation(win32heap, HeapCompatibilityInformation, &data, sizeof(data));
		HeapQueryInformation(win32heap, HeapCompatibilityInformation, &data, sizeof(data), NULL);
		if(2!=data)
		{
			printf("The win32 low frag allocator won't work under a debugger!\n");
		}
		else
		{
			printf("Testing win32 low frag allocator with %d threads ...\n\n", THREADS);
			whichmalloc=2;
			runtest();
		}
		HeapDestroy(win32heap);
	}
#endif
	if(std && ned)
	{	// ned should have more ops/sec
		printf("\n\nnedmalloc allocator is %lf times faster than standard\n", ned/std);
	}
	printf("\nPress a key to trim\n");
	getchar();
	nedmalloc_trim(0);
#ifdef _MSC_VER
	printf("\nPress a key to end\n");
	getchar();
#endif
	return 0;
}
Ejemplo n.º 4
0
static void threadcode(int threadidx)
{
	int n;
	unsigned int *toallocptr=threadstuff[threadidx].toalloc;
	void **allocptr=threadstuff[threadidx].allocs;
	unsigned int seed=threadidx;
	usCount start;
	threadstuff[threadidx].done=0;
	/*neddisablethreadcache(0);*/
	THREADSLEEP(100);
	start=GetUsCount();
#ifdef TORTURETEST
	/* A randomised malloc/realloc/free test (torture test) */
	for(n=0; n<RECORDS*100; n++)
	{
		unsigned int r=myrandom(&seed), i;
		i=(int)(r % RECORDS);
		if(!allocptr[i])
		{
			allocptr[i]=mallocs[whichmalloc](r & 0x1FFF);
			threadstuff[threadidx].ops++;
		}
		else if(r & (1<<31))
		{
			allocptr[i]=reallocs[whichmalloc](allocptr[i], r & 0x1FFF);
			threadstuff[threadidx].ops++;
		}
		else
		{
			frees[whichmalloc](allocptr[i]);
			allocptr[i]=0;
		}
	}
	for(n=0; n<RECORDS; n++)
	{
		if(allocptr[n])
		{
			frees[whichmalloc](allocptr[n]);
			allocptr[n]=0;
		}
	}
#else
	/* A simple stack which allocates and deallocates off the top (speed test) */
	for(n=0; n<RECORDS;)
	{
#if 1
		r=myrandom(&seed);
		if(allocptr>threadstuff[threadidx].allocs && (r & 65535)<32760) /*<32760)*/
		{	/* free */
			--toallocptr;
			--allocptr;
			--n;
			frees[whichmalloc](*allocptr);
			*allocptr=0;
		}
		else
#endif
		{
			if(doRealloc && allocptr>threadstuff[threadidx].allocs && (r & 1))
			{
	            allocptr[-1]=reallocs[whichmalloc](allocptr[-1], *toallocptr);
			}
			else
			{
	            allocptr[0]=mallocs[whichmalloc](*toallocptr);
				allocptr++;
			}
			n++;
			toallocptr++;
			threadstuff[threadidx].ops++;
		}
	}
	while(allocptr>threadstuff[threadidx].allocs)
	{
		frees[whichmalloc](*--allocptr);
	}
#endif
	times[threadidx]+=GetUsCount()-start;
	neddisablethreadcache(0);
	threadstuff[threadidx].done=1;
}
Ejemplo n.º 5
0
int main(void)
{
	double std=0, ned=0;
#if defined(WIN32) && defined(USE_NEDMALLOC_DLL)
	/*PatchInNedmallocDLL();*/
#endif

#if 0
	{
		usCount start, end;
		start=GetUsCount();
		THREADSLEEP(5000);
		end=GetUsCount();
		printf("Wait was %lf\n", (end-start)/1000000000000.0);
	}
#endif
#ifdef WIN32
#pragma comment(lib, "user32.lib")
	{	/* Force load of user32.dll so we can debug */
		BOOL v;
		SystemParametersInfo(SPI_GETBEEP, 0, &v, 0);
	}
#endif
#if 2==TESTTYPE
	printf("Running torture test\n"
		   "-=-=-=-=-=-=-=-=-=-=\n");
#elif 1==TESTTYPE
	printf("Running speed test\n"
		   "-=-=-=-=-=-=-=-=-=\n");
#endif
	printf("Block size <= %u, C++ test mode is %s\n", BLOCKSIZE, TESTCPLUSPLUS ? "on" : "off");
	if(0)
	{
		printf("\nTesting standard allocator with %d threads ...\n", THREADS);
		std=runtest();
	}
	if(1)
	{
		printf("\nTesting nedmalloc with %d threads ...\n", THREADS);
		whichmalloc=1;
		ned=runtest();
	}
#ifdef WIN32
	if(0)
	{
		ULONG data=2;
		win32heap=HeapCreate(0, 0, 0);
		HeapSetInformation(win32heap, HeapCompatibilityInformation, &data, sizeof(data));
		HeapQueryInformation(win32heap, HeapCompatibilityInformation, &data, sizeof(data), NULL);
		if(2!=data)
		{
			printf("The win32 low frag allocator won't work under a debugger!\n");
		}
		else
		{
			printf("Testing win32 low frag allocator with %d threads ...\n\n", THREADS);
			whichmalloc=2;
			runtest();
		}
		HeapDestroy(win32heap);
	}
#endif
	if(std && ned)
	{	// ned should have more ops/sec
		printf("\n\nnedmalloc allocator is %lf times faster than standard\n", ned/std);
	}
	printf("\nPress a key to trim\n");
	getchar();
	nedmalloc_trim(0);
#ifdef _MSC_VER
	printf("\nPress a key to end\n");
	getchar();
#endif
	return 0;
}
Ejemplo n.º 6
0
static void threadcode(int threadidx)
{
	int n;
	unsigned int *toallocptr=threadstuff[threadidx].toalloc;
	void **allocptr=threadstuff[threadidx].allocs;
	unsigned int r, seed=threadidx;
	usCount start;
	size_t allocated=0, size;
	threadstuff[threadidx].done=0;
	/*neddisablethreadcache(0);*/
	THREADSLEEP(100);
	start=GetUsCount();
#if 2==TESTTYPE
	/* A randomised malloc/realloc/free test (torture test) */
	for(n=0; n<RECORDS*100; n++)
	{
		static int reallocflip;
		unsigned int i, dorealloc=(reallocflip=!reallocflip);
		r=myrandom(&seed);
		i=(int)(r % RECORDS);
#if TESTCPLUSPLUS
		dorealloc=!(r&(15<<28));
		if(r&(1<<31))
		{   /* Make it two power multiple of less than 512 bytes to
			model frequent C++ new's */
			size=4<<(r & 7);
			dorealloc=0;
		}
		else
#endif
			size=(size_t)(r & (BLOCKSIZE-1));
		if(allocated<MAXMEMORY2 && !allocptr[i])
		{
			if(!(allocptr[i]=mallocs[whichmalloc](size))) abort();
#if TOUCH
			{
				volatile char *mem=(volatile char *)allocptr[i];
				volatile char *end=mem+size;
				for(; mem<end; mem+=4096) *mem;
			}
#endif
			allocated+=memsizes[whichmalloc](allocptr[i]);
			threadstuff[threadidx].ops.mallocs++;
		}
		else if(allocated<MAXMEMORY2 && dorealloc) /* If not TESTCPLUSPLUS, then how often realloc() gets called depends on how small RECORDS is. */
		{
			allocated-=memsizes[whichmalloc](allocptr[i]);
			if(!(allocptr[i]=reallocs[whichmalloc](allocptr[i], size))) abort();
#if TOUCH
			{
				volatile char *mem=(volatile char *)allocptr[i];
				volatile char *end=mem+size;
				for(; mem<end; mem+=4096) *mem;
			}
#endif
			allocated+=memsizes[whichmalloc](allocptr[i]);
			threadstuff[threadidx].ops.reallocs++;
		}
		else if(allocptr[i])
		{
			allocated-=memsizes[whichmalloc](allocptr[i]);
			frees[whichmalloc](allocptr[i]);
			allocptr[i]=0;
			threadstuff[threadidx].ops.frees++;
		}
	}
	for(n=0; n<RECORDS; n++)
	{
		if(allocptr[n])
		{
			allocated-=memsizes[whichmalloc](allocptr[n]);
			frees[whichmalloc](allocptr[n]);
			allocptr[n]=0;
			threadstuff[threadidx].ops.frees++;
		}
	}
	assert(!allocated);
#elif 1==TESTTYPE
	/* A simple stack which allocates and deallocates off the top (speed test) */
	for(n=0; n<RECORDS;)
	{
#if 1
		r=myrandom(&seed);
		if(allocptr>threadstuff[threadidx].allocs && (r & 65535)<32760) /*<32760)*/
		{	/* free */
			--toallocptr;
			--allocptr;
			--n;
			frees[whichmalloc](*allocptr);
			*allocptr=0;
			threadstuff[threadidx].ops.frees++;
		}
		else
#endif
		{
			if(doRealloc && allocptr>threadstuff[threadidx].allocs && (r & 1))
			{
	            if(!(allocptr[-1]=reallocs[whichmalloc](allocptr[-1], *toallocptr))) abort();
#if TOUCH
				{
					volatile char *mem=(volatile char *)allocptr[-1];
					volatile char *end=mem+*toallocptr;
					for(; mem<end; mem+=4096) *mem;
				}
#endif
				threadstuff[threadidx].ops.reallocs++;
			}
			else
			{
	            if(!(allocptr[0]=mallocs[whichmalloc](*toallocptr))) abort();
#if TOUCH
				{
					volatile char *mem=(volatile char *)allocptr[0];
					volatile char *end=mem+*toallocptr;
					for(; mem<end; mem+=4096) *mem;
				}
#endif
				threadstuff[threadidx].ops.mallocs++;
				allocptr++;
			}
			n++;
			toallocptr++;
			/*if(!(threadstuff[threadidx].ops & 0xff))
				nedtrimthreadcache(0,0);*/
		}
	}
	while(allocptr>threadstuff[threadidx].allocs)
	{
		frees[whichmalloc](*--allocptr);
		threadstuff[threadidx].ops.frees++;
	}
#endif
	times[threadidx]+=GetUsCount()-start;
	neddisablethreadcache(0);
	threadstuff[threadidx].done=1;
}
int main(void)
{
  size_t n, m;
  usCount start, end;
  size_t roundings[16];
  printf("N1527lib test program\n"
         "-=-=-=-=-=-=-=-=-=-=-\n");
  n=mpool_minimum_roundings(roundings, 16); assert(n<16);
  printf("Minimum roundings from available allocators:\n");
  for(m=0; m<n; m++)
  {
    printf("  %u\n", roundings[m]);
  }
  {
    mpool pool128, pool4096, poolA;
    void *temp1, *temp2;
    size_t usagecount, *alignments, *roundings;
    pool128=mpool_obtain(alignment128_attributes);
    temp1=mpool_malloc(pool128, 1);
    temp2=mpool_malloc(pool128, 1);
    printf("128 aligned %p (%u), %p (%u)", temp1, mpool_usable_size(pool128, temp1), temp2, mpool_usable_size(pool128, temp2));
    assert(!((size_t)temp1 & 127));
    assert(!((size_t)temp2 & 127));
    mpool_info(pool128, &usagecount, &alignments, &roundings, NULL);
    printf("  usagecount=%u, roundings[0]=%u\n", usagecount, roundings[0]);

    pool4096=mpool_obtain(alignment4096_attributes);
    temp1=mpool_malloc(pool4096, 1);
    temp2=mpool_malloc(pool4096, 1);
    printf("4096 aligned %p (%u), %p (%u)", temp1, mpool_usable_size(pool4096, temp1), temp2, mpool_usable_size(pool4096, temp2));
    assert(!((size_t)temp1 & 4095));
    assert(!((size_t)temp2 & 4095));
    mpool_info(pool4096, &usagecount, &alignments, &roundings, NULL);
    printf("  usagecount=%u, roundings[0]=%u\n", usagecount, roundings[0]);

    poolA=mpool_obtain(alignment128_attributes_a);
    mpool_info(poolA, &usagecount, &alignments, &roundings, NULL);
    printf("PoolA: usagecount=%u, roundings[0]=%u\n", usagecount, roundings[0]);
    assert(poolA==pool128);
  }

  syspool=mpool_obtain(MPOOL_DEFAULT);
  srand(1);
  for(n=0; n<RECORDS; n++)
    sizes[n]=rand() & 1023;
  if(1)
  {
    unsigned frees=0;
    printf("Fragmenting free space ...\n");
    start=GetUsCount();
    while(GetUsCount()-start<3000000000000)
    {
      n=rand() % RECORDS;
      if(ptrs[n]) { mpool_free(syspool, ptrs[n]); ptrs[n]=0; frees++; }
      else ptrs[n]=mpool_malloc(syspool, sizes[n]);
    }
    memset(ptrs, 0, RECORDS*sizeof(void *));
    printf("Did %u frees\n", frees);
  }

  if(0)
  {
    typedef void* mspace;
    extern mspace get_dlmalloc_mspace(mpool pool);
    extern void* mspace_malloc(mspace msp, size_t bytes);
    extern void mspace_free(mspace msp, void* mem);
    printf("\ndlmalloc Speed test\n"
             "-------------------\n");
    {
      mspace ms=get_dlmalloc_mspace(syspool);
      for(m=0; m<3; m++)
      {
        size_t count=RECORDS, size=1024;
        for(n=0; n<RECORDS; n++)
          sizes[n]=rand() & 1023;

        start=GetUsCount();
        for(n=0; n<RECORDS; n++)
        {
          ptrs[n]=mspace_malloc(ms, sizes[n]);
        }
        end=GetUsCount();
        printf("mspace_malloc() does %f mallocs/sec\n", RECORDS/((end-start)/1000000000000.0));

        start=GetUsCount();
        for(n=0; n<RECORDS; n++)
        {
          mspace_free(ms, ptrs[n]);
          ptrs[n]=0;
        }
        end=GetUsCount();
        printf("mspace_free() does %f frees/sec\n\n", RECORDS/((end-start)/1000000000000.0));
      }
    }
  }
  if(1)
  {
    printf("\nMPool Speed test\n"
             "----------------\n");
    for(m=0; m<3; m++)
    {
      size_t count=RECORDS, size=1024;
      for(n=0; n<RECORDS; n++)
        sizes[n]=rand() & 1023;

      start=GetUsCount();
      mpool_batch(syspool, NULL, ptrs, sizes, &count, 0);
      end=GetUsCount();
      printf("mpool_batch() does %f mallocs/sec\n", RECORDS/((end-start)/1000000000000.0));

      count=RECORDS;
      start=GetUsCount();
      mpool_batch(syspool, NULL, ptrs, NULL, &count, 0);
      end=GetUsCount();
      printf("mpool_batch() does %f frees/sec\n", RECORDS/((end-start)/1000000000000.0));

      start=GetUsCount();
      for(n=0; n<RECORDS; n++)
      {
        ptrs[n]=mpool_malloc(syspool, sizes[n]);
      }
      end=GetUsCount();
      printf("mpool_malloc() does %f mallocs/sec\n", RECORDS/((end-start)/1000000000000.0));

      start=GetUsCount();
      for(n=0; n<RECORDS; n++)
      {
        mpool_free(syspool, ptrs[n]);
        ptrs[n]=0;
      }
      end=GetUsCount();
      printf("mpool_free() does %f frees/sec\n\n", RECORDS/((end-start)/1000000000000.0));
    }
  }
#ifdef _MSC_VER
  printf("Press Return to exit ...\n");
  getchar();
#endif
  return 0;
}