'struct runq' currently takes 4128 bytes per cpu. With the 1024 default
value for MAXCPU on amd64, runq_pcpu[] takes more than 4 MiB of memory.
Considering that most systems have less than 32 cores with SMT, this is
clearly a waste of memory.
Besides providing per-CPU runqueues, runq_pcpu[] is used to determine
the CPU ID of a given thread's associated runqueue through pointer
arithmetic.
To save space, move the runqueues to per-CPU fields then add 'int
ts_rqcpu' and remove 'struct runq *ts_runq' from 'struct ts_sched' to
track the per-cpu runqueue it is on. Per-CPU structures indeed are only
allocated for present CPUs. Note that this is different from td_oncpu
which is set to NOCPU when it is not running. Set ts_sched to NOCPU when
it is running on the global runqueue although the value becomes
irrelevant under that circumstance.
Drop SKE_RUNQ_PCPU() macro as it can simply replaced with `ts_rqcpu !=
NOCPU`. Instead, introduce TS_RUNQ_PTR() macro to get pointer to the
runq for runq_add() and runq_remove().
The added 'ts_rqcpu' field consumes 4 more bytes per thread, to be
compared with the savings of 4128 * (MAXCPU - ncpu_on_system) / 4. For
example, on a 32-core system, we can save around 4 MB of memory when
there are no threads and the memory efficiency will hold until there are
1,023,744 threads.