KNN_threads.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /* KNN_threads.cpp
  2. *
  3. * Copyright (C) 2009 Ola Söder
  4. *
  5. * This code is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This code is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this work. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /*
  19. * os 20090123 First version
  20. */
  21. /////////////////////////////////////////////////////
  22. // //
  23. /////////////////////////////////////////////////////
  24. #include <stdlib.h>
  25. #include "KNN.h"
  26. #include "KNN_threads.h"
  27. #include "OlaP.h"
  28. // Threading disabled
  29. /*
  30. // Linux...
  31. #if defined (__linux__)
  32. #define __USE_GNU
  33. #include <sched.h>
  34. // BSD-style OSes
  35. #elif defined (__APPLE__)
  36. #include <sys/types.h>
  37. #include <sys/sysctl.h>
  38. #endif
  39. // Non-pthreaders, Windows
  40. #ifdef _WIN32
  41. #include <windows.h>
  42. // The rest of the pack
  43. #else
  44. #include <pthread.h>
  45. #endif
  46. */
  47. /////////////////////////////////////////////////////
  48. // KNN_getNumberOfCPUs //
  49. /////////////////////////////////////////////////////
  50. int KNN_getNumberOfCPUs ()
  51. {
  52. return(1);
  53. // Threading disabled
  54. /*
  55. int ncpus = 0;
  56. // Linux...
  57. #if defined (__linux__)
  58. cpu_set_t * cpuset = (cpu_set_t *) malloc(sizeof(cpu_set_t));
  59. if(cpuset)
  60. {
  61. sched_getaffinity(0, sizeof(cpu_set_t), cpuset);
  62. for(int cpu = 0; cpu <= CPU_SETSIZE; ++cpu)
  63. if(CPU_ISSET(cpu, cpuset))
  64. ++ncpus;
  65. free(cpuset);
  66. }
  67. Melder_assert(ncpus >= 1);
  68. // BSD-style OSes
  69. #elif defined (__APPLE__)
  70. int mib[2];
  71. size_t len = sizeof(ncpus);
  72. mib[0] = CTL_HW;
  73. mib[1] = HW_NCPU;
  74. sysctl(mib, 2, &ncpus, &len, 0, 0);
  75. // Non-pthreaders, Windows
  76. #elif defined (_WIN32)
  77. typedef BOOL (WINAPI *LPFN_GLPI)
  78. (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);
  79. BOOL done, rc;
  80. DWORD returnLength, byteOffset;
  81. PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer, ptr;
  82. LPFN_GLPI Glpi;
  83. Glpi = (LPFN_GLPI) GetProcAddress(GetModuleHandle(TEXT("kernel32")), "GetLogicalProcessorInformation");
  84. if(!Glpi)
  85. return(1);
  86. done = false;
  87. buffer = nullptr;
  88. returnLength = 0;
  89. while(!done)
  90. {
  91. rc = Glpi(buffer, &returnLength);
  92. if(!rc)
  93. {
  94. if(GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  95. {
  96. if(buffer)
  97. free(buffer);
  98. return (1);
  99. }
  100. else done = true;
  101. }
  102. byteOffset = 0;
  103. ptr=buffer;
  104. while (byteOffset < returnLength)
  105. {
  106. switch (ptr->Relationship)
  107. {
  108. case RelationProcessorCore:
  109. ++ncpus;
  110. default:
  111. }
  112. byteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
  113. ++ptr;
  114. }
  115. }
  116. free(buffer);
  117. ncpus = 1;
  118. // Unknown OS
  119. #else
  120. ncpus = 1;
  121. #endif
  122. Melder_assert(ncpus >= 1);
  123. return(ncpus);
  124. */
  125. }
  126. /////////////////////////////////////////////////////
  127. // KNN_threadDistribution //
  128. /////////////////////////////////////////////////////
  129. void * KNN_threadDistribution
  130. (
  131. void * (* function) (void *),
  132. void ** input,
  133. int nthreads
  134. )
  135. {
  136. Melder_assert(function && input && nthreads > 0);
  137. if(!(function && input && nthreads > 0))
  138. {
  139. KNN_thread_status * error = (KNN_thread_status *) malloc(sizeof(enum KNN_thread_status));
  140. if(error)
  141. *error = KNN_THREAD_ERROR;
  142. return((void *) error);
  143. }
  144. if(nthreads > 1)
  145. {
  146. #ifdef _WIN32
  147. // Threading disabled
  148. /*
  149. HANDLE hHandle[nthreads];
  150. for(int i = 0; i < nthreds; ++)
  151. hHandle[i] = CreateThread(nullptr, 0, function, input[i], 0, nullptr);
  152. while(nthreads--)
  153. WaitForSingleObject(hHandle[nthreds], INFINITE);
  154. */
  155. #else
  156. // Threading disabled
  157. /*
  158. pthread_t thread_ids[nthreads];
  159. for(int i = 0; i < nthreads; ++i)
  160. pthread_create(&thread_ids[i], nullptr, function, input[i]);
  161. while(nthreads--)
  162. pthread_join(thread_ids[nthreads], nullptr);
  163. return nullptr;
  164. */
  165. #endif
  166. }
  167. void *result = function (input [0]);
  168. return result;
  169. }
  170. /////////////////////////////////////////////////////
  171. // KNN_threadTest //
  172. /////////////////////////////////////////////////////
  173. void KNN_threadTest ()
  174. {
  175. void * dummy[KNN_getNumberOfCPUs()];
  176. KNN_threadDistribution(KNN_threadTestAux, (void **) &dummy, KNN_getNumberOfCPUs());
  177. }
  178. /////////////////////////////////////////////////////
  179. // KNN_threadTestAux //
  180. /////////////////////////////////////////////////////
  181. void * KNN_threadTestAux (void * dummy)
  182. {
  183. dummy = nullptr; // dummy assignment to avoid compiler warnings;
  184. for(int i = 0; i < 50000; ++i)
  185. for(int i = 0; i < 50000; ++i) ;
  186. return nullptr;
  187. }