/**原子变量操作是Linux的一种简单同步机制,是一种在操作过程中不会被打断的操作.***/
/****其API和原子类型定义在include/asm/atomic.h文件中,使用汇编实现
****优点是编写简单;缺点是功能太简单,只能做计数操作,保护的东西太少,
***/
typedef struct{
volatile int counter;
}atomic_t;
atomic_t count = ATOMIC_INIT(0);
#define atomic_tset(v,i) (((v)->counter)=i)
#define atomic_read(v) ((v)->counter)
atomic_add(int i, volatile atomic_t *v);
atomic_sub(int i, volatile atomic_t *v);
static inline void atomic_inc(volatile atomic_t *v);
static inline void atomic_dec(volatile atomic_t *v);
static inline void set_bit(int nr, volatile unsigned long *addr);
static inline void clear_bit(int nr, volatile unsigned long *addr);
static inline void change_bit(int nr, volatile unsigned long *addr);
static inline int test_and_set_bit(int nr, volatile unsigned long *addr);
static inline int test_and_clear_bit(int nr, volatile unsigned long *addr);
static inline int test_and_change_bit(int nr, volatile unsigned long *addr);
spinlocak_t lock = SPIN_LOCK_UNLOCKED;
void spin_lock_init(spinlock_t lock);
#define spin_lock(lock) _spin_lock(lock);
#define spin_unlock(lock) _spin_unlock(lock)
/****自旋锁等待不是讲进程挂起,而是不断地循环条件是否满足,满足则解锁,
*****所以自旋锁对系统性能有影响。程序不应该长时间持有自旋锁,它适合
*****短时间锁定的轻量级的轻量级加锁机制.*/
/***信号量只有当得到信号量的继承或者线程时才能够进入临界区.与自旋锁不同,
当进程不能获得信号量时,进程将自己加入等待队列睡眠,直到信号量被释放,进程才被唤醒.***/
struct semaphore{
spinlock_t lock;
unsigned int count;
struct list_head wait_list;
}
struct semaphore sema;
static inline void sema_init(struct semaphore *sem,int val);
#define init_MUTEX(sem) sema_init(sem,1)
#define init_MUTEX_LOCKED(sem) sema_init(sem,0)
void down(struct semaphore *sem)
{
unsigned long flags;
spin_lock_irqsave(&sem->lock, flags);
if (likely(sem->count > 0))
sem->count--;
else
__down(sem);
spin_unlock_irqrestore(&sem->lock, flags);
}
void up(struct semaphore *sem)
{
unsigned long flags;
spin_lock_irqsave(&sem->lock, flags);
if (likely(list_empty(&sem->wait_list)))
sem->count++;
else
__up(sem);
spin_unlock_irqrestore(&sem->lock, flags);
}
static noinline void __sched __up(struct semaphore *sem)
{
struct semaphore_waiter *waiter = list_first_entry(&sem->wait_list,
struct semaphore_waiter, list);
list_del(&waiter->list);
waiter->up = 1;
wake_up_process(waiter->task);
}
/***由对内核源码可以得出结论,在进程未调用down()函数时也可以调用up()函数,放出信号量,
****且up()函数每次只能唤醒最先进入等待队列的进程。
***/
/****Linux中提供一种机制,实现一个线程发送一个信号通知另外一个进程开始完成某个任务,
*****这种机制就是完成量.完成量的目的是告诉一个线程某个事件已经发生,和信号量比较类似,
*****但在这种线程通信情况下有更高的效率****/
struct completion{
unsigned int done;
wait_queue_head_t wait;
}
struct completion com;
static inline void init_completion(struct completion *x)
{
x->done = 0;
init_waitqueue_head(&x->wait);
}
#define DECLARE_COMPLETION(work) \
struct completion work = COMPLETION_INITIALIZER(work)
#define COMPLETION_INITIALIZER(work)
{0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait)}
void __sched wait_for_completion(struct completion *x);
void complete(struct completion *x);
void complete_all(struct completetion *x);