1/**
2 * \file
3 * \brief Lock scalability benchmark.
4 */
5
6/*
7 * Copyright (c) 2007, 2008, 2009, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#include <stdio.h>
16#include <omp.h>
17#include <stdlib.h>
18
19// Use spinlocks if defined, mutexes otherwise
20#define SPINLOCKS
21
22#ifdef POSIX
23#include <pthread.h>
24#include <stdint.h>
25
26#ifdef SPINLOCKS
27/** \brief spinlock */
28typedef volatile uint64_t spinlock_t __attribute__ ((aligned(64)));
29
30static inline void acquire_spinlock(spinlock_t * volatile lock)
31{
32    __asm__ __volatile__(
33                         "0:\n\t"
34                         "xor %%rax,%%rax\n\t"
35                         "lock bts %%rax,(%0)\n\t"
36                         "jc 0b\n\t"
37                         : : "S" (lock) : "rax"
38                        );
39}
40
41static inline void release_spinlock(spinlock_t * volatile lock)
42{
43    *lock = 0;
44}
45#endif
46
47static inline uint64_t rdtsc(void)
48{
49    uint64_t eax, edx;
50    __asm volatile ("rdtsc" : "=a" (eax), "=d" (edx));
51    return (edx << 32) | eax;
52}
53#endif
54
55int main(int argc, char *argv[])
56{
57        int i=0;
58
59	   bomp_bomp_init(4);
60       omp_set_num_threads(4);
61
62#ifndef POSIX
63#ifndef SPINLOCKS
64        static struct thread_mutex lock = THREAD_MUTEX_INITIALIZER;
65#else
66        static spinlock_t lock = 0;
67#endif
68#else
69#ifdef SPINLOCKS
70        static spinlock_t lock = 0;
71#else
72        static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
73#endif
74#endif
75
76        uint64_t begin = rdtsc();
77
78        #pragma omp parallel
79        {
80#pragma omp for private(i)
81		   for(i=0;i<1000000;i++)
82		   {
83#ifdef SPINLOCKS
84                       acquire_spinlock(&lock);
85                       release_spinlock(&lock);
86#else
87                       thread_mutex_lock(&lock);
88                       thread_mutex_unlock(&lock);
89#endif
90		   }
91	}
92
93        uint64_t end = rdtsc();
94
95        printf("took %lu\n", end - begin);
96}
97
98