* pointer if the task/tasklet remains valid, and return NULL if it has been
* deleted. The scheduler relies on this to know if it should update its state
* on return.
+ *
+ * Keep in mind that tasks can be cast to tasklets while in the final tasklet
+ * queues, and will be listed via the tasklet's <list> instead of the task's
+ * <rq>. However other fields (wq, common) must remain totally valid for the
+ * task during this time. This explains why certain elements are present in
+ * the common part even though pure tasklets do not need them.
*/
#define TASK_COMMON \
unsigned int state; /* task state : bitfield of TASK_ */ \
uint32_t wake_date; /* date of the last task wakeup */ \
unsigned int calls; /* number of times process was called */ \
TASK_DEBUG_STORAGE; \
- short last_run; /* 16-bit now_ms of last run */
- /* a 16- or 48-bit hole remains here and is used by task */
+ short last_run; /* 16-bit now_ms of last run */ \
+ short nice; /* task prio from -1024 to +1024 */ \
+ int expire; /* next expiration date for this task, in ticks */
+ /* total: 36 or 48 bytes on 32/64 bit platforms */
/* The base for all tasks */
struct task {
TASK_COMMON; /* must be at the beginning! */
- short nice; /* task prio from -1024 to +1024 */
- int expire; /* next expiration date for this task, in ticks */
struct eb32_node rq; /* ebtree node used to hold the task in the run queue */
/* WARNING: the struct task is often aliased as a struct tasklet when
* it is NOT in the run queue. The tasklet has its struct list here
/* lightweight tasks, without priority, mainly used for I/Os */
struct tasklet {
TASK_COMMON; /* must be at the beginning! */
- /* 48-bit hole here */
struct list list;
/* WARNING: the struct task is often aliased as a struct tasklet when
* it is not in the run queue. The task has its struct rq here where