Exemple #1
0
static void do_scheduled_release(struct vperfctr *child_perfctr)
{
	struct task_struct *parent_tsk = child_perfctr->parent_tsk;

	task_lock(parent_tsk);
	do_vperfctr_release(child_perfctr, parent_tsk);
	task_unlock(parent_tsk);
	put_task_struct(parent_tsk);
}
static void scheduled_release(struct work_struct *data)
{
	struct vperfctr *child_perfctr = 
		container_of(data, struct vperfctr, work);
	struct task_struct *parent_tsk = child_perfctr->parent_tsk;

	// why are we getting a lock on the parent task structure ?
	// of course, we incremented the reference count to parent's task_struct
	task_lock(parent_tsk);
	do_vperfctr_release(child_perfctr, parent_tsk);
	task_unlock(parent_tsk);
	
	// good, the incremented reference count of the parent task is now
	// decremented, now that we are done adding up our counts to that
	// of the parent
	put_task_struct(parent_tsk);
}
void __vperfctr_release(struct task_struct *child_tsk)
{
	struct task_struct *parent_tsk = child_tsk->parent;
	struct vperfctr *child_perfctr = child_tsk->thread.perfctr;

	// this is invoked either in the waitpid() or if there the parent is not
	// interesting in its children. In the latter case, "parent_tsk != current"

	// one releases oneself, when the parent is not interested in one's data
	// but even then we would like to add our counters to those of the parent's
	
	// another step towards freeing the task_struct(ure).
	child_tsk->thread.perfctr = NULL;

	// if the parent is releasing the children's task structure, then it (the
	// parent) can go ahead and add the children's vperfctr's values to the
	// 'children' field in the parent's 'vperfctr' structure.
	// So, am 'I' the parent of the task_structure I am attempting to release?
	// When current == parent_tsk, the child's counts can be merged
	// into the parent's immediately. This is the common case.

	// printk ("%s, %d\n", __FUNCTION__, __LINE__);
	if (child_perfctr == NULL) {
		// printk("%s, %d, child_perfctr == NULL\n", __FUNCTION__, __LINE__);
	}

	if (parent_tsk == current)
		do_vperfctr_release(child_perfctr, parent_tsk);
	else {

		/* When current != parent_tsk, the parent must be task_lock()ed
		 * before its perfctr state can be accessed. task_lock() is illegal
		 * here due to the write_lock_irq(&tasklist_lock) in release_task(),
		 * so the operation is done via schedule_work(). Also, increment
		 * the reference count of parent's task_struct so that it will not be
		 * freed for good
	     */

		get_task_struct(parent_tsk);	// increments the reference count

		INIT_WORK(&child_perfctr->work, scheduled_release);
		child_perfctr->parent_tsk = parent_tsk;
		schedule_work(&child_perfctr->work);
	}
}
Exemple #4
0
void __vperfctr_release(struct task_struct *child_tsk)
{

#if 0
	struct task_struct *parent_tsk = child_tsk->parent;
	struct vperfctr *child_perfctr = child_tsk->arch.thread.perfctr;

	child_tsk->arch.thread.perfctr = NULL;
	if (parent_tsk == current)
		do_vperfctr_release(child_perfctr, parent_tsk);
	else {
		get_task_struct(parent_tsk);

		INIT_WORK(&child_perfctr->work, scheduled_release);

		child_perfctr->parent_tsk = parent_tsk;
		schedule_work(&child_perfctr->work);
	}
#endif 

}