Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

liblockdep: Add public headers for pthread_mutex_t implementation

These headers provide the same API as their pthread mutex
counterparts.

The design here is to allow to easily switch to liblockdep lock
validation just by adding a "liblockdep_" to pthread_mutex_*()
calls, which means that it's easy to integrate liblockdep into
existing codebases.

Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Cc: torvalds@linux-foundation.org
Link: http://lkml.kernel.org/r/1371163284-6346-4-git-send-email-sasha.levin@oracle.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Sasha Levin and committed by
Ingo Molnar
45e62074 5634bd7d

+120
+50
tools/lib/lockdep/include/liblockdep/common.h
··· 1 + #ifndef _LIBLOCKDEP_COMMON_H 2 + #define _LIBLOCKDEP_COMMON_H 3 + 4 + #include <pthread.h> 5 + 6 + #define NR_LOCKDEP_CACHING_CLASSES 2 7 + #define MAX_LOCKDEP_SUBCLASSES 8UL 8 + 9 + #ifndef CALLER_ADDR0 10 + #define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) 11 + #endif 12 + 13 + #ifndef _RET_IP_ 14 + #define _RET_IP_ CALLER_ADDR0 15 + #endif 16 + 17 + #ifndef _THIS_IP_ 18 + #define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; }) 19 + #endif 20 + 21 + struct lockdep_subclass_key { 22 + char __one_byte; 23 + }; 24 + 25 + struct lock_class_key { 26 + struct lockdep_subclass_key subkeys[MAX_LOCKDEP_SUBCLASSES]; 27 + }; 28 + 29 + struct lockdep_map { 30 + struct lock_class_key *key; 31 + struct lock_class *class_cache[NR_LOCKDEP_CACHING_CLASSES]; 32 + const char *name; 33 + #ifdef CONFIG_LOCK_STAT 34 + int cpu; 35 + unsigned long ip; 36 + #endif 37 + }; 38 + 39 + void lockdep_init_map(struct lockdep_map *lock, const char *name, 40 + struct lock_class_key *key, int subclass); 41 + void lock_acquire(struct lockdep_map *lock, unsigned int subclass, 42 + int trylock, int read, int check, 43 + struct lockdep_map *nest_lock, unsigned long ip); 44 + void lock_release(struct lockdep_map *lock, int nested, 45 + unsigned long ip); 46 + 47 + #define STATIC_LOCKDEP_MAP_INIT(_name, _key) \ 48 + { .name = (_name), .key = (void *)(_key), } 49 + 50 + #endif
+70
tools/lib/lockdep/include/liblockdep/mutex.h
··· 1 + #ifndef _LIBLOCKDEP_MUTEX_H 2 + #define _LIBLOCKDEP_MUTEX_H 3 + 4 + #include <pthread.h> 5 + #include "common.h" 6 + 7 + struct liblockdep_pthread_mutex { 8 + pthread_mutex_t mutex; 9 + struct lockdep_map dep_map; 10 + }; 11 + 12 + typedef struct liblockdep_pthread_mutex liblockdep_pthread_mutex_t; 13 + 14 + #define LIBLOCKDEP_PTHREAD_MUTEX_INITIALIZER(mtx) \ 15 + (const struct liblockdep_pthread_mutex) { \ 16 + .mutex = PTHREAD_MUTEX_INITIALIZER, \ 17 + .dep_map = STATIC_LOCKDEP_MAP_INIT(#mtx, &((&(mtx))->dep_map)), \ 18 + } 19 + 20 + static inline int __mutex_init(liblockdep_pthread_mutex_t *lock, 21 + const char *name, 22 + struct lock_class_key *key, 23 + const pthread_mutexattr_t *__mutexattr) 24 + { 25 + lockdep_init_map(&lock->dep_map, name, key, 0); 26 + return pthread_mutex_init(&lock->mutex, __mutexattr); 27 + } 28 + 29 + #define liblockdep_pthread_mutex_init(mutex, mutexattr) \ 30 + ({ \ 31 + static struct lock_class_key __key; \ 32 + \ 33 + __mutex_init((mutex), #mutex, &__key, (mutexattr)); \ 34 + }) 35 + 36 + static inline int liblockdep_pthread_mutex_lock(liblockdep_pthread_mutex_t *lock) 37 + { 38 + lock_acquire(&lock->dep_map, 0, 0, 0, 2, NULL, (unsigned long)_RET_IP_); 39 + return pthread_mutex_lock(&lock->mutex); 40 + } 41 + 42 + static inline int liblockdep_pthread_mutex_unlock(liblockdep_pthread_mutex_t *lock) 43 + { 44 + lock_release(&lock->dep_map, 0, (unsigned long)_RET_IP_); 45 + return pthread_mutex_unlock(&lock->mutex); 46 + } 47 + 48 + static inline int liblockdep_pthread_mutex_trylock(liblockdep_pthread_mutex_t *lock) 49 + { 50 + lock_acquire(&lock->dep_map, 0, 1, 0, 2, NULL, (unsigned long)_RET_IP_); 51 + return pthread_mutex_trylock(&lock->mutex) == 0 ? 1 : 0; 52 + } 53 + 54 + static inline int liblockdep_pthread_mutex_destroy(liblockdep_pthread_mutex_t *lock) 55 + { 56 + return pthread_mutex_destroy(&lock->mutex); 57 + } 58 + 59 + #ifdef __USE_LIBLOCKDEP 60 + 61 + #define pthread_mutex_t liblockdep_pthread_mutex_t 62 + #define pthread_mutex_init liblockdep_pthread_mutex_init 63 + #define pthread_mutex_lock liblockdep_pthread_mutex_lock 64 + #define pthread_mutex_unlock liblockdep_pthread_mutex_unlock 65 + #define pthread_mutex_trylock liblockdep_pthread_mutex_trylock 66 + #define pthread_mutex_destroy liblockdep_pthread_mutex_destroy 67 + 68 + #endif 69 + 70 + #endif