[PATCH] per-task delay accounting: avoid send without listeners
[pandora-kernel.git] / include / linux / taskstats_kern.h
1 /* taskstats_kern.h - kernel header for per-task statistics interface
2  *
3  * Copyright (C) Shailabh Nagar, IBM Corp. 2006
4  *           (C) Balbir Singh,   IBM Corp. 2006
5  */
6
7 #ifndef _LINUX_TASKSTATS_KERN_H
8 #define _LINUX_TASKSTATS_KERN_H
9
10 #include <linux/taskstats.h>
11 #include <linux/sched.h>
12 #include <net/genetlink.h>
13
14 enum {
15         TASKSTATS_MSG_UNICAST,          /* send data only to requester */
16         TASKSTATS_MSG_MULTICAST,        /* send data to a group */
17 };
18
19 #ifdef CONFIG_TASKSTATS
20 extern kmem_cache_t *taskstats_cache;
21 extern struct mutex taskstats_exit_mutex;
22
23 static inline int taskstats_has_listeners(void)
24 {
25         if (!genl_sock)
26                 return 0;
27         return netlink_has_listeners(genl_sock, TASKSTATS_LISTEN_GROUP);
28 }
29
30
31 static inline void taskstats_exit_alloc(struct taskstats **ptidstats)
32 {
33         *ptidstats = NULL;
34         if (taskstats_has_listeners())
35                 *ptidstats = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL);
36 }
37
38 static inline void taskstats_exit_free(struct taskstats *tidstats)
39 {
40         if (tidstats)
41                 kmem_cache_free(taskstats_cache, tidstats);
42 }
43
44 static inline void taskstats_tgid_init(struct signal_struct *sig)
45 {
46         spin_lock_init(&sig->stats_lock);
47         sig->stats = NULL;
48 }
49
50 static inline void taskstats_tgid_alloc(struct signal_struct *sig)
51 {
52         struct taskstats *stats;
53         unsigned long flags;
54
55         stats = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL);
56         if (!stats)
57                 return;
58
59         spin_lock_irqsave(&sig->stats_lock, flags);
60         if (!sig->stats) {
61                 sig->stats = stats;
62                 stats = NULL;
63         }
64         spin_unlock_irqrestore(&sig->stats_lock, flags);
65
66         if (stats)
67                 kmem_cache_free(taskstats_cache, stats);
68 }
69
70 static inline void taskstats_tgid_free(struct signal_struct *sig)
71 {
72         struct taskstats *stats = NULL;
73         unsigned long flags;
74
75         spin_lock_irqsave(&sig->stats_lock, flags);
76         if (sig->stats) {
77                 stats = sig->stats;
78                 sig->stats = NULL;
79         }
80         spin_unlock_irqrestore(&sig->stats_lock, flags);
81         if (stats)
82                 kmem_cache_free(taskstats_cache, stats);
83 }
84
85 extern void taskstats_exit_send(struct task_struct *, struct taskstats *, int);
86 extern void taskstats_init_early(void);
87 extern void taskstats_tgid_alloc(struct signal_struct *);
88 #else
89 static inline void taskstats_exit_alloc(struct taskstats **ptidstats)
90 {}
91 static inline void taskstats_exit_free(struct taskstats *ptidstats)
92 {}
93 static inline void taskstats_exit_send(struct task_struct *tsk,
94                                        struct taskstats *tidstats,
95                                        int group_dead)
96 {}
97 static inline void taskstats_tgid_init(struct signal_struct *sig)
98 {}
99 static inline void taskstats_tgid_alloc(struct signal_struct *sig)
100 {}
101 static inline void taskstats_tgid_free(struct signal_struct *sig)
102 {}
103 static inline void taskstats_init_early(void)
104 {}
105 #endif /* CONFIG_TASKSTATS */
106
107 #endif
108