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