1/* Copyright (c) 2007-2009, Stanford University 2* All rights reserved. 3* 4* Redistribution and use in source and binary forms, with or without 5* modification, are permitted provided that the following conditions are met: 6* * Redistributions of source code must retain the above copyright 7* notice, this list of conditions and the following disclaimer. 8* * Redistributions in binary form must reproduce the above copyright 9* notice, this list of conditions and the following disclaimer in the 10* documentation and/or other materials provided with the distribution. 11* * Neither the name of Stanford University nor the names of its 12* contributors may be used to endorse or promote products derived from 13* this software without specific prior written permission. 14* 15* THIS SOFTWARE IS PROVIDED BY STANFORD UNIVERSITY ``AS IS'' AND ANY 16* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18* DISCLAIMED. IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE FOR ANY 19* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25*/ 26 27/* OS specific headers and defines. */ 28#ifdef _LINUX_ 29#define _GNU_SOURCE 30#include <sched.h> 31 32#elif defined (_SOLARIS_) 33#include <sys/procset.h> 34#include <sys/processor.h> 35#include <sys/lgrp_user.h> 36 37#elif defined (BARRELFISH) 38#else 39#error OS not supported 40#endif 41 42#include <stdlib.h> 43#include <sys/types.h> 44#include <assert.h> 45 46#include "processor.h" 47#include "memory.h" 48 49int num_cpus = 2; 50 51/* Query the number of CPUs online. */ 52int proc_get_num_cpus (void) 53{ 54 return num_cpus; 55 56 /* int num_cpus; */ 57 /* char *num_proc_str; */ 58 59 /* num_cpus = sysconf(_SC_NPROCESSORS_ONLN); */ 60 61 /* /\* Check if the user specified a different number of processors. *\/ */ 62 /* if ((num_proc_str = getenv("MAPRED_NPROCESSORS"))) */ 63 /* { */ 64 /* int temp = atoi(num_proc_str); */ 65 /* if (temp < 1 || temp > num_cpus) */ 66 /* num_cpus = 0; */ 67 /* else */ 68 /* num_cpus = temp; */ 69 /* } */ 70 71 /* return num_cpus; */ 72} 73 74#ifdef _LINUX_ 75static cpu_set_t full_cs; 76static cpu_set_t* proc_get_full_set(void) 77{ 78 static int inited = 0; 79 80 if (inited == 0) { 81 int i; 82 int n_cpus; 83 84 CPU_ZERO (&full_cs); 85 n_cpus = sysconf(_SC_NPROCESSORS_ONLN); 86 for (i = 0; i < n_cpus; i++) { 87 CPU_SET(i, &full_cs); 88 } 89 90 inited = 1; 91 } 92 93 return &full_cs; 94} 95#endif 96 97/* Bind the calling thread to run on CPU_ID. 98 Returns 0 if successful, -1 if failed. */ 99int proc_bind_thread (int cpu_id) 100{ 101#ifdef _LINUX_ 102 cpu_set_t cpu_set; 103 104 CPU_ZERO (&cpu_set); 105 CPU_SET (cpu_id, &cpu_set); 106 107 return sched_setaffinity (0, sizeof (cpu_set), &cpu_set); 108#elif defined (_SOLARIS_) 109 return processor_bind (P_LWPID, P_MYID, cpu_id, NULL); 110#elif defined (BARRELFISH) 111 return 0; 112#endif 113} 114 115int proc_unbind_thread () 116{ 117#ifdef _LINUX_ 118 return sched_setaffinity (0, sizeof (cpu_set_t), proc_get_full_set()); 119#elif defined (_SOLARIS_) 120 return processor_bind (P_LWPID, P_MYID, PBIND_NONE, NULL); 121#elif defined (BARRELFISH) 122 return 0; 123#endif 124} 125 126/* Test whether processor CPU_ID is available. */ 127bool proc_is_available (int cpu_id) 128{ 129#ifdef _LINUX_ 130 int ret; 131 cpu_set_t cpu_set; 132 133 ret = sched_getaffinity (0, sizeof (cpu_set), &cpu_set); 134 if (ret < 0) return false; 135 136 return CPU_ISSET (cpu_id, &cpu_set) ? true : false; 137#elif defined (_SOLARIS_) 138 return (p_online (cpu_id, P_STATUS) == P_ONLINE); 139#elif defined (BARRELFISH) 140 return true; 141#endif 142} 143 144int proc_get_cpuid (void) 145{ 146#ifdef _LINUX_ 147 int i, ret; 148 cpu_set_t cpu_set; 149 150 ret = sched_getaffinity (0, sizeof (cpu_set), &cpu_set); 151 if (ret < 0) return -1; 152 153 for (i = 0; i < CPU_SETSIZE; ++i) 154 { 155 if (CPU_ISSET (i, &cpu_set)) break; 156 } 157 return i; 158#elif defined (_SOLARIS_) 159 return getcpuid (); 160#elif defined (BARRELFISH) 161 return disp_get_core_id(); 162#endif 163} 164