aboutsummaryrefslogtreecommitdiffstats
path: root/plpa-1.3.2/src/libplpa/plpa_map.c
diff options
context:
space:
mode:
Diffstat (limited to 'plpa-1.3.2/src/libplpa/plpa_map.c')
-rw-r--r--plpa-1.3.2/src/libplpa/plpa_map.c1060
1 files changed, 0 insertions, 1060 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 89e107f..0000000
--- a/plpa-1.3.2/src/libplpa/plpa_map.c
+++ /dev/null
@@ -1,1060 +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];
-#if defined(PLPA_DEBUG) && PLPA_DEBUG
- printf("Creating map [%d]: (socket %d, core %d) -> ID %d\n",
- i * (max_core_id_overall + 1) + j,
- i, j, k);
-#endif
- 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;
-}