13e456101SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
264ac24e7SMatthew Wilcox /*
364ac24e7SMatthew Wilcox * Copyright (c) 2008 Intel Corporation
464ac24e7SMatthew Wilcox * Author: Matthew Wilcox <[email protected]>
564ac24e7SMatthew Wilcox *
62dd6fd2eSTycho Andersen * Please see kernel/locking/semaphore.c for documentation of these functions
764ac24e7SMatthew Wilcox */
864ac24e7SMatthew Wilcox #ifndef __LINUX_SEMAPHORE_H
964ac24e7SMatthew Wilcox #define __LINUX_SEMAPHORE_H
1064ac24e7SMatthew Wilcox
1164ac24e7SMatthew Wilcox #include <linux/list.h>
1264ac24e7SMatthew Wilcox #include <linux/spinlock.h>
1364ac24e7SMatthew Wilcox
14714493cdSMatthew Wilcox /* Please don't access any members of this structure directly */
1564ac24e7SMatthew Wilcox struct semaphore {
168292c9e1SThomas Gleixner raw_spinlock_t lock;
17b17170b2SMatthew Wilcox unsigned int count;
1864ac24e7SMatthew Wilcox struct list_head wait_list;
1964ac24e7SMatthew Wilcox };
2064ac24e7SMatthew Wilcox
2164ac24e7SMatthew Wilcox #define __SEMAPHORE_INITIALIZER(name, n) \
2264ac24e7SMatthew Wilcox { \
238292c9e1SThomas Gleixner .lock = __RAW_SPIN_LOCK_UNLOCKED((name).lock), \
2464ac24e7SMatthew Wilcox .count = n, \
2564ac24e7SMatthew Wilcox .wait_list = LIST_HEAD_INIT((name).wait_list), \
2664ac24e7SMatthew Wilcox }
2764ac24e7SMatthew Wilcox
28*48380368SPeter Zijlstra /*
29*48380368SPeter Zijlstra * Unlike mutexes, binary semaphores do not have an owner, so up() can
30*48380368SPeter Zijlstra * be called in a different thread from the one which called down().
31*48380368SPeter Zijlstra * It is also safe to call down_trylock() and up() from interrupt
32*48380368SPeter Zijlstra * context.
33*48380368SPeter Zijlstra */
34*48380368SPeter Zijlstra #define DEFINE_SEMAPHORE(_name, _n) \
35*48380368SPeter Zijlstra struct semaphore _name = __SEMAPHORE_INITIALIZER(_name, _n)
36febc88c5SThomas Gleixner
sema_init(struct semaphore * sem,int val)3764ac24e7SMatthew Wilcox static inline void sema_init(struct semaphore *sem, int val)
3864ac24e7SMatthew Wilcox {
3964ac24e7SMatthew Wilcox static struct lock_class_key __key;
4064ac24e7SMatthew Wilcox *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val);
4164ac24e7SMatthew Wilcox lockdep_init_map(&sem->lock.dep_map, "semaphore->lock", &__key, 0);
4264ac24e7SMatthew Wilcox }
4364ac24e7SMatthew Wilcox
4464ac24e7SMatthew Wilcox extern void down(struct semaphore *sem);
4564ac24e7SMatthew Wilcox extern int __must_check down_interruptible(struct semaphore *sem);
46f06d9686SMatthew Wilcox extern int __must_check down_killable(struct semaphore *sem);
4764ac24e7SMatthew Wilcox extern int __must_check down_trylock(struct semaphore *sem);
48f1241c87SMatthew Wilcox extern int __must_check down_timeout(struct semaphore *sem, long jiffies);
4964ac24e7SMatthew Wilcox extern void up(struct semaphore *sem);
5064ac24e7SMatthew Wilcox
5164ac24e7SMatthew Wilcox #endif /* __LINUX_SEMAPHORE_H */
52