1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef _LIBLOCKDEP_RWLOCK_H 3#define _LIBLOCKDEP_RWLOCK_H 4 5#include <pthread.h> 6#include "common.h" 7 8struct liblockdep_pthread_rwlock { 9 pthread_rwlock_t rwlock; 10 struct lockdep_map dep_map; 11}; 12 13typedef struct liblockdep_pthread_rwlock liblockdep_pthread_rwlock_t; 14 15#define LIBLOCKDEP_PTHREAD_RWLOCK_INITIALIZER(rwl) \ 16 (struct liblockdep_pthread_rwlock) { \ 17 .rwlock = PTHREAD_RWLOCK_INITIALIZER, \ 18 .dep_map = STATIC_LOCKDEP_MAP_INIT(#rwl, &((&(rwl))->dep_map)), \ 19} 20 21static inline int __rwlock_init(liblockdep_pthread_rwlock_t *lock, 22 const char *name, 23 struct lock_class_key *key, 24 const pthread_rwlockattr_t *attr) 25{ 26 lockdep_init_map(&lock->dep_map, name, key, 0); 27 28 return pthread_rwlock_init(&lock->rwlock, attr); 29} 30 31#define liblockdep_pthread_rwlock_init(lock, attr) \ 32({ \ 33 static struct lock_class_key __key; \ 34 \ 35 __rwlock_init((lock), #lock, &__key, (attr)); \ 36}) 37 38static inline int liblockdep_pthread_rwlock_rdlock(liblockdep_pthread_rwlock_t *lock) 39{ 40 lock_acquire(&lock->dep_map, 0, 0, 2, 1, NULL, (unsigned long)_RET_IP_); 41 return pthread_rwlock_rdlock(&lock->rwlock); 42 43} 44 45static inline int liblockdep_pthread_rwlock_unlock(liblockdep_pthread_rwlock_t *lock) 46{ 47 lock_release(&lock->dep_map, (unsigned long)_RET_IP_); 48 return pthread_rwlock_unlock(&lock->rwlock); 49} 50 51static inline int liblockdep_pthread_rwlock_wrlock(liblockdep_pthread_rwlock_t *lock) 52{ 53 lock_acquire(&lock->dep_map, 0, 0, 0, 1, NULL, (unsigned long)_RET_IP_); 54 return pthread_rwlock_wrlock(&lock->rwlock); 55} 56 57static inline int liblockdep_pthread_rwlock_tryrdlock(liblockdep_pthread_rwlock_t *lock) 58{ 59 lock_acquire(&lock->dep_map, 0, 1, 2, 1, NULL, (unsigned long)_RET_IP_); 60 return pthread_rwlock_tryrdlock(&lock->rwlock) == 0 ? 1 : 0; 61} 62 63static inline int liblockdep_pthread_rwlock_trywrlock(liblockdep_pthread_rwlock_t *lock) 64{ 65 lock_acquire(&lock->dep_map, 0, 1, 0, 1, NULL, (unsigned long)_RET_IP_); 66 return pthread_rwlock_trywrlock(&lock->rwlock) == 0 ? 1 : 0; 67} 68 69static inline int liblockdep_rwlock_destroy(liblockdep_pthread_rwlock_t *lock) 70{ 71 return pthread_rwlock_destroy(&lock->rwlock); 72} 73 74#ifdef __USE_LIBLOCKDEP 75 76#define pthread_rwlock_t liblockdep_pthread_rwlock_t 77#define pthread_rwlock_init liblockdep_pthread_rwlock_init 78#define pthread_rwlock_rdlock liblockdep_pthread_rwlock_rdlock 79#define pthread_rwlock_unlock liblockdep_pthread_rwlock_unlock 80#define pthread_rwlock_wrlock liblockdep_pthread_rwlock_wrlock 81#define pthread_rwlock_tryrdlock liblockdep_pthread_rwlock_tryrdlock 82#define pthread_rwlock_trywrlock liblockdep_pthread_rwlock_trywrlock 83#define pthread_rwlock_destroy liblockdep_rwlock_destroy 84 85#endif 86 87#endif 88