X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fcompiler.h;h=cfe90666017bf4aeed4ab04aabb8b1c5724292dc;hb=124f09c9279ae41eba4bf0d6419387e8ec9a1a78;hp=1c01fd1d6a78d18b643d095afbf20659259a1de7;hpb=97be153858b4cd175cbe7862b8e1624bf22ab98a;p=sliver-openvswitch.git diff --git a/lib/compiler.h b/lib/compiler.h index 1c01fd1d6..cfe906660 100644 --- a/lib/compiler.h +++ b/lib/compiler.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,11 +20,15 @@ #ifndef __has_feature #define __has_feature(x) 0 #endif +#ifndef __has_extension + #define __has_extension(x) 0 +#endif #if __GNUC__ && !__CHECKER__ #define NO_RETURN __attribute__((__noreturn__)) #define OVS_UNUSED __attribute__((__unused__)) #define PRINTF_FORMAT(FMT, ARG1) __attribute__((__format__(printf, FMT, ARG1))) +#define SCANF_FORMAT(FMT, ARG1) __attribute__((__format__(scanf, FMT, ARG1))) #define STRFTIME_FORMAT(FMT) __attribute__((__format__(__strftime__, FMT, 0))) #define MALLOC_LIKE __attribute__((__malloc__)) #define ALWAYS_INLINE __attribute__((always_inline)) @@ -36,6 +40,7 @@ #define NO_RETURN #define OVS_UNUSED #define PRINTF_FORMAT(FMT, ARG1) +#define SCANF_FORMAT(FMT, ARG1) #define STRFTIME_FORMAT(FMT) #define MALLOC_LIKE #define ALWAYS_INLINE @@ -65,6 +70,16 @@ * while the specific MUTEX is held. * * + * On a variable A of mutex type: + * + * - OVS_ACQ_BEFORE(B), where B is a mutex or a comma-separated list of + * mutexes, declare that if both A and B are acquired at the same time, + * then A must be acquired before B. That is, B nests inside A. + * + * - OVS_ACQ_AFTER(B) is the opposite of OVS_ACQ_BEFORE(B), that is, it + * declares that A nests inside B. + * + * * On a function, the following attributes apply to mutexes: * * - OVS_ACQUIRES(MUTEX) indicate that the function must be called without @@ -81,8 +96,9 @@ * - OVS_REQUIRES(MUTEX) indicate that the function may only be called with * MUTEX held and that the function does not release MUTEX. * - * - OVS_LOCKS_EXCLUDED(MUTEX) indicates that the function may only be - * called when MUTEX is not held. + * - OVS_EXCLUDED(MUTEX) indicates that the function may only be called when + * MUTEX is not held. + * * * The following variants, with the same syntax, apply to reader-writer locks: * @@ -92,7 +108,7 @@ * OVS_RELEASES OVS_RELEASES OVS_RELEASES * OVS_TRY_LOCK OVS_TRY_RDLOCK OVS_TRY_WRLOCK * OVS_REQUIRES OVS_REQ_RDLOCK OVS_REQ_WRLOCK - * OVS_LOCKS_EXCLUDED OVS_LOCKS_EXCLUDED OVS_LOCKS_EXCLUDED + * OVS_EXCLUDED OVS_EXCLUDED OVS_EXCLUDED */ #define OVS_LOCKABLE __attribute__((lockable)) #define OVS_REQ_RDLOCK(...) __attribute__((shared_locks_required(__VA_ARGS__))) @@ -114,30 +130,12 @@ #define OVS_GUARDED __attribute__((guarded_var)) #define OVS_GUARDED_BY(...) __attribute__((guarded_by(__VA_ARGS__))) #define OVS_RELEASES(...) __attribute__((unlock_function(__VA_ARGS__))) -#define OVS_LOCKS_EXCLUDED(...) __attribute__((locks_excluded(__VA_ARGS__))) -#elif __CHECKER__ -/* "sparse" annotations for mutexes and mutex-like constructs. - * - * Change the thread-safety check annotations to use "context" attribute. - * - * OVS_MACRO_LOCK and OVS_MACRO_RELEASE are suitable for use within macros, - * where there is no function prototype to annotate. */ -#define OVS_LOCKABLE -#define OVS_REQ_RDLOCK(...) __attribute__((context(MUTEX, 1, 1))) -#define OVS_ACQ_RDLOCK(...) __attribute__((context(MUTEX, 0, 1))) -#define OVS_REQ_WRLOCK(...) __attribute__((context(MUTEX, 1, 1))) -#define OVS_ACQ_WRLOCK(...) __attribute__((context(MUTEX, 0, 1))) -#define OVS_REQUIRES(...) __attribute__((context(MUTEX, 1, 1))) -#define OVS_ACQUIRES(...) __attribute__((context(MUTEX, 0, 1))) -#define OVS_TRY_WRLOCK(RETVAL, ...) -#define OVS_TRY_RDLOCK(RETVAL, ...) -#define OVS_TRY_LOCK(REVAL, ...) -#define OVS_GUARDED -#define OVS_GUARDED_BY(...) -#define OVS_RELEASES(...) __attribute__((context(MUTEX, 1, 0))) -#define OVS_MACRO_LOCK(...) __context__(MUTEX, 0, 1) -#define OVS_MACRO_RELEASE(...) __context__(MUTEX, 1, 0) -#else +#define OVS_EXCLUDED(...) __attribute__((locks_excluded(__VA_ARGS__))) +#define OVS_ACQ_BEFORE(...) __attribute__((acquired_before(__VA_ARGS__))) +#define OVS_ACQ_AFTER(...) __attribute__((acquired_after(__VA_ARGS__))) +#define OVS_NO_THREAD_SAFETY_ANALYSIS \ + __attribute__((no_thread_safety_analysis)) +#else /* not Clang */ #define OVS_LOCKABLE #define OVS_REQ_RDLOCK(...) #define OVS_ACQ_RDLOCK(...) @@ -150,9 +148,11 @@ #define OVS_TRY_LOCK(...) #define OVS_GUARDED #define OVS_GUARDED_BY(...) +#define OVS_EXCLUDED(...) #define OVS_RELEASES(...) -#define OVS_MACRO_LOCK(...) -#define OVS_MACRO_RELEASE(...) +#define OVS_ACQ_BEFORE(...) +#define OVS_ACQ_AFTER(...) +#define OVS_NO_THREAD_SAFETY_ANALYSIS #endif /* ISO C says that a C implementation may choose any integer type for an enum @@ -179,4 +179,45 @@ #define OVS_PACKED(DECL) __pragma(pack(push, 1)) DECL __pragma(pack(pop)) #endif +/* For defining a structure whose instances should aligned on an N-byte + * boundary. + * + * e.g. The following: + * OVS_ALIGNED_STRUCT(64, mystruct) { ... }; + * is equivalent to the following except that it specifies 64-byte alignment: + * struct mystruct { ... }; + */ +#ifndef _MSC_VER +#define OVS_ALIGNED_STRUCT(N, TAG) struct __attribute__((aligned(N))) TAG +#else +#define OVS_ALIGNED_STRUCT(N, TAG) __declspec(align(N)) struct TAG +#endif + +#ifdef _MSC_VER +#define CCALL __cdecl +#pragma section(".CRT$XCU",read) +#define OVS_CONSTRUCTOR(f) \ + static void __cdecl f(void); \ + __declspec(allocate(".CRT$XCU")) void (__cdecl*f##_)(void) = f; \ + static void __cdecl f(void) +#else +#define OVS_CONSTRUCTOR(f) \ + static void f(void) __attribute__((constructor)); \ + static void f(void) +#endif + +/* OVS_PREFETCH() can be used to instruct the CPU to fetch the cache + * line containing the given address to a CPU cache. + * OVS_PREFETCH_WRITE() should be used when the memory is going to be + * written to. Depending on the target CPU, this can generate the same + * instruction as OVS_PREFETCH(), or bring the data into the cache in an + * exclusive state. */ +#if __GNUC__ +#define OVS_PREFETCH(addr) __builtin_prefetch((addr)) +#define OVS_PREFETCH_WRITE(addr) __builtin_prefetch((addr), 1) +#else +#define OVS_PREFETCH(addr) +#define OVS_PREFETCH_WRITE(addr) +#endif + #endif /* compiler.h */