1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
|
/*
* Copyright (c) 2006-2008 Message Systems, Inc. All rights reserved
* This header file distributed under the terms of the CDDL.
* Portions Copyright 2004 Sun Microsystems, Inc. All Rights reserved.
*/
#ifndef _EC_UMEM_SOL_COMPAT_H_
#define _EC_UMEM_SOL_COMPAT_H_
#include "config.h"
#include <stdint.h>
#include <pthread.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef _WIN32
# define THR_RETURN DWORD
# define THR_API WINAPI
# define INLINE __inline
#else
# define THR_RETURN void *
# define THR_API
# define INLINE inline
#endif
#if defined(__MACH__) || defined(_WIN32)
#define NO_WEAK_SYMBOLS
#define _umem_cache_alloc(a,b) umem_cache_alloc(a,b)
#define _umem_cache_free(a,b) umem_cache_free(a,b)
#define _umem_zalloc(a,b) umem_zalloc(a,b)
#define _umem_alloc(a,b) umem_alloc(a,b)
#define _umem_alloc_align(a,b,c) umem_alloc_align(a,b,c)
#define _umem_free(a,b) umem_free(a,b)
#define _umem_free_align(a,b) umem_free_align(a,b)
#endif
#ifdef _WIN32
#define bcopy(s, d, n) memcpy(d, s, n)
#define bzero(m, s) memset(m, 0, s)
#endif
typedef pthread_t thread_t;
typedef pthread_mutex_t mutex_t;
typedef pthread_cond_t cond_t;
typedef u_int64_t hrtime_t;
typedef uint32_t uint_t;
typedef unsigned long ulong_t;
typedef struct timespec timestruc_t;
typedef long long longlong_t;
typedef struct timespec timespec_t;
static INLINE hrtime_t gethrtime(void) {
struct timeval tv;
gettimeofday(&tv, NULL);
return (((u_int64_t)tv.tv_sec) << 32) | tv.tv_usec;
}
# define thr_self() pthread_self()
static INLINE thread_t _thr_self(void) {
return thr_self();
}
#if defined(_MACH_PORT_T)
#define CPUHINT() (pthread_mach_thread_np(pthread_self()))
#endif
# define thr_sigsetmask pthread_sigmask
#define THR_BOUND 1
#define THR_DETACHED 2
#define THR_DAEMON 4
static INLINE int thr_create(void *stack_base,
size_t stack_size, THR_RETURN (THR_API *start_func)(void*),
void *arg, long flags, thread_t *new_thread_ID)
{
int ret;
pthread_attr_t attr;
pthread_attr_init(&attr);
if (flags & THR_DETACHED) {
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
}
ret = pthread_create(new_thread_ID, &attr, start_func, arg);
pthread_attr_destroy(&attr);
return ret;
}
# define mutex_init(mp, type, arg) pthread_mutex_init(mp, NULL)
# define mutex_lock(mp) pthread_mutex_lock(mp)
# define mutex_unlock(mp) pthread_mutex_unlock(mp)
# define mutex_destroy(mp) pthread_mutex_destroy(mp)
# define mutex_trylock(mp) pthread_mutex_trylock(mp)
# define DEFAULTMUTEX PTHREAD_MUTEX_INITIALIZER
# define DEFAULTCV PTHREAD_COND_INITIALIZER
# define MUTEX_HELD(mp) 1 /* not really, but only used in an assert */
# define cond_init(c, type, arg) pthread_cond_init(c, NULL)
# define cond_wait(c, m) pthread_cond_wait(c, m)
# define _cond_wait(c, m) pthread_cond_wait(c, m)
# define cond_signal(c) pthread_cond_signal(c)
# define cond_broadcast(c) pthread_cond_broadcast(c)
# define cond_destroy(c) pthread_cond_destroy(c)
# define cond_timedwait pthread_cond_timedwait
# define _cond_timedwait pthread_cond_timedwait
#ifndef RTLD_FIRST
# define RTLD_FIRST 0
#endif
#ifdef ECELERITY
# include "ec_atomic.h"
#else
# ifdef _WIN32
# define ec_atomic_inc(a) InterlockedIncrement(a)
# define ec_atomic_inc64(a) InterlockedIncrement64(a)
#elif defined(__powerpc) || defined(__powerpc__) ||\
defined(__powerpc64) || defined(__powerpc64__)
/* This code comes from
* http://www.mulle-kybernetik.com/artikel/Optimization/opti-4-atomic.html
*/
//
// This increments atomically. It will return the value
// after increment
//
static inline int MulleAtomicIncrement( int *p)
{
int tmp;
// code lifted from linux
asm volatile(
"1: lwarx %0,0,%1\n"
" addic %0,%0,1\n"
" stwcx. %0,0,%1\n"
" bne- 1b"
: "=&r" (tmp)
: "r" (p)
: "cc", "memory");
return( tmp);
}
#define ec_atomic_inc(a) MulleAtomicIncrement(a)
//
// This decrements atomically. It will return the value
// after decrement
//
static inline int MulleAtomicDecrement( int *p)
{
int tmp;
// code lifted from linux
asm volatile(
"1: lwarx %0,0,%1\n"
" addic %0,%0,-1\n" // addic allows r0, addi doesn't
" stwcx. %0,0,%1\n"
" bne- 1b"
: "=&r" (tmp)
: "r" (p)
: "cc", "memory");
return( tmp);
}
#define atomic_dec_32_nv(a) MulleAtomicDecrement(a)
# elif (defined(__i386__) || defined(__x86_64__)) && defined(__GNUC__)
static INLINE uint_t ec_atomic_cas(uint_t *mem, uint_t with, uint_t cmp)
{
uint_t prev;
asm volatile ("lock; cmpxchgl %1, %2"
: "=a" (prev)
: "r" (with), "m" (*(mem)), "0" (cmp)
: "memory");
return prev;
}
# elif defined(__sparc__) && defined(__GNUC__)
static INLINE uint_t ec_atomic_cas(uint_t *mem, uint_t with, uint_t cmp)
{
__asm volatile ("cas [%3],%2,%0"
: "+r"(with), "=m"(*(mem))
: "r"(cmp), "r"(mem), "m"(*(mem)) );
return with;
}
# endif
#if defined(__arm__)
//#include <asm-arm/irqflags.h>
//typedef struct { volatile int counter; } atomic_t;
/*
* Save the current interrupt enable state & disable IRQs
*/
#define raw_local_irq_save(x) \
({ \
unsigned long temp; \
(void) (&temp == &x); \
__asm__ __volatile__( \
"mrs %0, cpsr @ local_irq_save\n" \
" orr %1, %0, #128\n" \
" msr cpsr_c, %1" \
: "=r" (x), "=r" (temp) \
: \
: "memory", "cc"); \
})
/*
* restore saved IRQ & FIQ state
*/
#define raw_local_irq_restore(x) \
__asm__ __volatile__( \
"msr cpsr_c, %0 @ local_irq_restore\n" \
: \
: "r" (x) \
: "memory", "cc")
typedef uint_t atomic_t;
static inline uint_t atomic_add_return(int i, atomic_t *v)
{
unsigned long flags;
uint_t val;
raw_local_irq_save(flags);
// val = v->counter;
// v->counter = val += i;
val = *v;
*v = val += i;
raw_local_irq_restore(flags);
return val;
}
#define atomic_inc(v) atomic_add_return(1, v)
#define ec_atomic_inc(v) atomic_inc(v)
#endif
#endif
#define P2PHASE(x, align) ((x) & ((align) - 1))
#define P2ALIGN(x, align) ((x) & -(align))
#define P2NPHASE(x, align) (-(x) & ((align) - 1))
#define P2ROUNDUP(x, align) (-(-(x) & -(align)))
#define P2END(x, align) (-(~(x) & -(align)))
#define P2PHASEUP(x, align, phase) ((phase) - (((phase) - (x)) & -(align)))
#define P2CROSS(x, y, align) (((x) ^ (y)) > (align) - 1)
#define P2SAMEHIGHBIT(x, y) (((x) ^ (y)) < ((x) & (y)))
#define IS_P2ALIGNED(v, a) ((((uintptr_t)(v)) & ((uintptr_t)(a) - 1)) == 0)
#define ISP2(x) (((x) & ((x) - 1)) == 0)
/* beware! umem only uses these atomic adds for incrementing by 1 */
#if defined(_WIN32) || (defined(__GNUC__) && \
(defined(__i386__) || defined(__x86_64__) || defined(__sparc__)))
# ifndef ec_atomic_inc
static INLINE uint_t ec_atomic_inc(uint_t *mem)
{
register uint_t last;
do {
last = *mem;
} while (ec_atomic_cas(mem, last+1, last) != last);
return ++last;
}
# endif
# ifndef ec_atomic_inc64
/* yeah, it's not great. It's only used to bump failed allocation
* counts, so it is not critical right now. */
# define ec_atomic_inc64(a) (*a)++
# endif
#define atomic_add_64(lvalptr, delta) ec_atomic_inc64(lvalptr)
#define atomic_add_32_nv(a, b) ec_atomic_inc(a)
#elif defined(__powerpc) || defined(__powerpc__) ||\
defined(__arm__) || \
defined(__powerpc64) || defined(__powerpc64__)
# ifndef ec_atomic_inc64
# define ec_atomic_inc64(a) (*a)++
# endif
#define atomic_add_64(lvalptr, delta) ec_atomic_inc64(lvalptr)
#define atomic_add_32_nv(a, b) ec_atomic_inc(a)
#else
extern uint32_t atomic_add_32_nv(volatile uint32_t *, int32_t);
extern void atomic_add_64(volatile uint64_t *, int64_t);
#endif
#ifndef NANOSEC
#define NANOSEC 1000000000
#endif
#ifdef _WIN32
#define issetugid() 0
#elif !HAVE_ISSETUGID
#define issetugid() (geteuid() == 0)
#endif
#define _sysconf(a) sysconf(a)
#define __NORETURN __attribute__ ((noreturn))
#define EC_UMEM_DUMMY_PCSTACK 1
static INLINE int __nthreads(void)
{
/* or more; just to force multi-threaded mode */
return 2;
}
#if (SIZEOF_VOID_P == 8)
# define _LP64 1
#endif
#ifndef MIN
# define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
#ifndef MAX
# define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
#endif
|