00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00020
00021
00022 #include "arch-specific.h"
00023
00024
00025 enum { SPIN_LIMIT = 100 };
00026
00027
00028 enum { UNLOCKED = 0, LOCKED = 1 };
00029
00030 extern "C" {
00031
00032 #ifdef WIN32
00033
00034 unsigned long hoardInterlockedExchange (unsigned long * oldval,
00035 unsigned long newval)
00036 {
00037 return InterlockedExchange (reinterpret_cast<long *>(oldval), newval);
00038 }
00039
00040 void hoardCreateThread (hoardThreadType& t,
00041 void *(*function) (void *),
00042 void * arg)
00043 {
00044 t = CreateThread (0, 0, (LPTHREAD_START_ROUTINE) function, (LPVOID) arg, 0, 0);
00045 }
00046
00047 void hoardJoinThread (hoardThreadType& t)
00048 {
00049 WaitForSingleObject (t, INFINITE);
00050 }
00051
00052 void hoardSetConcurrency (int)
00053 {
00054 }
00055
00056 int hoardGetThreadID (void) {
00057
00058
00059 int tid = GetCurrentThreadId() >> 1;
00060 return tid;
00061 }
00062
00063 void hoardLockInit (hoardLockType& mutex) {
00064 mutex = UNLOCKED;
00065
00066 }
00067
00068 void hoardLock (hoardLockType& mutex) {
00069 #if 0
00070 int spincount = 0;
00071 while (InterlockedExchange (&mutex, LOCKED) != UNLOCKED) {
00072 spincount++;
00073 if (spincount > 100) {
00074 hoardYield();
00075 spincount = 0;
00076 }
00077 }
00078 #else
00079 while (InterlockedExchange (&mutex, LOCKED) != UNLOCKED) {
00080 hoardYield();
00081 }
00082 #endif
00083
00084 }
00085
00086 void hoardYield (void) {
00087 Sleep (0);
00088 }
00089
00090 void hoardUnlock (hoardLockType& mutex) {
00091 mutex = UNLOCKED;
00092
00093 }
00094
00095 #if 0
00096 void hoardLockDestroy (hoardLockType& mutex) {
00097
00098 }
00099 #endif
00100
00101 static hoardLockType memoryLock = UNLOCKED;
00102 extern "C" void * dlmalloc (size_t);
00103 extern "C" void dlfree (void *);
00104
00105 void * hoardGetMemory (long size)
00106 {
00107 #if 0
00108 hoardLock (memoryLock);
00109 void * ptr = dlmalloc (size);
00110 hoardUnlock (memoryLock);
00111 #else
00112 void * ptr = HeapAlloc (GetProcessHeap(), 0, size);
00113 #endif
00114
00115 return (void *) ptr;
00116 }
00117
00118
00119 void hoardFreeMemory (void * ptr)
00120 {
00121 #if 0
00122 hoardLock (memoryLock);
00123 dlfree (ptr);
00124 hoardUnlock (memoryLock);
00125 #else
00126 HeapFree (GetProcessHeap(), 0, ptr);
00127 #endif
00128 }
00129
00130 int hoardGetPageSize (void)
00131 {
00132 SYSTEM_INFO infoReturn[1];
00133 GetSystemInfo (infoReturn);
00134 return (int) (infoReturn -> dwPageSize);
00135 }
00136
00137
00138 int hoardGetNumProcessors (void)
00139 {
00140 static int numProcessors = 0;
00141 if (numProcessors == 0) {
00142 SYSTEM_INFO infoReturn[1];
00143 GetSystemInfo (infoReturn);
00144 numProcessors = (int) (infoReturn -> dwNumberOfProcessors);
00145 }
00146 return numProcessors;
00147 }
00148
00149 #else // UNIX
00150
00151 #if USE_SPROC
00152 #include <sys/types.h>
00153 #include <sys/wait.h>
00154 #include <unistd.h>
00155 #include <ulocks.h>
00156 #endif
00157
00158 void hoardCreateThread (hoardThreadType& t,
00159 void *(*function) (void *),
00160 void * arg)
00161 {
00162 #if USE_SPROC
00163 typedef void (*sprocFunction) (void *);
00164 t = sproc ((sprocFunction) function, PR_SADDR, arg);
00165 #else
00166 pthread_attr_t attr;
00167 pthread_attr_init (&attr);
00168 #if defined(_AIX)
00169
00170 pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
00171 #endif
00172 pthread_create (&t, &attr, function, arg);
00173 #endif
00174 }
00175
00176 void hoardJoinThread (hoardThreadType& t)
00177 {
00178 #if USE_SPROC
00179 waitpid (t, 0, 0);
00180 #else
00181 pthread_join (t, NULL);
00182 #endif
00183 }
00184
00185 #if 0 // DISABLED!
00186 #if defined(__linux)
00187
00188 extern "C" void pthread_setconcurrency (int n);
00189 #endif
00190 #endif
00191
00192 void hoardSetConcurrency (int n)
00193 {
00194 #if USE_SPROC
00195 usconfig (CONF_INITUSERS, n);
00196 #elif defined(__SVR4) // Solaris
00197 thr_setconcurrency (n);
00198 #else
00199 pthread_setconcurrency (n);
00200 #endif
00201 }
00202
00203
00204 #if defined(__SVR4) // Solaris
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 extern "C" unsigned int lwp_self(void);
00217 #endif
00218
00219 int hoardGetThreadID (void) {
00220 #if USE_SPROC
00221
00222
00223
00224 int pid = (int) PRDA->sys_prda.prda_sys.t_pid;
00225 return pid;
00226 #else
00227 #if defined(__linux)
00228
00229 return (int) pthread_self() / 1024;
00230 #endif
00231 #if defined(__AIX)
00232
00233 return (int) pthread_self() / 257;
00234 #endif
00235 #if defined(__SVR4)
00236 return (int) lwp_self();
00237 #endif
00238 return (int) pthread_self();
00239 #endif
00240 }
00241
00242
00243
00244
00245
00246 #if USER_LOCKS
00247
00248 #include <sched.h>
00249
00250 #if defined(__sgi)
00251 #include <mutex.h>
00252 #endif
00253
00254
00255
00256
00257
00258
00259
00260 #if defined(sparc) && !defined(__GNUC__)
00261 extern "C" unsigned long InterlockedExchange (unsigned long * oldval,
00262 unsigned long newval);
00263 #else
00264 unsigned long InterlockedExchange (unsigned long * oldval,
00265 unsigned long newval)
00266 {
00267 #if defined(sparc)
00268 asm volatile ("swap [%1],%0"
00269 :"=r" (newval)
00270 :"r" (oldval), "0" (newval)
00271 : "memory");
00272
00273 #endif
00274 #if defined(i386)
00275 asm volatile ("xchgl %0, %1"
00276 : "=r" (newval)
00277 : "m" (*oldval), "0" (newval)
00278 : "memory");
00279 #endif
00280 #if defined(__sgi)
00281 newval = test_and_set (oldval, newval);
00282 #endif
00283 #if defined(ppc)
00284 int ret;
00285 asm volatile ("sync;"
00286 "0: lwarx %0,0,%1 ;"
00287 " xor. %0,%3,%0;"
00288 " bne 1f;"
00289 " stwcx. %2,0,%1;"
00290 " bne- 0b;"
00291 "1: sync"
00292 : "=&r"(ret)
00293 : "r"(oldval), "r"(newval), "r"(*oldval)
00294 : "cr0", "memory");
00295 #endif
00296 #if !(defined(sparc) || defined(i386) || defined(__sgi) || defined(ppc))
00297 #error "Hoard does not include support for user-level locks for this platform."
00298 #endif
00299 return newval;
00300 }
00301 #endif
00302
00303 unsigned long hoardInterlockedExchange (unsigned long * oldval,
00304 unsigned long newval)
00305 {
00306 return InterlockedExchange (oldval, newval);
00307 }
00308
00309 void hoardLockInit (hoardLockType& mutex) {
00310 InterlockedExchange (&mutex, UNLOCKED);
00311 }
00312
00313 #include <stdio.h>
00314
00315 void hoardLock (hoardLockType& mutex) {
00316 int spincount = 0;
00317 while (InterlockedExchange (&mutex, LOCKED) != UNLOCKED) {
00318 spincount++;
00319 if (spincount > 100) {
00320 hoardYield();
00321 spincount = 0;
00322 }
00323 }
00324 }
00325
00326 void hoardUnlock (hoardLockType& mutex) {
00327 mutex = UNLOCKED;
00328
00329 }
00330
00331 #else
00332
00333
00334
00335 #endif // USER_LOCKS
00336
00337
00338 #if defined(__SVR4)
00339 #include <thread.h>
00340 #endif
00341
00342 void hoardYield (void)
00343 {
00344 #if defined(__SVR4)
00345 thr_yield();
00346 #else
00347 sched_yield();
00348 #endif
00349 }
00350
00351
00352 extern "C" void * dlmalloc (size_t);
00353 extern "C" void dlfree (void *);
00354
00355
00356 #if USER_LOCKS
00357 static hoardLockType getMemoryLock = 0;
00358 #else
00359 static hoardLockType getMemoryLock = PTHREAD_MUTEX_INITIALIZER;
00360 #endif
00361
00362 #include <stdio.h>
00363
00364 void * hoardGetMemory (long size) {
00365 hoardLock (getMemoryLock);
00366 void * ptr = dlmalloc (size);
00367 hoardUnlock (getMemoryLock);
00368 return ptr;
00369 }
00370
00371
00372 void hoardFreeMemory (void * ptr)
00373 {
00374 hoardLock (getMemoryLock);
00375 dlfree (ptr);
00376 hoardUnlock (getMemoryLock);
00377 }
00378
00379
00380 int hoardGetPageSize (void)
00381 {
00382 return (int) sysconf(_SC_PAGESIZE);
00383 }
00384
00385
00386 #if defined(linux)
00387 #include <sys/types.h>
00388 #include <sys/stat.h>
00389 #include <fcntl.h>
00390 #include <string.h>
00391 #endif
00392
00393 #if defined(__sgi)
00394 #include <sys/types.h>
00395 #include <sys/sysmp.h>
00396 #include <sys/sysinfo.h>
00397 #endif
00398
00399 int hoardGetNumProcessors (void)
00400 {
00401 #if !(defined(linux))
00402 #if defined(__sgi)
00403 static int np = (int) sysmp(MP_NAPROCS);
00404 return np;
00405 #else
00406 static int np = (int) sysconf(_SC_NPROCESSORS_ONLN);
00407 return np;
00408 #endif
00409 #else
00410 static int numProcessors = 0;
00411
00412 if (numProcessors == 0) {
00413
00414
00415
00416
00417
00418
00419
00420 enum { MAX_PROCFILE_SIZE = 32768 };
00421 char line[MAX_PROCFILE_SIZE];
00422 int fd = open ("/proc/cpuinfo", O_RDONLY);
00423
00424 read(fd, line, MAX_PROCFILE_SIZE);
00425 char * str = line;
00426 while (str) {
00427 str = strstr(str, "processor");
00428 if (str) {
00429 numProcessors++;
00430 str++;
00431 }
00432 }
00433 close (fd);
00434
00435 }
00436 return numProcessors;
00437 #endif
00438 }
00439
00440 #endif // UNIX
00441
00442 }