[PATCH] per-task delay accounting taskstats interface: control exit data through...
[linux-2.6.git] / include / linux / taskstats_kern.h
index bd0ecb9..16894b7 100644 (file)
@@ -9,45 +9,77 @@
 
 #include <linux/taskstats.h>
 #include <linux/sched.h>
-
-enum {
-       TASKSTATS_MSG_UNICAST,          /* send data only to requester */
-       TASKSTATS_MSG_MULTICAST,        /* send data to a group */
-};
+#include <net/genetlink.h>
 
 #ifdef CONFIG_TASKSTATS
 extern kmem_cache_t *taskstats_cache;
+extern struct mutex taskstats_exit_mutex;
 
-static inline void taskstats_exit_alloc(struct taskstats **ptidstats,
-                                       struct taskstats **ptgidstats)
+static inline void taskstats_exit_free(struct taskstats *tidstats)
 {
-       *ptidstats = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL);
-       *ptgidstats = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL);
+       if (tidstats)
+               kmem_cache_free(taskstats_cache, tidstats);
 }
 
-static inline void taskstats_exit_free(struct taskstats *tidstats,
-                                       struct taskstats *tgidstats)
+static inline void taskstats_tgid_init(struct signal_struct *sig)
 {
-       if (tidstats)
-               kmem_cache_free(taskstats_cache, tidstats);
-       if (tgidstats)
-               kmem_cache_free(taskstats_cache, tgidstats);
+       spin_lock_init(&sig->stats_lock);
+       sig->stats = NULL;
 }
 
-extern void taskstats_exit_send(struct task_struct *, struct taskstats *,
-                               struct taskstats *);
-extern void taskstats_init_early(void);
+static inline void taskstats_tgid_alloc(struct signal_struct *sig)
+{
+       struct taskstats *stats;
+       unsigned long flags;
+
+       stats = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL);
+       if (!stats)
+               return;
 
+       spin_lock_irqsave(&sig->stats_lock, flags);
+       if (!sig->stats) {
+               sig->stats = stats;
+               stats = NULL;
+       }
+       spin_unlock_irqrestore(&sig->stats_lock, flags);
+
+       if (stats)
+               kmem_cache_free(taskstats_cache, stats);
+}
+
+static inline void taskstats_tgid_free(struct signal_struct *sig)
+{
+       struct taskstats *stats = NULL;
+       unsigned long flags;
+
+       spin_lock_irqsave(&sig->stats_lock, flags);
+       if (sig->stats) {
+               stats = sig->stats;
+               sig->stats = NULL;
+       }
+       spin_unlock_irqrestore(&sig->stats_lock, flags);
+       if (stats)
+               kmem_cache_free(taskstats_cache, stats);
+}
+
+extern void taskstats_exit_alloc(struct taskstats **, unsigned int *);
+extern void taskstats_exit_send(struct task_struct *, struct taskstats *, int, unsigned int);
+extern void taskstats_init_early(void);
+extern void taskstats_tgid_alloc(struct signal_struct *);
 #else
-static inline void taskstats_exit_alloc(struct taskstats **ptidstats,
-                                       struct taskstats **ptgidstats)
+static inline void taskstats_exit_alloc(struct taskstats **ptidstats, unsigned int *mycpu)
 {}
-static inline void taskstats_exit_free(struct taskstats *ptidstats,
-                                       struct taskstats *ptgidstats)
+static inline void taskstats_exit_free(struct taskstats *ptidstats)
 {}
 static inline void taskstats_exit_send(struct task_struct *tsk,
-                                       struct taskstats *tidstats,
-                                       struct taskstats *tgidstats)
+                                      struct taskstats *tidstats,
+                                      int group_dead, unsigned int cpu)
+{}
+static inline void taskstats_tgid_init(struct signal_struct *sig)
+{}
+static inline void taskstats_tgid_alloc(struct signal_struct *sig)
+{}
+static inline void taskstats_tgid_free(struct signal_struct *sig)
 {}
 static inline void taskstats_init_early(void)
 {}