lk中的mutex_t机制
来源:互联网 发布:mac如何退出dashboard 编辑:程序博客网 时间:2024/06/10 15:54
lk中还实现thread对全局资源保护的机制:mutex_t。主要用于对全局变量资源保护.而event 主要用于多thread之间
实现这套机制总共就5个函数,我们一个一个看一下
mutex_x的初始化函数和event一样,也是每个mutex_t 需要时wait queue
void mutex_init(mutex_t *m)
{
#if MUTEX_CHECK
// ASSERT(m->magic != MUTEX_MAGIC);
#endif
m->magic = MUTEX_MAGIC;
m->count = 0;
m->holder = 0;
wait_queue_init(&m->wait);
}
mutex_x的获取函数如下,可见如果只是两个thread之间协调的话m->count ==1,并不会使用wait_queue,而且会记住这个mutex_x 是哪个thread持有
status_t mutex_acquire(mutex_t *m)
{
status_t ret = NO_ERROR;
if (current_thread == m->holder)
panic("mutex_acquire: thread %p (%s) tried to acquire mutex %p it already owns.\n",
current_thread, current_thread->name, m);
enter_critical_section();
m->count++;
if (unlikely(m->count > 1)) {
ret = wait_queue_block(&m->wait, INFINITE_TIME);
if (ret < 0)
goto err;
}
m->holder = current_thread;
err:
exit_critical_section();
return ret;
}
如果用在一个thread之内保护资源的话mutex_acquire_timeout 和 mutex_acquire 是一样
status_t mutex_release(mutex_t *m)
{
if (current_thread != m->holder)
panic("mutex_release: thread %p (%s) tried to release mutex %p it doesn't own. owned by %p (%s)\n",
current_thread, current_thread->name, m, m->holder, m->holder ? m->holder->name : "none");
enter_critical_section();
m->holder = 0;
m->count--;
if (unlikely(m->count >= 1)) {
/* release a thread */
// dprintf("releasing thread\n");
wait_queue_wake_one(&m->wait, true, NO_ERROR);
}
exit_critical_section();
return NO_ERROR;
}
mutex_release的实现也很简单,将m->count--,一般情况下等于0.也就是if (unlikely(m->count >= 1))
一般不成立。
void mutex_destroy(mutex_t *m)
{
enter_critical_section();
#if MUTEX_CHECK
ASSERT(m->magic == MUTEX_MAGIC);
#endif
// if (m->holder != 0 && current_thread != m->holder)
// panic("mutex_destroy: thread %p (%s) tried to release mutex %p it doesn't own. owned by %p (%s)\n",
// current_thread, current_thread->name, m, m->holder, m->holder ? m->holder->name : "none");
m->magic = 0;
m->count = 0;
wait_queue_destroy(&m->wait, true);
exit_critical_section();
}
mutex_destroy用于销毁mutex_x。个人感觉这个函数应该要先判断一下m->count-- 是否为0,如果为0的话,就没必要调用wait_queue_destroy 这个函数了
void wait_queue_destroy(wait_queue_t *wait, bool reschedule)
{
#if THREAD_CHECKS
ASSERT(wait->magic == WAIT_QUEUE_MAGIC);
ASSERT(in_critical_section());
#endif
wait_queue_wake_all(wait, reschedule, ERR_OBJECT_DESTROYED);
wait->magic = 0;
}
继续调用wait_queue_wake_all 来wakeup在等待这个mutex_x的所有thread
int wait_queue_wake_all(wait_queue_t *wait, bool reschedule, status_t wait_queue_error)
{
thread_t *t;
int ret = 0;
if (reschedule && wait->count > 0) {
current_thread->state = THREAD_READY;
insert_in_run_queue_head(current_thread);
}
/* pop all the threads off the wait queue into the run queue */
while ((t = list_remove_head_type(&wait->list, thread_t, queue_node))) {
wait->count--;
t->state = THREAD_READY;
t->wait_queue_block_ret = wait_queue_error;
t->blocking_wait_queue = NULL;
insert_in_run_queue_head(t);
ret++;
}
if (reschedule && ret > 0)
thread_resched();
return ret;
}
如果wait->count > 0的话,由于reschedule ==1.就说明多个thread在使用这个mutex_x.就先将当前thread 放到run_queue中,然后设置current_thread->state = THREAD_READY;,再将其放到run_queue中,饭后将wait list中的每一个thread 都取出来放到run_queue中,单后调用thread_resched来调用
这样run_queue就先运行wait list中的thread.
实现这套机制总共就5个函数,我们一个一个看一下
mutex_x的初始化函数和event一样,也是每个mutex_t 需要时wait queue
void mutex_init(mutex_t *m)
{
#if MUTEX_CHECK
// ASSERT(m->magic != MUTEX_MAGIC);
#endif
m->magic = MUTEX_MAGIC;
m->count = 0;
m->holder = 0;
wait_queue_init(&m->wait);
}
mutex_x的获取函数如下,可见如果只是两个thread之间协调的话m->count ==1,并不会使用wait_queue,而且会记住这个mutex_x 是哪个thread持有
status_t mutex_acquire(mutex_t *m)
{
status_t ret = NO_ERROR;
if (current_thread == m->holder)
panic("mutex_acquire: thread %p (%s) tried to acquire mutex %p it already owns.\n",
current_thread, current_thread->name, m);
enter_critical_section();
m->count++;
if (unlikely(m->count > 1)) {
ret = wait_queue_block(&m->wait, INFINITE_TIME);
if (ret < 0)
goto err;
}
m->holder = current_thread;
err:
exit_critical_section();
return ret;
}
如果用在一个thread之内保护资源的话mutex_acquire_timeout 和 mutex_acquire 是一样
status_t mutex_release(mutex_t *m)
{
if (current_thread != m->holder)
panic("mutex_release: thread %p (%s) tried to release mutex %p it doesn't own. owned by %p (%s)\n",
current_thread, current_thread->name, m, m->holder, m->holder ? m->holder->name : "none");
enter_critical_section();
m->holder = 0;
m->count--;
if (unlikely(m->count >= 1)) {
/* release a thread */
// dprintf("releasing thread\n");
wait_queue_wake_one(&m->wait, true, NO_ERROR);
}
exit_critical_section();
return NO_ERROR;
}
mutex_release的实现也很简单,将m->count--,一般情况下等于0.也就是if (unlikely(m->count >= 1))
一般不成立。
void mutex_destroy(mutex_t *m)
{
enter_critical_section();
#if MUTEX_CHECK
ASSERT(m->magic == MUTEX_MAGIC);
#endif
// if (m->holder != 0 && current_thread != m->holder)
// panic("mutex_destroy: thread %p (%s) tried to release mutex %p it doesn't own. owned by %p (%s)\n",
// current_thread, current_thread->name, m, m->holder, m->holder ? m->holder->name : "none");
m->magic = 0;
m->count = 0;
wait_queue_destroy(&m->wait, true);
exit_critical_section();
}
mutex_destroy用于销毁mutex_x。个人感觉这个函数应该要先判断一下m->count-- 是否为0,如果为0的话,就没必要调用wait_queue_destroy 这个函数了
void wait_queue_destroy(wait_queue_t *wait, bool reschedule)
{
#if THREAD_CHECKS
ASSERT(wait->magic == WAIT_QUEUE_MAGIC);
ASSERT(in_critical_section());
#endif
wait_queue_wake_all(wait, reschedule, ERR_OBJECT_DESTROYED);
wait->magic = 0;
}
继续调用wait_queue_wake_all 来wakeup在等待这个mutex_x的所有thread
int wait_queue_wake_all(wait_queue_t *wait, bool reschedule, status_t wait_queue_error)
{
thread_t *t;
int ret = 0;
if (reschedule && wait->count > 0) {
current_thread->state = THREAD_READY;
insert_in_run_queue_head(current_thread);
}
/* pop all the threads off the wait queue into the run queue */
while ((t = list_remove_head_type(&wait->list, thread_t, queue_node))) {
wait->count--;
t->state = THREAD_READY;
t->wait_queue_block_ret = wait_queue_error;
t->blocking_wait_queue = NULL;
insert_in_run_queue_head(t);
ret++;
}
if (reschedule && ret > 0)
thread_resched();
return ret;
}
如果wait->count > 0的话,由于reschedule ==1.就说明多个thread在使用这个mutex_x.就先将当前thread 放到run_queue中,然后设置current_thread->state = THREAD_READY;,再将其放到run_queue中,饭后将wait list中的每一个thread 都取出来放到run_queue中,单后调用thread_resched来调用
这样run_queue就先运行wait list中的thread.
0 0
- lk中的mutex_t机制
- lk中的bcache机制
- lk中的bio机制 1
- lk中的bio机制 2
- android lk机制介绍
- Qualcomm LK机制介绍
- lk中的flashlayout
- lk中的idle thread
- lk中的timer
- lk中的threadlocal 变量
- lk中的event wait
- lk中的event siganl
- lk中的dprintf实现
- lk中的cbuf
- lk中的ptable
- lk中的partition.c
- lk中的smp
- LK
- python print'hello' File "<stdin>",line 1 print 'hello' SyntaxError:invalid syntax
- webservice解析wsdl出错解决办法
- android 自定义listview——实现上拉刷新下拉加载的功能
- 在ubuntu14.04下搭建caffe-lstm(cpu版)
- struts2的核心和工作原理
- lk中的mutex_t机制
- Sublime Text 3 快捷键总结
- iOS10 权限崩溃问题
- 2013蓝桥杯省赛 颠倒的价牌
- C#综合揭秘——细说进程、应用程序域与上下文之间的关系
- HDOJ 5738 Eureka 数学原理
- markdown编辑器语法——字体、字号与颜色
- 【奔跑的菜鸟】Java中的设计模式——策略模式
- ViewConfiguration.getScaledTouchSlop () 用法