diff --git a/newbrt/locking-benchmarks/pthread-locks.c b/newbrt/locking-benchmarks/pthread-locks.c index 18a4bd7328b..831b30e439d 100644 --- a/newbrt/locking-benchmarks/pthread-locks.c +++ b/newbrt/locking-benchmarks/pthread-locks.c @@ -41,91 +41,106 @@ static inline void brwl_rlock_xchg (struct brwl *l) { xchg(&l->mutex, 0); } +// Something wrong with the compiler for longs +static inline long +fetch_and_add (volatile long *p, long incr) +{ + long result = incr; + + __asm__ __volatile__ ("lock; xaddl %0, %1" : + "+r" (result), "+m" (*p) : : "memory"); + return result; +} + +static inline int +fetch_and_add_i (volatile int *p, int incr) +{ + int result = incr; + + __asm__ __volatile__ ("lock; xadd %0, %1" : + "+r" (result), "+m" (*p) : : "memory"); + return result; +} + +// Something wrong with the compiler for longs +/* Returns nonzero if the comparison succeeded. */ +static inline long +compare_and_swap_full(volatile long *addr, + long old, long new_val) +{ + char result; + __asm__ __volatile__("lock; cmpxchgl %2, %0; setz %1" + : "+m"(*(addr)), "=q"(result) + : "r" (new_val), "a"(old) : "memory"); + return (int) result; +} + +/* Returns nonzero if the comparison succeeded. */ +// Atomically compare *addr to old_val, and replace *addr by new_val +// if the first comparison succeeds. Returns nonzero if the comparison +// succeeded and *addr was updated. +static inline int +compare_and_swap_full_i(volatile int *addr, + int old, int new_val) +{ + char result; + __asm__ __volatile__("lock; cmpxchgl %2, %0; setz %1" + : "+m"(*(addr)), "=q"(result) + : "r" (new_val), "a"(old) : "memory"); + return (int) result; +} enum {K=100000}; pthread_rwlock_t rwlocks[K]; struct brwl blocks[K]; pthread_mutex_t mlocks[K]; +long lvals[K]; +int ivals[K]; + +#define TIME(s, i, init, body) ({ \ + int j_tmp; \ + printf("%-24s", s); \ + for (j_tmp=0; j_tmp<3; j_tmp++) { \ + struct timeval start,end; \ + int i; \ + for (i=0; i