Blame sysdeps/x86/cacheinfo.c

Packit Service 82fcde
/* x86_64 cache info.
Packit Service 82fcde
   Copyright (C) 2003-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#if IS_IN (libc)
Packit Service 82fcde
Packit Service 82fcde
#include <assert.h>
Packit Service 82fcde
#include <stdbool.h>
Packit Service 82fcde
#include <stdlib.h>
Packit Service 82fcde
#include <unistd.h>
Packit Service 82fcde
#include <cpuid.h>
Packit Service 82fcde
#include <init-arch.h>
Packit Service 82fcde
Packit Service 82fcde
static const struct intel_02_cache_info
Packit Service 82fcde
{
Packit Service 82fcde
  unsigned char idx;
Packit Service 82fcde
  unsigned char assoc;
Packit Service 82fcde
  unsigned char linesize;
Packit Service 82fcde
  unsigned char rel_name;
Packit Service 82fcde
  unsigned int size;
Packit Service 82fcde
} intel_02_known [] =
Packit Service 82fcde
  {
Packit Service 82fcde
#define M(sc) ((sc) - _SC_LEVEL1_ICACHE_SIZE)
Packit Service 82fcde
    { 0x06,  4, 32, M(_SC_LEVEL1_ICACHE_SIZE),    8192 },
Packit Service 82fcde
    { 0x08,  4, 32, M(_SC_LEVEL1_ICACHE_SIZE),   16384 },
Packit Service 82fcde
    { 0x09,  4, 32, M(_SC_LEVEL1_ICACHE_SIZE),   32768 },
Packit Service 82fcde
    { 0x0a,  2, 32, M(_SC_LEVEL1_DCACHE_SIZE),    8192 },
Packit Service 82fcde
    { 0x0c,  4, 32, M(_SC_LEVEL1_DCACHE_SIZE),   16384 },
Packit Service 82fcde
    { 0x0d,  4, 64, M(_SC_LEVEL1_DCACHE_SIZE),   16384 },
Packit Service 82fcde
    { 0x0e,  6, 64, M(_SC_LEVEL1_DCACHE_SIZE),   24576 },
Packit Service 82fcde
    { 0x21,  8, 64, M(_SC_LEVEL2_CACHE_SIZE),   262144 },
Packit Service 82fcde
    { 0x22,  4, 64, M(_SC_LEVEL3_CACHE_SIZE),   524288 },
Packit Service 82fcde
    { 0x23,  8, 64, M(_SC_LEVEL3_CACHE_SIZE),  1048576 },
Packit Service 82fcde
    { 0x25,  8, 64, M(_SC_LEVEL3_CACHE_SIZE),  2097152 },
Packit Service 82fcde
    { 0x29,  8, 64, M(_SC_LEVEL3_CACHE_SIZE),  4194304 },
Packit Service 82fcde
    { 0x2c,  8, 64, M(_SC_LEVEL1_DCACHE_SIZE),   32768 },
Packit Service 82fcde
    { 0x30,  8, 64, M(_SC_LEVEL1_ICACHE_SIZE),   32768 },
Packit Service 82fcde
    { 0x39,  4, 64, M(_SC_LEVEL2_CACHE_SIZE),   131072 },
Packit Service 82fcde
    { 0x3a,  6, 64, M(_SC_LEVEL2_CACHE_SIZE),   196608 },
Packit Service 82fcde
    { 0x3b,  2, 64, M(_SC_LEVEL2_CACHE_SIZE),   131072 },
Packit Service 82fcde
    { 0x3c,  4, 64, M(_SC_LEVEL2_CACHE_SIZE),   262144 },
Packit Service 82fcde
    { 0x3d,  6, 64, M(_SC_LEVEL2_CACHE_SIZE),   393216 },
Packit Service 82fcde
    { 0x3e,  4, 64, M(_SC_LEVEL2_CACHE_SIZE),   524288 },
Packit Service 82fcde
    { 0x3f,  2, 64, M(_SC_LEVEL2_CACHE_SIZE),   262144 },
Packit Service 82fcde
    { 0x41,  4, 32, M(_SC_LEVEL2_CACHE_SIZE),   131072 },
Packit Service 82fcde
    { 0x42,  4, 32, M(_SC_LEVEL2_CACHE_SIZE),   262144 },
Packit Service 82fcde
    { 0x43,  4, 32, M(_SC_LEVEL2_CACHE_SIZE),   524288 },
Packit Service 82fcde
    { 0x44,  4, 32, M(_SC_LEVEL2_CACHE_SIZE),  1048576 },
Packit Service 82fcde
    { 0x45,  4, 32, M(_SC_LEVEL2_CACHE_SIZE),  2097152 },
Packit Service 82fcde
    { 0x46,  4, 64, M(_SC_LEVEL3_CACHE_SIZE),  4194304 },
Packit Service 82fcde
    { 0x47,  8, 64, M(_SC_LEVEL3_CACHE_SIZE),  8388608 },
Packit Service 82fcde
    { 0x48, 12, 64, M(_SC_LEVEL2_CACHE_SIZE),  3145728 },
Packit Service 82fcde
    { 0x49, 16, 64, M(_SC_LEVEL2_CACHE_SIZE),  4194304 },
Packit Service 82fcde
    { 0x4a, 12, 64, M(_SC_LEVEL3_CACHE_SIZE),  6291456 },
Packit Service 82fcde
    { 0x4b, 16, 64, M(_SC_LEVEL3_CACHE_SIZE),  8388608 },
Packit Service 82fcde
    { 0x4c, 12, 64, M(_SC_LEVEL3_CACHE_SIZE), 12582912 },
Packit Service 82fcde
    { 0x4d, 16, 64, M(_SC_LEVEL3_CACHE_SIZE), 16777216 },
Packit Service 82fcde
    { 0x4e, 24, 64, M(_SC_LEVEL2_CACHE_SIZE),  6291456 },
Packit Service 82fcde
    { 0x60,  8, 64, M(_SC_LEVEL1_DCACHE_SIZE),   16384 },
Packit Service 82fcde
    { 0x66,  4, 64, M(_SC_LEVEL1_DCACHE_SIZE),    8192 },
Packit Service 82fcde
    { 0x67,  4, 64, M(_SC_LEVEL1_DCACHE_SIZE),   16384 },
Packit Service 82fcde
    { 0x68,  4, 64, M(_SC_LEVEL1_DCACHE_SIZE),   32768 },
Packit Service 82fcde
    { 0x78,  8, 64, M(_SC_LEVEL2_CACHE_SIZE),  1048576 },
Packit Service 82fcde
    { 0x79,  8, 64, M(_SC_LEVEL2_CACHE_SIZE),   131072 },
Packit Service 82fcde
    { 0x7a,  8, 64, M(_SC_LEVEL2_CACHE_SIZE),   262144 },
Packit Service 82fcde
    { 0x7b,  8, 64, M(_SC_LEVEL2_CACHE_SIZE),   524288 },
Packit Service 82fcde
    { 0x7c,  8, 64, M(_SC_LEVEL2_CACHE_SIZE),  1048576 },
Packit Service 82fcde
    { 0x7d,  8, 64, M(_SC_LEVEL2_CACHE_SIZE),  2097152 },
Packit Service 82fcde
    { 0x7f,  2, 64, M(_SC_LEVEL2_CACHE_SIZE),   524288 },
Packit Service 82fcde
    { 0x80,  8, 64, M(_SC_LEVEL2_CACHE_SIZE),   524288 },
Packit Service 82fcde
    { 0x82,  8, 32, M(_SC_LEVEL2_CACHE_SIZE),   262144 },
Packit Service 82fcde
    { 0x83,  8, 32, M(_SC_LEVEL2_CACHE_SIZE),   524288 },
Packit Service 82fcde
    { 0x84,  8, 32, M(_SC_LEVEL2_CACHE_SIZE),  1048576 },
Packit Service 82fcde
    { 0x85,  8, 32, M(_SC_LEVEL2_CACHE_SIZE),  2097152 },
Packit Service 82fcde
    { 0x86,  4, 64, M(_SC_LEVEL2_CACHE_SIZE),   524288 },
Packit Service 82fcde
    { 0x87,  8, 64, M(_SC_LEVEL2_CACHE_SIZE),  1048576 },
Packit Service 82fcde
    { 0xd0,  4, 64, M(_SC_LEVEL3_CACHE_SIZE),   524288 },
Packit Service 82fcde
    { 0xd1,  4, 64, M(_SC_LEVEL3_CACHE_SIZE),  1048576 },
Packit Service 82fcde
    { 0xd2,  4, 64, M(_SC_LEVEL3_CACHE_SIZE),  2097152 },
Packit Service 82fcde
    { 0xd6,  8, 64, M(_SC_LEVEL3_CACHE_SIZE),  1048576 },
Packit Service 82fcde
    { 0xd7,  8, 64, M(_SC_LEVEL3_CACHE_SIZE),  2097152 },
Packit Service 82fcde
    { 0xd8,  8, 64, M(_SC_LEVEL3_CACHE_SIZE),  4194304 },
Packit Service 82fcde
    { 0xdc, 12, 64, M(_SC_LEVEL3_CACHE_SIZE),  2097152 },
Packit Service 82fcde
    { 0xdd, 12, 64, M(_SC_LEVEL3_CACHE_SIZE),  4194304 },
Packit Service 82fcde
    { 0xde, 12, 64, M(_SC_LEVEL3_CACHE_SIZE),  8388608 },
Packit Service 82fcde
    { 0xe2, 16, 64, M(_SC_LEVEL3_CACHE_SIZE),  2097152 },
Packit Service 82fcde
    { 0xe3, 16, 64, M(_SC_LEVEL3_CACHE_SIZE),  4194304 },
Packit Service 82fcde
    { 0xe4, 16, 64, M(_SC_LEVEL3_CACHE_SIZE),  8388608 },
Packit Service 82fcde
    { 0xea, 24, 64, M(_SC_LEVEL3_CACHE_SIZE), 12582912 },
Packit Service 82fcde
    { 0xeb, 24, 64, M(_SC_LEVEL3_CACHE_SIZE), 18874368 },
Packit Service 82fcde
    { 0xec, 24, 64, M(_SC_LEVEL3_CACHE_SIZE), 25165824 },
Packit Service 82fcde
  };
Packit Service 82fcde
Packit Service 82fcde
#define nintel_02_known (sizeof (intel_02_known) / sizeof (intel_02_known [0]))
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
intel_02_known_compare (const void *p1, const void *p2)
Packit Service 82fcde
{
Packit Service 82fcde
  const struct intel_02_cache_info *i1;
Packit Service 82fcde
  const struct intel_02_cache_info *i2;
Packit Service 82fcde
Packit Service 82fcde
  i1 = (const struct intel_02_cache_info *) p1;
Packit Service 82fcde
  i2 = (const struct intel_02_cache_info *) p2;
Packit Service 82fcde
Packit Service 82fcde
  if (i1->idx == i2->idx)
Packit Service 82fcde
    return 0;
Packit Service 82fcde
Packit Service 82fcde
  return i1->idx < i2->idx ? -1 : 1;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
static long int
Packit Service 82fcde
__attribute__ ((noinline))
Packit Service 82fcde
intel_check_word (int name, unsigned int value, bool *has_level_2,
Packit Service 82fcde
		  bool *no_level_2_or_3,
Packit Service 82fcde
		  const struct cpu_features *cpu_features)
Packit Service 82fcde
{
Packit Service 82fcde
  if ((value & 0x80000000) != 0)
Packit Service 82fcde
    /* The register value is reserved.  */
Packit Service 82fcde
    return 0;
Packit Service 82fcde
Packit Service 82fcde
  /* Fold the name.  The _SC_ constants are always in the order SIZE,
Packit Service 82fcde
     ASSOC, LINESIZE.  */
Packit Service 82fcde
  int folded_rel_name = (M(name) / 3) * 3;
Packit Service 82fcde
Packit Service 82fcde
  while (value != 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      unsigned int byte = value & 0xff;
Packit Service 82fcde
Packit Service 82fcde
      if (byte == 0x40)
Packit Service 82fcde
	{
Packit Service 82fcde
	  *no_level_2_or_3 = true;
Packit Service 82fcde
Packit Service 82fcde
	  if (folded_rel_name == M(_SC_LEVEL3_CACHE_SIZE))
Packit Service 82fcde
	    /* No need to look further.  */
Packit Service 82fcde
	    break;
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (byte == 0xff)
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* CPUID leaf 0x4 contains all the information.  We need to
Packit Service 82fcde
	     iterate over it.  */
Packit Service 82fcde
	  unsigned int eax;
Packit Service 82fcde
	  unsigned int ebx;
Packit Service 82fcde
	  unsigned int ecx;
Packit Service 82fcde
	  unsigned int edx;
Packit Service 82fcde
Packit Service 82fcde
	  unsigned int round = 0;
Packit Service 82fcde
	  while (1)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      __cpuid_count (4, round, eax, ebx, ecx, edx);
Packit Service 82fcde
Packit Service 82fcde
	      enum { null = 0, data = 1, inst = 2, uni = 3 } type = eax & 0x1f;
Packit Service 82fcde
	      if (type == null)
Packit Service 82fcde
		/* That was the end.  */
Packit Service 82fcde
		break;
Packit Service 82fcde
Packit Service 82fcde
	      unsigned int level = (eax >> 5) & 0x7;
Packit Service 82fcde
Packit Service 82fcde
	      if ((level == 1 && type == data
Packit Service 82fcde
		   && folded_rel_name == M(_SC_LEVEL1_DCACHE_SIZE))
Packit Service 82fcde
		  || (level == 1 && type == inst
Packit Service 82fcde
		      && folded_rel_name == M(_SC_LEVEL1_ICACHE_SIZE))
Packit Service 82fcde
		  || (level == 2 && folded_rel_name == M(_SC_LEVEL2_CACHE_SIZE))
Packit Service 82fcde
		  || (level == 3 && folded_rel_name == M(_SC_LEVEL3_CACHE_SIZE))
Packit Service 82fcde
		  || (level == 4 && folded_rel_name == M(_SC_LEVEL4_CACHE_SIZE)))
Packit Service 82fcde
		{
Packit Service 82fcde
		  unsigned int offset = M(name) - folded_rel_name;
Packit Service 82fcde
Packit Service 82fcde
		  if (offset == 0)
Packit Service 82fcde
		    /* Cache size.  */
Packit Service 82fcde
		    return (((ebx >> 22) + 1)
Packit Service 82fcde
			    * (((ebx >> 12) & 0x3ff) + 1)
Packit Service 82fcde
			    * ((ebx & 0xfff) + 1)
Packit Service 82fcde
			    * (ecx + 1));
Packit Service 82fcde
		  if (offset == 1)
Packit Service 82fcde
		    return (ebx >> 22) + 1;
Packit Service 82fcde
Packit Service 82fcde
		  assert (offset == 2);
Packit Service 82fcde
		  return (ebx & 0xfff) + 1;
Packit Service 82fcde
		}
Packit Service 82fcde
Packit Service 82fcde
	      ++round;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  /* There is no other cache information anywhere else.  */
Packit Service 82fcde
	  break;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (byte == 0x49 && folded_rel_name == M(_SC_LEVEL3_CACHE_SIZE))
Packit Service 82fcde
	    {
Packit Service 82fcde
	      /* Intel reused this value.  For family 15, model 6 it
Packit Service 82fcde
		 specifies the 3rd level cache.  Otherwise the 2nd
Packit Service 82fcde
		 level cache.  */
Packit Service 82fcde
	      unsigned int family = cpu_features->family;
Packit Service 82fcde
	      unsigned int model = cpu_features->model;
Packit Service 82fcde
Packit Service 82fcde
	      if (family == 15 && model == 6)
Packit Service 82fcde
		{
Packit Service 82fcde
		  /* The level 3 cache is encoded for this model like
Packit Service 82fcde
		     the level 2 cache is for other models.  Pretend
Packit Service 82fcde
		     the caller asked for the level 2 cache.  */
Packit Service 82fcde
		  name = (_SC_LEVEL2_CACHE_SIZE
Packit Service 82fcde
			  + (name - _SC_LEVEL3_CACHE_SIZE));
Packit Service 82fcde
		  folded_rel_name = M(_SC_LEVEL2_CACHE_SIZE);
Packit Service 82fcde
		}
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  struct intel_02_cache_info *found;
Packit Service 82fcde
	  struct intel_02_cache_info search;
Packit Service 82fcde
Packit Service 82fcde
	  search.idx = byte;
Packit Service 82fcde
	  found = bsearch (&search, intel_02_known, nintel_02_known,
Packit Service 82fcde
			   sizeof (intel_02_known[0]), intel_02_known_compare);
Packit Service 82fcde
	  if (found != NULL)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      if (found->rel_name == folded_rel_name)
Packit Service 82fcde
		{
Packit Service 82fcde
		  unsigned int offset = M(name) - folded_rel_name;
Packit Service 82fcde
Packit Service 82fcde
		  if (offset == 0)
Packit Service 82fcde
		    /* Cache size.  */
Packit Service 82fcde
		    return found->size;
Packit Service 82fcde
		  if (offset == 1)
Packit Service 82fcde
		    return found->assoc;
Packit Service 82fcde
Packit Service 82fcde
		  assert (offset == 2);
Packit Service 82fcde
		  return found->linesize;
Packit Service 82fcde
		}
Packit Service 82fcde
Packit Service 82fcde
	      if (found->rel_name == M(_SC_LEVEL2_CACHE_SIZE))
Packit Service 82fcde
		*has_level_2 = true;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* Next byte for the next round.  */
Packit Service 82fcde
      value >>= 8;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* Nothing found.  */
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
static long int __attribute__ ((noinline))
Packit Service 82fcde
handle_intel (int name, const struct cpu_features *cpu_features)
Packit Service 82fcde
{
Packit Service 82fcde
  unsigned int maxidx = cpu_features->max_cpuid;
Packit Service 82fcde
Packit Service 82fcde
  /* Return -1 for older CPUs.  */
Packit Service 82fcde
  if (maxidx < 2)
Packit Service 82fcde
    return -1;
Packit Service 82fcde
Packit Service 82fcde
  /* OK, we can use the CPUID instruction to get all info about the
Packit Service 82fcde
     caches.  */
Packit Service 82fcde
  unsigned int cnt = 0;
Packit Service 82fcde
  unsigned int max = 1;
Packit Service 82fcde
  long int result = 0;
Packit Service 82fcde
  bool no_level_2_or_3 = false;
Packit Service 82fcde
  bool has_level_2 = false;
Packit Service 82fcde
Packit Service 82fcde
  while (cnt++ < max)
Packit Service 82fcde
    {
Packit Service 82fcde
      unsigned int eax;
Packit Service 82fcde
      unsigned int ebx;
Packit Service 82fcde
      unsigned int ecx;
Packit Service 82fcde
      unsigned int edx;
Packit Service 82fcde
      __cpuid (2, eax, ebx, ecx, edx);
Packit Service 82fcde
Packit Service 82fcde
      /* The low byte of EAX in the first round contain the number of
Packit Service 82fcde
	 rounds we have to make.  At least one, the one we are already
Packit Service 82fcde
	 doing.  */
Packit Service 82fcde
      if (cnt == 1)
Packit Service 82fcde
	{
Packit Service 82fcde
	  max = eax & 0xff;
Packit Service 82fcde
	  eax &= 0xffffff00;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* Process the individual registers' value.  */
Packit Service 82fcde
      result = intel_check_word (name, eax, &has_level_2,
Packit Service 82fcde
				 &no_level_2_or_3, cpu_features);
Packit Service 82fcde
      if (result != 0)
Packit Service 82fcde
	return result;
Packit Service 82fcde
Packit Service 82fcde
      result = intel_check_word (name, ebx, &has_level_2,
Packit Service 82fcde
				 &no_level_2_or_3, cpu_features);
Packit Service 82fcde
      if (result != 0)
Packit Service 82fcde
	return result;
Packit Service 82fcde
Packit Service 82fcde
      result = intel_check_word (name, ecx, &has_level_2,
Packit Service 82fcde
				 &no_level_2_or_3, cpu_features);
Packit Service 82fcde
      if (result != 0)
Packit Service 82fcde
	return result;
Packit Service 82fcde
Packit Service 82fcde
      result = intel_check_word (name, edx, &has_level_2,
Packit Service 82fcde
				 &no_level_2_or_3, cpu_features);
Packit Service 82fcde
      if (result != 0)
Packit Service 82fcde
	return result;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (name >= _SC_LEVEL2_CACHE_SIZE && name <= _SC_LEVEL3_CACHE_LINESIZE
Packit Service 82fcde
      && no_level_2_or_3)
Packit Service 82fcde
    return -1;
Packit Service 82fcde
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
static long int __attribute__ ((noinline))
Packit Service 82fcde
handle_amd (int name)
Packit Service 82fcde
{
Packit Service 82fcde
  unsigned int eax;
Packit Service 82fcde
  unsigned int ebx;
Packit Service 82fcde
  unsigned int ecx;
Packit Service 82fcde
  unsigned int edx;
Packit Service 82fcde
  __cpuid (0x80000000, eax, ebx, ecx, edx);
Packit Service 82fcde
Packit Service 82fcde
  /* No level 4 cache (yet).  */
Packit Service 82fcde
  if (name > _SC_LEVEL3_CACHE_LINESIZE)
Packit Service 82fcde
    return 0;
Packit Service 82fcde
Packit Service 82fcde
  unsigned int fn = 0x80000005 + (name >= _SC_LEVEL2_CACHE_SIZE);
Packit Service 82fcde
  if (eax < fn)
Packit Service 82fcde
    return 0;
Packit Service 82fcde
Packit Service 82fcde
  __cpuid (fn, eax, ebx, ecx, edx);
Packit Service 82fcde
Packit Service 82fcde
  if (name < _SC_LEVEL1_DCACHE_SIZE)
Packit Service 82fcde
    {
Packit Service 82fcde
      name += _SC_LEVEL1_DCACHE_SIZE - _SC_LEVEL1_ICACHE_SIZE;
Packit Service 82fcde
      ecx = edx;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  switch (name)
Packit Service 82fcde
    {
Packit Service 82fcde
    case _SC_LEVEL1_DCACHE_SIZE:
Packit Service 82fcde
      return (ecx >> 14) & 0x3fc00;
Packit Service 82fcde
Packit Service 82fcde
    case _SC_LEVEL1_DCACHE_ASSOC:
Packit Service 82fcde
      ecx >>= 16;
Packit Service 82fcde
      if ((ecx & 0xff) == 0xff)
Packit Service 82fcde
	/* Fully associative.  */
Packit Service 82fcde
	return (ecx << 2) & 0x3fc00;
Packit Service 82fcde
      return ecx & 0xff;
Packit Service 82fcde
Packit Service 82fcde
    case _SC_LEVEL1_DCACHE_LINESIZE:
Packit Service 82fcde
      return ecx & 0xff;
Packit Service 82fcde
Packit Service 82fcde
    case _SC_LEVEL2_CACHE_SIZE:
Packit Service 82fcde
      return (ecx & 0xf000) == 0 ? 0 : (ecx >> 6) & 0x3fffc00;
Packit Service 82fcde
Packit Service 82fcde
    case _SC_LEVEL2_CACHE_ASSOC:
Packit Service 82fcde
      switch ((ecx >> 12) & 0xf)
Packit Service 82fcde
	{
Packit Service 82fcde
	case 0:
Packit Service 82fcde
	case 1:
Packit Service 82fcde
	case 2:
Packit Service 82fcde
	case 4:
Packit Service 82fcde
	  return (ecx >> 12) & 0xf;
Packit Service 82fcde
	case 6:
Packit Service 82fcde
	  return 8;
Packit Service 82fcde
	case 8:
Packit Service 82fcde
	  return 16;
Packit Service 82fcde
	case 10:
Packit Service 82fcde
	  return 32;
Packit Service 82fcde
	case 11:
Packit Service 82fcde
	  return 48;
Packit Service 82fcde
	case 12:
Packit Service 82fcde
	  return 64;
Packit Service 82fcde
	case 13:
Packit Service 82fcde
	  return 96;
Packit Service 82fcde
	case 14:
Packit Service 82fcde
	  return 128;
Packit Service 82fcde
	case 15:
Packit Service 82fcde
	  return ((ecx >> 6) & 0x3fffc00) / (ecx & 0xff);
Packit Service 82fcde
	default:
Packit Service 82fcde
	  return 0;
Packit Service 82fcde
	}
Packit Service 82fcde
      /* NOTREACHED */
Packit Service 82fcde
Packit Service 82fcde
    case _SC_LEVEL2_CACHE_LINESIZE:
Packit Service 82fcde
      return (ecx & 0xf000) == 0 ? 0 : ecx & 0xff;
Packit Service 82fcde
Packit Service 82fcde
    case _SC_LEVEL3_CACHE_SIZE:
Packit Service 82fcde
      return (edx & 0xf000) == 0 ? 0 : (edx & 0x3ffc0000) << 1;
Packit Service 82fcde
Packit Service 82fcde
    case _SC_LEVEL3_CACHE_ASSOC:
Packit Service 82fcde
      switch ((edx >> 12) & 0xf)
Packit Service 82fcde
	{
Packit Service 82fcde
	case 0:
Packit Service 82fcde
	case 1:
Packit Service 82fcde
	case 2:
Packit Service 82fcde
	case 4:
Packit Service 82fcde
	  return (edx >> 12) & 0xf;
Packit Service 82fcde
	case 6:
Packit Service 82fcde
	  return 8;
Packit Service 82fcde
	case 8:
Packit Service 82fcde
	  return 16;
Packit Service 82fcde
	case 10:
Packit Service 82fcde
	  return 32;
Packit Service 82fcde
	case 11:
Packit Service 82fcde
	  return 48;
Packit Service 82fcde
	case 12:
Packit Service 82fcde
	  return 64;
Packit Service 82fcde
	case 13:
Packit Service 82fcde
	  return 96;
Packit Service 82fcde
	case 14:
Packit Service 82fcde
	  return 128;
Packit Service 82fcde
	case 15:
Packit Service 82fcde
	  return ((edx & 0x3ffc0000) << 1) / (edx & 0xff);
Packit Service 82fcde
	default:
Packit Service 82fcde
	  return 0;
Packit Service 82fcde
	}
Packit Service 82fcde
      /* NOTREACHED */
Packit Service 82fcde
Packit Service 82fcde
    case _SC_LEVEL3_CACHE_LINESIZE:
Packit Service 82fcde
      return (edx & 0xf000) == 0 ? 0 : edx & 0xff;
Packit Service 82fcde
Packit Service 82fcde
    default:
Packit Service 82fcde
      assert (! "cannot happen");
Packit Service 82fcde
    }
Packit Service 82fcde
  return -1;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Get the value of the system variable NAME.  */
Packit Service 82fcde
long int
Packit Service 82fcde
attribute_hidden
Packit Service 82fcde
__cache_sysconf (int name)
Packit Service 82fcde
{
Packit Service 82fcde
  const struct cpu_features *cpu_features = __get_cpu_features ();
Packit Service 82fcde
Packit Service 82fcde
  if (cpu_features->kind == arch_kind_intel)
Packit Service 82fcde
    return handle_intel (name, cpu_features);
Packit Service 82fcde
Packit Service 82fcde
  if (cpu_features->kind == arch_kind_amd)
Packit Service 82fcde
    return handle_amd (name);
Packit Service 82fcde
Packit Service 82fcde
  // XXX Fill in more vendors.
Packit Service 82fcde
Packit Service 82fcde
  /* CPU not known, we have no information.  */
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Data cache size for use in memory and string routines, typically
Packit Service 82fcde
   L1 size, rounded to multiple of 256 bytes.  */
Packit Service 82fcde
long int __x86_data_cache_size_half attribute_hidden = 32 * 1024 / 2;
Packit Service 82fcde
long int __x86_data_cache_size attribute_hidden = 32 * 1024;
Packit Service 82fcde
/* Similar to __x86_data_cache_size_half, but not rounded.  */
Packit Service 82fcde
long int __x86_raw_data_cache_size_half attribute_hidden = 32 * 1024 / 2;
Packit Service 82fcde
/* Similar to __x86_data_cache_size, but not rounded.  */
Packit Service 82fcde
long int __x86_raw_data_cache_size attribute_hidden = 32 * 1024;
Packit Service 82fcde
/* Shared cache size for use in memory and string routines, typically
Packit Service 82fcde
   L2 or L3 size, rounded to multiple of 256 bytes.  */
Packit Service 82fcde
long int __x86_shared_cache_size_half attribute_hidden = 1024 * 1024 / 2;
Packit Service 82fcde
long int __x86_shared_cache_size attribute_hidden = 1024 * 1024;
Packit Service 82fcde
/* Similar to __x86_shared_cache_size_half, but not rounded.  */
Packit Service 82fcde
long int __x86_raw_shared_cache_size_half attribute_hidden = 1024 * 1024 / 2;
Packit Service 82fcde
/* Similar to __x86_shared_cache_size, but not rounded.  */
Packit Service 82fcde
long int __x86_raw_shared_cache_size attribute_hidden = 1024 * 1024;
Packit Service 82fcde
Packit Service 82fcde
/* Threshold to use non temporal store.  */
Packit Service 82fcde
long int __x86_shared_non_temporal_threshold attribute_hidden;
Packit Service 82fcde
Packit Service 82fcde
#ifndef DISABLE_PREFETCHW
Packit Service 82fcde
/* PREFETCHW support flag for use in memory and string routines.  */
Packit Service 82fcde
int __x86_prefetchw attribute_hidden;
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
__attribute__((constructor))
Packit Service 82fcde
init_cacheinfo (void)
Packit Service 82fcde
{
Packit Service 82fcde
  /* Find out what brand of processor.  */
Packit Service 82fcde
  unsigned int eax;
Packit Service 82fcde
  unsigned int ebx;
Packit Service 82fcde
  unsigned int ecx;
Packit Service 82fcde
  unsigned int edx;
Packit Service 82fcde
  int max_cpuid_ex;
Packit Service 82fcde
  long int data = -1;
Packit Service 82fcde
  long int shared = -1;
Packit Service 82fcde
  unsigned int level;
Packit Service 82fcde
  unsigned int threads = 0;
Packit Service 82fcde
  const struct cpu_features *cpu_features = __get_cpu_features ();
Packit Service 82fcde
  int max_cpuid = cpu_features->max_cpuid;
Packit Service 82fcde
Packit Service 82fcde
  if (cpu_features->kind == arch_kind_intel)
Packit Service 82fcde
    {
Packit Service 82fcde
      data = handle_intel (_SC_LEVEL1_DCACHE_SIZE, cpu_features);
Packit Service 82fcde
Packit Service 82fcde
      long int core = handle_intel (_SC_LEVEL2_CACHE_SIZE, cpu_features);
Packit Service 82fcde
      bool inclusive_cache = true;
Packit Service 82fcde
Packit Service 82fcde
      /* Try L3 first.  */
Packit Service 82fcde
      level  = 3;
Packit Service 82fcde
      shared = handle_intel (_SC_LEVEL3_CACHE_SIZE, cpu_features);
Packit Service 82fcde
Packit Service 82fcde
      /* Number of logical processors sharing L2 cache.  */
Packit Service 82fcde
      int threads_l2;
Packit Service 82fcde
Packit Service 82fcde
      /* Number of logical processors sharing L3 cache.  */
Packit Service 82fcde
      int threads_l3;
Packit Service 82fcde
Packit Service 82fcde
      if (shared <= 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* Try L2 otherwise.  */
Packit Service 82fcde
	  level  = 2;
Packit Service 82fcde
	  shared = core;
Packit Service 82fcde
	  threads_l2 = 0;
Packit Service 82fcde
	  threads_l3 = -1;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  threads_l2 = 0;
Packit Service 82fcde
	  threads_l3 = 0;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* A value of 0 for the HTT bit indicates there is only a single
Packit Service 82fcde
	 logical processor.  */
Packit Service 82fcde
      if (HAS_CPU_FEATURE (HTT))
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* Figure out the number of logical threads that share the
Packit Service 82fcde
	     highest cache level.  */
Packit Service 82fcde
	  if (max_cpuid >= 4)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      unsigned int family = cpu_features->family;
Packit Service 82fcde
	      unsigned int model = cpu_features->model;
Packit Service 82fcde
Packit Service 82fcde
	      int i = 0;
Packit Service 82fcde
Packit Service 82fcde
	      /* Query until cache level 2 and 3 are enumerated.  */
Packit Service 82fcde
	      int check = 0x1 | (threads_l3 == 0) << 1;
Packit Service 82fcde
	      do
Packit Service 82fcde
		{
Packit Service 82fcde
		  __cpuid_count (4, i++, eax, ebx, ecx, edx);
Packit Service 82fcde
Packit Service 82fcde
		  /* There seems to be a bug in at least some Pentium Ds
Packit Service 82fcde
		     which sometimes fail to iterate all cache parameters.
Packit Service 82fcde
		     Do not loop indefinitely here, stop in this case and
Packit Service 82fcde
		     assume there is no such information.  */
Packit Service 82fcde
		  if ((eax & 0x1f) == 0)
Packit Service 82fcde
		    goto intel_bug_no_cache_info;
Packit Service 82fcde
Packit Service 82fcde
		  switch ((eax >> 5) & 0x7)
Packit Service 82fcde
		    {
Packit Service 82fcde
		    default:
Packit Service 82fcde
		      break;
Packit Service 82fcde
		    case 2:
Packit Service 82fcde
		      if ((check & 0x1))
Packit Service 82fcde
			{
Packit Service 82fcde
			  /* Get maximum number of logical processors
Packit Service 82fcde
			     sharing L2 cache.  */
Packit Service 82fcde
			  threads_l2 = (eax >> 14) & 0x3ff;
Packit Service 82fcde
			  check &= ~0x1;
Packit Service 82fcde
			}
Packit Service 82fcde
		      break;
Packit Service 82fcde
		    case 3:
Packit Service 82fcde
		      if ((check & (0x1 << 1)))
Packit Service 82fcde
			{
Packit Service 82fcde
			  /* Get maximum number of logical processors
Packit Service 82fcde
			     sharing L3 cache.  */
Packit Service 82fcde
			  threads_l3 = (eax >> 14) & 0x3ff;
Packit Service 82fcde
Packit Service 82fcde
			  /* Check if L2 and L3 caches are inclusive.  */
Packit Service 82fcde
			  inclusive_cache = (edx & 0x2) != 0;
Packit Service 82fcde
			  check &= ~(0x1 << 1);
Packit Service 82fcde
			}
Packit Service 82fcde
		      break;
Packit Service 82fcde
		    }
Packit Service 82fcde
		}
Packit Service 82fcde
	      while (check);
Packit Service 82fcde
Packit Service 82fcde
	      /* If max_cpuid >= 11, THREADS_L2/THREADS_L3 are the maximum
Packit Service 82fcde
		 numbers of addressable IDs for logical processors sharing
Packit Service 82fcde
		 the cache, instead of the maximum number of threads
Packit Service 82fcde
		 sharing the cache.  */
Packit Service 82fcde
	      if (max_cpuid >= 11)
Packit Service 82fcde
		{
Packit Service 82fcde
		  /* Find the number of logical processors shipped in
Packit Service 82fcde
		     one core and apply count mask.  */
Packit Service 82fcde
		  i = 0;
Packit Service 82fcde
Packit Service 82fcde
		  /* Count SMT only if there is L3 cache.  Always count
Packit Service 82fcde
		     core if there is no L3 cache.  */
Packit Service 82fcde
		  int count = ((threads_l2 > 0 && level == 3)
Packit Service 82fcde
			       | ((threads_l3 > 0
Packit Service 82fcde
				   || (threads_l2 > 0 && level == 2)) << 1));
Packit Service 82fcde
Packit Service 82fcde
		  while (count)
Packit Service 82fcde
		    {
Packit Service 82fcde
		      __cpuid_count (11, i++, eax, ebx, ecx, edx);
Packit Service 82fcde
Packit Service 82fcde
		      int shipped = ebx & 0xff;
Packit Service 82fcde
		      int type = ecx & 0xff00;
Packit Service 82fcde
		      if (shipped == 0 || type == 0)
Packit Service 82fcde
			break;
Packit Service 82fcde
		      else if (type == 0x100)
Packit Service 82fcde
			{
Packit Service 82fcde
			  /* Count SMT.  */
Packit Service 82fcde
			  if ((count & 0x1))
Packit Service 82fcde
			    {
Packit Service 82fcde
			      int count_mask;
Packit Service 82fcde
Packit Service 82fcde
			      /* Compute count mask.  */
Packit Service 82fcde
			      asm ("bsr %1, %0"
Packit Service 82fcde
				   : "=r" (count_mask) : "g" (threads_l2));
Packit Service 82fcde
			      count_mask = ~(-1 << (count_mask + 1));
Packit Service 82fcde
			      threads_l2 = (shipped - 1) & count_mask;
Packit Service 82fcde
			      count &= ~0x1;
Packit Service 82fcde
			    }
Packit Service 82fcde
			}
Packit Service 82fcde
		      else if (type == 0x200)
Packit Service 82fcde
			{
Packit Service 82fcde
			  /* Count core.  */
Packit Service 82fcde
			  if ((count & (0x1 << 1)))
Packit Service 82fcde
			    {
Packit Service 82fcde
			      int count_mask;
Packit Service 82fcde
			      int threads_core
Packit Service 82fcde
				= (level == 2 ? threads_l2 : threads_l3);
Packit Service 82fcde
Packit Service 82fcde
			      /* Compute count mask.  */
Packit Service 82fcde
			      asm ("bsr %1, %0"
Packit Service 82fcde
				   : "=r" (count_mask) : "g" (threads_core));
Packit Service 82fcde
			      count_mask = ~(-1 << (count_mask + 1));
Packit Service 82fcde
			      threads_core = (shipped - 1) & count_mask;
Packit Service 82fcde
			      if (level == 2)
Packit Service 82fcde
				threads_l2 = threads_core;
Packit Service 82fcde
			      else
Packit Service 82fcde
				threads_l3 = threads_core;
Packit Service 82fcde
			      count &= ~(0x1 << 1);
Packit Service 82fcde
			    }
Packit Service 82fcde
			}
Packit Service 82fcde
		    }
Packit Service 82fcde
		}
Packit Service 82fcde
	      if (threads_l2 > 0)
Packit Service 82fcde
		threads_l2 += 1;
Packit Service 82fcde
	      if (threads_l3 > 0)
Packit Service 82fcde
		threads_l3 += 1;
Packit Service 82fcde
	      if (level == 2)
Packit Service 82fcde
		{
Packit Service 82fcde
		  if (threads_l2)
Packit Service 82fcde
		    {
Packit Service 82fcde
		      threads = threads_l2;
Packit Service 82fcde
		      if (threads > 2 && family == 6)
Packit Service 82fcde
			switch (model)
Packit Service 82fcde
			  {
Packit Service 82fcde
			  case 0x37:
Packit Service 82fcde
			  case 0x4a:
Packit Service 82fcde
			  case 0x4d:
Packit Service 82fcde
			  case 0x5a:
Packit Service 82fcde
			  case 0x5d:
Packit Service 82fcde
			    /* Silvermont has L2 cache shared by 2 cores.  */
Packit Service 82fcde
			    threads = 2;
Packit Service 82fcde
			    break;
Packit Service 82fcde
			  default:
Packit Service 82fcde
			    break;
Packit Service 82fcde
			  }
Packit Service 82fcde
		    }
Packit Service 82fcde
		}
Packit Service 82fcde
	      else if (threads_l3)
Packit Service 82fcde
		threads = threads_l3;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  else
Packit Service 82fcde
	    {
Packit Service 82fcde
intel_bug_no_cache_info:
Packit Service 82fcde
	      /* Assume that all logical threads share the highest cache
Packit Service 82fcde
		 level.  */
Packit Service 82fcde
Packit Service 82fcde
	      threads
Packit Service 82fcde
		= ((cpu_features->cpuid[COMMON_CPUID_INDEX_1].ebx
Packit Service 82fcde
		    >> 16) & 0xff);
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  /* Cap usage of highest cache level to the number of supported
Packit Service 82fcde
	     threads.  */
Packit Service 82fcde
	  if (shared > 0 && threads > 0)
Packit Service 82fcde
	    shared /= threads;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* Account for non-inclusive L2 and L3 caches.  */
Packit Service 82fcde
      if (!inclusive_cache)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (threads_l2 > 0)
Packit Service 82fcde
	    core /= threads_l2;
Packit Service 82fcde
	  shared += core;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
  else if (cpu_features->kind == arch_kind_amd)
Packit Service 82fcde
    {
Packit Service 82fcde
      data   = handle_amd (_SC_LEVEL1_DCACHE_SIZE);
Packit Service 82fcde
      long int core = handle_amd (_SC_LEVEL2_CACHE_SIZE);
Packit Service 82fcde
      shared = handle_amd (_SC_LEVEL3_CACHE_SIZE);
Packit Service 82fcde
Packit Service 82fcde
      /* Get maximum extended function. */
Packit Service 82fcde
      __cpuid (0x80000000, max_cpuid_ex, ebx, ecx, edx);
Packit Service 82fcde
Packit Service 82fcde
      if (shared <= 0)
Packit Service 82fcde
	/* No shared L3 cache.  All we have is the L2 cache.  */
Packit Service 82fcde
	shared = core;
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* Figure out the number of logical threads that share L3.  */
Packit Service 82fcde
	  if (max_cpuid_ex >= 0x80000008)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      /* Get width of APIC ID.  */
Packit Service 82fcde
	      __cpuid (0x80000008, max_cpuid_ex, ebx, ecx, edx);
Packit Service 82fcde
	      threads = 1 << ((ecx >> 12) & 0x0f);
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  if (threads == 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      /* If APIC ID width is not available, use logical
Packit Service 82fcde
		 processor count.  */
Packit Service 82fcde
	      __cpuid (0x00000001, max_cpuid_ex, ebx, ecx, edx);
Packit Service 82fcde
Packit Service 82fcde
	      if ((edx & (1 << 28)) != 0)
Packit Service 82fcde
		threads = (ebx >> 16) & 0xff;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  /* Cap usage of highest cache level to the number of
Packit Service 82fcde
	     supported threads.  */
Packit Service 82fcde
	  if (threads > 0)
Packit Service 82fcde
	    shared /= threads;
Packit Service 82fcde
Packit Service 82fcde
	  /* Account for exclusive L2 and L3 caches.  */
Packit Service 82fcde
	  shared += core;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
#ifndef DISABLE_PREFETCHW
Packit Service 82fcde
      if (max_cpuid_ex >= 0x80000001)
Packit Service 82fcde
	{
Packit Service 82fcde
	  __cpuid (0x80000001, eax, ebx, ecx, edx);
Packit Service 82fcde
	  /*  PREFETCHW     || 3DNow!  */
Packit Service 82fcde
	  if ((ecx & 0x100) || (edx & 0x80000000))
Packit Service 82fcde
	    __x86_prefetchw = -1;
Packit Service 82fcde
	}
Packit Service 82fcde
#endif
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (cpu_features->data_cache_size != 0)
Packit Service 82fcde
    data = cpu_features->data_cache_size;
Packit Service 82fcde
Packit Service 82fcde
  if (data > 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      __x86_raw_data_cache_size_half = data / 2;
Packit Service 82fcde
      __x86_raw_data_cache_size = data;
Packit Service 82fcde
      /* Round data cache size to multiple of 256 bytes.  */
Packit Service 82fcde
      data = data & ~255L;
Packit Service 82fcde
      __x86_data_cache_size_half = data / 2;
Packit Service 82fcde
      __x86_data_cache_size = data;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (cpu_features->shared_cache_size != 0)
Packit Service 82fcde
    shared = cpu_features->shared_cache_size;
Packit Service 82fcde
Packit Service 82fcde
  if (shared > 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      __x86_raw_shared_cache_size_half = shared / 2;
Packit Service 82fcde
      __x86_raw_shared_cache_size = shared;
Packit Service 82fcde
      /* Round shared cache size to multiple of 256 bytes.  */
Packit Service 82fcde
      shared = shared & ~255L;
Packit Service 82fcde
      __x86_shared_cache_size_half = shared / 2;
Packit Service 82fcde
      __x86_shared_cache_size = shared;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* The large memcpy micro benchmark in glibc shows that 6 times of
Packit Service 82fcde
     shared cache size is the approximate value above which non-temporal
Packit Service 82fcde
     store becomes faster on a 8-core processor.  This is the 3/4 of the
Packit Service 82fcde
     total shared cache size.  */
Packit Service 82fcde
  __x86_shared_non_temporal_threshold
Packit Service 82fcde
    = (cpu_features->non_temporal_threshold != 0
Packit Service 82fcde
       ? cpu_features->non_temporal_threshold
Packit Service 82fcde
       : __x86_shared_cache_size * threads * 3 / 4);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#endif