1 /* Locking performance tests. Gives locsk&unlocks/second. */
14 #define MAX_LOCKS 471234567
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);
97 if (silc_unlikely(hval3 != hval2 + i + hval)) {
98 fprintf(stderr, "MUTEX CORRUPT 1\n");
101 if (silc_unlikely(hval2 != i)) {
102 fprintf(stderr, "MUTEX CORRUPT 2 (%llu != %d)\n", hval2, i);
105 silc_mutex_unlock(mutex);
107 c->time = rdtsc() - s;
113 int main(int argc, char **argv)
115 Context c[MAX_THREADS * MAX_MUL];
121 fprintf(stderr, "Usage: ./test_silcmutex <cpu_freq_mhz>\n");
122 fprintf(stderr, "Example: ./test_silcmutex 3000\n");
125 cpu_freq = (SilcUInt64)atoi(argv[1]);
126 cpu_freq *= 1000; /* Will give us milliseconds */
128 max_locks = MAX_LOCKS;
130 fprintf(stderr, "lock/unlock per second\n");
132 for (j = 0; j < MAX_ROUND; j++) {
133 for (i = 0; i < 1; i++)
134 c[i].thread = silc_thread_create(mutex_thread, &c[i], TRUE);
137 for (i = 0; i < 1; i++) {
138 silc_thread_wait(c[i].thread, NULL);
141 fprintf(stderr, "%llu mutex lock/unlock per second (%d threads)\n",
142 (1000LL * max_locks * 1) / val, 1);
145 /* If MAX_LOCKS is too large for this CPU, optimize. We don't want to
146 wait a whole day for this test. */
147 if ((SilcInt64)(max_locks / 10) >
148 (SilcInt64)((1000LL * max_locks) / val))
155 max_locks2 = max_locks;
156 for (k = 0; k < MAX_MUL; k++) {
158 max_locks = max_locks2 / (k + 1);
159 for (j = 0; j < MAX_ROUND; j++) {
160 for (i = 0; i < MAX_THREADS * (k + 1); i++)
161 c[i].thread = silc_thread_create(mutex_thread, &c[i], TRUE);
164 for (i = 0; i < MAX_THREADS * (k + 1); i++) {
165 silc_thread_wait(c[i].thread, NULL);
168 fprintf(stderr, "%llu mutex lock/unlock per second (%d threads)\n",
169 (1000LL * max_locks * (MAX_THREADS * (k + 1))) / val,
170 MAX_THREADS * (k + 1));
174 max_locks = max_locks2;
176 fprintf(stderr, "Spinning/holding lock, lock/unlock per second\n");
180 for (j = 0; j < MAX_ROUND / 2; j++) {
181 for (i = 0; i < 1; i++)
182 c[i].thread = silc_thread_create(mutex_thread_hold, &c[i], TRUE);
185 for (i = 0; i < 1; i++) {
186 silc_thread_wait(c[i].thread, NULL);
189 fprintf(stderr, "%llu mutex lock/unlock per second (%d threads)\n",
190 (1000LL * (max_locks / 4) * 1) / val, 1);
194 max_locks2 = max_locks;
196 for (k = 0; k < MAX_MUL; k++) {
198 max_locks = max_locks2 / (k + 1);
199 for (j = 0; j < MAX_ROUND / 2; j++) {
201 for (i = 0; i < MAX_THREADS * (k + 1); i++)
202 c[i].thread = silc_thread_create(mutex_thread_hold, &c[i], TRUE);
205 for (i = 0; i < MAX_THREADS * (k + 1); i++) {
206 silc_thread_wait(c[i].thread, NULL);
209 fprintf(stderr, "%llu mutex lock/unlock per second (%d threads)\n",
210 (1000LL * (max_locks / 4) *
211 (MAX_THREADS * (k + 1))) / val,
212 MAX_THREADS * (k + 1));
219 fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE");