task_work.c (158e1645e07f3e9f7e4962d7a0997f5c3b98311b) | task_work.c (67d1214551e800f9fe7dc7c47a346d2df0fafed5) |
---|---|
1#include <linux/spinlock.h> 2#include <linux/task_work.h> 3#include <linux/tracehook.h> 4 5int | 1#include <linux/spinlock.h> 2#include <linux/task_work.h> 3#include <linux/tracehook.h> 4 5int |
6task_work_add(struct task_struct *task, struct task_work *twork, bool notify) | 6task_work_add(struct task_struct *task, struct callback_head *twork, bool notify) |
7{ 8 unsigned long flags; 9 int err = -ESRCH; 10 11#ifndef TIF_NOTIFY_RESUME 12 if (notify) 13 return -ENOTSUPP; 14#endif 15 /* 16 * We must not insert the new work if the task has already passed 17 * exit_task_work(). We rely on do_exit()->raw_spin_unlock_wait() 18 * and check PF_EXITING under pi_lock. 19 */ 20 raw_spin_lock_irqsave(&task->pi_lock, flags); 21 if (likely(!(task->flags & PF_EXITING))) { | 7{ 8 unsigned long flags; 9 int err = -ESRCH; 10 11#ifndef TIF_NOTIFY_RESUME 12 if (notify) 13 return -ENOTSUPP; 14#endif 15 /* 16 * We must not insert the new work if the task has already passed 17 * exit_task_work(). We rely on do_exit()->raw_spin_unlock_wait() 18 * and check PF_EXITING under pi_lock. 19 */ 20 raw_spin_lock_irqsave(&task->pi_lock, flags); 21 if (likely(!(task->flags & PF_EXITING))) { |
22 struct task_work *last = task->task_works; 23 struct task_work *first = last ? last->next : twork; | 22 struct callback_head *last = task->task_works; 23 struct callback_head *first = last ? last->next : twork; |
24 twork->next = first; 25 if (last) 26 last->next = twork; 27 task->task_works = twork; 28 err = 0; 29 } 30 raw_spin_unlock_irqrestore(&task->pi_lock, flags); 31 32 /* test_and_set_bit() implies mb(), see tracehook_notify_resume(). */ 33 if (likely(!err) && notify) 34 set_notify_resume(task); 35 return err; 36} 37 | 24 twork->next = first; 25 if (last) 26 last->next = twork; 27 task->task_works = twork; 28 err = 0; 29 } 30 raw_spin_unlock_irqrestore(&task->pi_lock, flags); 31 32 /* test_and_set_bit() implies mb(), see tracehook_notify_resume(). */ 33 if (likely(!err) && notify) 34 set_notify_resume(task); 35 return err; 36} 37 |
38struct task_work * | 38struct callback_head * |
39task_work_cancel(struct task_struct *task, task_work_func_t func) 40{ 41 unsigned long flags; | 39task_work_cancel(struct task_struct *task, task_work_func_t func) 40{ 41 unsigned long flags; |
42 struct task_work *last, *res = NULL; | 42 struct callback_head *last, *res = NULL; |
43 44 raw_spin_lock_irqsave(&task->pi_lock, flags); 45 last = task->task_works; 46 if (last) { | 43 44 raw_spin_lock_irqsave(&task->pi_lock, flags); 45 last = task->task_works; 46 if (last) { |
47 struct task_work *q = last, *p = q->next; | 47 struct callback_head *q = last, *p = q->next; |
48 while (1) { 49 if (p->func == func) { 50 q->next = p->next; 51 if (p == last) 52 task->task_works = q == p ? NULL : q; 53 res = p; 54 break; 55 } --- 5 unchanged lines hidden (view full) --- 61 } 62 raw_spin_unlock_irqrestore(&task->pi_lock, flags); 63 return res; 64} 65 66void task_work_run(void) 67{ 68 struct task_struct *task = current; | 48 while (1) { 49 if (p->func == func) { 50 q->next = p->next; 51 if (p == last) 52 task->task_works = q == p ? NULL : q; 53 res = p; 54 break; 55 } --- 5 unchanged lines hidden (view full) --- 61 } 62 raw_spin_unlock_irqrestore(&task->pi_lock, flags); 63 return res; 64} 65 66void task_work_run(void) 67{ 68 struct task_struct *task = current; |
69 struct task_work *p, *q; | 69 struct callback_head *p, *q; |
70 71 raw_spin_lock_irq(&task->pi_lock); 72 p = task->task_works; 73 task->task_works = NULL; 74 raw_spin_unlock_irq(&task->pi_lock); 75 76 if (unlikely(!p)) 77 return; 78 79 q = p->next; /* head */ 80 p->next = NULL; /* cut it */ 81 while (q) { 82 p = q->next; 83 q->func(q); 84 q = p; 85 } 86} | 70 71 raw_spin_lock_irq(&task->pi_lock); 72 p = task->task_works; 73 task->task_works = NULL; 74 raw_spin_unlock_irq(&task->pi_lock); 75 76 if (unlikely(!p)) 77 return; 78 79 q = p->next; /* head */ 80 p->next = NULL; /* cut it */ 81 while (q) { 82 p = q->next; 83 q->func(q); 84 q = p; 85 } 86} |