1 /* Locking performance tests. Gives locsk&unlocks/second. */
14 #define MAX_LOCKS 271234567
17 SilcUInt64 cpu_freq = 0;
18 int max_locks, max_locks2;
22 static __inline__ unsigned long long rdtsc(void)
24 unsigned long long int x;
25 __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
30 typedef unsigned long long int unsigned long long;
31 static __inline__ unsigned long long rdtsc(void)
34 __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
35 return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
39 typedef unsigned long long int unsigned long long;
40 static __inline__ unsigned long long rdtsc(void)
42 unsigned long long int result = 0;
43 unsigned long int upper, lower,tmp;
51 : "=r"(upper),"=r"(lower),"=r"(tmp)
54 result = result << 32;
55 result = result | lower;
61 void *mutex_thread(void *context)
68 for (i = 0; i < max_locks; i++) {
69 silc_mutex_lock(mutex);
70 silc_mutex_unlock(mutex);
72 c->time = rdtsc() - s;
82 void *mutex_thread_hold(void *context)
89 for (i = 0; i < max_locks / 4; i++) {
90 silc_mutex_lock(mutex);
101 if (silc_unlikely(hval3 != hval2 + i + hval)) {
102 fprintf(stderr, "MUTEX CORRUPT 1\n");
105 if (silc_unlikely(hval2 != i)) {
106 fprintf(stderr, "MUTEX CORRUPT 2 (%llu != %d)\n", hval2, i);
109 silc_mutex_unlock(mutex);
111 c->time = rdtsc() - s;
117 int main(int argc, char **argv)
119 Context c[MAX_THREADS * MAX_MUL];
125 fprintf(stderr, "Usage: ./test_silcmutex <cpu_freq_mhz>\n");
126 fprintf(stderr, "Example: ./test_silcmutex 3000\n");
129 cpu_freq = (SilcUInt64)atoi(argv[1]);
130 cpu_freq *= 1000; /* Will give us milliseconds */
132 max_locks = MAX_LOCKS;
134 fprintf(stderr, "lock/unlock per second\n");
136 for (j = 0; j < MAX_ROUND; j++) {
137 for (i = 0; i < 1; i++)
138 c[i].thread = silc_thread_create(mutex_thread, &c[i], TRUE);
141 for (i = 0; i < 1; i++) {
142 silc_thread_wait(c[i].thread, NULL);
145 fprintf(stderr, "%llu mutex lock/unlock per second (%d threads)\n",
146 (1000LL * max_locks * 1) / val, 1);
149 /* If MAX_LOCKS is too large for this CPU, optimize. We don't want to
150 wait a whole day for this test. */
151 if ((SilcInt64)(max_locks / 10) >
152 (SilcInt64)((1000LL * max_locks) / val))
159 max_locks2 = max_locks;
160 for (k = 0; k < MAX_MUL; k++) {
162 max_locks = max_locks2 / (k + 1);
163 for (j = 0; j < MAX_ROUND; j++) {
164 for (i = 0; i < MAX_THREADS * (k + 1); i++)
165 c[i].thread = silc_thread_create(mutex_thread, &c[i], TRUE);
168 for (i = 0; i < MAX_THREADS * (k + 1); i++) {
169 silc_thread_wait(c[i].thread, NULL);
172 fprintf(stderr, "%llu mutex lock/unlock per second (%d threads)\n",
173 (1000LL * max_locks * (MAX_THREADS * (k + 1))) / val,
174 MAX_THREADS * (k + 1));
178 max_locks = max_locks2;
180 fprintf(stderr, "Spinning/holding lock, lock/unlock per second\n");
183 for (j = 0; j < MAX_ROUND; j++) {
184 for (i = 0; i < 1; i++)
185 c[i].thread = silc_thread_create(mutex_thread_hold, &c[i], TRUE);
188 for (i = 0; i < 1; i++) {
189 silc_thread_wait(c[i].thread, NULL);
192 fprintf(stderr, "%llu mutex lock/unlock per second (%d threads)\n",
193 (1000LL * (max_locks / 4)) / val, 1);
197 max_locks2 = max_locks;
198 for (k = 0; k < MAX_MUL; k++) {
200 max_locks = max_locks2 / (k + 1);
201 for (j = 0; j < MAX_ROUND; j++) {
203 for (i = 0; i < MAX_THREADS * (k + 1); i++)
204 c[i].thread = silc_thread_create(mutex_thread, &c[i], TRUE);
207 for (i = 0; i < MAX_THREADS * (k + 1); i++) {
208 silc_thread_wait(c[i].thread, NULL);
211 fprintf(stderr, "%llu mutex lock/unlock per second (%d threads)\n",
212 (1000LL * (max_locks / 4) *
213 (MAX_THREADS * (k + 1))) / val,
214 MAX_THREADS * (k + 1));
218 max_locks = max_locks2;
222 fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE");