Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / native_client / src / include / concurrency_ops.h
1 /*
2  * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6
7
8 #ifndef NATIVE_CLIENT_SRC_INCLUDE_CONCURRENCY_OPS_H_
9 #define NATIVE_CLIENT_SRC_INCLUDE_CONCURRENCY_OPS_H_ 1
10
11
12 #include "native_client/src/include/nacl_base.h"
13 #include "native_client/src/include/portability.h"
14
15 #if NACL_WINDOWS && (NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86)
16 #include <intrin.h>
17 #include <mmintrin.h>
18 #endif
19
20 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86
21
22 static INLINE void NaClWriteMemoryBarrier(void) {
23 #if NACL_WINDOWS
24   /* Inline assembly is not available in x86-64 MSVC.  Use built-in. */
25   _mm_sfence();
26 #else
27   __asm__ __volatile__("sfence");
28 #endif
29 }
30
31 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm
32
33 static INLINE void NaClWriteMemoryBarrier(void) {
34   /* Note that this depends on ARMv7. */
35   __asm__ __volatile__("dsb");
36
37   /*
38    * We could support ARMv6 by instead using:
39    * __asm__ __volatile__("mcr p15, 0, %0, c7, c10, 5"
40    *                      : : "r" (0) : "memory");
41    */
42 }
43
44 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips
45
46 static INLINE void NaClWriteMemoryBarrier(void) {
47   __asm__ __volatile__("sync" : : : "memory");
48 }
49
50 #else
51
52 #error "Define for other architectures"
53
54 #endif
55
56
57 static INLINE void NaClFlushCacheForDoublyMappedCode(uint8_t *writable_addr,
58                                                      uint8_t *executable_addr,
59                                                      size_t size) {
60 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86
61   /*
62    * Clearing the icache explicitly is not necessary on x86.  We could
63    * call gcc's __builtin___clear_cache() on x86, where it is a no-op,
64    * except that it is not available in Mac OS X's old version of gcc.
65    * We simply prevent the compiler from moving loads or stores around
66    * this function.
67    */
68   UNREFERENCED_PARAMETER(writable_addr);
69   UNREFERENCED_PARAMETER(executable_addr);
70   UNREFERENCED_PARAMETER(size);
71 #if NACL_WINDOWS
72   _ReadWriteBarrier();
73 #else
74   __asm__ __volatile__("" : : : "memory");
75 #endif
76 #elif defined(__GNUC__)
77   /*
78    * __clear_cache() does two things:
79    *
80    *  1) It flushes the write buffer for the address range.
81    *     We need to do this for writable_addr.
82    *  2) It clears the instruction cache for the address range.
83    *     We need to do this for executable_addr.
84    *
85    * We do not need apply (1) to executable_addr or apply (2) to
86    * writable_addr, but the Linux kernel does not expose (1) and (2)
87    * as separate operations; it just provides a single syscall that
88    * does both.  For background, see:
89    * http://code.google.com/p/nativeclient/issues/detail?id=2443
90    *
91    * We use __builtin___clear_cache since __clear_cache is only available
92    * with gnu extensions available.
93    *
94    * Casts are needed since clang's prototype for __builtin___clear_cache
95    * doesn't match gcc's.
96    */
97   __builtin___clear_cache((char *) writable_addr,
98                           (char *) writable_addr + size);
99   __builtin___clear_cache((char *) executable_addr,
100                           (char *) executable_addr + size);
101 #else
102   /*
103    * Give an error in case we ever target a non-gcc compiler for ARM
104    * or for some other architecture that we might support in the
105    * future.
106    */
107 # error "Don't know how to clear the icache on this architecture"
108 #endif
109 }
110
111
112 #endif  /* NATIVE_CLIENT_SRC_INCLUDE_CONCURRENCY_OPS_H_ */