tlds
Transactional Operations for Linked Data Structures
|
#include <stm/config.h>
#include <stdint.h>
#include <limits.h>
#include <unistd.h>
Go to the source code of this file.
Macros | |
#define | CACHELINE_BYTES 64 |
#define | NORETURN __attribute__((noreturn)) |
#define | NOINLINE __attribute__((noinline)) |
#define | ALWAYS_INLINE __attribute__((always_inline)) |
#define | USED __attribute__((used)) |
#define | REGPARM(N) __attribute__((regparm(N))) |
#define | STM_BITS_32 |
#define | GCC_FASTCALL __attribute__((fastcall)) |
#define | TM_INLINE ALWAYS_INLINE |
#define | TM_FASTCALL |
#define | TM_ALIGN(N) __attribute__((aligned(N))) |
Functions | |
void | sleep_ms (uint32_t ms) |
#define ALWAYS_INLINE __attribute__((always_inline)) |
#define CACHELINE_BYTES 64 |
Copyright (C) 2011 University of Rochester Department of Computer Science and Lehigh University Department of Computer Science and Engineering
License: Modified BSD Please see the file LICENSE.RSTM for licensing information This file hides differences that are based on compiler, CPU, and OS. In particular, we define:
1) atomic operations (cas, swap, etc, atomic 64-bit load/store) 2) access to the tick counter 3) clean definitions of custom compiler constructs (__builtin_expect, alignment attributes, etc) 4) scheduler syscalls (sleep, yield) 5) a high-resolution timer We set up a bunch of macros that we use to insulate the rest of the code from potentially platform-dependent behavior.
NB: This is partially keyed off of LP64 which isn't universally defined for -m64 code, but it works on the platforms that we support.
NB2: We don't really support non-gcc compatible compilers, so there isn't any compiler logic in these ifdefs. If we begin to support the Windows platform these will need to be more complicated We begin by hard-coding some macros that may become platform-dependent in the future.
#define GCC_FASTCALL __attribute__((fastcall)) |
GCC's fastcall attribute causes a warning on x86_64, so we don't use it there (it's not necessary in any case because of the native calling convention.
#define NOINLINE __attribute__((noinline)) |
#define NORETURN __attribute__((noreturn)) |
#define REGPARM | ( | N | ) | __attribute__((regparm(N))) |
#define STM_BITS_32 |
Pick up the BITS define from the LP64 token.
#define TM_ALIGN | ( | N | ) | __attribute__((aligned(N))) |
#define TM_FASTCALL |
#define TM_INLINE ALWAYS_INLINE |
We rely on the configured parameters here (no cross platform building yet)
#define USED __attribute__((used)) |
|
inline |
The first task for this file is to declare atomic operations (cas, swap, etc) and custom assembly codes, such as compiler fences, memory barriers, and no-op instructions. This code depends on the compiler and processor. icc is nominally an x86/x86-64 compiler that supports sync builtins, however the stm prototype doesn't support operations on pointer types, which we perform all the time. This header performs the fixes by #defining the __sync builtin symbols as partial templates. Here is the declaration of atomic operations when we're on an x86 (32bit or 64bit) and using the GNU compiler collection. This assumes that the compiler is recent enough that it supports the builtin __sync operations Here is the declaration of atomic operations when we're on a sparc (32bit) and using the GNU compiler collection. For some reason, gcc 4.3.1 __sync_* operations can sometimes cause odd compiler crashes, so we provide our own assembly and use it instead.
NB: gcc doesn't provide a builtin equivalent to the SPARC swap instruction, and thus we have to implement atomicswap ourselves. Here is the declaration of atomic operations when we're using Sun Studio 12.1. These work for x86 and SPARC, at 32-bit or 64-bit Now we must deal with the ability to load/store 64-bit values safely. In 32-bit mode, this is potentially a problem, so we handle 64-bit atomic load/store via the mvx() function. mvx() depends on the bit level and the CPU The next task for this file is to establish access to a high-resolution CPU timer. The code depends on the CPU and bit level. It is identical for 32/64-bit x86. For sparc, the code depends on if we are 32-bit or 64-bit. Next, we provide a platform-independent function for sleeping for a number of milliseconds. This code depends on the OS.
NB: since we do not have Win32 support, this is now very easy... we just use the usleep instruction.