2 * The Computer Language Benchmarks Game
3 * http://shootout.alioth.debian.org/
4 * Contributed by Premysl Hruby
5 * convert to C++ by The Anh Tran
6 * Some optimisation by Pauli Nieminen
19 #include <sys/sysinfo.h>
22 typedef unsigned int uint
;
24 const uint16_t NUM_THREADS
= 503;
25 const uint STACK_SIZE
= PTHREAD_STACK_MIN
;
27 // hw_concurrency should be <cores in use>-1
28 // a core is reserved for new threads initializing
29 const uint16_t hw_concurrency
= 3;
30 #define real_hw_concurrency 4
33 pthread_mutex_t mutex_
;
35 mutex_t() : mutex_(PTHREAD_MUTEX_INITIALIZER
)
41 pthread_mutex_lock( &mutex_
);
46 pthread_mutex_unlock( &mutex_
);
51 void* threadStarter(void *param
)
53 F
* func
= reinterpret_cast<F
*>(param
);
61 thread(const thread
&);
62 thread
& operator=(const thread
&);
67 void createThread(F
& func
,
71 pthread_create(&id
, &attr
, &threadStarter
<F
>,static_cast<void*>(&func
));
74 static void join(pthread_t
& id
)
82 pthread_barrier_t barrier
;
86 pthread_barrier_init(&barrier
, 0, 2);
91 pthread_barrier_wait(&barrier
);
98 barrier_t main_barrier
;
99 mutex_t mutex
[NUM_THREADS
];
100 char stacks
[NUM_THREADS
][STACK_SIZE
];
102 #if real_hw_concurrency > 1 || real_hw_concurrency == 0
103 cpu_set_t cpu_set_free
;
104 cpu_set_t cpu_set_restrict
;
109 #if real_hw_concurrency > 1 || real_hw_concurrency == 0
110 CPU_ZERO(&cpu_set_restrict
);
111 CPU_SET(0,&cpu_set_restrict
);
112 // Run free thread everywhere else except first cpu
113 sched_getaffinity(getpid(), sizeof(cpu_set_t
), &cpu_set_free
);
114 if (real_hw_concurrency
== 0)
116 if (hw_concurrency
< get_nprocs())
117 CPU_CLR(0, &cpu_set_free
);
119 if (hw_concurrency
< real_hw_concurrency
)
120 CPU_CLR(0, &cpu_set_free
);
129 static thread threads
[NUM_THREADS
];
130 static thread_func functions
[NUM_THREADS
];
132 void set_id(uint16_t new_id
) {
138 if (hw_concurrency
> 1
139 && (id
+ 1) < hw_concurrency
)
142 const uint16_t start
= (NUM_THREADS
*(id
+1))/hw_concurrency
;
143 const uint16_t end
= (NUM_THREADS
*(id
+2))/hw_concurrency
;
144 thread_func::createThreads(start
, end
);
146 #if real_hw_concurrency > 1 || real_hw_concurrency == 0
147 pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t
), &cpu_set_restrict
);
150 mutex_t
&mutex_this_node
= mutex
[id
];
151 mutex_t
&mutex_next_node
= mutex
[(id
+1)%NUM_THREADS
];
155 mutex_this_node
.lock();
159 mutex_next_node
.unlock();
163 printf("%d\n", id
+1 );
169 static void createThreads(uint16_t start
, const uint16_t& end
)
171 pthread_attr_t stack_attr
;
172 pthread_attr_init(&stack_attr
);
173 if (1 < hw_concurrency
174 && (start
+1) < hw_concurrency
)
176 #if real_hw_concurrency > 1 || real_hw_concurrency == 0
177 pthread_attr_setaffinity_np(&stack_attr
, sizeof(cpu_set_t
), &cpu_set_free
);
179 if (hw_concurrency
-1 < end
)
180 docreateThreads(start
, hw_concurrency
-1, stack_attr
);
182 docreateThreads(start
, end
, stack_attr
);
185 #if real_hw_concurrency > 1 || real_hw_concurrency == 0
186 pthread_attr_setaffinity_np(&stack_attr
, sizeof(cpu_set_t
), &cpu_set_restrict
);
188 docreateThreads(start
, end
, stack_attr
);
193 static void docreateThreads(uint16_t& start
, const uint16_t& end
, pthread_attr_t
& stack_attr
)
196 for (; start
< end
; ++start
)
200 // manual set stack space & stack size for each thread
201 // to reduce memory usage
202 pthread_attr_setstack( &stack_attr
, &(stacks
[start
]), STACK_SIZE
);
203 functions
[start
].set_id(start
);
205 // create thread using specified stackspace
206 threads
[start
].createThread(functions
[start
], id
, stack_attr
);
213 thread
thread_func::threads
[NUM_THREADS
];
214 thread_func
thread_func::functions
[NUM_THREADS
];
216 int main(int argc
, char** args
)
219 token
= atoi(args
[1]);
223 const uint16_t start
= 0;
224 const uint16_t end
= NUM_THREADS
/hw_concurrency
;
225 thread_func::createThreads(start
, end
);