diff options
Diffstat (limited to 'plpa-1.3.2/src/libplpa/plpa_map.c')
-rw-r--r-- | plpa-1.3.2/src/libplpa/plpa_map.c | 1055 |
1 files changed, 0 insertions, 1055 deletions
diff --git a/plpa-1.3.2/src/libplpa/plpa_map.c b/plpa-1.3.2/src/libplpa/plpa_map.c deleted file mode 100644 index fcbf7f86..00000000 --- a/plpa-1.3.2/src/libplpa/plpa_map.c +++ /dev/null @@ -1,1055 +0,0 @@ -/* - * Copyright (c) 2007-2008 Cisco Systems, Inc. All rights reserved. - * - * Portions of this file originally contributed by Advanced Micro - * Devices, Inc. See notice below. - */ -/* ============================================================ - License Agreement - - Copyright (c) 2006, 2007 Advanced Micro Devices, Inc. - All rights reserved. - - Redistribution and use in any form of this material and any product - thereof including software in source or binary forms, along with any - related documentation, with or without modification ("this material"), - is permitted provided that the following conditions are met: - - + Redistributions of source code of any software must retain the above - copyright notice and all terms of this license as part of the code. - - + Redistributions in binary form of any software must reproduce the - above copyright notice and all terms of this license in any related - documentation and/or other materials. - - + Neither the names nor trademarks of Advanced Micro Devices, Inc. or - any copyright holders or contributors may be used to endorse or - promote products derived from this material without specific prior - written permission. - - + Notice about U.S. Government restricted rights: This material is - provided with "RESTRICTED RIGHTS." Use, duplication or disclosure by - the U.S. Government is subject to the full extent of restrictions set - forth in FAR52.227 and DFARS252.227 et seq., or any successor or - applicable regulations. Use of this material by the U.S. Government - constitutes acknowledgment of the proprietary rights of Advanced Micro - Devices, Inc. - and any copyright holders and contributors. - - + ANY BREACH OF ANY TERM OF THIS LICENSE SHALL RESULT IN THE IMMEDIATE - REVOCATION OF ALL RIGHTS TO REDISTRIBUTE, ACCESS OR USE THIS MATERIAL. - - THIS MATERIAL IS PROVIDED BY ADVANCED MICRO DEVICES, INC. AND ANY - COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" IN ITS CURRENT CONDITION - AND WITHOUT ANY REPRESENTATIONS, GUARANTEE, OR WARRANTY OF ANY KIND OR - IN ANY WAY RELATED TO SUPPORT, INDEMNITY, ERROR FREE OR UNINTERRUPTED - OPERATION, OR THAT IT IS FREE FROM DEFECTS OR VIRUSES. ALL - OBLIGATIONS ARE HEREBY DISCLAIMED - WHETHER EXPRESS, IMPLIED, OR - STATUTORY - INCLUDING, BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF - TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, - COMPLETENESS, OPERABILITY, QUALITY OF SERVICE, OR NON-INFRINGEMENT. IN - NO EVENT SHALL ADVANCED MICRO DEVICES, INC. OR ANY COPYRIGHT HOLDERS - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, PUNITIVE, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - USE, REVENUE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED OR BASED ON ANY THEORY OF LIABILITY ARISING IN ANY WAY RELATED - TO THIS MATERIAL, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - THE ENTIRE AND AGGREGATE LIABILITY OF ADVANCED MICRO DEVICES, INC. AND - ANY COPYRIGHT HOLDERS AND CONTRIBUTORS SHALL NOT EXCEED TEN DOLLARS - (US $10.00). ANYONE REDISTRIBUTING OR ACCESSING OR USING THIS MATERIAL - ACCEPTS THIS ALLOCATION OF RISK AND AGREES TO RELEASE ADVANCED MICRO - DEVICES, INC. AND ANY COPYRIGHT HOLDERS AND CONTRIBUTORS FROM ANY AND - ALL LIABILITIES, OBLIGATIONS, CLAIMS, OR DEMANDS IN EXCESS OF TEN - DOLLARS (US $10.00). THE FOREGOING ARE ESSENTIAL TERMS OF THIS LICENSE - AND, IF ANY OF THESE TERMS ARE CONSTRUED AS UNENFORCEABLE, FAIL IN - ESSENTIAL PURPOSE, OR BECOME VOID OR DETRIMENTAL TO ADVANCED MICRO - DEVICES, INC. OR ANY COPYRIGHT HOLDERS OR CONTRIBUTORS FOR ANY REASON, - THEN ALL RIGHTS TO REDISTRIBUTE, ACCESS OR USE THIS MATERIAL SHALL - TERMINATE IMMEDIATELY. MOREOVER, THE FOREGOING SHALL SURVIVE ANY - EXPIRATION OR TERMINATION OF THIS LICENSE OR ANY AGREEMENT OR ACCESS - OR USE RELATED TO THIS MATERIAL. - - NOTICE IS HEREBY PROVIDED, AND BY REDISTRIBUTING OR ACCESSING OR USING - THIS MATERIAL SUCH NOTICE IS ACKNOWLEDGED, THAT THIS MATERIAL MAY BE - SUBJECT TO RESTRICTIONS UNDER THE LAWS AND REGULATIONS OF THE UNITED - STATES OR OTHER COUNTRIES, WHICH INCLUDE BUT ARE NOT LIMITED TO, U.S. - EXPORT CONTROL LAWS SUCH AS THE EXPORT ADMINISTRATION REGULATIONS AND - NATIONAL SECURITY CONTROLS AS DEFINED THEREUNDER, AS WELL AS STATE - DEPARTMENT CONTROLS UNDER THE U.S. MUNITIONS LIST. THIS MATERIAL MAY - NOT BE USED, RELEASED, TRANSFERRED, IMPORTED, EXPORTED AND/OR RE- - EXPORTED IN ANY MANNER PROHIBITED UNDER ANY APPLICABLE LAWS, INCLUDING - U.S. EXPORT CONTROL LAWS REGARDING SPECIFICALLY DESIGNATED PERSONS, - COUNTRIES AND NATIONALS OF COUNTRIES SUBJECT TO NATIONAL SECURITY - CONTROLS. - MOREOVER, - THE FOREGOING SHALL SURVIVE ANY EXPIRATION OR TERMINATION OF ANY - LICENSE OR AGREEMENT OR ACCESS OR USE RELATED TO THIS MATERIAL. - - This license forms the entire agreement regarding the subject matter - hereof and supersedes all proposals and prior discussions and writings - between the parties with respect thereto. This license does not affect - any ownership, rights, title, or interest in, or relating to, this - material. No terms of this license can be modified or waived, and no - breach of this license can be excused, unless done so in a writing - signed by all affected parties. Each term of this license is - separately enforceable. If any term of this license is determined to - be or becomes unenforceable or illegal, such term shall be reformed to - the minimum extent necessary in order for this license to remain in - effect in accordance with its terms as modified by such reformation. - This license shall be governed by and construed in accordance with the - laws of the State of Texas without regard to rules on conflicts of law - of any state or jurisdiction or the United Nations Convention on the - International Sale of Goods. All disputes arising out of this license - shall be subject to the jurisdiction of the federal and state courts - in Austin, Texas, and all defenses are hereby waived concerning - personal jurisdiction and venue of these courts. - ============================================================ */ - -#include "plpa_config.h" -#include "plpa.h" -#include "plpa_internal.h" - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdio.h> -#include <dirent.h> -#include <limits.h> -#include <errno.h> -#include <stdlib.h> -#include <stdbool.h> - -typedef struct tuple_t_ { - int processor_id, socket_id, core_id, online; -} tuple_t; - -static const char *sysfs_mount = "/sys"; -static int supported = 0; -static int num_processors = -1; -static int max_processor_id = -1; -static int num_sockets = -1; -static int max_socket_id = -1; -static int *max_core_id = NULL; -static int *num_cores = NULL; -static int max_core_id_overall = -1; -static tuple_t *map_processor_id_to_tuple = NULL; -static tuple_t **map_tuple_to_processor_id = NULL; -static PLPA_NAME(cache_behavior_t) cache_behavior = PLPA_NAME_CAPS(CACHE_IGNORE); - -static void clear_cache(void) -{ - if (NULL != max_core_id) { - free(max_core_id); - max_core_id = NULL; - } - if (NULL != num_cores) { - free(num_cores); - num_cores = NULL; - } - if (NULL != map_processor_id_to_tuple) { - free(map_processor_id_to_tuple); - map_processor_id_to_tuple = NULL; - } - if (NULL != map_tuple_to_processor_id) { - free(map_tuple_to_processor_id); - map_tuple_to_processor_id = NULL; - } - - num_processors = max_processor_id = -1; - num_sockets = max_socket_id = -1; - max_core_id_overall = -1; -} - -static void load_cache(void) -{ - int i, j, k, invalid_entry, fd, found_online; - char path[PATH_MAX], buf[8]; - PLPA_NAME(cpu_set_t) valid_processors; - PLPA_NAME(cpu_set_t) *cores_on_sockets; - int found; - DIR *dir; - struct dirent dentry, *dentryp = NULL; - -#if PLPA_DEBUG - char *temp = getenv("PLPA_SYSFS_MOUNT"); - if (temp) { - sysfs_mount = temp; - } -#endif - - /* Check for the parent directory */ - sprintf(path, "%s/devices/system/cpu", sysfs_mount); - if (access(path, R_OK|X_OK)) { - return; - } - - dir = opendir(path); - if (NULL == dir) { - return; - } - - /* Catch all entries of format "cpu%d", count them and maintain - max_processor_id */ - num_processors = 0; - PLPA_CPU_ZERO(&valid_processors); - do { - int ret = readdir_r(dir, &dentry, &dentryp); - if (0 != ret) { - closedir(dir); - clear_cache(); - return; - } - - if (dentryp) { - int cpuid; - - ret = sscanf(dentryp->d_name, "cpu%d", &cpuid); - if (1 == ret) { - ++num_processors; - if (cpuid >= PLPA_BITMASK_CPU_MAX) { - closedir(dir); - clear_cache(); - return; - } else if (cpuid > max_processor_id) { - max_processor_id = cpuid; - } - PLPA_CPU_SET(cpuid, &valid_processors); - } - } - } while (NULL != dentryp); - closedir(dir); - - /* If we found no processors, then we have no topology info */ - if (0 == num_processors) { - clear_cache(); - return; - } - - /* Malloc space for the first map (processor ID -> tuple). - Include enough space for one invalid entry. */ - map_processor_id_to_tuple = malloc(sizeof(tuple_t) * - (max_processor_id + 2)); - if (NULL == map_processor_id_to_tuple) { - clear_cache(); - return; - } - for (i = 0; i <= max_processor_id; ++i) { - if (PLPA_CPU_ISSET(i, &valid_processors)) { - map_processor_id_to_tuple[i].processor_id = i; - } else { - map_processor_id_to_tuple[i].processor_id = -1; - } - map_processor_id_to_tuple[i].socket_id = -1; - map_processor_id_to_tuple[i].core_id = -1; - } - /* Set the invalid entry */ - invalid_entry = i; - map_processor_id_to_tuple[invalid_entry].processor_id = -1; - map_processor_id_to_tuple[invalid_entry].socket_id = -1; - map_processor_id_to_tuple[invalid_entry].core_id = -1; - - /* Build a cached map of (socket,core) tuples */ - for (found = 0, i = 0; i <= max_processor_id; ++i) { - - /* Check for invalid processor ID */ - if (map_processor_id_to_tuple[i].processor_id < 0) { - continue; - } - - /* Read the "online" state for this processor. If the online - file is not there, then the kernel likely doesn't have - hotplug support so just assume that it's online. Some notes: - - - the perms on the "online" file are root/600, so only root - will see this info - - if online is 0, then all the topology files disappear (!) - -- so PLPA needs to compensate for that - */ - found_online = 0; - sprintf(path, "%s/devices/system/cpu/cpu%d/online", - sysfs_mount, i); - fd = open(path, O_RDONLY); - memset(buf, 0, sizeof(buf)); - if (fd >= 0 && read(fd, buf, sizeof(buf) - 1) > 0) { - found_online = 1; - sscanf(buf, "%d", &(map_processor_id_to_tuple[i].online)); - } else { - map_processor_id_to_tuple[i].online = 1; - } - if (fd >= 0) { - close(fd); - } - - /* Core ID */ - sprintf(path, "%s/devices/system/cpu/cpu%d/topology/core_id", - sysfs_mount, i); - fd = open(path, O_RDONLY); - if (fd >= 0) { - memset(buf, 0, sizeof(buf)); - if (read(fd, buf, sizeof(buf) - 1) > 0) { - sscanf(buf, "%d", &(map_processor_id_to_tuple[i].core_id)); - } else { - map_processor_id_to_tuple[i].core_id = -1; - } - close(fd); - } - /* Special case: we didn't find the core_id file, but we *did* - find the online file and the processor is offline -- then - just mark the core ID as "unknown" and keep going (because - if a processor is offline, the core_id file won't exist -- - grumble) */ - else if (found_online && 0 == map_processor_id_to_tuple[i].online) { - map_processor_id_to_tuple[i].core_id = -1; - } - - /* Socket ID */ - sprintf(path, - "%s/devices/system/cpu/cpu%d/topology/physical_package_id", - sysfs_mount, i); - fd = open(path, O_RDONLY); - if (fd >= 0) { - memset(buf, 0, sizeof(buf)); - if (read(fd, buf, sizeof(buf) - 1) > 0) { - sscanf(buf, "%d", &(map_processor_id_to_tuple[i].socket_id)); - } - close(fd); - found = 1; - } - /* Special case: we didn't find the socket_id file, but we - *did* find the online file and the processor is offline -- - then just mark the socket ID as "unknown" and keep going - (because if a processor is offline, the socket_id file won't - exist -- grumble) */ - else if (found_online && 0 == map_processor_id_to_tuple[i].online) { - map_processor_id_to_tuple[i].socket_id = -1; - } - - /* Keep a running tab on the max socket number */ - if (map_processor_id_to_tuple[i].socket_id > max_socket_id) { - max_socket_id = map_processor_id_to_tuple[i].socket_id; - } - } - - /* If we didn't find any core_id/physical_package_id's, then we - don't have the topology info */ - if (!found) { - clear_cache(); - return; - } - - /* Now that we know the max number of sockets, allocate some - arrays */ - max_core_id = malloc(sizeof(int) * (max_socket_id + 1)); - if (NULL == max_core_id) { - clear_cache(); - return; - } - num_cores = malloc(sizeof(int) * (max_socket_id + 1)); - if (NULL == num_cores) { - clear_cache(); - return; - } - for (i = 0; i <= max_socket_id; ++i) { - num_cores[i] = -1; - max_core_id[i] = -1; - } - - /* Find the max core number on each socket */ - for (i = 0; i <= max_processor_id; ++i) { - if (map_processor_id_to_tuple[i].processor_id < 0 || - map_processor_id_to_tuple[i].socket_id < 0) { - continue; - } - if (map_processor_id_to_tuple[i].core_id > - max_core_id[map_processor_id_to_tuple[i].socket_id]) { - max_core_id[map_processor_id_to_tuple[i].socket_id] = - map_processor_id_to_tuple[i].core_id; - } - if (max_core_id[map_processor_id_to_tuple[i].socket_id] > - max_core_id_overall) { - max_core_id_overall = - max_core_id[map_processor_id_to_tuple[i].socket_id]; - } - } - - /* Go through and count the number of unique sockets found. It - may not be the same as max_socket_id because there may be - "holes" -- e.g., sockets 0 and 3 are used, but sockets 1 and 2 - are empty. */ - for (j = i = 0; i <= max_socket_id; ++i) { - if (max_core_id[i] >= 0) { - ++j; - } - } - if (j > 0) { - num_sockets = j; - } - - /* Count how many cores are available on each socket. This may - not be the same as max_core_id[socket_num] if there are - "holes". I don't know if holes can happen (i.e., if specific - cores can be taken offline), but what the heck... */ - cores_on_sockets = malloc(sizeof(PLPA_NAME(cpu_set_t)) * - (max_socket_id + 1)); - if (NULL == cores_on_sockets) { - clear_cache(); - return; - } - for (i = 0; i <= max_socket_id; ++i) { - PLPA_CPU_ZERO(&(cores_on_sockets[i])); - } - for (i = 0; i <= max_processor_id; ++i) { - if (map_processor_id_to_tuple[i].socket_id >= 0) { - PLPA_CPU_SET(map_processor_id_to_tuple[i].core_id, - &(cores_on_sockets[map_processor_id_to_tuple[i].socket_id])); - } - } - for (i = 0; i <= max_socket_id; ++i) { - int count = 0; - for (j = 0; j <= max_core_id[i]; ++j) { - if (PLPA_CPU_ISSET(j, &(cores_on_sockets[i]))) { - ++count; - } - } - if (count > 0) { - num_cores[i] = count; - } - } - free(cores_on_sockets); - - /* Now go through and build the map in the other direction: - (socket,core) => processor_id. This map simply points to - entries in the other map (i.e., it's by reference instead of by - value). */ - map_tuple_to_processor_id = malloc(sizeof(tuple_t *) * - ((max_socket_id + 1) * - (max_core_id_overall + 1))); - if (NULL == map_tuple_to_processor_id) { - clear_cache(); - return; - } - /* Compute map */ - for (i = 0; i <= max_socket_id; ++i) { - for (j = 0; j <= max_core_id_overall; ++j) { - tuple_t **tuple_ptr = &map_tuple_to_processor_id[ - i * (max_core_id_overall + 1) + j]; - - /* Default to the invalid entry in the other map, meaning - that this (socket,core) combination doesn't exist - (e.g., the core number does not exist in this socket, - although it does exist in other sockets). */ - *tuple_ptr = &map_processor_id_to_tuple[invalid_entry]; - - /* See if this (socket,core) tuple exists in the other - map. If so, set this entry to point to it (overriding - the invalid entry default). */ - for (k = 0; k <= max_processor_id; ++k) { - if (map_processor_id_to_tuple[k].socket_id == i && - map_processor_id_to_tuple[k].core_id == j) { - *tuple_ptr = &map_processor_id_to_tuple[k]; - break; - } - } - } - } - - supported = 1; -} - -static int cache_action(void) -{ - switch (cache_behavior) { - case PLPA_NAME_CAPS(CACHE_USE): - if (NULL == map_processor_id_to_tuple) { - load_cache(); - } - break; - - case PLPA_NAME_CAPS(CACHE_IGNORE): - clear_cache(); - load_cache(); - break; - - default: - return EINVAL; - } - - return 0; -} - -/* Return whether this kernel supports topology information or not */ -int PLPA_NAME(have_topology_information)(int *supported_arg) -{ - int ret; - - /* Initialize if not already done so */ - if (!PLPA_NAME(initialized)) { - if (0 != (ret = PLPA_NAME(init)())) { - return ret; - } - } - - /* Check for bozo arguments */ - if (NULL == supported_arg) { - return EINVAL; - } - - *supported_arg = supported; - return 0; -} - -int PLPA_NAME(map_to_processor_id)(int socket_id, int core_id, - int *processor_id) -{ - int ret; - - /* Initialize if not already done so */ - if (!PLPA_NAME(initialized)) { - if (0 != (ret = PLPA_NAME(init)())) { - return ret; - } - } - - /* If this system doesn't support mapping, sorry Charlie */ - if (!supported) { - return ENOSYS; - } - - /* Check for bozo arguments */ - if (NULL == processor_id) { - return EINVAL; - } - - /* Check cache behavior */ - if (0 != (ret = cache_action())) { - return ret; - } - - /* Check for some invalid entries */ - if (socket_id < 0 || socket_id > max_socket_id || - core_id < 0 || core_id > max_core_id[socket_id]) { - return ENOENT; - } - /* If the mapping returns -1, then this is a non-existent - socket/core combo (even though they fall within the max socket - / max core overall values) */ - ret = map_tuple_to_processor_id[socket_id * (max_core_id_overall + 1) + - core_id]->processor_id; - if (-1 == ret) { - return ENOENT; - } - - /* Ok, all should be good -- return the mapping */ - *processor_id = ret; - return 0; -} - -int PLPA_NAME(map_to_socket_core)(int processor_id, - int *socket_id, int *core_id) -{ - int ret; - - /* Initialize if not already done so */ - if (!PLPA_NAME(initialized)) { - if (0 != (ret = PLPA_NAME(init)())) { - return ret; - } - } - - /* If this system doesn't support mapping, sorry Charlie */ - if (!supported) { - return ENOSYS; - } - - /* Check for bozo arguments */ - if (NULL == socket_id || NULL == core_id) { - return EINVAL; - } - - /* Check cache behavior */ - if (0 != (ret = cache_action())) { - return ret; - } - - /* Check for some invalid entries */ - if (processor_id < 0 || processor_id > max_processor_id || - map_processor_id_to_tuple[processor_id].processor_id < 0) { - return ENOENT; - } - ret = map_processor_id_to_tuple[processor_id].socket_id; - if (-1 == ret) { - return ENOENT; - } - - /* Ok, all should be good -- return the mapping */ - *socket_id = ret; - *core_id = map_processor_id_to_tuple[processor_id].core_id; - return 0; -} - -/* Deprecated function */ -int PLPA_NAME(get_processor_info)(int *num_processors_arg, - int *max_processor_id_arg) -{ - return PLPA_NAME(get_processor_data)(PLPA_NAME_CAPS(COUNT_ALL), - num_processors_arg, - max_processor_id_arg); -} - -int PLPA_NAME(get_processor_data)(PLPA_NAME(count_specification_t) count_spec, - int *num_processors_arg, - int *max_processor_id_arg) -{ - int i, ret; - bool match; - - /* Initialize if not already done so */ - if (!PLPA_NAME(initialized)) { - if (0 != (ret = PLPA_NAME(init)())) { - return ret; - } - } - - /* If this system doesn't support mapping, sorry Charlie */ - if (!supported) { - return ENOSYS; - } - - /* Check cache behavior */ - if (0 != (ret = cache_action())) { - return ret; - } - - /* Check for bozo arguments */ - if (NULL == max_processor_id_arg || NULL == num_processors_arg) { - return EINVAL; - } - - /* If we wanted all processors, we're done */ - if (PLPA_NAME_CAPS(COUNT_ALL) == count_spec) { - *num_processors_arg = num_processors; - *max_processor_id_arg = max_processor_id; - } else { - /* Otherwise, count the appropriate type */ - *num_processors_arg = 0; - *max_processor_id_arg = 0; - for (i = 0; i <= max_processor_id; ++i) { - if (map_processor_id_to_tuple[i].processor_id >= 0) { - match = false; - switch (count_spec) { - case PLPA_NAME_CAPS(COUNT_ONLINE): - if (map_processor_id_to_tuple[i].online) { - match = true; - } - break; - - case PLPA_NAME_CAPS(COUNT_OFFLINE): - if (!map_processor_id_to_tuple[i].online) { - match = true; - } - break; - default: - /* Just so that compilers don't complain */ - break; - } - if (match) { - ++(*num_processors_arg); - if (*max_processor_id_arg < - map_processor_id_to_tuple[i].processor_id) { - *max_processor_id_arg = - map_processor_id_to_tuple[i].processor_id; - } - } - } - } - } - return 0; -} - -/* Returns the Linux processor ID for the Nth processor (starting with - 0). */ -int PLPA_NAME(get_processor_id)(int processor_num, - PLPA_NAME(count_specification_t) count_spec, - int *processor_id) -{ - int ret, i, count; - bool match; - - /* Initialize if not already done so */ - if (!PLPA_NAME(initialized)) { - if (0 != (ret = PLPA_NAME(init)())) { - return ret; - } - } - - /* If this system doesn't support mapping, sorry Charlie */ - if (!supported) { - return ENOSYS; - } - - /* Check for bozo arguments */ - if (NULL == processor_id) { - return EINVAL; - } - - /* Check cache behavior */ - if (0 != (ret = cache_action())) { - return ret; - } - - /* Check for out of range params */ - if (processor_num < 0 || processor_num > num_processors) { - return EINVAL; - } - - /* Find the processor_num'th processor */ - for (count = i = 0; i <= max_processor_id; ++i) { - if (map_processor_id_to_tuple[i].processor_id >= 0) { - match = false; - switch (count_spec) { - case PLPA_NAME_CAPS(COUNT_ONLINE): - if (map_processor_id_to_tuple[i].online) { - match = true; - } - break; - - case PLPA_NAME_CAPS(COUNT_OFFLINE): - if (!map_processor_id_to_tuple[i].online) { - match = true; - } - break; - - case PLPA_NAME_CAPS(COUNT_ALL): - match = true; - break; - } - if (match) { - if (count++ == processor_num) { - *processor_id = map_processor_id_to_tuple[i].processor_id; - return 0; - } - } - } - } - - /* Didn't find it */ - return ENODEV; -} - -/* Check to see if a given Linux processor ID exists / is online. - Returns 0 on success. */ -int PLPA_NAME(get_processor_flags)(int processor_id, - int *exists_arg, int *online_arg) -{ - int ret, exists, online; - - /* Initialize if not already done so */ - if (!PLPA_NAME(initialized)) { - if (0 != (ret = PLPA_NAME(init)())) { - return ret; - } - } - - /* If this system doesn't support mapping, sorry Charlie */ - if (!supported) { - return ENOSYS; - } - - /* Check for bozo arguments */ - if (NULL == exists_arg && NULL == online_arg) { - return EINVAL; - } - - /* Check cache behavior */ - if (0 != (ret = cache_action())) { - return ret; - } - - /* Check for out of range params */ - if (processor_id < 0 || processor_id > max_processor_id) { - return EINVAL; - } - - exists = online = 0; - if (processor_id == map_processor_id_to_tuple[processor_id].processor_id) { - exists = 1; - if (map_processor_id_to_tuple[processor_id].online) { - online = 1; - } - } - if (NULL != exists_arg) { - *exists_arg = exists; - } - if (NULL != online_arg) { - *online_arg = online; - } - - return 0; -} - -/* Return the max socket number */ -int PLPA_NAME(get_socket_info)(int *num_sockets_arg, int *max_socket_id_arg) -{ - int ret; - - /* Initialize if not already done so */ - if (!PLPA_NAME(initialized)) { - if (0 != (ret = PLPA_NAME(init)())) { - return ret; - } - } - - /* If this system doesn't support mapping, sorry Charlie */ - if (!supported) { - return ENOSYS; - } - - /* Check cache behavior */ - if (0 != (ret = cache_action())) { - return ret; - } - - /* Check for bozo arguments */ - if (NULL == max_socket_id_arg || NULL == num_sockets_arg) { - return EINVAL; - } - - /* All done */ - *num_sockets_arg = num_sockets; - *max_socket_id_arg = max_socket_id; - return 0; -} - -/* Returns the Linux socket ID for the Nth socket (starting with 0). */ -int PLPA_NAME(get_socket_id)(int socket_num, int *socket_id) -{ - int ret, i, j, k, count; - - /* Initialize if not already done so */ - if (!PLPA_NAME(initialized)) { - if (0 != (ret = PLPA_NAME(init)())) { - return ret; - } - } - - /* If this system doesn't support mapping, sorry Charlie */ - if (!supported) { - return ENOSYS; - } - - /* Check for bozo arguments */ - if (NULL == socket_id) { - return EINVAL; - } - - /* Check cache behavior */ - if (0 != (ret = cache_action())) { - return ret; - } - - /* Check for out of range params */ - if (socket_num < 0 || socket_num > num_sockets) { - return EINVAL; - } - - /* Find the socket_num'th socket */ - for (count = i = 0; i <= max_socket_id; ++i) { - /* See if any core in this socket is active. If so, count - this socket */ - for (j = 0; j <= max_core_id_overall; ++j) { - k = i * (max_core_id_overall + 1) + j; - if (map_tuple_to_processor_id[k]->processor_id >= 0) { - if (count++ == socket_num) { - *socket_id = map_tuple_to_processor_id[k]->socket_id; - return 0; - } - /* Ok, we found one -- skip to the end of this socket */ - j = max_core_id_overall + 1; - } - } - } - - /* Didn't find it */ - return ENODEV; -} - -/* Return the number of cores in a socket and the max core ID number */ -int PLPA_NAME(get_core_info)(int socket_id, int *num_cores_arg, - int *max_core_id_arg) -{ - int ret; - - /* Initialize if not already done so */ - if (!PLPA_NAME(initialized)) { - if (0 != (ret = PLPA_NAME(init)())) { - return ret; - } - } - - /* If this system doesn't support mapping, sorry Charlie */ - if (!supported) { - return ENOSYS; - } - - /* Check for bozo arguments */ - if (NULL == max_core_id_arg || NULL == num_cores_arg) { - return EINVAL; - } - - /* Check cache behavior */ - if (0 != (ret = cache_action())) { - return ret; - } - - /* Check for some invalid entries */ - if (socket_id < 0 || socket_id > max_socket_id || - -1 == max_core_id[socket_id]) { - return ENOENT; - } - ret = num_cores[socket_id]; - if (-1 == ret) { - return ENOENT; - } - - /* All done */ - *num_cores_arg = ret; - *max_core_id_arg = max_core_id[socket_id]; - return 0; -} - -/* Given a specific socket, returns the Linux core ID for the Nth core - (starting with 0) */ -int PLPA_NAME(get_core_id)(int socket_id, int core_num, int *core_id) -{ - int ret, i, j, count; - - /* Initialize if not already done so */ - if (!PLPA_NAME(initialized)) { - if (0 != (ret = PLPA_NAME(init)())) { - return ret; - } - } - - /* If this system doesn't support mapping, sorry Charlie */ - if (!supported) { - return ENOSYS; - } - - /* Check for bozo arguments */ - if (NULL == core_id) { - return EINVAL; - } - - /* Check cache behavior */ - if (0 != (ret = cache_action())) { - return ret; - } - - /* Check for out of range params */ - if (socket_id < 0 || socket_id > max_socket_id || - core_num < 0 || core_num > max_core_id_overall) { - return EINVAL; - } - - /* Find the core_num'th core */ - for (count = i = 0, j = socket_id * (max_core_id_overall + 1); - i <= max_core_id_overall; ++i) { - if (map_tuple_to_processor_id[j + i]->processor_id >= 0) { - if (count++ == core_num) { - *core_id = map_tuple_to_processor_id[j + i]->core_id; - return 0; - } - } - } - - /* Didn't find it */ - return ENODEV; -} - -/* Check to see if a given Linux (socket_id,core_id) tuple exists / is - online. Returns 0 on success. */ -int PLPA_NAME(get_core_flags)(int socket_id, int core_id, - int *exists_arg, int *online_arg) -{ - int ret, i, exists, online; - - /* Initialize if not already done so */ - if (!PLPA_NAME(initialized)) { - if (0 != (ret = PLPA_NAME(init)())) { - return ret; - } - } - - /* If this system doesn't support mapping, sorry Charlie */ - if (!supported) { - return ENOSYS; - } - - /* Check for bozo arguments */ - if (NULL == exists_arg && NULL == online_arg) { - return EINVAL; - } - - /* Check cache behavior */ - if (0 != (ret = cache_action())) { - return ret; - } - - /* Check for out of range params */ - if (socket_id < 0 || socket_id > max_socket_id || - core_id < 0 || core_id > max_core_id_overall) { - return EINVAL; - } - - exists = online = 0; - i = socket_id * (max_core_id_overall + 1) + core_id; - if (map_tuple_to_processor_id[i]->processor_id >= 0) { - exists = 1; - if (map_tuple_to_processor_id[i]->online) { - online = 1; - } - } - - if (NULL != exists_arg) { - *exists_arg = exists; - } - if (NULL != online_arg) { - *online_arg = online; - } - return 0; -} - -/* Set PLPA's caching behavior */ -int PLPA_NAME(set_cache_behavior)(PLPA_NAME(cache_behavior_t) behavior) -{ - switch (behavior) { - case PLPA_NAME_CAPS(CACHE_USE): - if (PLPA_NAME_CAPS(CACHE_USE) != cache_behavior) { - load_cache(); - cache_behavior = PLPA_NAME_CAPS(CACHE_USE); - } - break; - - case PLPA_NAME_CAPS(CACHE_IGNORE): - if (PLPA_NAME_CAPS(CACHE_IGNORE) != cache_behavior) { - clear_cache(); - cache_behavior = PLPA_NAME_CAPS(CACHE_IGNORE); - } - break; - - case PLPA_NAME_CAPS(CACHE_REFRESH): - if (PLPA_NAME_CAPS(CACHE_USE) != cache_behavior) { - return EINVAL; - } - clear_cache(); - load_cache(); - break; - - default: - return EINVAL; - } - - return 0; -} |