contributed by <yaohwang99
>
= number of bits needed to store , for example, ,
Therefore, ceil_log2(uint32_t x)
is find last set for x-1
.
After line 14, x has 2 bit left, we also need to update r
. With the same approach, The code after line 14 is
The above code can be reduced to return (EXP1) + 1
, where EXP 1 is r | shift | x >> 1
.
Similar to Problem 1, the following code uses t
as mask and check if any of the shift
less significant bit are set. If none, increase the return value o
by shift
.
EXP2: x & t
EXP3: o |= shift
At the start of for
at line 23, con
points to foo->consumers
Then con
traverse through the list untill *con == fc
, therefore, EXP4 is con = &(*con)->next
.
Then remove fc
from the list, EXP3: fc->next
The structure stores the env
value. tasks
is function designator
task_add
inserts a new tast from tail and task_switch
removes the first task in the list. Therefore, EXP6 is list_del(&t->list)
.
task_join
goes through each task in the list and complete them, so EXP7 is list_del(&t->list)
.
longjmp(sched, 1)
will jump to setjump(sched)
in schedule
.
For each tast, the program prints n
then add itself to tasklist
then do EXP8.
From the output, we can see that the program jumps back to schedule()
after n is printed, so EXP8 and EXP9 is longjmp(sched, 1)
Here, we would like to implement READ_ONCE using the above macro.
The parameter res
corresponds to the argument __u.__c
.
The intuitve answer is let DECL0 be void *__c
, however, case 1 (line 8) of the above macro indicates that we need *res
to be 1 byte.
Therefore, DECL0 is char __c[1]
, where __c
is a pointer to 1 byte memory.