Blame source/uds/cpu.h

Packit Service 310c69
/*
Packit Service 310c69
 * Copyright (c) 2020 Red Hat, Inc.
Packit Service 310c69
 *
Packit Service 310c69
 * This program is free software; you can redistribute it and/or
Packit Service 310c69
 * modify it under the terms of the GNU General Public License
Packit Service 310c69
 * as published by the Free Software Foundation; either version 2
Packit Service 310c69
 * of the License, or (at your option) any later version.
Packit Service 310c69
 * 
Packit Service 310c69
 * This program is distributed in the hope that it will be useful,
Packit Service 310c69
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 310c69
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 310c69
 * GNU General Public License for more details.
Packit Service 310c69
 * 
Packit Service 310c69
 * You should have received a copy of the GNU General Public License
Packit Service 310c69
 * along with this program; if not, write to the Free Software
Packit Service 310c69
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service 310c69
 * 02110-1301, USA. 
Packit Service 310c69
 *
Packit Service 310c69
 * $Id: //eng/uds-releases/jasper/src/uds/cpu.h#1 $
Packit Service 310c69
 */
Packit Service 310c69
Packit Service 310c69
#ifndef CPU_H
Packit Service 310c69
#define CPU_H
Packit Service 310c69
Packit Service 310c69
#include "compiler.h"
Packit Service 310c69
#include "typeDefs.h"
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * The number of bytes in a CPU cache line. In the future, we'll probably need
Packit Service 310c69
 * to move this to a processor-specific file or discover it at compilation
Packit Service 310c69
 * time (or runtime, if sufficiently heterogeneous), but this will do for now.
Packit Service 310c69
 * (Must be a \#define since enums are not proper compile-time constants.)
Packit Service 310c69
 **/
Packit Service 310c69
#ifdef __PPC__
Packit Service 310c69
// N.B.: Some PPC processors have smaller cache lines.
Packit Service 310c69
#define CACHE_LINE_BYTES 128
Packit Service 310c69
#elif defined(__s390x__)
Packit Service 310c69
#define CACHE_LINE_BYTES 256
Packit Service 310c69
#elif defined(__x86_64__) || defined(__aarch64__)
Packit Service 310c69
#define CACHE_LINE_BYTES  64
Packit Service 310c69
#else
Packit Service 310c69
#error "unknown cache line size"
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Minimize cache-miss latency by moving data into a CPU cache before it is
Packit Service 310c69
 * accessed.
Packit Service 310c69
 *
Packit Service 310c69
 * @param address   the address to fetch (may be invalid)
Packit Service 310c69
 * @param forWrite  must be constant at compile time--false if
Packit Service 310c69
 *                  for reading, true if for writing
Packit Service 310c69
 **/
Packit Service 310c69
static INLINE void prefetchAddress(const void *address, bool forWrite)
Packit Service 310c69
{
Packit Service 310c69
  // forWrite won't won't be a constant if we are compiled with optimization
Packit Service 310c69
  // turned off, in which case prefetching really doesn't matter.
Packit Service 310c69
  if (__builtin_constant_p(forWrite)) {
Packit Service 310c69
    __builtin_prefetch(address, forWrite);
Packit Service 310c69
  }
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Minimize cache-miss latency by moving a range of addresses into a
Packit Service 310c69
 * CPU cache before they are accessed.
Packit Service 310c69
 *
Packit Service 310c69
 * @param start     the starting address to fetch (may be invalid)
Packit Service 310c69
 * @param size      the number of bytes in the address range
Packit Service 310c69
 * @param forWrite  must be constant at compile time--false if
Packit Service 310c69
 *                  for reading, true if for writing
Packit Service 310c69
 **/
Packit Service 310c69
static INLINE void prefetchRange(const void   *start,
Packit Service 310c69
                                 unsigned int  size,
Packit Service 310c69
                                 bool          forWrite)
Packit Service 310c69
{
Packit Service 310c69
  // Count the number of cache lines to fetch, allowing for the address range
Packit Service 310c69
  // to span an extra cache line boundary due to address alignment.
Packit Service 310c69
  const char *address = (const char *) start;
Packit Service 310c69
  unsigned int offset = ((uintptr_t) address % CACHE_LINE_BYTES);
Packit Service 310c69
  size += offset;
Packit Service 310c69
Packit Service 310c69
  unsigned int cacheLines = (1 + (size / CACHE_LINE_BYTES));
Packit Service 310c69
  while (cacheLines-- > 0) {
Packit Service 310c69
    prefetchAddress(address, forWrite);
Packit Service 310c69
    address += CACHE_LINE_BYTES;
Packit Service 310c69
  }
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
#endif /* CPU_H */