1
2
3
4
5
|
struct
semaphore {
spinlock_t lock;
/* 自旋锁结构体变量 */
unsigned
int
count;
/* 用于计录资料数量 */
struct
list_head wait_list;
/* 内部链表结构体变量 */
};
|
1
2
|
#define DECLARE_MUTEX(name) \
struct
semaphore name = __SEMAPHORE_INITIALIZER(name, 1)
|
1
|
DECLARE_MUTEX(my_semaphore);
|
1
2
3
4
5
6
|
#define __SEMAPHORE_INITIALIZER(name, n) \
{ \
.lock = __SPIN_LOCK_UNLOCKED((name).lock), \
.count = n, \
.wait_list = LIST_HEAD_INIT((name).wait_list), \
}
|
1
|
#define init_MUTEX(sem) sema_init(sem, 1)
|
1
2
3
4
5
6
|
static
inline
void
sema_init(
struct
semaphore *sem,
int
val)
{
static
struct
lock_class_key __key;
*sem = (
struct
semaphore) __SEMAPHORE_INITIALIZER(*sem, val);
lockdep_init_map(&sem->lock.dep_map,
"semaphore->lock"
, &__key, 0);
}
|
1
|
#define init_MUTEX_LOCKED(sem) sema_init(sem, 0)
|
1
2
|
static
inline
int
__sched __down_common(
struct
semaphore *sem,
long
state,
long
timeout)
|
1
|
timeout = schedule_timeout(timeout);
|
1
2
3
4
5
6
7
8
9
10
11
|
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);
}
|
1
2
3
4
5
|
static
noinline
void
__sched __down(
struct
semaphore *sem)
{
__down_common(sem,TASK_UNINTERRUPTIBLE,\
MAX_SCHEDULE_TIMEOUT);
}
|
1
|
#define MAX_SCHEDULE_TIMEOUT LONG_MAX
|
1
|
#define LONG_MAX ((long)(~0UL>>1))
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
int
down_trylock(
struct
semaphore *sem)
{
unsigned
long
flags;
int
count;
spin_lock_irqsave(&sem->lock, flags);
count = sem->count - 1;
if
(likely(count >= 0))
sem->count = count;
spin_unlock_irqrestore(&sem->lock, flags);
return
(count < 0);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
int
down_timeout(
struct
semaphore *sem,
long
jiffies)
{
unsigned
long
flags;
int
result = 0;
spin_lock_irqsave(&sem->lock, flags);
if
(likely(sem->count > 0))
sem->count--;
else
result = __down_timeout(sem, jiffies);
spin_unlock_irqrestore(&sem->lock, flags);
return
result;
}
|
1
2
3
4
5
6
7
8
|
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);
}
|