/* os.h                  -*-C++-*-
 *
 *************************************************************************
 *
 *  @copyright
 *  Copyright (C) 2009-2013, Intel Corporation
 *  All rights reserved.
 *  
 *  @copyright
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *  
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in
 *      the documentation and/or other materials provided with the
 *      distribution.
 *    * Neither the name of Intel Corporation nor the names of its
 *      contributors may be used to endorse or promote products derived
 *      from this software without specific prior written permission.
 *  
 *  @copyright
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
 *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 **************************************************************************/

/* gcc before 4.4 does not implement __sync_synchronize properly */
#if (__ICC >= 1110 && !(__MIC__ || __MIC2__))                      \
    || (!defined __ICC && __GNUC__ * 10 + __GNUC_MINOR__ > 43)
#   define HAVE_SYNC_INTRINSICS 1
#endif


/*
 * void __cilkrts_fence(void)
 *
 * Executes an MFENCE instruction to serialize all load and store instructions
 * that were issued prior the MFENCE instruction. This serializing operation
 * guarantees that every load and store instruction that precedes the MFENCE
 * instruction is globally visible before any load or store instruction that
 * follows the MFENCE instruction. The MFENCE instruction is ordered with
 * respect to all load and store instructions, other MFENCE instructions, any
 * SFENCE and LFENCE instructions, and any serializing instructions (such as
 * the CPUID instruction).
 */
#ifdef HAVE_SYNC_INTRINSICS
#   define __cilkrts_fence() __sync_synchronize()
#elif defined __ICC || defined __GNUC__
    /* mfence is a strict subset of lock add but takes longer on many
     * processors. */
// #   define __cilkrts_fence() __asm__ volatile ("mfence")
    /* On MIC, fence seems to be completely unnecessary.
     * Just for simplicity of 1st implementation, it defaults to x86 */ 
#   define __cilkrts_fence() __asm__ volatile ("lock addl $0,(%rsp)")
// #elif defined _WIN32
// #   pragma intrinsic(_ReadWriteBarrier)
// #   define __cilkrts_fence() _ReadWriteBarrier()
#else
COMMON_SYSDEP void __cilkrts_fence(void); ///< MFENCE instruction
#endif
