github.com/jaypipes/ghw@v0.21.1/pkg/memory/memory_cache.go (about)

     1  //
     2  // Use and distribution licensed under the Apache license version 2.
     3  //
     4  // See the COPYING file in the root project directory for full text.
     5  //
     6  
     7  package memory
     8  
     9  import (
    10  	"encoding/json"
    11  	"fmt"
    12  	"strconv"
    13  	"strings"
    14  
    15  	"github.com/jaypipes/ghw/pkg/unitutil"
    16  )
    17  
    18  // CacheType indicates the type of memory stored in a memory cache.
    19  type CacheType int
    20  
    21  const (
    22  	// CacheTypeUnified indicates the memory cache stores both instructions and
    23  	// data.
    24  	CacheTypeUnified CacheType = iota
    25  	// CacheTypeInstruction indicates the memory cache stores only instructions
    26  	// (executable bytecode).
    27  	CacheTypeInstruction
    28  	// CacheTypeData indicates the memory cache stores only data
    29  	// (non-executable bytecode).
    30  	CacheTypeData
    31  )
    32  
    33  const (
    34  	// DEPRECATED: Please use CacheTypeUnified
    35  	CACHE_TYPE_UNIFIED = CacheTypeUnified
    36  	// DEPRECATED: Please use CacheTypeUnified
    37  	CACHE_TYPE_INSTRUCTION = CacheTypeInstruction
    38  	// DEPRECATED: Please use CacheTypeUnified
    39  	CACHE_TYPE_DATA = CacheTypeData
    40  )
    41  
    42  var (
    43  	memoryCacheTypeString = map[CacheType]string{
    44  		CacheTypeUnified:     "Unified",
    45  		CacheTypeInstruction: "Instruction",
    46  		CacheTypeData:        "Data",
    47  	}
    48  
    49  	// NOTE(fromani): the keys are all lowercase and do not match
    50  	// the keys in the opposite table `memoryCacheTypeString`.
    51  	// This is done because of the choice we made in
    52  	// CacheType:MarshalJSON.
    53  	// We use this table only in UnmarshalJSON, so it should be OK.
    54  	stringMemoryCacheType = map[string]CacheType{
    55  		"unified":     CacheTypeUnified,
    56  		"instruction": CacheTypeInstruction,
    57  		"data":        CacheTypeData,
    58  	}
    59  )
    60  
    61  func (a CacheType) String() string {
    62  	return memoryCacheTypeString[a]
    63  }
    64  
    65  // NOTE(jaypipes): since serialized output is as "official" as we're going to
    66  // get, let's lowercase the string output when serializing, in order to
    67  // "normalize" the expected serialized output
    68  func (a CacheType) MarshalJSON() ([]byte, error) {
    69  	return []byte(strconv.Quote(strings.ToLower(a.String()))), nil
    70  }
    71  
    72  func (a *CacheType) UnmarshalJSON(b []byte) error {
    73  	var s string
    74  	if err := json.Unmarshal(b, &s); err != nil {
    75  		return err
    76  	}
    77  	key := strings.ToLower(s)
    78  	val, ok := stringMemoryCacheType[key]
    79  	if !ok {
    80  		return fmt.Errorf("unknown memory cache type: %q", key)
    81  	}
    82  	*a = val
    83  	return nil
    84  }
    85  
    86  type SortByCacheLevelTypeFirstProcessor []*Cache
    87  
    88  func (a SortByCacheLevelTypeFirstProcessor) Len() int      { return len(a) }
    89  func (a SortByCacheLevelTypeFirstProcessor) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
    90  func (a SortByCacheLevelTypeFirstProcessor) Less(i, j int) bool {
    91  	if a[i].Level < a[j].Level {
    92  		return true
    93  	} else if a[i].Level == a[j].Level {
    94  		if a[i].Type < a[j].Type {
    95  			return true
    96  		} else if a[i].Type == a[j].Type {
    97  			// NOTE(jaypipes): len(LogicalProcessors) is always >0 and is always
    98  			// sorted lowest LP ID to highest LP ID
    99  			return a[i].LogicalProcessors[0] < a[j].LogicalProcessors[0]
   100  		}
   101  	}
   102  	return false
   103  }
   104  
   105  type SortByLogicalProcessorId []uint32
   106  
   107  func (a SortByLogicalProcessorId) Len() int           { return len(a) }
   108  func (a SortByLogicalProcessorId) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
   109  func (a SortByLogicalProcessorId) Less(i, j int) bool { return a[i] < a[j] }
   110  
   111  // Cache contains information about a single memory cache on a physical CPU
   112  // package. Caches have a 1-based numeric level, with lower numbers indicating
   113  // the cache is "closer" to the processing cores and reading memory from the
   114  // cache will be faster relative to caches with higher levels. Note that this
   115  // has nothing to do with RAM or memory modules like DIMMs.
   116  type Cache struct {
   117  	// Level is a 1-based numeric level that indicates the relative closeness
   118  	// of this cache to processing cores on the physical package. Lower numbers
   119  	// are "closer" to the processing cores and therefore have faster access
   120  	// times.
   121  	Level uint8 `json:"level"`
   122  	// Type indicates what type of memory is stored in the cache. Can be
   123  	// instruction (executable bytecodes), data or both.
   124  	Type CacheType `json:"type"`
   125  	// SizeBytes indicates the size of the cache in bytes.
   126  	SizeBytes uint64 `json:"size_bytes"`
   127  	// The set of logical processors (hardware threads) that have access to
   128  	// this cache.
   129  	LogicalProcessors []uint32 `json:"logical_processors"`
   130  }
   131  
   132  func (c *Cache) String() string {
   133  	sizeKb := c.SizeBytes / uint64(unitutil.KB)
   134  	typeStr := ""
   135  	if c.Type == CacheTypeInstruction {
   136  		typeStr = "i"
   137  	} else if c.Type == CacheTypeData {
   138  		typeStr = "d"
   139  	}
   140  	cacheIDStr := fmt.Sprintf("L%d%s", c.Level, typeStr)
   141  	processorMapStr := ""
   142  	if c.LogicalProcessors != nil {
   143  		lpStrings := make([]string, len(c.LogicalProcessors))
   144  		for x, lpid := range c.LogicalProcessors {
   145  			lpStrings[x] = strconv.Itoa(int(lpid))
   146  		}
   147  		processorMapStr = " shared with logical processors: " + strings.Join(lpStrings, ",")
   148  	}
   149  	return fmt.Sprintf(
   150  		"%s cache (%d KB)%s",
   151  		cacheIDStr,
   152  		sizeKb,
   153  		processorMapStr,
   154  	)
   155  }