18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _LIBLOCKDEP_RWLOCK_H
38c2ecf20Sopenharmony_ci#define _LIBLOCKDEP_RWLOCK_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <pthread.h>
68c2ecf20Sopenharmony_ci#include "common.h"
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_cistruct liblockdep_pthread_rwlock {
98c2ecf20Sopenharmony_ci	pthread_rwlock_t rwlock;
108c2ecf20Sopenharmony_ci	struct lockdep_map dep_map;
118c2ecf20Sopenharmony_ci};
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_citypedef struct liblockdep_pthread_rwlock liblockdep_pthread_rwlock_t;
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#define LIBLOCKDEP_PTHREAD_RWLOCK_INITIALIZER(rwl)			\
168c2ecf20Sopenharmony_ci		(struct liblockdep_pthread_rwlock) {			\
178c2ecf20Sopenharmony_ci	.rwlock = PTHREAD_RWLOCK_INITIALIZER,				\
188c2ecf20Sopenharmony_ci	.dep_map = STATIC_LOCKDEP_MAP_INIT(#rwl, &((&(rwl))->dep_map)),	\
198c2ecf20Sopenharmony_ci}
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_cistatic inline int __rwlock_init(liblockdep_pthread_rwlock_t *lock,
228c2ecf20Sopenharmony_ci				const char *name,
238c2ecf20Sopenharmony_ci				struct lock_class_key *key,
248c2ecf20Sopenharmony_ci				const pthread_rwlockattr_t *attr)
258c2ecf20Sopenharmony_ci{
268c2ecf20Sopenharmony_ci	lockdep_init_map(&lock->dep_map, name, key, 0);
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci	return pthread_rwlock_init(&lock->rwlock, attr);
298c2ecf20Sopenharmony_ci}
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci#define liblockdep_pthread_rwlock_init(lock, attr)		\
328c2ecf20Sopenharmony_ci({							\
338c2ecf20Sopenharmony_ci	static struct lock_class_key __key;		\
348c2ecf20Sopenharmony_ci							\
358c2ecf20Sopenharmony_ci	__rwlock_init((lock), #lock, &__key, (attr));	\
368c2ecf20Sopenharmony_ci})
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_cistatic inline int liblockdep_pthread_rwlock_rdlock(liblockdep_pthread_rwlock_t *lock)
398c2ecf20Sopenharmony_ci{
408c2ecf20Sopenharmony_ci	lock_acquire(&lock->dep_map, 0, 0, 2, 1, NULL, (unsigned long)_RET_IP_);
418c2ecf20Sopenharmony_ci	return pthread_rwlock_rdlock(&lock->rwlock);
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci}
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_cistatic inline int liblockdep_pthread_rwlock_unlock(liblockdep_pthread_rwlock_t *lock)
468c2ecf20Sopenharmony_ci{
478c2ecf20Sopenharmony_ci	lock_release(&lock->dep_map, (unsigned long)_RET_IP_);
488c2ecf20Sopenharmony_ci	return pthread_rwlock_unlock(&lock->rwlock);
498c2ecf20Sopenharmony_ci}
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_cistatic inline int liblockdep_pthread_rwlock_wrlock(liblockdep_pthread_rwlock_t *lock)
528c2ecf20Sopenharmony_ci{
538c2ecf20Sopenharmony_ci	lock_acquire(&lock->dep_map, 0, 0, 0, 1, NULL, (unsigned long)_RET_IP_);
548c2ecf20Sopenharmony_ci	return pthread_rwlock_wrlock(&lock->rwlock);
558c2ecf20Sopenharmony_ci}
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_cistatic inline int liblockdep_pthread_rwlock_tryrdlock(liblockdep_pthread_rwlock_t *lock)
588c2ecf20Sopenharmony_ci{
598c2ecf20Sopenharmony_ci	lock_acquire(&lock->dep_map, 0, 1, 2, 1, NULL, (unsigned long)_RET_IP_);
608c2ecf20Sopenharmony_ci	return pthread_rwlock_tryrdlock(&lock->rwlock) == 0 ? 1 : 0;
618c2ecf20Sopenharmony_ci}
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_cistatic inline int liblockdep_pthread_rwlock_trywrlock(liblockdep_pthread_rwlock_t *lock)
648c2ecf20Sopenharmony_ci{
658c2ecf20Sopenharmony_ci	lock_acquire(&lock->dep_map, 0, 1, 0, 1, NULL, (unsigned long)_RET_IP_);
668c2ecf20Sopenharmony_ci	return pthread_rwlock_trywrlock(&lock->rwlock) == 0 ? 1 : 0;
678c2ecf20Sopenharmony_ci}
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_cistatic inline int liblockdep_rwlock_destroy(liblockdep_pthread_rwlock_t *lock)
708c2ecf20Sopenharmony_ci{
718c2ecf20Sopenharmony_ci	return pthread_rwlock_destroy(&lock->rwlock);
728c2ecf20Sopenharmony_ci}
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci#ifdef __USE_LIBLOCKDEP
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci#define pthread_rwlock_t		liblockdep_pthread_rwlock_t
778c2ecf20Sopenharmony_ci#define pthread_rwlock_init		liblockdep_pthread_rwlock_init
788c2ecf20Sopenharmony_ci#define pthread_rwlock_rdlock		liblockdep_pthread_rwlock_rdlock
798c2ecf20Sopenharmony_ci#define pthread_rwlock_unlock		liblockdep_pthread_rwlock_unlock
808c2ecf20Sopenharmony_ci#define pthread_rwlock_wrlock		liblockdep_pthread_rwlock_wrlock
818c2ecf20Sopenharmony_ci#define pthread_rwlock_tryrdlock	liblockdep_pthread_rwlock_tryrdlock
828c2ecf20Sopenharmony_ci#define pthread_rwlock_trywrlock	liblockdep_pthread_rwlock_trywrlock
838c2ecf20Sopenharmony_ci#define pthread_rwlock_destroy		liblockdep_rwlock_destroy
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci#endif
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci#endif
88