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