Uclinux uses a structure called cpumask_t to hold information about each CPU. The definition is in Include/linux/cpumask.h, as follows:
typedef struct {Declare_bitmap (bits, Nr_cpus);} cpumask_t;
Where Declare_bitmap is defined as:
#define BITS_TO_LONGS(bits) /
(((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
#define DECLARE_BITMAP(name,bits) /
unsigned long name[BITS_TO_LONGS(bits)]
So for bf561, the definition of cpumask_t is equivalent to:
typedef struct {unsigned long bits[1];} cpumask_t;
The information for each CPU is represented by one of the integers. Some basic actions related to this mask are defined in Cpumask.h:
/* The available cpumask operations are:
*
* void Cpu_set (CPU, mask) turn on bit ' CPU ' in mask
* void Cpu_clear (CPU, mask) turn off bit ' CPU ' in mask
* void Cpus_setall (mask) set all bits
* void Cpus_clear (mask) Clear all bits
* int Cpu_isset (CPU, mask) True iff bit ' CPU ' set in mask
* int Cpu_test_and_set (CPU, mask) test and set bit ' CPU ' in mask
*
* Void Cpus_and (DST, Src1, src2) DST = src1 & Src2 [intersection]
* Void Cpus_or (DST, Src1, src2) DST = Src1 | SRC2 [Union]
* Void Cpus_xor (DST, Src1, src2) DST = src1 ^ src2
* Void Cpus_andnot (DST, Src1, src2) DST = src1 & ~SRC2
* Void Cpus_complement (DST, src) DST = ~src
*
* int cpus_equal (MASK1, mask2) does mask1 = = Mask2?
* int cpus_intersects (MASK1, Mask2) do mask1 and Mask2 intersect?
* int Cpus_subset (MASK1, Mask2) is mask1 a subset of Mask2?
* int Cpus_empty (mask) is mask empty (no bits sets)?
* int Cpus_full (mask) is mask full (all bits sets)?
* int Cpus_weight (mask) Hamming Weigh-number of Set bits
*
* Void Cpus_shift_right (DST, SRC, n) Shift right
* Void Cpus_shift_left (DST, SRC, N) shift left
*
* int FIRST_CPU (mask) number lowest set bit, or Nr_cpus
* int next_cpu (CPU, mask) Next CPU past ' CPU ', or Nr_cpus
*
* cpumask_t cpumask_of_cpu (CPU) return cpumask with bit ' CPU ' Set
* Cpu_mask_all Initializer-all bits Set
* Cpu_mask_none initializer-no bits Set
* Unsigned long *cpus_addr (mask) Array of unsigned long ' in mask
*
* int cpumask_scnprintf (buf, Len, mask) Format cpumask for printing
* int Cpumask_parse_user (UBUF, Ulen, mask) parse ASCII string as Cpumask
* int cpulist_scnprintf (buf, Len, mask) Format cpumask as list for printing
* int Cpulist_parse (BUF, map) parse ASCII string as Cpulist
* int Cpu_remap (oldbit, old, new) Newbit = Map (old, new) (Oldbit)
* int Cpus_remap (DST, SRC, old, new) *DST = Map (old, new) (SRC)
*
* For_each_cpu_mask (CPU, mask) For-loop CPU over mask
*
* int Num_online_cpus () Number of online CPUs
* int Num_possible_cpus () Number of all possible CPUs
* int Num_present_cpus () Number of present CPUs
*
* int Cpu_online (CPU) is some CPU online?
* int cpu_possible (CPU) is some CPU possible?
* int Cpu_present (CPU) is some CPU present (can schedule)?
*
* int Any_online_cpu (mask), the ' I ' mask
*
* FOR_EACH_POSSIBLE_CPU (CPU) For-loop CPU over Cpu_possible_map
* FOR_EACH_ONLINE_CPU (CPU) For-loop CPU over Cpu_online_map
* FOR_EACH_PRESENT_CPU (CPU) For-loop CPU over Cpu_present_map
*
* Subtlety:
* 1) The ' type-checked ' form of cpu_isset () causes GCC (3.3.2, anyway)
* To generate slightly worse code. Note For example the additional
* Lines of assembly code compiling the "for each possible CPU"
* Loops buried in the Disk_stat_read () macros calls when compiling
* DRIVERS/BLOCK/GENHD.C (Arch i386, Config_smp=y). A simple
* One-line #define FOR Cpu_isset (), instead of wrapping a inline
* Inside a macro, the way we do the other calls.
*/