/* -*- c -*- * * Copyright (c) 2004-2005 The Trustees of Indiana University. * All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2006-2008 Cisco, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */ /* * Some notes about the declarations and definitions in this file: * * This file is a mix of internal and public declarations. * Applications are warned against using the internal types; they are * subject to change with no warning. * * The PLPA_NAME() and PLPA_NAME_CAPS() macros are used for prefixing * the PLPA type names, enum names, and symbol names when embedding * PLPA. When not embedding, the default prefix is "plpa_" (or * "PLPA_" when using PLPA_NAME_CAPS()). Hence, if you see a * declaration like this: * * int PLPA_NAME(foo)(void); * * It's a function named plpa_foo() that returns an int and takes no * arguments when building PLPA as a standalone library. It's a * function with a different prefix than "plpa_" when the * --enable-included-mode and --with-plpa-symbol-prefix options are * supplied to PLPA's configure script. */ #ifndef PLPA_H #define PLPA_H /* Absolutely must not include here or it will generate conflicts. */ /* For memset() */ #include /* For pid_t and size_t */ #include /*************************************************************************** * Internal types ***************************************************************************/ /* If we're building PLPA itself, will have already been included. But is a private header file; it is not installed into $includedir. Hence, applications including will not have included (this is by design). So include just enough information here to allow us to continue. */ #ifndef PLPA_CONFIG_H /* The PLPA symbol prefix */ #define PLPA_SYM_PREFIX plpa_ /* The PLPA symbol prefix in all caps */ #define PLPA_SYM_PREFIX_CAPS PLPA_ #endif /* Preprocessors are fun -- the double inderection is unfortunately necessary. */ #define PLPA_MUNGE_NAME(a, b) PLPA_MUNGE_NAME2(a, b) #define PLPA_MUNGE_NAME2(a, b) a ## b #define PLPA_NAME(name) PLPA_MUNGE_NAME(PLPA_SYM_PREFIX, name) #define PLPA_NAME_CAPS(name) PLPA_MUNGE_NAME(PLPA_SYM_PREFIX_CAPS, name) /*************************************************************************** * Public type ***************************************************************************/ /* Values that can be returned from plpa_api_probe() */ typedef enum { /* Sentinel value */ PLPA_NAME_CAPS(PROBE_UNSET), /* sched_setaffinity syscall available */ PLPA_NAME_CAPS(PROBE_OK), /* syscall unavailable/unimplemented */ PLPA_NAME_CAPS(PROBE_NOT_SUPPORTED), /* we experienced some strange failure that the user should report */ PLPA_NAME_CAPS(PROBE_UNKNOWN) } PLPA_NAME(api_type_t); /*************************************************************************** * Internal types ***************************************************************************/ /* Internal PLPA bitmask type. This type should not be used by external applications! */ typedef unsigned long int PLPA_NAME(bitmask_t); #define PLPA_BITMASK_T_NUM_BITS (sizeof(PLPA_NAME(bitmask_t)) * 8) #define PLPA_BITMASK_CPU_MAX 1024 #define PLPA_BITMASK_NUM_ELEMENTS (PLPA_BITMASK_CPU_MAX / PLPA_BITMASK_T_NUM_BITS) /*************************************************************************** * Public type ***************************************************************************/ /* Public type for the PLPA cpu set. */ typedef struct { PLPA_NAME(bitmask_t) bitmask[PLPA_BITMASK_NUM_ELEMENTS]; } PLPA_NAME(cpu_set_t); /*************************************************************************** * Internal macros ***************************************************************************/ /* Internal macro for identifying the byte in a bitmask array. This macro should not be used by external applications! */ #define PLPA_CPU_BYTE(num) ((num) / PLPA_BITMASK_T_NUM_BITS) /* Internal macro for identifying the bit in a bitmask array. This macro should not be used by external applications! */ #define PLPA_CPU_BIT(num) ((num) % PLPA_BITMASK_T_NUM_BITS) /*************************************************************************** * Public macros ***************************************************************************/ /* Public macro to zero out a PLPA cpu set (analogous to the FD_ZERO() macro; see select(2)). */ #define PLPA_CPU_ZERO(cpuset) \ memset((cpuset), 0, sizeof(PLPA_NAME(cpu_set_t))) /* Public macro to set a bit in a PLPA cpu set (analogous to the FD_SET() macro; see select(2)). */ #define PLPA_CPU_SET(num, cpuset) \ (cpuset)->bitmask[PLPA_CPU_BYTE(num)] |= ((PLPA_NAME(bitmask_t))1 << PLPA_CPU_BIT(num)) /* Public macro to clear a bit in a PLPA cpu set (analogous to the FD_CLR() macro; see select(2)). */ #define PLPA_CPU_CLR(num, cpuset) \ (cpuset)->bitmask[PLPA_CPU_BYTE(num)] &= ~((PLPA_NAME(bitmask_t))1 << PLPA_CPU_BIT(num)) /* Public macro to test if a bit is set in a PLPA cpu set (analogous to the FD_ISSET() macro; see select(2)). */ #define PLPA_CPU_ISSET(num, cpuset) \ (0 != (((cpuset)->bitmask[PLPA_CPU_BYTE(num)]) & ((PLPA_NAME(bitmask_t))1 << PLPA_CPU_BIT(num)))) /*************************************************************************** * Public functions ***************************************************************************/ /* Setup PLPA internals. This function is optional; it will be automatically invoked by all the other API functions if you do not invoke it explicitly. Returns 0 upon success. */ int PLPA_NAME(init)(void); /* Check what API is on this machine. If api_type returns PLPA_PROBE_OK, then PLPA can function properly on this machine. Returns 0 upon success. */ int PLPA_NAME(api_probe)(PLPA_NAME(api_type_t) *api_type); /* Set processor affinity. Use the PLPA_CPU_* macros to set the cpuset value. The same rules and restrictions about pid apply as they do for the sched_setaffinity(2) system call. Returns 0 upon success. */ int PLPA_NAME(sched_setaffinity)(pid_t pid, size_t cpusetsize, const PLPA_NAME(cpu_set_t) *cpuset); /* Get processor affinity. Use the PLPA_CPU_* macros to analyze the returned value of cpuset. The same rules and restrictions about pid apply as they do for the sched_getaffinity(2) system call. Returns 0 upon success. */ int PLPA_NAME(sched_getaffinity)(pid_t pid, size_t cpusetsize, PLPA_NAME(cpu_set_t) *cpuset); /* Return whether topology information is available (i.e., plpa_map_to_*, plpa_max_*). The topology functions will be available if supported == 1 and the function returns 0. */ int PLPA_NAME(have_topology_information)(int *supported); /* Map (socket,core) tuple to virtual processor ID. processor_id is then suitable for use with the PLPA_CPU_* macros, probably leading to a call to plpa_sched_setaffinity(). Returns 0 upon success. */ int PLPA_NAME(map_to_processor_id)(int socket, int core, int *processor_id); /* Map processor_id to (socket,core) tuple. The processor_id input is usually obtained from the return from the plpa_sched_getaffinity() call, using PLPA_CPU_ISSET to find individual bits in the map that were set/unset. plpa_map_to_socket_core() can map the bit indexes to a socket/core tuple. Returns 0 upon success. */ int PLPA_NAME(map_to_socket_core)(int processor_id, int *socket, int *core); /* Return the max processor ID. Returns both the number of processors (cores) in a system and the maximum Linux virtual processor ID (because it may be higher than the number of processors if there are "holes" in the available Linux virtual processor IDs). Returns 0 upon success. */ int PLPA_NAME(get_processor_info)(int *num_processors, int *max_processor_id); /* Returns both the number of sockets in the system and the maximum socket ID number (in case there are "holes" in the list of available socket IDs). Returns 0 upon sucess. */ int PLPA_NAME(get_socket_info)(int *num_sockets, int *max_socket_id); /* Return both the number of cores and the max code ID for a given socket (in case there are "holes" in the list of available core IDs). Returns 0 upon success. */ int PLPA_NAME(get_core_info)(int socket, int *num_cores, int *max_core_id); /* Shut down PLPA. This function releases resources used by the PLPA. It should be the last PLPA function invoked, or can be used to forcibly cause PLPA to dump its topology cache and re-analyze the underlying system the next time another PLPA function is called. Specifically: it is safe to call plpa_init() (or any other PLPA function) again after plpa_finalized(). Returns 0 upon success. */ int PLPA_NAME(finalize)(void); #endif /* PLPA_H */