Esempio n. 1
0
static inline long __sched
do_wait_for_common(struct completion *x,
		   long (*action)(long), long timeout, int state)
{
	if (!x->done) {
		DECLARE_WAITQUEUE(wait, current);

		__add_wait_queue_tail_exclusive(&x->wait, &wait);
		do {
			if (signal_pending_state(state, current)) {
				timeout = -ERESTARTSYS;
				break;
			}
			__set_current_state(state);
			spin_unlock_irq(&x->wait.lock);
			timeout = action(timeout);
			spin_lock_irq(&x->wait.lock);
		} while (!x->done && timeout);
		__remove_wait_queue(&x->wait, &wait);
		if (!x->done)
			return timeout;
	}
	x->done--;
	return timeout ?: 1;
}
Esempio n. 2
0
// ARM10C 20170830
// x: &kthreadd_done, action: schedule_timeout, timeout: 0x7FFFFFFF, state: 2
static inline long __sched
do_wait_for_common(struct completion *x,
		   long (*action)(long), long timeout, int state)
{
	// x->done: (&kthreadd_done)->done: 0
	if (!x->done) {
		// current: kmem_cache#15-oX (struct task_struct) (pid: 1)
		DECLARE_WAITQUEUE(wait, current);
		// DECLARE_WAITQUEUE(wait, kmem_cache#15-oX (struct task_struct) (pid: 1)):
		// wait_queue_t wait =
		// {
		//     .private	= kmem_cache#15-oX (struct task_struct) (pid: 1),
		//     .func = default_wake_function,
		//     .task_list = { NULL, NULL }
		// }

		// &x->wait: &(&kthreadd_done)->wait
		__add_wait_queue_tail_exclusive(&x->wait, &wait);

		// __add_wait_queue_tail_exclusive 에서 한일:
		// (&wait)->flags: ? | 0x01
		// &(&(&kthreadd_done)->wait)->task_list 과 (&(&(&kthreadd_done)->wait)->task_list)->prev 사이에 &(&wait)->task_list 를 추가함
		// 간단히 말하면 head 인 &(&(&kthreadd_done)->wait)->task_list 의 tail에 &(&wait)->task_list 가 추가됨
		//
		// (&(&(&kthreadd_done)->wait)->task_list)->prev = &(&wait)->task_list;
		// (&(&wait)->task_list)->next = &(&(&kthreadd_done)->wait)->task_list;
		// (&(&wait)->task_list)->prev = &(&(&kthreadd_done)->wait)->task_list;
		// (&(&(&kthreadd_done)->wait)->task_list)->next = &(&wait)->task_list;

// 2017/08/30 종료
// 2017/09/06 시작

		do {
			// state: 2, current: kmem_cache#15-oX (struct task_struct) (pid: 1)
			// signal_pending_state(2, kmem_cache#15-oX (struct task_struct) (pid: 1)): 0
			if (signal_pending_state(state, current)) {
				timeout = -ERESTARTSYS;
				break;
			}

			// state: 2
			__set_current_state(state);

			// __set_current_state 에서 한일:
			// (kmem_cache#15-oX (struct task_struct) (pid: 1))->state: 2

			// &x->wait.lock: &(&kthreadd_done)->wait.lock
			spin_unlock_irq(&x->wait.lock);

			// spin_unlock_irq 에서 한일:
			// &(&kthreadd_done)->wait.lock 을 사용하여 spin unlock 을 수행

			// action: schedule_timeout, timeout: 0x7FFFFFFF
			timeout = action(timeout);
			spin_lock_irq(&x->wait.lock);
		} while (!x->done && timeout);
		__remove_wait_queue(&x->wait, &wait);
		if (!x->done)
			return timeout;
	}
	x->done--;
	return timeout ?: 1;
}