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 void hoardCreateThread (hoardThreadType& t,
00033 void *(*function) (void *),
00034 void * arg)
00035 {
00036 pthread_attr_t attr;
00037 pthread_attr_init (&attr);
00038 pthread_create (&t, &attr, function, arg);
00039 }
00040
00041 void hoardJoinThread (hoardThreadType& t)
00042 {
00043 pthread_join (t, NULL);
00044 }
00045
00046 #if 0 // DISABLED!
00047 #if defined(__linux)
00048
00049 extern "C" void pthread_setconcurrency (int n);
00050 #endif
00051 #endif
00052
00053 void hoardSetConcurrency (int n)
00054 {
00055 pthread_setconcurrency (n);
00056 }
00057
00058
00059 int hoardGetThreadID (void) {
00060
00061 return (int) pthread_self() / 1024;
00062 }
00063
00064
00065
00066
00067
00068 #if USER_LOCKS
00069
00070 #include <sched.h>
00071
00072 #if defined(__sgi)
00073 #include <mutex.h>
00074 #endif
00075
00076
00077
00078
00079
00080
00081
00082 #if defined(sparc) && !defined(__GNUC__)
00083 extern "C" unsigned long InterlockedExchange (unsigned long * oldval,
00084 unsigned long newval);
00085 #else
00086 unsigned long InterlockedExchange (unsigned long * oldval,
00087 unsigned long newval)
00088 {
00089 #if defined(sparc)
00090 asm volatile ("swap [%1],%0"
00091 :"=r" (newval)
00092 :"r" (oldval), "0" (newval)
00093 : "memory");
00094
00095 #endif
00096 #if defined(i386)
00097 asm volatile ("xchgl %0, %1"
00098 : "=r" (newval)
00099 : "m" (*oldval), "0" (newval)
00100 : "memory");
00101 #endif
00102 #if defined(__sgi)
00103 newval = test_and_set (oldval, newval);
00104 #endif
00105 #if defined(ppc)
00106 int ret;
00107 asm volatile ("sync;"
00108 "0: lwarx %0,0,%1 ;"
00109 " xor. %0,%3,%0;"
00110 " bne 1f;"
00111 " stwcx. %2,0,%1;"
00112 " bne- 0b;"
00113 "1: sync"
00114 : "=&r"(ret)
00115 : "r"(oldval), "r"(newval), "r"(*oldval)
00116 : "cr0", "memory");
00117 #endif
00118 #if !(defined(sparc) || defined(i386) || defined(__sgi) || defined(ppc))
00119 #error "Hoard does not include support for user-level locks for this platform."
00120 #endif
00121 return newval;
00122 }
00123 #endif
00124
00125 unsigned long hoardInterlockedExchange (unsigned long * oldval,
00126 unsigned long newval)
00127 {
00128 return InterlockedExchange (oldval, newval);
00129 }
00130
00131 void hoardLockInit (hoardLockType& mutex) {
00132 InterlockedExchange (&mutex, UNLOCKED);
00133 }
00134
00135 #include <stdio.h>
00136
00137 void hoardLock (hoardLockType& mutex) {
00138 int spincount = 0;
00139 while (InterlockedExchange (&mutex, LOCKED) != UNLOCKED) {
00140 spincount++;
00141 if (spincount > 100) {
00142 hoardYield();
00143 spincount = 0;
00144 }
00145 }
00146 }
00147
00148 void hoardUnlock (hoardLockType& mutex) {
00149 mutex = UNLOCKED;
00150
00151 }
00152
00153 #else
00154
00155
00156
00157 #endif // USER_LOCKS
00158
00159
00160 void hoardYield (void)
00161 {
00162 sched_yield();
00163 }
00164
00165
00166 extern "C" void *malloc (size_t);
00167 extern "C" void free (void *);
00168
00169
00170 #if USER_LOCKS
00171 static hoardLockType getMemoryLock = 0;
00172 #else
00173 static hoardLockType getMemoryLock = PTHREAD_MUTEX_INITIALIZER;
00174 #endif
00175
00176 #include <stdio.h>
00177
00178 void * hoardGetMemory (long size) {
00179 hoardLock (getMemoryLock);
00180 void * ptr = malloc (size);
00181 hoardUnlock (getMemoryLock);
00182 return ptr;
00183 }
00184
00185
00186 void hoardFreeMemory (void * ptr)
00187 {
00188 hoardLock (getMemoryLock);
00189 free (ptr);
00190 hoardUnlock (getMemoryLock);
00191 }
00192
00193
00194 int hoardGetPageSize (void)
00195 {
00196 return (int) sysconf(_SC_PAGESIZE);
00197 }
00198
00199
00200 #include <sys/types.h>
00201 #include <sys/stat.h>
00202 #include <fcntl.h>
00203 #include <string.h>
00204
00205
00206 int hoardGetNumProcessors (void)
00207 {
00208 static int numProcessors = 0;
00209
00210 if (numProcessors == 0) {
00211
00212
00213
00214
00215
00216
00217
00218 enum { MAX_PROCFILE_SIZE = 32768 };
00219 char line[MAX_PROCFILE_SIZE];
00220 int fd = open ("/proc/cpuinfo", O_RDONLY);
00221
00222 read(fd, line, MAX_PROCFILE_SIZE);
00223 char * str = line;
00224 while (str) {
00225 str = strstr(str, "processor");
00226 if (str) {
00227 numProcessors++;
00228 str++;
00229 }
00230 }
00231 close (fd);
00232
00233 }
00234 return numProcessors;
00235 }
00236
00237 }