userfault userfault - 1 month ago 14
Linux Question

find if task 'target' is descendant of task `ancestor` (linux kernel tasks)

This is my solution so far:

int is_descendant(task_t* ansc, task_t* targ)
{
task_t* p_tmp;
for(p_tmp = targ ; (p_tmp) && (ansc) && (p_tmp->pid) && (p_tmp->pid != ansc->pid) ; p_tmp = p_tmp->p_pptr) ;
if((!p_tmp) || (!current) || (!p_tmp->pid)) return -ESRCH;
return 0;
}


It works but I'm unsure about several things:


  1. without checking if
    p_tmp->pid == 0
    it iterates forever, does that mean that the parent pointer of the first process is not NULL ?

  2. is it necessary to check if
    p_tmp
    or
    ansc
    are NULL ?

  3. is there a better way to do this ? (using O(1) space compl.)

  4. macro vs. function ?

    Thanks


Answer

As for 4.: What are you hoping to get by using a macro instead of a function? It is almost always better to use a function and to not use a macro.

The basic problems with macros include (but are not necessarily limited to) the following:

  • Macros are error-prone, because they use text substitution. They might not always do what you expect them to do, and to find these errors is not always trivial.
  • Macros can cause unwanted side effects like evaluating an expression multiple times.
  • Macros cannot return a value as in your return NOTDESCENDANT line. (It might work, if the macro is used inside of a function that has a matching return type.)
  • Writing (and possibly also reading) macros that span multiple lines is a pain.

All these points are also discussed here: Macro vs Function in C You can also see some examples for all these problems there.

Bottom line: When in doubt, always use functions or inline functions instead of macros.

Comments