testmt.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * Test program from:
  3. * Debian Bug report logs - #241156
  4. * electric-fence (2.1.13-0.1) breaks with 2.6.x kernel
  5. *
  6. * changed to compile on Windows by Hayati Ayguen
  7. */
  8. /* $Id$ */
  9. /* gcc foo.c -pthread -lefence -g -ggdb -o foo */
  10. /* (defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)) */
  11. /* remove "|| defined(__CYGWIN__)" in following line
  12. * to test with pthread library on Win32-Cygwin
  13. */
  14. #if ( defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) )
  15. #include <windows.h>
  16. #else
  17. #include <pthread.h>
  18. #include <unistd.h>
  19. #include <errno.h>
  20. #define HAVE_PTHREADS
  21. #endif
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include "../duma.h"
  26. volatile int iKillThreads = 0;
  27. #define MAX_NUM_THREADS 32
  28. volatile int aiCounter[MAX_NUM_THREADS];
  29. /* thread function
  30. * permanently allocate, initialize and deallocate in a loop
  31. */
  32. #ifdef HAVE_PTHREADS
  33. void* poster(void* arg)
  34. #else
  35. DWORD WINAPI poster( LPVOID arg )
  36. #endif
  37. {
  38. char* foo = NULL;
  39. int iThreadNo = *((int*)arg);
  40. #if 0
  41. /* sleep a bit, that other threads can get started
  42. * before producing high load
  43. */
  44. #ifdef HAVE_PTHREADS
  45. sleep(1); /* wait 1 sec */
  46. #else
  47. Sleep(1000);
  48. #endif
  49. #endif
  50. for( ; !iKillThreads; )
  51. {
  52. foo = (char*)malloc(4096);
  53. if (foo)
  54. {
  55. memset(foo, 0, 4096);
  56. free(foo);
  57. }
  58. ++ aiCounter[iThreadNo];
  59. }
  60. #ifdef HAVE_PTHREADS
  61. pthread_exit(NULL);
  62. #endif
  63. return 0;
  64. }
  65. #define MAX_NUM_THREADS 32
  66. int main(int argc, char *argv[])
  67. {
  68. int iSleepTime = 60; /* in seconds; default = 30 sec */
  69. int iNumThreads = 4;
  70. int i;
  71. #ifdef HAVE_PTHREADS
  72. pthread_t tId[MAX_NUM_THREADS];
  73. #else
  74. HANDLE tId[MAX_NUM_THREADS];
  75. #endif
  76. int tArg[MAX_NUM_THREADS];
  77. #ifdef DUMA_EXPLICIT_INIT
  78. /* necessary on some platforms!
  79. * like on Win32-Cygwin
  80. */
  81. duma_init();
  82. #endif
  83. if ( argc > 1 )
  84. {
  85. i = atoi(argv[1]);
  86. if ( i > 0 )
  87. iSleepTime = i;
  88. }
  89. if ( argc > 2 )
  90. {
  91. i = atoi(argv[2]);
  92. if ( i > 0 )
  93. iNumThreads = i;
  94. if ( iNumThreads > MAX_NUM_THREADS )
  95. iNumThreads = MAX_NUM_THREADS;
  96. }
  97. fprintf(stdout, "running %d threads for %d secs ..", iNumThreads, iSleepTime);
  98. fflush(stdout);
  99. for ( i = 0; i < iNumThreads; ++i )
  100. {
  101. tArg[i] = i;
  102. aiCounter[i] = 0;
  103. }
  104. #ifdef HAVE_PTHREADS
  105. fprintf(stdout, "creating threads with pthread library .. \n");
  106. fflush(stdout);
  107. for ( i = 0; i < iNumThreads; ++i )
  108. {
  109. pthread_t *pt = &tId[i];
  110. int r = pthread_create( pt, NULL, poster, &tArg[i] );
  111. if ( r )
  112. {
  113. fprintf(stderr, "\nerror in pthread_create() for thread %d: ", i);
  114. switch(r)
  115. {
  116. case EAGAIN: fprintf(stderr, "EAGAIN"); break;
  117. case EINVAL: fprintf(stderr, "EINVAL"); break;
  118. case EPERM: fprintf(stderr, "EPERM"); break;
  119. default: fprintf(stderr, "unexpected!"); break;
  120. }
  121. }
  122. }
  123. fprintf(stdout, ".. creating done\n");
  124. fflush(stdout);
  125. /* sleep(iSleepTime); */
  126. for ( i = 0; i < iSleepTime; ++i )
  127. {
  128. sleep(1); /* wait 1 sec */
  129. fprintf(stdout, ".");
  130. fflush(stdout);
  131. }
  132. #else
  133. fprintf(stdout, "creating threads with Win32 API calls\n");
  134. fflush(stdout);
  135. for ( i = 0; i < iNumThreads; ++i )
  136. {
  137. tId[i] = CreateThread( NULL /* default security attributes */
  138. , 0 /* use default stack size */
  139. , poster /* thread function name */
  140. , &tArg[i]/* argument to thread function */
  141. , 0 /* use default creation flags */
  142. , NULL /* returns the thread identifier */
  143. );
  144. if ( NULL == tId[i] )
  145. fprintf(stderr, "\nerror in CreateThread() for thread %d: ", i);
  146. }
  147. /* Sleep(iSleepTime*1000); */
  148. for ( i =0; i < iSleepTime; ++i )
  149. {
  150. Sleep(1000); /* wait 1000 ms */
  151. fprintf(stdout, ".");
  152. fflush(stdout);
  153. }
  154. #endif
  155. fprintf(stdout, "..done\n");
  156. iKillThreads = 1;
  157. fprintf(stdout, "wating threads to end ..");
  158. fflush(stdout);
  159. #ifdef HAVE_PTHREADS
  160. for ( i = 0; i < iNumThreads; ++i )
  161. {
  162. pthread_t *pt = &tId[i];
  163. int r = pthread_join( *pt, NULL );
  164. if ( r )
  165. {
  166. fprintf(stderr, "\nerror in pthread_join() for thread %d: ", i);
  167. switch(r)
  168. {
  169. case EINVAL: fprintf(stderr, "EINVAL"); break;
  170. case ESRCH: fprintf(stderr, "ESRCH"); break;
  171. case EDEADLK: fprintf(stderr, "EDEADLK"); break;
  172. default: fprintf(stderr, "unexpected!"); break;
  173. }
  174. }
  175. }
  176. #else
  177. // Wait until all threads have terminated.
  178. WaitForMultipleObjects( iNumThreads, tId, TRUE, INFINITE);
  179. for ( i = 0; i < iNumThreads; ++i )
  180. CloseHandle(tId[i]);
  181. #endif
  182. fprintf(stdout, "..done\n");
  183. fprintf(stdout, "state:\n");
  184. for ( i = 0; i < iNumThreads; ++i )
  185. fprintf(stdout, "Thread %d did %d (de)allocations\n", i, aiCounter[i]);
  186. fflush(stdout);
  187. return 0;
  188. }