I send this patch as and RFC to get comments on the approach.
As it stands it can be already useful. The plan is to provide
a low level interface to thread/task affinity using unprivileged
processor ports, and a POSIX emulated interface using a bitmap
in glibc. The reason to not use directly a bitmap is because it
clashes with the processor set virtualizable API. Happy to hear
your opinion on this approach.
Gnumach currently offers a mechanism for the partition of the
available processors in terms of the processor set API. This API has
been designed to be fully virtualizable, and is designed with
etherogeneous architectures, processor hot swapping, as well as
transparent multi-host clustered architectures in mind.
The current Hurd SMP support utlized this API to confine all the
software to CPU 0. This confines this CPU in his own processor set.
An escape hatch consists in the smp utility, that configures
the other processors as a second processor set before forking.
This use of the processor set API is not optimal, since it partitions
the available resources. The preferable way to confine the software
to a single processor would consist in per-task and per-thread
affinites.
In preparation of that, this RFC adds a new RPC,
processor_set_name_processors, compatible with the virtualization
features of the processor set API. This allows unprivileged
applications to query the available processor in their set.
Usage example:
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <mach.h>
static
void print_processor_info(processor_name_t proc) {
kern_return_t err;
struct processor_basic_info info;
host_t processor_host;
natural_t count;
processor_info (proc, PROCESSOR_BASIC_INFO, &processor_host,
(processor_info_t)&info, &count);
if (err != 1) {
fprintf (stderr, "Unable to get processor info: %d\n",
err);
exit(err);
}
printf("\t\thost: <0x%08x>\n", processor_host);
printf("\t\ttype: 0x%02x\n", info.cpu_type);
printf("\t\tsubtype: 0x%02x\n", info.cpu_subtype);
printf("\t\trunning: 0x%01x\n", info.running);
printf("\t\tslot_num: 0x%02x\n", info.slot_num);
printf("\t\tis_master: 0x%01x\n", info.is_master);
}
int main(void) {
kern_return_t err;
processor_set_name_t pset;
processor_name_array_t procs;
natural_t count;
int i;
err = task_get_assignment (mach_task_self(), &pset);
if (err != KERN_SUCCESS) {
fprintf (stderr, "Unable to get processor set name: %d\n",
err);
exit(err);
}
err = processor_set_name_processors (pset, &procs, &count);
if (err != KERN_SUCCESS) {
fprintf (stderr, "Unable to get processor list: %d\n",
err);
exit(err);
}
printf ("Found %d processors:\n", count);
for (i = 0; i < count; i++) {
printf ("\t<0x%08x>\n", procs[i]);
print_processor_info(procs[i]);
}
exit(0);
}
Manolo de Medici (3):
Add unprivileged processor_name_t type
Add processor_set_name_processors RPC
Can processor_info unprivileged ports
include/mach/mach_host.defs | 9 +++++-
include/mach/mach_types.defs | 10 +++++++
include/mach/mach_types.h | 2 ++
kern/host.c | 40 ++++++++++++++++++++++++++
kern/ipc_host.c | 56 +++++++++++++++++++++++++++++++++++-
kern/ipc_host.h | 6 ++++
kern/ipc_kobject.h | 5 ++--
kern/processor.c | 1 +
kern/processor.h | 2 ++
9 files changed, 127 insertions(+), 4 deletions(-)
--
2.53.0