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#include <assert.h> 28 29#include "scheduler.h" 30#include "locality.h" 31#include "processor.h" 32 33/* TODO: Detect this automatically. */ 34#ifdef _SOLARIS_ 35#define NUM_CORES_PER_CHIP 8 36#define NUM_STRANDS_PER_CORE 8 37#endif 38 39static int map_fill_strand(sched_policy* sp, int thr); 40static int map_fill_core(sched_policy* sp, int thr); 41static int map_fill_chip(sched_policy* sp, int thr); 42 43struct sched_policy 44{ 45 int num_cpus; 46 int num_chips_per_sys; 47 int (*map)(sched_policy* sp, int thr_idx); 48}; 49 50struct sched_policy policies[SCHED_POLICY_LAST + 1] = { 51 { .map = map_fill_strand }, 52 { .map = map_fill_core }, 53 { .map = map_fill_chip }, 54}; 55 56sched_policy* sched_policy_get(unsigned int policy) 57{ 58 assert (policy <= SCHED_POLICY_LAST); 59 /* XXX make this configurable */ 60 policies[policy].num_cpus = proc_get_num_cpus(); 61 policies[policy].num_chips_per_sys = loc_get_num_lgrps (); 62 return &policies[policy]; 63} 64 65void sched_policy_put(sched_policy* sp) 66{ 67 /* STUB */ 68} 69 70/** 71 * Given a thread index, gives the cpu it should be assigned to. 72 */ 73int sched_thr_to_cpu(sched_policy* sp, int thr) 74{ 75 return sp->map(sp, thr); 76} 77 78static int map_fill_strand(sched_policy* sp, int thr) 79{ 80 int num_cpus = sp->num_cpus; 81 return (thr % num_cpus); 82} 83 84static int map_fill_core(sched_policy* sp, int thr) 85{ 86 int num_cpus = sp->num_cpus; 87 88#ifdef NUM_CORES_PER_CHIP 89 int core, strand; 90 91 thr %= num_cpus; 92 core = thr % (NUM_CORES_PER_CHIP * sp->num_chips_per_sys); 93 strand = (thr / (NUM_CORES_PER_CHIP * sp->num_chips_per_sys)); 94 strand %= NUM_STRANDS_PER_CORE; 95 return (core * NUM_STRANDS_PER_CORE + strand); 96#else 97 return thr % num_cpus; 98#endif 99} 100 101static int map_fill_chip(sched_policy* sp, int thr) 102{ 103 int num_cpus = sp->num_cpus; 104 105#ifdef NUM_CORES_PER_CHIP 106 int chip, core, strand; 107 108 thr %= num_cpus; 109 110 chip = thr % sp->num_chips_per_sys; 111 core = (thr / sp->num_chips_per_sys) % NUM_CORES_PER_CHIP; 112 strand = thr / (NUM_CORES_PER_CHIP * NUM_STRANDS_PER_CORE); 113 strand %= NUM_STRANDS_PER_CORE; 114 115 return (chip * (NUM_CORES_PER_CHIP * NUM_STRANDS_PER_CORE) + 116 core * (NUM_STRANDS_PER_CORE) + 117 strand); 118#else 119 return thr % num_cpus; 120#endif 121} 122