一、信号量:
信号量——是一种睡眠锁,如果一个任务试图获取一个不可用(已经被占用)的信号量时,信号量会将其推向一个等待队列,然后让其睡眠。
这是处理器能重获自由,从而去执行其他的代码,当持有信号量可用(被释放)后,处于等待队列的那个任务将被唤醒,并获得该信号量
#include <linux/semaphore.h>
struct semaphore {
raw_spinlock_t lock;
unsigned int count;
struct list_head wait_list;
};
主要API:
DEFINE_SEMAPHORE(name)
#define DEFINE_SEMAPHORE(name) struct semaphore name = __SEMAPHORE_INITIALIZER(name, 1)
静态初始化一个信号量
举例:
static DEFINE_SEMAPHORE(console_sem);
void sema_init(struct semaphore *sem, int val)
动态初始化一个信号量
举例:
struct semaphore sem;
sema_init(&sem, 1);
void down(struct semaphore *sem)
获取制定信号量
举例:
down(&sem);
int down_interruptible(struct semaphore *sem)
acquire the semaphore unless interrupted
返回0:信号量成功获取到,If the semaphore is successfully acquired, this function returns 0.
返回-EINTR: 睡眠被信号打断,If the sleep is interrupted by a signal, this function will return -EINTR.
举例:
if (down_interruptible(&sem)
return -ERESTARTSYS;
int down_killable(struct semaphore *sem) //很少使用
acquire the semaphore unless killed
返回0:If the semaphore is successfully acquired, this function returns 0.
返回-EINTR:If the sleep is interrupted by a fatal signal, this function will return -EINTR
int down_trylock(struct semaphore *sem)
try to acquire the semaphore, without waiting
Returns 0 :if the semaphore has been acquired successfully
Returns 1: if it it cannot be acquired.
int down_timeout(struct semaphore *sem, long jiffies)
down_timeout - acquire the semaphore within a specified time
@sem: the semaphore to be acquired
@timeout: how long to wait before failing
* Attempts to acquire the semaphore. If no more tasks are allowed to
* acquire the semaphore, calling this function will put the task to sleep.
* If the semaphore is not released within the specified number of jiffies,
* this function returns -ETIME. It returns 0 if the semaphore was acquired.
void up(struct semaphore *sem)
release the semaphore
二、读写信号量:
#include <linux/rwsem.h>
struct rw_semaphore {
long count;
struct list_head wait_list;
raw_spinlock_t wait_lock;
#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
struct optimistic_spin_queue osq; /* spinner MCS lock */
/*
* Write owner. Used as a speculative check to see
* if the owner is running on the cpu.
*/
struct task_struct *owner;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
};
主要API:
DECLARE_RWSEM(name)
#define DECLARE_RWSEM(name) \
struct rw_semaphore name = __RWSEM_INITIALIZER(name)
静态初始化一个读写信号量
举例:
DECLARE_RWSEM(leds_list_lock);
init_rwsem(sem)
动态初始化一个信号量
#define init_rwsem(sem) \
do { \
static struct lock_class_key __key; \
__init_rwsem((sem), #sem, &__key); \
} while (0)
举例:
struct rw_semaphore commit_root_sem;
init_rwsem(&commit_root_sem);
void down_read(struct rw_semaphore *sem)
lock for reading
int down_read_trylock(struct rw_semaphore *sem);
trylock for reading -- returns 1 if successful, 0 if contention
void down_write(struct rw_semaphore *sem);
lock for writing
int down_write_trylock(struct rw_semaphore *sem);
trylock for writing -- returns 1 if successful, 0 if contention
void up_read(struct rw_semaphore *sem);
release a read lock
void up_write(struct rw_semaphore *sem);
release a write lock
int rwsem_is_locked(struct rw_semaphore *sem)
/* In all implementations count != 0 means locked */
static inline int rwsem_is_locked(struct rw_semaphore *sem)
{
return sem->count != 0;
}
int rwsem_is_contended(struct rw_semaphore *sem)
static inline int rwsem_is_contended(struct rw_semaphore *sem)
{
return !list_empty(&sem->wait_list);
}
void downgrade_write(struct rw_semaphore *sem);
downgrade write lock to read lock
三、互斥体:
#include <linux/rwsem.h>
struct mutex {
/* 1: unlocked, 0: locked, negative: locked, possible waiters */
atomic_t count;
spinlock_t wait_lock;
struct list_head wait_list;
#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_MUTEX_SPIN_ON_OWNER)
struct task_struct *owner;
#endif
#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
struct optimistic_spin_queue osq; /* Spinner MCS lock */
#endif
#ifdef CONFIG_DEBUG_MUTEXES
void *magic;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
};
主要API:
DEFINE_MUTEX(mutexname)
静态初始化一个互斥体
#define DEFINE_MUTEX(mutexname) \
struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
举例:
static DEFINE_MUTEX(mdp_clk_lock);
static DEFINE_MUTEX(mdp_iommu_ref_cnt_lock);
mutex_init(mutex)
动态初始化一个互斥体
#define mutex_init(mutex) \
do { \
static struct lock_class_key __key; \
\
__mutex_init((mutex), #mutex, &__key); \
} while (0)
举例:
struct mutex bl_lock;
mutex_init(&bl_lock);
int mutex_is_locked(struct mutex *lock)
mutex_is_locked - is the mutex locked
Returns 1 if the mutex is locked, 0 if unlocked.
void mutex_lock(struct mutex *lock);
int mutex_lock_interruptible(struct mutex *lock);
int mutex_lock_killable(struct mutex *lock);
int mutex_trylock(struct mutex *lock);
Returns 1 if the mutex has been acquired successfully, and 0 on contention.
void mutex_unlock(struct mutex *lock);
int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock);