一些内核进程调度API (4)

//实现将等待队列元素插入等待队列第一个元素的位置
//并设置这个元素的flags为 非WQ_FLAG_EXCLUSIVE ,代表此进程不是高优先级进程
void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)
{
unsigned long flags;


wait->flags &= ~WQ_FLAG_EXCLUSIVE;
spin_lock_irqsave(&q->lock, flags);
__add_wait_queue(q, wait);
spin_unlock_irqrestore(&q->lock, flags);
}


//与 add_wait_queue 相反,将等待元素加入到等待队列的尾部
//并设置这个元素的flags为 WQ_FLAG_EXCLUSIVE , 代表此进程是高优先级进程
void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait)
{
unsigned long flags;


wait->flags |= WQ_FLAG_EXCLUSIVE;
spin_lock_irqsave(&q->lock, flags);
__add_wait_queue_tail(q, wait);
spin_unlock_irqrestore(&q->lock, flags);
}


//唤醒等待队列中某一进程,唤醒成功后把它从等待队列中删除
/*wait 某个进程
  mode 处于如下状态的进程才能够被唤醒:TASK_ALL/TASK_NORMAL
                                       TASK_NORMAL:可中断或不可中断的等待状态的进程
   TASK_ALL:   TASK_NORMAL及暂停状态和跟踪状态的进程
  sync 0-非同步唤醒   非0-同步唤醒
  key  唤醒时执行函数,一般给NULL
  
  返回值:0-唤醒失败,并且进程没有从等待队列中删除,没有找到满足条件的进程
          1-唤醒成功,并且使进程由 其他状态,变为 TASK_RUNNING 态,获得CPU资源,从而被调度执行
*/
int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key)
{
int ret = default_wake_function(wait, mode, sync, key);


if (ret)
list_del_init(&wait->task_list);
return ret;
}


//唤醒等待队列中的睡眠进程,记录唤醒次数,保存在 done 中
//唤醒不同步,按等待队列中元素顺序,一个一个唤醒,遇到flags字段为 WQ_FLAG_EXCLUSIVE ,则停止
//唤醒
#define WQ_FLAG_EXCLUSIVE 0x01  //等待队列的flags字段的值
#define WQ_FLAG_WOKEN 0x02
struct completion {
unsigned int done;      //等待队列的唤醒情况,代表等待队列中元素被唤醒的次数
wait_queue_head_t wait; //等待队列的头元素
};
void complete(struct completion *x)
{
unsigned long flags;


spin_lock_irqsave(&x->wait.lock, flags);
x->done++;
__wake_up_locked(&x->wait, TASK_NORMAL, 1);
spin_unlock_irqrestore(&x->wait.lock, flags);
}


//唤醒所有睡眠进程
/*与 complete 的区别:
  complete_all 的 done无法再代表唤醒次数
  complete_all 遇到flags为 WQ_FLAG_EXCLUSIVE ,不会再停下来,而是继续唤醒后面的进程
*/
void complete_all(struct completion *x)
{
unsigned long flags;


spin_lock_irqsave(&x->wait.lock, flags);
x->done += UINT_MAX/2;
__wake_up_locked(&x->wait, TASK_NORMAL, 0);
spin_unlock_irqrestore(&x->wait.lock, flags);
}
void __wake_up_locked(wait_queue_head_t *q, unsigned int mode, int nr)
{
__wake_up_common(q, mode, nr, 0, NULL);
}
static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
                 int nr_exclusive    , int wake_flags   , void *key)
{
wait_queue_t *curr, *next;


list_for_each_entry_safe(curr, next, &q->task_list, task_list) {
unsigned flags = curr->flags;


if (curr->func(curr, mode, wake_flags, key) &&
(flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
break;
}
}




//查看等待队列是否有等待者,1-没有等待者 0-有等待者
bool completion_done(struct completion *x)
{
unsigned long flags;
int ret = 1;


spin_lock_irqsave(&x->wait.lock, flags);
if (!x->done)
ret = 0;
spin_unlock_irqrestore(&x->wait.lock, flags);
return ret;
}

猜你喜欢

转载自blog.csdn.net/Dummkopfer/article/details/80448247