]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/plat-omap/dsp/proclist.h
7265ea0fd4ffde6967ba41cbab1f63372998cd5e
[linux-2.6-omap-h63xx.git] / arch / arm / plat-omap / dsp / proclist.h
1 /*
2  * linux/arch/arm/mach-omap/dsp/proclist.h
3  *
4  * Linux task list handler
5  *
6  * Copyright (C) 2004,2005 Nokia Corporation
7  *
8  * Written by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  *
24  * 2004/11/22:  DSP Gateway version 3.3
25  */
26
27 struct proc_list {
28         struct list_head list_head;
29         pid_t pid;
30         unsigned int cnt;
31 };
32
33 static __inline__ void proc_list_add(struct list_head *list,
34                                      struct task_struct *tsk)
35 {
36         struct proc_list *pl;
37         struct proc_list *new;
38
39         list_for_each_entry(pl, list, list_head) {
40                 if (pl->pid == tsk->pid) {
41                         /*
42                          * this process has opened DSP devices multi time
43                          */
44                         pl->cnt++;
45                         return;
46                 }
47         }
48
49         new = kmalloc(sizeof(struct proc_list), GFP_KERNEL);
50         new->pid = tsk->pid;
51         new->cnt = 1;
52         list_add_tail(&new->list_head, list);
53 }
54
55 static __inline__ void proc_list_del(struct list_head *list,
56                                      struct task_struct *tsk)
57 {
58         struct proc_list *pl, *next;
59
60         list_for_each_entry(pl, list, list_head) {
61                 if (pl->pid == tsk->pid) {
62                         if (--pl->cnt == 0) {
63                                 list_del(&pl->list_head);
64                                 kfree(pl);
65                         }
66                         return;
67                 }
68         }
69
70         /*
71          * correspinding pid wasn't found in the list
72          * -- this means the caller of proc_list_del is different from
73          * the proc_list_add's caller. in this case, the parent is
74          * cleaning up the context of a killed child.
75          * let's delete exiting task from the list.
76          */
77         /* need to lock tasklist_lock before calling find_task_by_pid_type. */
78         read_lock(&tasklist_lock);
79         list_for_each_entry_safe(pl, next, list, list_head) {
80                 if (find_task_by_pid_type(PIDTYPE_PID, pl->pid) == NULL) {
81                         list_del(&pl->list_head);
82                         kfree(pl);
83                 }
84         }
85         read_unlock(&tasklist_lock);
86 }
87
88 static __inline__ void proc_list_flush(struct list_head *list)
89 {
90         struct proc_list *pl;
91
92         while (!list_empty(list)) {
93                 pl = list_entry(list->next, struct proc_list, list_head);
94                 list_del(&pl->list_head);
95                 kfree(pl);
96         }
97 }