1/** 2 * \file 3 * \brief Spinning synchronizations 4 */ 5 6/* 7 * Copyright (c) 2007, 2008, 2009, 2010, 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#ifndef BOMP_SPIN_H 16#define BOMP_SPIN_H 17 18#include <barrelfish/barrelfish.h> 19/* #include <string.h> */ 20#include <omp.h> 21 22/** \brief spinlock */ 23typedef volatile unsigned int bomp_lock_t; 24 25static inline void bomp_lock(bomp_lock_t *lock) 26{ 27#ifdef __k1om__ 28 /* The Xeon Phi does not support pause instruction. we use delay instead 29 * which does the same thing as pause but with a variable amount of delay. 30 * 750 cycles for now. 31 */ 32 uint32_t wait = 750; 33 __asm__ __volatile__("0:\n\t" 34 "cmpq $0, %0\n\t" 35 "je 1f\n\t" 36 "delay %1\n\t" 37 "jmp 0b\n\t" 38 "1:\n\t" 39 "lock btsq $0, %0\n\t" 40 "jc 0b\n\t" 41 : "+m" (*lock), "=r"(wait) : : "memory", "cc"); 42#else 43 __asm__ __volatile__("0:\n\t" 44 "cmpq $0, %0\n\t" 45 "je 1f\n\t" 46 "pause\n\t" 47 "jmp 0b\n\t" 48 "1:\n\t" 49 "lock btsq $0, %0\n\t" 50 "jc 0b\n\t" 51 : "+m" (*lock) : : "memory", "cc"); 52#endif 53} 54 55static inline void bomp_unlock(bomp_lock_t *lock) 56{ 57 *lock = 0; 58} 59 60static inline void bomp_lock_init(bomp_lock_t *lock) 61{ 62 /* nop */ 63} 64 65struct bomp_barrier 66{ 67 unsigned max; 68 volatile unsigned cycle; 69 volatile unsigned counter; 70}; 71 72static inline void bomp_barrier_init(struct bomp_barrier *barrier, 73 int count) 74{ 75 barrier->max = count; 76 barrier->cycle = 0; 77 barrier->counter = 0; 78} 79 80static inline void bomp_clear_barrier(struct bomp_barrier *barrier) 81{ 82 /* nop */ 83} 84 85static inline void bomp_barrier_wait(struct bomp_barrier *barrier) 86{ 87 int cycle = barrier->cycle; 88 if (__sync_fetch_and_add(&barrier->counter, 1) == barrier->max - 1) { 89 barrier->counter = 0; 90 barrier->cycle = !barrier->cycle; 91 } else { 92 uint64_t waitcnt = 0; 93 94 while (cycle == barrier->cycle) { 95 if (waitcnt == 0x400) { 96 waitcnt = 0; 97 thread_yield(); 98 } 99 waitcnt++; 100 } 101 } 102} 103 104#endif /* BOMP_SPIN_H */ 105