1 /* Locking performance tests. Gives locsk&unlocks/second. */
4 #include "silcruntime.h"
14 #define MAX_LOCKS 471234567
17 SilcUInt64 cpu_freq = 0;
18 int max_locks, max_locks2;
19 SilcTimerStruct timer;
21 #define rdtsc() silc_timer_tick(&timer, FALSE)
23 void *mutex_thread(void *context)
30 for (i = 0; i < max_locks; i++) {
31 silc_mutex_lock(mutex);
32 silc_mutex_unlock(mutex);
34 c->time = rdtsc() - s;
44 void *mutex_thread_hold(void *context)
51 for (i = 0; i < max_locks / 4; i++) {
52 silc_mutex_lock(mutex);
59 if (silc_unlikely(hval3 != hval2 + i + hval)) {
60 fprintf(stderr, "MUTEX CORRUPT 1\n");
63 if (silc_unlikely(hval2 != i)) {
64 fprintf(stderr, "MUTEX CORRUPT 2 (%llu != %d)\n", hval2, i);
67 silc_mutex_unlock(mutex);
69 c->time = rdtsc() - s;
75 int main(int argc, char **argv)
77 Context c[MAX_THREADS * MAX_MUL];
82 silc_timer_synchronize(&timer);
86 val /= 1000; /* Gives us milliseconds */
88 fprintf(stderr, "CPU frequency: %llu\n", val);
90 max_locks = MAX_LOCKS;
92 fprintf(stderr, "lock/unlock per second\n");
94 for (j = 0; j < MAX_ROUND; j++) {
95 for (i = 0; i < 1; i++)
96 c[i].thread = silc_thread_create(mutex_thread, &c[i], TRUE);
99 for (i = 0; i < 1; i++) {
100 silc_thread_wait(c[i].thread, NULL);
103 fprintf(stderr, "%llu mutex lock/unlock per second (%d threads)\n",
104 (1000LL * max_locks * 1) / val, 1);
107 /* If MAX_LOCKS is too large for this CPU, optimize. We don't want to
108 wait a whole day for this test. */
109 if ((SilcInt64)(max_locks / 10) >
110 (SilcInt64)((1000LL * max_locks) / val))
117 max_locks2 = max_locks;
118 for (k = 0; k < MAX_MUL; k++) {
120 max_locks = max_locks2 / (k + 1);
121 for (j = 0; j < MAX_ROUND; j++) {
122 for (i = 0; i < MAX_THREADS * (k + 1); i++)
123 c[i].thread = silc_thread_create(mutex_thread, &c[i], TRUE);
126 for (i = 0; i < MAX_THREADS * (k + 1); i++) {
127 silc_thread_wait(c[i].thread, NULL);
130 fprintf(stderr, "%llu mutex lock/unlock per second (%d threads)\n",
131 (1000LL * max_locks * (MAX_THREADS * (k + 1))) / val,
132 MAX_THREADS * (k + 1));
136 max_locks = max_locks2;
138 fprintf(stderr, "Spinning/holding lock, lock/unlock per second\n");
142 for (j = 0; j < MAX_ROUND / 2; j++) {
143 for (i = 0; i < 1; i++)
144 c[i].thread = silc_thread_create(mutex_thread_hold, &c[i], TRUE);
147 for (i = 0; i < 1; i++) {
148 silc_thread_wait(c[i].thread, NULL);
151 fprintf(stderr, "%llu mutex lock/unlock per second (%d threads)\n",
152 (1000LL * (max_locks / 4) * 1) / val, 1);
156 max_locks2 = max_locks;
158 for (k = 0; k < MAX_MUL; k++) {
160 max_locks = max_locks2 / (k + 1);
161 for (j = 0; j < MAX_ROUND / 2; j++) {
163 for (i = 0; i < MAX_THREADS * (k + 1); i++)
164 c[i].thread = silc_thread_create(mutex_thread_hold, &c[i], TRUE);
167 for (i = 0; i < MAX_THREADS * (k + 1); i++) {
168 silc_thread_wait(c[i].thread, NULL);
171 fprintf(stderr, "%llu mutex lock/unlock per second (%d threads)\n",
172 (1000LL * (max_locks / 4) *
173 (MAX_THREADS * (k + 1))) / val,
174 MAX_THREADS * (k + 1));
181 fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE");