| @ -0,0 +1,157 @@ | |||||
| # Copyright (C) 2011 Google Inc. | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| cmake_minimum_required (VERSION 2.8) | |||||
| project (libphonenumber) | |||||
| # Find Google Test library | |||||
| find_path (GTEST_INCLUDE_DIR gtest/gtest.h) | |||||
| if (GTEST_INCLUDE_DIR STREQUAL "GTEST_INCLUDE_DIR-NOTFOUND") | |||||
| message (FATAL_ERROR | |||||
| "Can't find Google Test framework headers. Please read README.") | |||||
| endif () | |||||
| include_directories (${GTEST_INCLUDE_DIR}) | |||||
| find_library (GTEST_LIB gtest) | |||||
| if (GTEST_LIB STREQUAL "GTEST_LIB-NOTFOUND") | |||||
| message (FATAL_ERROR | |||||
| "Can't find Google Test framework library. Please read README.") | |||||
| endif () | |||||
| # Find Google RE2 library | |||||
| find_path (RE2_INCLUDE_DIR re2/re2.h) | |||||
| if (RE2_INCLUDE_DIR STREQUAL "RE2_INCLUDE_DIR-NOTFOUND") | |||||
| message (FATAL_ERROR | |||||
| "Can't find Google RE2 headers. Please read README.") | |||||
| endif () | |||||
| include_directories (${RE2_INCLUDE_DIR}) | |||||
| find_library (RE2_LIB re2) | |||||
| if (RE2_LIB STREQUAL "RE2_LIB-NOTFOUND") | |||||
| message (FATAL_ERROR | |||||
| "Can't find Google RE2 library. Please read README.") | |||||
| endif () | |||||
| # Find Protocol Buffers compiler | |||||
| find_program (PROTOC NAMES protoc) | |||||
| if (PROTOC STREQUAL "PROTOC-NOTFOUND") | |||||
| message (FATAL_ERROR | |||||
| "Can't find Google Protocol Buffers compiler (protoc). " | |||||
| "Please read README.") | |||||
| endif () | |||||
| # Add protoc (Protocol Buffers compiler) target | |||||
| set ( | |||||
| PROTOBUF_SOURCES "${CMAKE_SOURCE_DIR}/src/phonemetadata.proto" | |||||
| "${CMAKE_SOURCE_DIR}/src/phonenumber.proto" | |||||
| ) | |||||
| set ( | |||||
| PROTOBUF_OUTPUT "${CMAKE_SOURCE_DIR}/src/phonemetadata.pb.cc" | |||||
| "${CMAKE_SOURCE_DIR}/src/phonemetadata.pb.h" | |||||
| "${CMAKE_SOURCE_DIR}/src/phonenumber.pb.cc" | |||||
| "${CMAKE_SOURCE_DIR}/src/phonenumber.pb.h" | |||||
| ) | |||||
| add_custom_command ( | |||||
| COMMAND ${PROTOC} --cpp_out=${CMAKE_SOURCE_DIR} | |||||
| --proto_path=${CMAKE_SOURCE_DIR} ${PROTOBUF_SOURCES} | |||||
| OUTPUT ${PROTOBUF_OUTPUT} | |||||
| DEPENDS ${PROTOBUF_SOURCES} | |||||
| ) | |||||
| add_custom_target ( | |||||
| generate-sources | |||||
| DEPENDS ${PROTOBUF_OUTPUT} | |||||
| COMMENT "Generating Protocol Buffers code" | |||||
| ) | |||||
| # Platform independent sources | |||||
| set ( | |||||
| SOURCES | |||||
| "src/base/at_exit.cc" | |||||
| "src/base/lazy_instance.cc" | |||||
| "src/base/synchronization/lock.cc" | |||||
| "src/base/threading/thread_restrictions.cc" | |||||
| "src/phonenumberutil.cc" | |||||
| "src/utf/rune.c" | |||||
| ) | |||||
| if (UNIX) | |||||
| if (CMAKE_COMPILER_IS_GNUCXX) | |||||
| add_definitions ("-Wall -Wextra -Werror") | |||||
| # The next flags are needed by base/ source files to compile | |||||
| # low level code needed by Singleton | |||||
| add_definitions ("-DCOMPILER_GCC -DOS_POSIX -DOS_LINUX") | |||||
| if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86.*") | |||||
| add_definitions ("-DARCH_CPU_X86_FAMILY") | |||||
| # Add GCC specific sources | |||||
| list (APPEND SOURCES "src/base/atomicops_internals_x86_gcc.cc") | |||||
| endif () | |||||
| # TODO: add support for ARCM arch | |||||
| endif () | |||||
| # Add POSIX specific sources | |||||
| list ( | |||||
| APPEND SOURCES | |||||
| "src/base/synchronization/lock_impl_posix.cc" | |||||
| "src/base/threading/platform_thread_posix.cc" | |||||
| "src/base/threading/thread_local_posix.cc" | |||||
| ) | |||||
| else (WIN32) | |||||
| # TODO: add Windows support (define COMPILER_MSVC, OS_WIN) | |||||
| list ( | |||||
| APPEND SOURCES | |||||
| "src/base/synchronization/lock_impl_win.cc" | |||||
| "src/base/threading/platform_thread_win.cc" | |||||
| "src/base/threading/thread_local_win.cc" | |||||
| ) | |||||
| # TODO: Windows specific flags | |||||
| endif () | |||||
| include_directories ("src") | |||||
| add_library (phonenumber STATIC ${SOURCES}) | |||||
| add_dependencies (phonenumber generate-sources) | |||||
| target_link_libraries (phonenumber re2) | |||||
| # Tests | |||||
| set (TEST_SOURCES | |||||
| "src/phonenumberutil_test.cc" | |||||
| "src/run_tests.cc" | |||||
| ) | |||||
| add_executable (libphonenumber_test ${TEST_SOURCES}) | |||||
| target_link_libraries (libphonenumber_test phonenumber gtest pthread) | |||||
| @ -0,0 +1,13 @@ | |||||
| Copyright (C) 2011 Google Inc. | |||||
| Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| you may not use this file except in compliance with the License. | |||||
| You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| @ -0,0 +1,45 @@ | |||||
| C++ version of the libphonenumber project. | |||||
| Work in progress. | |||||
| This is a port of the Java version. | |||||
| This project uses some third-party code: | |||||
| - src/base/ sources come from Chromium browser. | |||||
| - src/utf/ sources come from lib9 which is also used in Go. | |||||
| Requirements: | |||||
| - CMake build system | |||||
| http://www.cmake.org | |||||
| You can install it very easily on a Debian-based GNU/Linux distribution: | |||||
| $ sudo apt-get install cmake | |||||
| - RE2 | |||||
| http://code.google.com/p/re2/ | |||||
| You can install it very easily on Ubuntu Maverick and later: | |||||
| $ sudo apt-get install libre2-dev | |||||
| Otherwise if you use a Debian-based distribution you can fetch the Ubuntu | |||||
| package which should work: | |||||
| http://packages.ubuntu.com/maverick/libre2-dev | |||||
| If you want to install it manually: | |||||
| You need Mercurial to checkout its source code: | |||||
| $ sudo apt-get install mercurial | |||||
| Then checkout, build and install it: | |||||
| $ hg clone https://re2.googlecode.com/hg re2 | |||||
| $ cd re2 | |||||
| $ make test | |||||
| $ make install | |||||
| $ make testinstall | |||||
| How to build libphonenumber C++: | |||||
| $ cd libphonenumber | |||||
| $ mkdir build | |||||
| $ cd build | |||||
| $ cmake .. | |||||
| $ make | |||||
| @ -0,0 +1,67 @@ | |||||
| // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #include "base/at_exit.h" | |||||
| #include "base/logging.h" | |||||
| namespace base { | |||||
| // Keep a stack of registered AtExitManagers. We always operate on the most | |||||
| // recent, and we should never have more than one outside of testing, when we | |||||
| // use the shadow version of the constructor. We don't protect this for | |||||
| // thread-safe access, since it will only be modified in testing. | |||||
| static AtExitManager* g_top_manager = NULL; | |||||
| AtExitManager::AtExitManager() : next_manager_(NULL) { | |||||
| DCHECK(!g_top_manager); | |||||
| g_top_manager = this; | |||||
| } | |||||
| AtExitManager::~AtExitManager() { | |||||
| if (!g_top_manager) { | |||||
| NOTREACHED() << "Tried to ~AtExitManager without an AtExitManager"; | |||||
| return; | |||||
| } | |||||
| DCHECK(g_top_manager == this); | |||||
| ProcessCallbacksNow(); | |||||
| g_top_manager = next_manager_; | |||||
| } | |||||
| // static | |||||
| void AtExitManager::RegisterCallback(AtExitCallbackType func, void* param) { | |||||
| if (!g_top_manager) { | |||||
| NOTREACHED() << "Tried to RegisterCallback without an AtExitManager"; | |||||
| return; | |||||
| } | |||||
| DCHECK(func); | |||||
| AutoLock lock(g_top_manager->lock_); | |||||
| g_top_manager->stack_.push(CallbackAndParam(func, param)); | |||||
| } | |||||
| // static | |||||
| void AtExitManager::ProcessCallbacksNow() { | |||||
| if (!g_top_manager) { | |||||
| NOTREACHED() << "Tried to ProcessCallbacksNow without an AtExitManager"; | |||||
| return; | |||||
| } | |||||
| AutoLock lock(g_top_manager->lock_); | |||||
| while (!g_top_manager->stack_.empty()) { | |||||
| CallbackAndParam callback_and_param = g_top_manager->stack_.top(); | |||||
| g_top_manager->stack_.pop(); | |||||
| callback_and_param.func_(callback_and_param.param_); | |||||
| } | |||||
| } | |||||
| AtExitManager::AtExitManager(bool shadow) : next_manager_(g_top_manager) { | |||||
| DCHECK(shadow || !g_top_manager); | |||||
| g_top_manager = this; | |||||
| } | |||||
| } // namespace base | |||||
| @ -0,0 +1,79 @@ | |||||
| // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #ifndef BASE_AT_EXIT_H_ | |||||
| #define BASE_AT_EXIT_H_ | |||||
| #pragma once | |||||
| #include <stack> | |||||
| #include "base/basictypes.h" | |||||
| #include "base/synchronization/lock.h" | |||||
| namespace base { | |||||
| // This class provides a facility similar to the CRT atexit(), except that | |||||
| // we control when the callbacks are executed. Under Windows for a DLL they | |||||
| // happen at a really bad time and under the loader lock. This facility is | |||||
| // mostly used by base::Singleton. | |||||
| // | |||||
| // The usage is simple. Early in the main() or WinMain() scope create an | |||||
| // AtExitManager object on the stack: | |||||
| // int main(...) { | |||||
| // base::AtExitManager exit_manager; | |||||
| // | |||||
| // } | |||||
| // When the exit_manager object goes out of scope, all the registered | |||||
| // callbacks and singleton destructors will be called. | |||||
| class AtExitManager { | |||||
| public: | |||||
| typedef void (*AtExitCallbackType)(void*); | |||||
| AtExitManager(); | |||||
| // The dtor calls all the registered callbacks. Do not try to register more | |||||
| // callbacks after this point. | |||||
| ~AtExitManager(); | |||||
| // Registers the specified function to be called at exit. The prototype of | |||||
| // the callback function is void func(). | |||||
| static void RegisterCallback(AtExitCallbackType func, void* param); | |||||
| // Calls the functions registered with RegisterCallback in LIFO order. It | |||||
| // is possible to register new callbacks after calling this function. | |||||
| static void ProcessCallbacksNow(); | |||||
| protected: | |||||
| // This constructor will allow this instance of AtExitManager to be created | |||||
| // even if one already exists. This should only be used for testing! | |||||
| // AtExitManagers are kept on a global stack, and it will be removed during | |||||
| // destruction. This allows you to shadow another AtExitManager. | |||||
| explicit AtExitManager(bool shadow); | |||||
| private: | |||||
| struct CallbackAndParam { | |||||
| CallbackAndParam(AtExitCallbackType func, void* param) | |||||
| : func_(func), param_(param) { } | |||||
| AtExitCallbackType func_; | |||||
| void* param_; | |||||
| }; | |||||
| base::Lock lock_; | |||||
| std::stack<CallbackAndParam> stack_; | |||||
| AtExitManager* next_manager_; // Stack of managers to allow shadowing. | |||||
| DISALLOW_COPY_AND_ASSIGN(AtExitManager); | |||||
| }; | |||||
| #if defined(UNIT_TEST) | |||||
| class ShadowingAtExitManager : public AtExitManager { | |||||
| public: | |||||
| ShadowingAtExitManager() : AtExitManager(true) {} | |||||
| }; | |||||
| #endif // defined(UNIT_TEST) | |||||
| } // namespace base | |||||
| #endif // BASE_AT_EXIT_H_ | |||||
| @ -0,0 +1,148 @@ | |||||
| // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| // For atomic operations on reference counts, see atomic_refcount.h. | |||||
| // For atomic operations on sequence numbers, see atomic_sequence_num.h. | |||||
| // The routines exported by this module are subtle. If you use them, even if | |||||
| // you get the code right, it will depend on careful reasoning about atomicity | |||||
| // and memory ordering; it will be less readable, and harder to maintain. If | |||||
| // you plan to use these routines, you should have a good reason, such as solid | |||||
| // evidence that performance would otherwise suffer, or there being no | |||||
| // alternative. You should assume only properties explicitly guaranteed by the | |||||
| // specifications in this file. You are almost certainly _not_ writing code | |||||
| // just for the x86; if you assume x86 semantics, x86 hardware bugs and | |||||
| // implementations on other archtectures will cause your code to break. If you | |||||
| // do not know what you are doing, avoid these routines, and use a Mutex. | |||||
| // | |||||
| // It is incorrect to make direct assignments to/from an atomic variable. | |||||
| // You should use one of the Load or Store routines. The NoBarrier | |||||
| // versions are provided when no barriers are needed: | |||||
| // NoBarrier_Store() | |||||
| // NoBarrier_Load() | |||||
| // Although there are currently no compiler enforcement, you are encouraged | |||||
| // to use these. | |||||
| // | |||||
| #ifndef BASE_ATOMICOPS_H_ | |||||
| #define BASE_ATOMICOPS_H_ | |||||
| #pragma once | |||||
| #include "base/basictypes.h" | |||||
| #include "base/port.h" | |||||
| namespace base { | |||||
| namespace subtle { | |||||
| // Bug 1308991. We need this for /Wp64, to mark it safe for AtomicWord casting. | |||||
| #ifndef OS_WIN | |||||
| #define __w64 | |||||
| #endif | |||||
| typedef __w64 int32 Atomic32; | |||||
| #ifdef ARCH_CPU_64_BITS | |||||
| // We need to be able to go between Atomic64 and AtomicWord implicitly. This | |||||
| // means Atomic64 and AtomicWord should be the same type on 64-bit. | |||||
| #if defined(OS_NACL) | |||||
| // NaCl's intptr_t is not actually 64-bits on 64-bit! | |||||
| // http://code.google.com/p/nativeclient/issues/detail?id=1162 | |||||
| typedef int64_t Atomic64; | |||||
| #else | |||||
| typedef intptr_t Atomic64; | |||||
| #endif | |||||
| #endif | |||||
| // Use AtomicWord for a machine-sized pointer. It will use the Atomic32 or | |||||
| // Atomic64 routines below, depending on your architecture. | |||||
| typedef intptr_t AtomicWord; | |||||
| // Atomically execute: | |||||
| // result = *ptr; | |||||
| // if (*ptr == old_value) | |||||
| // *ptr = new_value; | |||||
| // return result; | |||||
| // | |||||
| // I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value". | |||||
| // Always return the old value of "*ptr" | |||||
| // | |||||
| // This routine implies no memory barriers. | |||||
| Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, | |||||
| Atomic32 old_value, | |||||
| Atomic32 new_value); | |||||
| // Atomically store new_value into *ptr, returning the previous value held in | |||||
| // *ptr. This routine implies no memory barriers. | |||||
| Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value); | |||||
| // Atomically increment *ptr by "increment". Returns the new value of | |||||
| // *ptr with the increment applied. This routine implies no memory barriers. | |||||
| Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment); | |||||
| Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, | |||||
| Atomic32 increment); | |||||
| // These following lower-level operations are typically useful only to people | |||||
| // implementing higher-level synchronization operations like spinlocks, | |||||
| // mutexes, and condition-variables. They combine CompareAndSwap(), a load, or | |||||
| // a store with appropriate memory-ordering instructions. "Acquire" operations | |||||
| // ensure that no later memory access can be reordered ahead of the operation. | |||||
| // "Release" operations ensure that no previous memory access can be reordered | |||||
| // after the operation. "Barrier" operations have both "Acquire" and "Release" | |||||
| // semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory | |||||
| // access. | |||||
| Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, | |||||
| Atomic32 old_value, | |||||
| Atomic32 new_value); | |||||
| Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, | |||||
| Atomic32 old_value, | |||||
| Atomic32 new_value); | |||||
| void MemoryBarrier(); | |||||
| void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value); | |||||
| void Acquire_Store(volatile Atomic32* ptr, Atomic32 value); | |||||
| void Release_Store(volatile Atomic32* ptr, Atomic32 value); | |||||
| Atomic32 NoBarrier_Load(volatile const Atomic32* ptr); | |||||
| Atomic32 Acquire_Load(volatile const Atomic32* ptr); | |||||
| Atomic32 Release_Load(volatile const Atomic32* ptr); | |||||
| // 64-bit atomic operations (only available on 64-bit processors). | |||||
| #ifdef ARCH_CPU_64_BITS | |||||
| Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, | |||||
| Atomic64 old_value, | |||||
| Atomic64 new_value); | |||||
| Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value); | |||||
| Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment); | |||||
| Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment); | |||||
| Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, | |||||
| Atomic64 old_value, | |||||
| Atomic64 new_value); | |||||
| Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, | |||||
| Atomic64 old_value, | |||||
| Atomic64 new_value); | |||||
| void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value); | |||||
| void Acquire_Store(volatile Atomic64* ptr, Atomic64 value); | |||||
| void Release_Store(volatile Atomic64* ptr, Atomic64 value); | |||||
| Atomic64 NoBarrier_Load(volatile const Atomic64* ptr); | |||||
| Atomic64 Acquire_Load(volatile const Atomic64* ptr); | |||||
| Atomic64 Release_Load(volatile const Atomic64* ptr); | |||||
| #endif // ARCH_CPU_64_BITS | |||||
| } // namespace base::subtle | |||||
| } // namespace base | |||||
| // Include our platform specific implementation. | |||||
| #if defined(OS_WIN) && defined(COMPILER_MSVC) && defined(ARCH_CPU_X86_FAMILY) | |||||
| #include "base/atomicops_internals_x86_msvc.h" | |||||
| #elif defined(OS_MACOSX) && defined(ARCH_CPU_X86_FAMILY) | |||||
| #include "base/atomicops_internals_x86_macosx.h" | |||||
| #elif defined(COMPILER_GCC) && defined(ARCH_CPU_X86_FAMILY) | |||||
| #include "base/atomicops_internals_x86_gcc.h" | |||||
| #elif defined(COMPILER_GCC) && defined(ARCH_CPU_ARM_FAMILY) | |||||
| #include "base/atomicops_internals_arm_gcc.h" | |||||
| #else | |||||
| #error "Atomic operations are not supported on your platform" | |||||
| #endif | |||||
| #endif // BASE_ATOMICOPS_H_ | |||||
| @ -0,0 +1,125 @@ | |||||
| // Copyright (c) 2009 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| // This file is an internal atomic implementation, use base/atomicops.h instead. | |||||
| // | |||||
| // LinuxKernelCmpxchg and Barrier_AtomicIncrement are from Google Gears. | |||||
| #ifndef BASE_ATOMICOPS_INTERNALS_ARM_GCC_H_ | |||||
| #define BASE_ATOMICOPS_INTERNALS_ARM_GCC_H_ | |||||
| #pragma once | |||||
| namespace base { | |||||
| namespace subtle { | |||||
| // 0xffff0fc0 is the hard coded address of a function provided by | |||||
| // the kernel which implements an atomic compare-exchange. On older | |||||
| // ARM architecture revisions (pre-v6) this may be implemented using | |||||
| // a syscall. This address is stable, and in active use (hard coded) | |||||
| // by at least glibc-2.7 and the Android C library. | |||||
| typedef Atomic32 (*LinuxKernelCmpxchgFunc)(Atomic32 old_value, | |||||
| Atomic32 new_value, | |||||
| volatile Atomic32* ptr); | |||||
| LinuxKernelCmpxchgFunc pLinuxKernelCmpxchg __attribute__((weak)) = | |||||
| (LinuxKernelCmpxchgFunc) 0xffff0fc0; | |||||
| typedef void (*LinuxKernelMemoryBarrierFunc)(void); | |||||
| LinuxKernelMemoryBarrierFunc pLinuxKernelMemoryBarrier __attribute__((weak)) = | |||||
| (LinuxKernelMemoryBarrierFunc) 0xffff0fa0; | |||||
| inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, | |||||
| Atomic32 old_value, | |||||
| Atomic32 new_value) { | |||||
| Atomic32 prev_value = *ptr; | |||||
| do { | |||||
| if (!pLinuxKernelCmpxchg(old_value, new_value, | |||||
| const_cast<Atomic32*>(ptr))) { | |||||
| return old_value; | |||||
| } | |||||
| prev_value = *ptr; | |||||
| } while (prev_value == old_value); | |||||
| return prev_value; | |||||
| } | |||||
| inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, | |||||
| Atomic32 new_value) { | |||||
| Atomic32 old_value; | |||||
| do { | |||||
| old_value = *ptr; | |||||
| } while (pLinuxKernelCmpxchg(old_value, new_value, | |||||
| const_cast<Atomic32*>(ptr))); | |||||
| return old_value; | |||||
| } | |||||
| inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, | |||||
| Atomic32 increment) { | |||||
| return Barrier_AtomicIncrement(ptr, increment); | |||||
| } | |||||
| inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, | |||||
| Atomic32 increment) { | |||||
| for (;;) { | |||||
| // Atomic exchange the old value with an incremented one. | |||||
| Atomic32 old_value = *ptr; | |||||
| Atomic32 new_value = old_value + increment; | |||||
| if (pLinuxKernelCmpxchg(old_value, new_value, | |||||
| const_cast<Atomic32*>(ptr)) == 0) { | |||||
| // The exchange took place as expected. | |||||
| return new_value; | |||||
| } | |||||
| // Otherwise, *ptr changed mid-loop and we need to retry. | |||||
| } | |||||
| } | |||||
| inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, | |||||
| Atomic32 old_value, | |||||
| Atomic32 new_value) { | |||||
| return NoBarrier_CompareAndSwap(ptr, old_value, new_value); | |||||
| } | |||||
| inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, | |||||
| Atomic32 old_value, | |||||
| Atomic32 new_value) { | |||||
| return NoBarrier_CompareAndSwap(ptr, old_value, new_value); | |||||
| } | |||||
| inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { | |||||
| *ptr = value; | |||||
| } | |||||
| inline void MemoryBarrier() { | |||||
| pLinuxKernelMemoryBarrier(); | |||||
| } | |||||
| inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { | |||||
| *ptr = value; | |||||
| MemoryBarrier(); | |||||
| } | |||||
| inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { | |||||
| MemoryBarrier(); | |||||
| *ptr = value; | |||||
| } | |||||
| inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { | |||||
| return *ptr; | |||||
| } | |||||
| inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { | |||||
| Atomic32 value = *ptr; | |||||
| MemoryBarrier(); | |||||
| return value; | |||||
| } | |||||
| inline Atomic32 Release_Load(volatile const Atomic32* ptr) { | |||||
| MemoryBarrier(); | |||||
| return *ptr; | |||||
| } | |||||
| } // namespace base::subtle | |||||
| } // namespace base | |||||
| #endif // BASE_ATOMICOPS_INTERNALS_ARM_GCC_H_ | |||||
| @ -0,0 +1,104 @@ | |||||
| // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| // This module gets enough CPU information to optimize the | |||||
| // atomicops module on x86. | |||||
| #include <string.h> | |||||
| #include "base/atomicops.h" | |||||
| #include "base/basictypes.h" | |||||
| // This file only makes sense with atomicops_internals_x86_gcc.h -- it | |||||
| // depends on structs that are defined in that file. If atomicops.h | |||||
| // doesn't sub-include that file, then we aren't needed, and shouldn't | |||||
| // try to do anything. | |||||
| #ifdef BASE_ATOMICOPS_INTERNALS_X86_GCC_H_ | |||||
| // Inline cpuid instruction. In PIC compilations, %ebx contains the address | |||||
| // of the global offset table. To avoid breaking such executables, this code | |||||
| // must preserve that register's value across cpuid instructions. | |||||
| #if defined(__i386__) | |||||
| #define cpuid(a, b, c, d, inp) \ | |||||
| asm ("mov %%ebx, %%edi\n" \ | |||||
| "cpuid\n" \ | |||||
| "xchg %%edi, %%ebx\n" \ | |||||
| : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp)) | |||||
| #elif defined (__x86_64__) | |||||
| #define cpuid(a, b, c, d, inp) \ | |||||
| asm ("mov %%rbx, %%rdi\n" \ | |||||
| "cpuid\n" \ | |||||
| "xchg %%rdi, %%rbx\n" \ | |||||
| : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp)) | |||||
| #endif | |||||
| #if defined(cpuid) // initialize the struct only on x86 | |||||
| // Set the flags so that code will run correctly and conservatively, so even | |||||
| // if we haven't been initialized yet, we're probably single threaded, and our | |||||
| // default values should hopefully be pretty safe. | |||||
| struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures = { | |||||
| false, // bug can't exist before process spawns multiple threads | |||||
| false, // no SSE2 | |||||
| }; | |||||
| // Initialize the AtomicOps_Internalx86CPUFeatures struct. | |||||
| static void AtomicOps_Internalx86CPUFeaturesInit() { | |||||
| uint32 eax; | |||||
| uint32 ebx; | |||||
| uint32 ecx; | |||||
| uint32 edx; | |||||
| // Get vendor string (issue CPUID with eax = 0) | |||||
| cpuid(eax, ebx, ecx, edx, 0); | |||||
| char vendor[13]; | |||||
| memcpy(vendor, &ebx, 4); | |||||
| memcpy(vendor + 4, &edx, 4); | |||||
| memcpy(vendor + 8, &ecx, 4); | |||||
| vendor[12] = 0; | |||||
| // get feature flags in ecx/edx, and family/model in eax | |||||
| cpuid(eax, ebx, ecx, edx, 1); | |||||
| int family = (eax >> 8) & 0xf; // family and model fields | |||||
| int model = (eax >> 4) & 0xf; | |||||
| if (family == 0xf) { // use extended family and model fields | |||||
| family += (eax >> 20) & 0xff; | |||||
| model += ((eax >> 16) & 0xf) << 4; | |||||
| } | |||||
| // Opteron Rev E has a bug in which on very rare occasions a locked | |||||
| // instruction doesn't act as a read-acquire barrier if followed by a | |||||
| // non-locked read-modify-write instruction. Rev F has this bug in | |||||
| // pre-release versions, but not in versions released to customers, | |||||
| // so we test only for Rev E, which is family 15, model 32..63 inclusive. | |||||
| if (strcmp(vendor, "AuthenticAMD") == 0 && // AMD | |||||
| family == 15 && | |||||
| 32 <= model && model <= 63) { | |||||
| AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = true; | |||||
| } else { | |||||
| AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = false; | |||||
| } | |||||
| // edx bit 26 is SSE2 which we use to tell use whether we can use mfence | |||||
| AtomicOps_Internalx86CPUFeatures.has_sse2 = ((edx >> 26) & 1); | |||||
| } | |||||
| namespace { | |||||
| class AtomicOpsx86Initializer { | |||||
| public: | |||||
| AtomicOpsx86Initializer() { | |||||
| AtomicOps_Internalx86CPUFeaturesInit(); | |||||
| } | |||||
| }; | |||||
| // A global to get use initialized on startup via static initialization :/ | |||||
| AtomicOpsx86Initializer g_initer; | |||||
| } // namespace | |||||
| #endif // if x86 | |||||
| #endif // ifdef BASE_ATOMICOPS_INTERNALS_X86_GCC_H_ | |||||
| @ -0,0 +1,266 @@ | |||||
| // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| // This file is an internal atomic implementation, use base/atomicops.h instead. | |||||
| #ifndef BASE_ATOMICOPS_INTERNALS_X86_GCC_H_ | |||||
| #define BASE_ATOMICOPS_INTERNALS_X86_GCC_H_ | |||||
| #pragma once | |||||
| // This struct is not part of the public API of this module; clients may not | |||||
| // use it. | |||||
| // Features of this x86. Values may not be correct before main() is run, | |||||
| // but are set conservatively. | |||||
| struct AtomicOps_x86CPUFeatureStruct { | |||||
| bool has_amd_lock_mb_bug; // Processor has AMD memory-barrier bug; do lfence | |||||
| // after acquire compare-and-swap. | |||||
| bool has_sse2; // Processor has SSE2. | |||||
| }; | |||||
| extern struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures; | |||||
| #define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory") | |||||
| namespace base { | |||||
| namespace subtle { | |||||
| // 32-bit low-level operations on any platform. | |||||
| inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, | |||||
| Atomic32 old_value, | |||||
| Atomic32 new_value) { | |||||
| Atomic32 prev; | |||||
| __asm__ __volatile__("lock; cmpxchgl %1,%2" | |||||
| : "=a" (prev) | |||||
| : "q" (new_value), "m" (*ptr), "0" (old_value) | |||||
| : "memory"); | |||||
| return prev; | |||||
| } | |||||
| inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, | |||||
| Atomic32 new_value) { | |||||
| __asm__ __volatile__("xchgl %1,%0" // The lock prefix is implicit for xchg. | |||||
| : "=r" (new_value) | |||||
| : "m" (*ptr), "0" (new_value) | |||||
| : "memory"); | |||||
| return new_value; // Now it's the previous value. | |||||
| } | |||||
| inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, | |||||
| Atomic32 increment) { | |||||
| Atomic32 temp = increment; | |||||
| __asm__ __volatile__("lock; xaddl %0,%1" | |||||
| : "+r" (temp), "+m" (*ptr) | |||||
| : : "memory"); | |||||
| // temp now holds the old value of *ptr | |||||
| return temp + increment; | |||||
| } | |||||
| inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, | |||||
| Atomic32 increment) { | |||||
| Atomic32 temp = increment; | |||||
| __asm__ __volatile__("lock; xaddl %0,%1" | |||||
| : "+r" (temp), "+m" (*ptr) | |||||
| : : "memory"); | |||||
| // temp now holds the old value of *ptr | |||||
| if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) { | |||||
| __asm__ __volatile__("lfence" : : : "memory"); | |||||
| } | |||||
| return temp + increment; | |||||
| } | |||||
| inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, | |||||
| Atomic32 old_value, | |||||
| Atomic32 new_value) { | |||||
| Atomic32 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value); | |||||
| if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) { | |||||
| __asm__ __volatile__("lfence" : : : "memory"); | |||||
| } | |||||
| return x; | |||||
| } | |||||
| inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, | |||||
| Atomic32 old_value, | |||||
| Atomic32 new_value) { | |||||
| return NoBarrier_CompareAndSwap(ptr, old_value, new_value); | |||||
| } | |||||
| inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { | |||||
| *ptr = value; | |||||
| } | |||||
| #if defined(__x86_64__) | |||||
| // 64-bit implementations of memory barrier can be simpler, because it | |||||
| // "mfence" is guaranteed to exist. | |||||
| inline void MemoryBarrier() { | |||||
| __asm__ __volatile__("mfence" : : : "memory"); | |||||
| } | |||||
| inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { | |||||
| *ptr = value; | |||||
| MemoryBarrier(); | |||||
| } | |||||
| #else | |||||
| inline void MemoryBarrier() { | |||||
| if (AtomicOps_Internalx86CPUFeatures.has_sse2) { | |||||
| __asm__ __volatile__("mfence" : : : "memory"); | |||||
| } else { // mfence is faster but not present on PIII | |||||
| Atomic32 x = 0; | |||||
| NoBarrier_AtomicExchange(&x, 0); // acts as a barrier on PIII | |||||
| } | |||||
| } | |||||
| inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { | |||||
| if (AtomicOps_Internalx86CPUFeatures.has_sse2) { | |||||
| *ptr = value; | |||||
| __asm__ __volatile__("mfence" : : : "memory"); | |||||
| } else { | |||||
| NoBarrier_AtomicExchange(ptr, value); | |||||
| // acts as a barrier on PIII | |||||
| } | |||||
| } | |||||
| #endif | |||||
| inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { | |||||
| ATOMICOPS_COMPILER_BARRIER(); | |||||
| *ptr = value; // An x86 store acts as a release barrier. | |||||
| // See comments in Atomic64 version of Release_Store(), below. | |||||
| } | |||||
| inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { | |||||
| return *ptr; | |||||
| } | |||||
| inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { | |||||
| Atomic32 value = *ptr; // An x86 load acts as a acquire barrier. | |||||
| // See comments in Atomic64 version of Release_Store(), below. | |||||
| ATOMICOPS_COMPILER_BARRIER(); | |||||
| return value; | |||||
| } | |||||
| inline Atomic32 Release_Load(volatile const Atomic32* ptr) { | |||||
| MemoryBarrier(); | |||||
| return *ptr; | |||||
| } | |||||
| #if defined(__x86_64__) | |||||
| // 64-bit low-level operations on 64-bit platform. | |||||
| inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, | |||||
| Atomic64 old_value, | |||||
| Atomic64 new_value) { | |||||
| Atomic64 prev; | |||||
| __asm__ __volatile__("lock; cmpxchgq %1,%2" | |||||
| : "=a" (prev) | |||||
| : "q" (new_value), "m" (*ptr), "0" (old_value) | |||||
| : "memory"); | |||||
| return prev; | |||||
| } | |||||
| inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, | |||||
| Atomic64 new_value) { | |||||
| __asm__ __volatile__("xchgq %1,%0" // The lock prefix is implicit for xchg. | |||||
| : "=r" (new_value) | |||||
| : "m" (*ptr), "0" (new_value) | |||||
| : "memory"); | |||||
| return new_value; // Now it's the previous value. | |||||
| } | |||||
| inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, | |||||
| Atomic64 increment) { | |||||
| Atomic64 temp = increment; | |||||
| __asm__ __volatile__("lock; xaddq %0,%1" | |||||
| : "+r" (temp), "+m" (*ptr) | |||||
| : : "memory"); | |||||
| // temp now contains the previous value of *ptr | |||||
| return temp + increment; | |||||
| } | |||||
| inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, | |||||
| Atomic64 increment) { | |||||
| Atomic64 temp = increment; | |||||
| __asm__ __volatile__("lock; xaddq %0,%1" | |||||
| : "+r" (temp), "+m" (*ptr) | |||||
| : : "memory"); | |||||
| // temp now contains the previous value of *ptr | |||||
| if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) { | |||||
| __asm__ __volatile__("lfence" : : : "memory"); | |||||
| } | |||||
| return temp + increment; | |||||
| } | |||||
| inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { | |||||
| *ptr = value; | |||||
| } | |||||
| inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { | |||||
| *ptr = value; | |||||
| MemoryBarrier(); | |||||
| } | |||||
| inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { | |||||
| ATOMICOPS_COMPILER_BARRIER(); | |||||
| *ptr = value; // An x86 store acts as a release barrier | |||||
| // for current AMD/Intel chips as of Jan 2008. | |||||
| // See also Acquire_Load(), below. | |||||
| // When new chips come out, check: | |||||
| // IA-32 Intel Architecture Software Developer's Manual, Volume 3: | |||||
| // System Programming Guide, Chatper 7: Multiple-processor management, | |||||
| // Section 7.2, Memory Ordering. | |||||
| // Last seen at: | |||||
| // http://developer.intel.com/design/pentium4/manuals/index_new.htm | |||||
| // | |||||
| // x86 stores/loads fail to act as barriers for a few instructions (clflush | |||||
| // maskmovdqu maskmovq movntdq movnti movntpd movntps movntq) but these are | |||||
| // not generated by the compiler, and are rare. Users of these instructions | |||||
| // need to know about cache behaviour in any case since all of these involve | |||||
| // either flushing cache lines or non-temporal cache hints. | |||||
| } | |||||
| inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { | |||||
| return *ptr; | |||||
| } | |||||
| inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { | |||||
| Atomic64 value = *ptr; // An x86 load acts as a acquire barrier, | |||||
| // for current AMD/Intel chips as of Jan 2008. | |||||
| // See also Release_Store(), above. | |||||
| ATOMICOPS_COMPILER_BARRIER(); | |||||
| return value; | |||||
| } | |||||
| inline Atomic64 Release_Load(volatile const Atomic64* ptr) { | |||||
| MemoryBarrier(); | |||||
| return *ptr; | |||||
| } | |||||
| inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, | |||||
| Atomic64 old_value, | |||||
| Atomic64 new_value) { | |||||
| Atomic64 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value); | |||||
| if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) { | |||||
| __asm__ __volatile__("lfence" : : : "memory"); | |||||
| } | |||||
| return x; | |||||
| } | |||||
| inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, | |||||
| Atomic64 old_value, | |||||
| Atomic64 new_value) { | |||||
| return NoBarrier_CompareAndSwap(ptr, old_value, new_value); | |||||
| } | |||||
| #endif // defined(__x86_64__) | |||||
| } // namespace base::subtle | |||||
| } // namespace base | |||||
| #undef ATOMICOPS_COMPILER_BARRIER | |||||
| #endif // BASE_ATOMICOPS_INTERNALS_X86_GCC_H_ | |||||
| @ -0,0 +1,281 @@ | |||||
| // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| // This file is an internal atomic implementation, use base/atomicops.h instead. | |||||
| #ifndef BASE_ATOMICOPS_INTERNALS_X86_MACOSX_H_ | |||||
| #define BASE_ATOMICOPS_INTERNALS_X86_MACOSX_H_ | |||||
| #pragma once | |||||
| #include <libkern/OSAtomic.h> | |||||
| namespace base { | |||||
| namespace subtle { | |||||
| inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr, | |||||
| Atomic32 old_value, | |||||
| Atomic32 new_value) { | |||||
| Atomic32 prev_value; | |||||
| do { | |||||
| if (OSAtomicCompareAndSwap32(old_value, new_value, | |||||
| const_cast<Atomic32*>(ptr))) { | |||||
| return old_value; | |||||
| } | |||||
| prev_value = *ptr; | |||||
| } while (prev_value == old_value); | |||||
| return prev_value; | |||||
| } | |||||
| inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr, | |||||
| Atomic32 new_value) { | |||||
| Atomic32 old_value; | |||||
| do { | |||||
| old_value = *ptr; | |||||
| } while (!OSAtomicCompareAndSwap32(old_value, new_value, | |||||
| const_cast<Atomic32*>(ptr))); | |||||
| return old_value; | |||||
| } | |||||
| inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr, | |||||
| Atomic32 increment) { | |||||
| return OSAtomicAdd32(increment, const_cast<Atomic32*>(ptr)); | |||||
| } | |||||
| inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32 *ptr, | |||||
| Atomic32 increment) { | |||||
| return OSAtomicAdd32Barrier(increment, const_cast<Atomic32*>(ptr)); | |||||
| } | |||||
| inline void MemoryBarrier() { | |||||
| OSMemoryBarrier(); | |||||
| } | |||||
| inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr, | |||||
| Atomic32 old_value, | |||||
| Atomic32 new_value) { | |||||
| Atomic32 prev_value; | |||||
| do { | |||||
| if (OSAtomicCompareAndSwap32Barrier(old_value, new_value, | |||||
| const_cast<Atomic32*>(ptr))) { | |||||
| return old_value; | |||||
| } | |||||
| prev_value = *ptr; | |||||
| } while (prev_value == old_value); | |||||
| return prev_value; | |||||
| } | |||||
| inline Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr, | |||||
| Atomic32 old_value, | |||||
| Atomic32 new_value) { | |||||
| return Acquire_CompareAndSwap(ptr, old_value, new_value); | |||||
| } | |||||
| inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { | |||||
| *ptr = value; | |||||
| } | |||||
| inline void Acquire_Store(volatile Atomic32 *ptr, Atomic32 value) { | |||||
| *ptr = value; | |||||
| MemoryBarrier(); | |||||
| } | |||||
| inline void Release_Store(volatile Atomic32 *ptr, Atomic32 value) { | |||||
| MemoryBarrier(); | |||||
| *ptr = value; | |||||
| } | |||||
| inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { | |||||
| return *ptr; | |||||
| } | |||||
| inline Atomic32 Acquire_Load(volatile const Atomic32 *ptr) { | |||||
| Atomic32 value = *ptr; | |||||
| MemoryBarrier(); | |||||
| return value; | |||||
| } | |||||
| inline Atomic32 Release_Load(volatile const Atomic32 *ptr) { | |||||
| MemoryBarrier(); | |||||
| return *ptr; | |||||
| } | |||||
| #ifdef __LP64__ | |||||
| // 64-bit implementation on 64-bit platform | |||||
| inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64 *ptr, | |||||
| Atomic64 old_value, | |||||
| Atomic64 new_value) { | |||||
| Atomic64 prev_value; | |||||
| do { | |||||
| if (OSAtomicCompareAndSwap64(old_value, new_value, | |||||
| reinterpret_cast<volatile int64_t*>(ptr))) { | |||||
| return old_value; | |||||
| } | |||||
| prev_value = *ptr; | |||||
| } while (prev_value == old_value); | |||||
| return prev_value; | |||||
| } | |||||
| inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64 *ptr, | |||||
| Atomic64 new_value) { | |||||
| Atomic64 old_value; | |||||
| do { | |||||
| old_value = *ptr; | |||||
| } while (!OSAtomicCompareAndSwap64(old_value, new_value, | |||||
| reinterpret_cast<volatile int64_t*>(ptr))); | |||||
| return old_value; | |||||
| } | |||||
| inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64 *ptr, | |||||
| Atomic64 increment) { | |||||
| return OSAtomicAdd64(increment, reinterpret_cast<volatile int64_t*>(ptr)); | |||||
| } | |||||
| inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64 *ptr, | |||||
| Atomic64 increment) { | |||||
| return OSAtomicAdd64Barrier(increment, | |||||
| reinterpret_cast<volatile int64_t*>(ptr)); | |||||
| } | |||||
| inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64 *ptr, | |||||
| Atomic64 old_value, | |||||
| Atomic64 new_value) { | |||||
| Atomic64 prev_value; | |||||
| do { | |||||
| if (OSAtomicCompareAndSwap64Barrier( | |||||
| old_value, new_value, reinterpret_cast<volatile int64_t*>(ptr))) { | |||||
| return old_value; | |||||
| } | |||||
| prev_value = *ptr; | |||||
| } while (prev_value == old_value); | |||||
| return prev_value; | |||||
| } | |||||
| inline Atomic64 Release_CompareAndSwap(volatile Atomic64 *ptr, | |||||
| Atomic64 old_value, | |||||
| Atomic64 new_value) { | |||||
| // The lib kern interface does not distinguish between | |||||
| // Acquire and Release memory barriers; they are equivalent. | |||||
| return Acquire_CompareAndSwap(ptr, old_value, new_value); | |||||
| } | |||||
| inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { | |||||
| *ptr = value; | |||||
| } | |||||
| inline void Acquire_Store(volatile Atomic64 *ptr, Atomic64 value) { | |||||
| *ptr = value; | |||||
| MemoryBarrier(); | |||||
| } | |||||
| inline void Release_Store(volatile Atomic64 *ptr, Atomic64 value) { | |||||
| MemoryBarrier(); | |||||
| *ptr = value; | |||||
| } | |||||
| inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { | |||||
| return *ptr; | |||||
| } | |||||
| inline Atomic64 Acquire_Load(volatile const Atomic64 *ptr) { | |||||
| Atomic64 value = *ptr; | |||||
| MemoryBarrier(); | |||||
| return value; | |||||
| } | |||||
| inline Atomic64 Release_Load(volatile const Atomic64 *ptr) { | |||||
| MemoryBarrier(); | |||||
| return *ptr; | |||||
| } | |||||
| #endif // defined(__LP64__) | |||||
| // MacOS uses long for intptr_t, AtomicWord and Atomic32 are always different | |||||
| // on the Mac, even when they are the same size. We need to explicitly cast | |||||
| // from AtomicWord to Atomic32 to implement the AtomicWord interface. | |||||
| // When in 64-bit mode, AtomicWord is the same as Atomic64, so we need not | |||||
| // add duplicate definitions. | |||||
| #ifndef __LP64__ | |||||
| #define AtomicWordCastType Atomic32 | |||||
| inline AtomicWord NoBarrier_CompareAndSwap(volatile AtomicWord* ptr, | |||||
| AtomicWord old_value, | |||||
| AtomicWord new_value) { | |||||
| return NoBarrier_CompareAndSwap( | |||||
| reinterpret_cast<volatile AtomicWordCastType*>(ptr), | |||||
| old_value, new_value); | |||||
| } | |||||
| inline AtomicWord NoBarrier_AtomicExchange(volatile AtomicWord* ptr, | |||||
| AtomicWord new_value) { | |||||
| return NoBarrier_AtomicExchange( | |||||
| reinterpret_cast<volatile AtomicWordCastType*>(ptr), new_value); | |||||
| } | |||||
| inline AtomicWord NoBarrier_AtomicIncrement(volatile AtomicWord* ptr, | |||||
| AtomicWord increment) { | |||||
| return NoBarrier_AtomicIncrement( | |||||
| reinterpret_cast<volatile AtomicWordCastType*>(ptr), increment); | |||||
| } | |||||
| inline AtomicWord Barrier_AtomicIncrement(volatile AtomicWord* ptr, | |||||
| AtomicWord increment) { | |||||
| return Barrier_AtomicIncrement( | |||||
| reinterpret_cast<volatile AtomicWordCastType*>(ptr), increment); | |||||
| } | |||||
| inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr, | |||||
| AtomicWord old_value, | |||||
| AtomicWord new_value) { | |||||
| return base::subtle::Acquire_CompareAndSwap( | |||||
| reinterpret_cast<volatile AtomicWordCastType*>(ptr), | |||||
| old_value, new_value); | |||||
| } | |||||
| inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr, | |||||
| AtomicWord old_value, | |||||
| AtomicWord new_value) { | |||||
| return base::subtle::Release_CompareAndSwap( | |||||
| reinterpret_cast<volatile AtomicWordCastType*>(ptr), | |||||
| old_value, new_value); | |||||
| } | |||||
| inline void NoBarrier_Store(volatile AtomicWord *ptr, AtomicWord value) { | |||||
| NoBarrier_Store( | |||||
| reinterpret_cast<volatile AtomicWordCastType*>(ptr), value); | |||||
| } | |||||
| inline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) { | |||||
| return base::subtle::Acquire_Store( | |||||
| reinterpret_cast<volatile AtomicWordCastType*>(ptr), value); | |||||
| } | |||||
| inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) { | |||||
| return base::subtle::Release_Store( | |||||
| reinterpret_cast<volatile AtomicWordCastType*>(ptr), value); | |||||
| } | |||||
| inline AtomicWord NoBarrier_Load(volatile const AtomicWord *ptr) { | |||||
| return NoBarrier_Load( | |||||
| reinterpret_cast<volatile const AtomicWordCastType*>(ptr)); | |||||
| } | |||||
| inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) { | |||||
| return base::subtle::Acquire_Load( | |||||
| reinterpret_cast<volatile const AtomicWordCastType*>(ptr)); | |||||
| } | |||||
| inline AtomicWord Release_Load(volatile const AtomicWord* ptr) { | |||||
| return base::subtle::Release_Load( | |||||
| reinterpret_cast<volatile const AtomicWordCastType*>(ptr)); | |||||
| } | |||||
| #undef AtomicWordCastType | |||||
| #endif | |||||
| } // namespace base::subtle | |||||
| } // namespace base | |||||
| #endif // BASE_ATOMICOPS_INTERNALS_X86_MACOSX_H_ | |||||
| @ -0,0 +1,181 @@ | |||||
| // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| // This file is an internal atomic implementation, use base/atomicops.h instead. | |||||
| #ifndef BASE_ATOMICOPS_INTERNALS_X86_MSVC_H_ | |||||
| #define BASE_ATOMICOPS_INTERNALS_X86_MSVC_H_ | |||||
| #pragma once | |||||
| #include <windows.h> | |||||
| namespace base { | |||||
| namespace subtle { | |||||
| inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, | |||||
| Atomic32 old_value, | |||||
| Atomic32 new_value) { | |||||
| LONG result = InterlockedCompareExchange( | |||||
| reinterpret_cast<volatile LONG*>(ptr), | |||||
| static_cast<LONG>(new_value), | |||||
| static_cast<LONG>(old_value)); | |||||
| return static_cast<Atomic32>(result); | |||||
| } | |||||
| inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, | |||||
| Atomic32 new_value) { | |||||
| LONG result = InterlockedExchange( | |||||
| reinterpret_cast<volatile LONG*>(ptr), | |||||
| static_cast<LONG>(new_value)); | |||||
| return static_cast<Atomic32>(result); | |||||
| } | |||||
| inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, | |||||
| Atomic32 increment) { | |||||
| return InterlockedExchangeAdd( | |||||
| reinterpret_cast<volatile LONG*>(ptr), | |||||
| static_cast<LONG>(increment)) + increment; | |||||
| } | |||||
| inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, | |||||
| Atomic32 increment) { | |||||
| return Barrier_AtomicIncrement(ptr, increment); | |||||
| } | |||||
| #if !(defined(_MSC_VER) && _MSC_VER >= 1400) | |||||
| #error "We require at least vs2005 for MemoryBarrier" | |||||
| #endif | |||||
| inline void MemoryBarrier() { | |||||
| // We use MemoryBarrier from WinNT.h | |||||
| ::MemoryBarrier(); | |||||
| } | |||||
| inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, | |||||
| Atomic32 old_value, | |||||
| Atomic32 new_value) { | |||||
| return NoBarrier_CompareAndSwap(ptr, old_value, new_value); | |||||
| } | |||||
| inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, | |||||
| Atomic32 old_value, | |||||
| Atomic32 new_value) { | |||||
| return NoBarrier_CompareAndSwap(ptr, old_value, new_value); | |||||
| } | |||||
| inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { | |||||
| *ptr = value; | |||||
| } | |||||
| inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { | |||||
| NoBarrier_AtomicExchange(ptr, value); | |||||
| // acts as a barrier in this implementation | |||||
| } | |||||
| inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { | |||||
| *ptr = value; // works w/o barrier for current Intel chips as of June 2005 | |||||
| // See comments in Atomic64 version of Release_Store() below. | |||||
| } | |||||
| inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { | |||||
| return *ptr; | |||||
| } | |||||
| inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { | |||||
| Atomic32 value = *ptr; | |||||
| return value; | |||||
| } | |||||
| inline Atomic32 Release_Load(volatile const Atomic32* ptr) { | |||||
| MemoryBarrier(); | |||||
| return *ptr; | |||||
| } | |||||
| #if defined(_WIN64) | |||||
| // 64-bit low-level operations on 64-bit platform. | |||||
| COMPILE_ASSERT(sizeof(Atomic64) == sizeof(PVOID), atomic_word_is_atomic); | |||||
| inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, | |||||
| Atomic64 old_value, | |||||
| Atomic64 new_value) { | |||||
| PVOID result = InterlockedCompareExchangePointer( | |||||
| reinterpret_cast<volatile PVOID*>(ptr), | |||||
| reinterpret_cast<PVOID>(new_value), reinterpret_cast<PVOID>(old_value)); | |||||
| return reinterpret_cast<Atomic64>(result); | |||||
| } | |||||
| inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, | |||||
| Atomic64 new_value) { | |||||
| PVOID result = InterlockedExchangePointer( | |||||
| reinterpret_cast<volatile PVOID*>(ptr), | |||||
| reinterpret_cast<PVOID>(new_value)); | |||||
| return reinterpret_cast<Atomic64>(result); | |||||
| } | |||||
| inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, | |||||
| Atomic64 increment) { | |||||
| return InterlockedExchangeAdd64( | |||||
| reinterpret_cast<volatile LONGLONG*>(ptr), | |||||
| static_cast<LONGLONG>(increment)) + increment; | |||||
| } | |||||
| inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, | |||||
| Atomic64 increment) { | |||||
| return Barrier_AtomicIncrement(ptr, increment); | |||||
| } | |||||
| inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { | |||||
| *ptr = value; | |||||
| } | |||||
| inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { | |||||
| NoBarrier_AtomicExchange(ptr, value); | |||||
| // acts as a barrier in this implementation | |||||
| } | |||||
| inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { | |||||
| *ptr = value; // works w/o barrier for current Intel chips as of June 2005 | |||||
| // When new chips come out, check: | |||||
| // IA-32 Intel Architecture Software Developer's Manual, Volume 3: | |||||
| // System Programming Guide, Chatper 7: Multiple-processor management, | |||||
| // Section 7.2, Memory Ordering. | |||||
| // Last seen at: | |||||
| // http://developer.intel.com/design/pentium4/manuals/index_new.htm | |||||
| } | |||||
| inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { | |||||
| return *ptr; | |||||
| } | |||||
| inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { | |||||
| Atomic64 value = *ptr; | |||||
| return value; | |||||
| } | |||||
| inline Atomic64 Release_Load(volatile const Atomic64* ptr) { | |||||
| MemoryBarrier(); | |||||
| return *ptr; | |||||
| } | |||||
| inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, | |||||
| Atomic64 old_value, | |||||
| Atomic64 new_value) { | |||||
| return NoBarrier_CompareAndSwap(ptr, old_value, new_value); | |||||
| } | |||||
| inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, | |||||
| Atomic64 old_value, | |||||
| Atomic64 new_value) { | |||||
| return NoBarrier_CompareAndSwap(ptr, old_value, new_value); | |||||
| } | |||||
| #endif // defined(_WIN64) | |||||
| } // namespace base::subtle | |||||
| } // namespace base | |||||
| #endif // BASE_ATOMICOPS_INTERNALS_X86_MSVC_H_ | |||||
| @ -0,0 +1,364 @@ | |||||
| // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #ifndef BASE_BASICTYPES_H_ | |||||
| #define BASE_BASICTYPES_H_ | |||||
| #pragma once | |||||
| #include <limits.h> // So we can set the bounds of our types | |||||
| #include <stddef.h> // For size_t | |||||
| #include <string.h> // for memcpy | |||||
| #include "base/port.h" // Types that only need exist on certain systems | |||||
| #ifndef COMPILER_MSVC | |||||
| // stdint.h is part of C99 but MSVC doesn't have it. | |||||
| #include <stdint.h> // For intptr_t. | |||||
| #endif | |||||
| typedef signed char schar; | |||||
| typedef signed char int8; | |||||
| typedef short int16; | |||||
| // TODO: Remove these type guards. These are to avoid conflicts with | |||||
| // obsolete/protypes.h in the Gecko SDK. | |||||
| #ifndef _INT32 | |||||
| #define _INT32 | |||||
| typedef int int32; | |||||
| #endif | |||||
| // The NSPR system headers define 64-bit as |long| when possible. In order to | |||||
| // not have typedef mismatches, we do the same on LP64. | |||||
| #if __LP64__ | |||||
| typedef long int64; | |||||
| #else | |||||
| typedef long long int64; | |||||
| #endif | |||||
| // NOTE: unsigned types are DANGEROUS in loops and other arithmetical | |||||
| // places. Use the signed types unless your variable represents a bit | |||||
| // pattern (eg a hash value) or you really need the extra bit. Do NOT | |||||
| // use 'unsigned' to express "this value should always be positive"; | |||||
| // use assertions for this. | |||||
| typedef unsigned char uint8; | |||||
| typedef unsigned short uint16; | |||||
| // TODO: Remove these type guards. These are to avoid conflicts with | |||||
| // obsolete/protypes.h in the Gecko SDK. | |||||
| #ifndef _UINT32 | |||||
| #define _UINT32 | |||||
| typedef unsigned int uint32; | |||||
| #endif | |||||
| // See the comment above about NSPR and 64-bit. | |||||
| #if __LP64__ | |||||
| typedef unsigned long uint64; | |||||
| #else | |||||
| typedef unsigned long long uint64; | |||||
| #endif | |||||
| // A type to represent a Unicode code-point value. As of Unicode 4.0, | |||||
| // such values require up to 21 bits. | |||||
| // (For type-checking on pointers, make this explicitly signed, | |||||
| // and it should always be the signed version of whatever int32 is.) | |||||
| typedef signed int char32; | |||||
| const uint8 kuint8max = (( uint8) 0xFF); | |||||
| const uint16 kuint16max = ((uint16) 0xFFFF); | |||||
| const uint32 kuint32max = ((uint32) 0xFFFFFFFF); | |||||
| const uint64 kuint64max = ((uint64) GG_LONGLONG(0xFFFFFFFFFFFFFFFF)); | |||||
| const int8 kint8min = (( int8) 0x80); | |||||
| const int8 kint8max = (( int8) 0x7F); | |||||
| const int16 kint16min = (( int16) 0x8000); | |||||
| const int16 kint16max = (( int16) 0x7FFF); | |||||
| const int32 kint32min = (( int32) 0x80000000); | |||||
| const int32 kint32max = (( int32) 0x7FFFFFFF); | |||||
| const int64 kint64min = (( int64) GG_LONGLONG(0x8000000000000000)); | |||||
| const int64 kint64max = (( int64) GG_LONGLONG(0x7FFFFFFFFFFFFFFF)); | |||||
| // A macro to disallow the copy constructor and operator= functions | |||||
| // This should be used in the private: declarations for a class | |||||
| #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ | |||||
| TypeName(const TypeName&); \ | |||||
| void operator=(const TypeName&) | |||||
| // An older, deprecated, politically incorrect name for the above. | |||||
| // NOTE: The usage of this macro was baned from our code base, but some | |||||
| // third_party libraries are yet using it. | |||||
| // TODO(tfarina): Figure out how to fix the usage of this macro in the | |||||
| // third_party libraries and get rid of it. | |||||
| #define DISALLOW_EVIL_CONSTRUCTORS(TypeName) DISALLOW_COPY_AND_ASSIGN(TypeName) | |||||
| // A macro to disallow all the implicit constructors, namely the | |||||
| // default constructor, copy constructor and operator= functions. | |||||
| // | |||||
| // This should be used in the private: declarations for a class | |||||
| // that wants to prevent anyone from instantiating it. This is | |||||
| // especially useful for classes containing only static methods. | |||||
| #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ | |||||
| TypeName(); \ | |||||
| DISALLOW_COPY_AND_ASSIGN(TypeName) | |||||
| // The arraysize(arr) macro returns the # of elements in an array arr. | |||||
| // The expression is a compile-time constant, and therefore can be | |||||
| // used in defining new arrays, for example. If you use arraysize on | |||||
| // a pointer by mistake, you will get a compile-time error. | |||||
| // | |||||
| // One caveat is that arraysize() doesn't accept any array of an | |||||
| // anonymous type or a type defined inside a function. In these rare | |||||
| // cases, you have to use the unsafe ARRAYSIZE_UNSAFE() macro below. This is | |||||
| // due to a limitation in C++'s template system. The limitation might | |||||
| // eventually be removed, but it hasn't happened yet. | |||||
| // This template function declaration is used in defining arraysize. | |||||
| // Note that the function doesn't need an implementation, as we only | |||||
| // use its type. | |||||
| template <typename T, size_t N> | |||||
| char (&ArraySizeHelper(T (&array)[N]))[N]; | |||||
| // That gcc wants both of these prototypes seems mysterious. VC, for | |||||
| // its part, can't decide which to use (another mystery). Matching of | |||||
| // template overloads: the final frontier. | |||||
| #ifndef _MSC_VER | |||||
| template <typename T, size_t N> | |||||
| char (&ArraySizeHelper(const T (&array)[N]))[N]; | |||||
| #endif | |||||
| #define arraysize(array) (sizeof(ArraySizeHelper(array))) | |||||
| // ARRAYSIZE_UNSAFE performs essentially the same calculation as arraysize, | |||||
| // but can be used on anonymous types or types defined inside | |||||
| // functions. It's less safe than arraysize as it accepts some | |||||
| // (although not all) pointers. Therefore, you should use arraysize | |||||
| // whenever possible. | |||||
| // | |||||
| // The expression ARRAYSIZE_UNSAFE(a) is a compile-time constant of type | |||||
| // size_t. | |||||
| // | |||||
| // ARRAYSIZE_UNSAFE catches a few type errors. If you see a compiler error | |||||
| // | |||||
| // "warning: division by zero in ..." | |||||
| // | |||||
| // when using ARRAYSIZE_UNSAFE, you are (wrongfully) giving it a pointer. | |||||
| // You should only use ARRAYSIZE_UNSAFE on statically allocated arrays. | |||||
| // | |||||
| // The following comments are on the implementation details, and can | |||||
| // be ignored by the users. | |||||
| // | |||||
| // ARRAYSIZE_UNSAFE(arr) works by inspecting sizeof(arr) (the # of bytes in | |||||
| // the array) and sizeof(*(arr)) (the # of bytes in one array | |||||
| // element). If the former is divisible by the latter, perhaps arr is | |||||
| // indeed an array, in which case the division result is the # of | |||||
| // elements in the array. Otherwise, arr cannot possibly be an array, | |||||
| // and we generate a compiler error to prevent the code from | |||||
| // compiling. | |||||
| // | |||||
| // Since the size of bool is implementation-defined, we need to cast | |||||
| // !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final | |||||
| // result has type size_t. | |||||
| // | |||||
| // This macro is not perfect as it wrongfully accepts certain | |||||
| // pointers, namely where the pointer size is divisible by the pointee | |||||
| // size. Since all our code has to go through a 32-bit compiler, | |||||
| // where a pointer is 4 bytes, this means all pointers to a type whose | |||||
| // size is 3 or greater than 4 will be (righteously) rejected. | |||||
| #define ARRAYSIZE_UNSAFE(a) \ | |||||
| ((sizeof(a) / sizeof(*(a))) / \ | |||||
| static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))) | |||||
| // Use implicit_cast as a safe version of static_cast or const_cast | |||||
| // for upcasting in the type hierarchy (i.e. casting a pointer to Foo | |||||
| // to a pointer to SuperclassOfFoo or casting a pointer to Foo to | |||||
| // a const pointer to Foo). | |||||
| // When you use implicit_cast, the compiler checks that the cast is safe. | |||||
| // Such explicit implicit_casts are necessary in surprisingly many | |||||
| // situations where C++ demands an exact type match instead of an | |||||
| // argument type convertable to a target type. | |||||
| // | |||||
| // The From type can be inferred, so the preferred syntax for using | |||||
| // implicit_cast is the same as for static_cast etc.: | |||||
| // | |||||
| // implicit_cast<ToType>(expr) | |||||
| // | |||||
| // implicit_cast would have been part of the C++ standard library, | |||||
| // but the proposal was submitted too late. It will probably make | |||||
| // its way into the language in the future. | |||||
| template<typename To, typename From> | |||||
| inline To implicit_cast(From const &f) { | |||||
| return f; | |||||
| } | |||||
| // The COMPILE_ASSERT macro can be used to verify that a compile time | |||||
| // expression is true. For example, you could use it to verify the | |||||
| // size of a static array: | |||||
| // | |||||
| // COMPILE_ASSERT(ARRAYSIZE_UNSAFE(content_type_names) == CONTENT_NUM_TYPES, | |||||
| // content_type_names_incorrect_size); | |||||
| // | |||||
| // or to make sure a struct is smaller than a certain size: | |||||
| // | |||||
| // COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); | |||||
| // | |||||
| // The second argument to the macro is the name of the variable. If | |||||
| // the expression is false, most compilers will issue a warning/error | |||||
| // containing the name of the variable. | |||||
| template <bool> | |||||
| struct CompileAssert { | |||||
| }; | |||||
| #undef COMPILE_ASSERT | |||||
| #define COMPILE_ASSERT(expr, msg) \ | |||||
| typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] | |||||
| // Implementation details of COMPILE_ASSERT: | |||||
| // | |||||
| // - COMPILE_ASSERT works by defining an array type that has -1 | |||||
| // elements (and thus is invalid) when the expression is false. | |||||
| // | |||||
| // - The simpler definition | |||||
| // | |||||
| // #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1] | |||||
| // | |||||
| // does not work, as gcc supports variable-length arrays whose sizes | |||||
| // are determined at run-time (this is gcc's extension and not part | |||||
| // of the C++ standard). As a result, gcc fails to reject the | |||||
| // following code with the simple definition: | |||||
| // | |||||
| // int foo; | |||||
| // COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is | |||||
| // // not a compile-time constant. | |||||
| // | |||||
| // - By using the type CompileAssert<(bool(expr))>, we ensures that | |||||
| // expr is a compile-time constant. (Template arguments must be | |||||
| // determined at compile-time.) | |||||
| // | |||||
| // - The outter parentheses in CompileAssert<(bool(expr))> are necessary | |||||
| // to work around a bug in gcc 3.4.4 and 4.0.1. If we had written | |||||
| // | |||||
| // CompileAssert<bool(expr)> | |||||
| // | |||||
| // instead, these compilers will refuse to compile | |||||
| // | |||||
| // COMPILE_ASSERT(5 > 0, some_message); | |||||
| // | |||||
| // (They seem to think the ">" in "5 > 0" marks the end of the | |||||
| // template argument list.) | |||||
| // | |||||
| // - The array size is (bool(expr) ? 1 : -1), instead of simply | |||||
| // | |||||
| // ((expr) ? 1 : -1). | |||||
| // | |||||
| // This is to avoid running into a bug in MS VC 7.1, which | |||||
| // causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. | |||||
| // MetatagId refers to metatag-id that we assign to | |||||
| // each metatag <name, value> pair.. | |||||
| typedef uint32 MetatagId; | |||||
| // Argument type used in interfaces that can optionally take ownership | |||||
| // of a passed in argument. If TAKE_OWNERSHIP is passed, the called | |||||
| // object takes ownership of the argument. Otherwise it does not. | |||||
| enum Ownership { | |||||
| DO_NOT_TAKE_OWNERSHIP, | |||||
| TAKE_OWNERSHIP | |||||
| }; | |||||
| // bit_cast<Dest,Source> is a template function that implements the | |||||
| // equivalent of "*reinterpret_cast<Dest*>(&source)". We need this in | |||||
| // very low-level functions like the protobuf library and fast math | |||||
| // support. | |||||
| // | |||||
| // float f = 3.14159265358979; | |||||
| // int i = bit_cast<int32>(f); | |||||
| // // i = 0x40490fdb | |||||
| // | |||||
| // The classical address-casting method is: | |||||
| // | |||||
| // // WRONG | |||||
| // float f = 3.14159265358979; // WRONG | |||||
| // int i = * reinterpret_cast<int*>(&f); // WRONG | |||||
| // | |||||
| // The address-casting method actually produces undefined behavior | |||||
| // according to ISO C++ specification section 3.10 -15 -. Roughly, this | |||||
| // section says: if an object in memory has one type, and a program | |||||
| // accesses it with a different type, then the result is undefined | |||||
| // behavior for most values of "different type". | |||||
| // | |||||
| // This is true for any cast syntax, either *(int*)&f or | |||||
| // *reinterpret_cast<int*>(&f). And it is particularly true for | |||||
| // conversions betweeen integral lvalues and floating-point lvalues. | |||||
| // | |||||
| // The purpose of 3.10 -15- is to allow optimizing compilers to assume | |||||
| // that expressions with different types refer to different memory. gcc | |||||
| // 4.0.1 has an optimizer that takes advantage of this. So a | |||||
| // non-conforming program quietly produces wildly incorrect output. | |||||
| // | |||||
| // The problem is not the use of reinterpret_cast. The problem is type | |||||
| // punning: holding an object in memory of one type and reading its bits | |||||
| // back using a different type. | |||||
| // | |||||
| // The C++ standard is more subtle and complex than this, but that | |||||
| // is the basic idea. | |||||
| // | |||||
| // Anyways ... | |||||
| // | |||||
| // bit_cast<> calls memcpy() which is blessed by the standard, | |||||
| // especially by the example in section 3.9 . Also, of course, | |||||
| // bit_cast<> wraps up the nasty logic in one place. | |||||
| // | |||||
| // Fortunately memcpy() is very fast. In optimized mode, with a | |||||
| // constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline | |||||
| // code with the minimal amount of data movement. On a 32-bit system, | |||||
| // memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8) | |||||
| // compiles to two loads and two stores. | |||||
| // | |||||
| // I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1. | |||||
| // | |||||
| // WARNING: if Dest or Source is a non-POD type, the result of the memcpy | |||||
| // is likely to surprise you. | |||||
| template <class Dest, class Source> | |||||
| inline Dest bit_cast(const Source& source) { | |||||
| // Compile time assertion: sizeof(Dest) == sizeof(Source) | |||||
| // A compile error here means your Dest and Source have different sizes. | |||||
| typedef char VerifySizesAreEqual [sizeof(Dest) == sizeof(Source) ? 1 : -1]; | |||||
| Dest dest; | |||||
| memcpy(&dest, &source, sizeof(dest)); | |||||
| return dest; | |||||
| } | |||||
| // Used to explicitly mark the return value of a function as unused. If you are | |||||
| // really sure you don't want to do anything with the return value of a function | |||||
| // that has been marked WARN_UNUSED_RESULT, wrap it with this. Example: | |||||
| // | |||||
| // scoped_ptr<MyType> my_var = ...; | |||||
| // if (TakeOwnership(my_var.get()) == SUCCESS) | |||||
| // ignore_result(my_var.release()); | |||||
| // | |||||
| template<typename T> | |||||
| inline void ignore_result(const T& ignored) { | |||||
| } | |||||
| // The following enum should be used only as a constructor argument to indicate | |||||
| // that the variable has static storage class, and that the constructor should | |||||
| // do nothing to its state. It indicates to the reader that it is legal to | |||||
| // declare a static instance of the class, provided the constructor is given | |||||
| // the base::LINKER_INITIALIZED argument. Normally, it is unsafe to declare a | |||||
| // static variable that has a constructor or a destructor because invocation | |||||
| // order is undefined. However, IF the type can be initialized by filling with | |||||
| // zeroes (which the loader does for static variables), AND the destructor also | |||||
| // does nothing to the storage, AND there are no virtual methods, then a | |||||
| // constructor declared as | |||||
| // explicit MyClass(base::LinkerInitialized x) {} | |||||
| // and invoked as | |||||
| // static MyClass my_variable_name(base::LINKER_INITIALIZED); | |||||
| namespace base { | |||||
| enum LinkerInitialized { LINKER_INITIALIZED }; | |||||
| } // base | |||||
| #endif // BASE_BASICTYPES_H_ | |||||
| @ -0,0 +1,121 @@ | |||||
| // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #ifndef BASE_COMPILER_SPECIFIC_H_ | |||||
| #define BASE_COMPILER_SPECIFIC_H_ | |||||
| #pragma once | |||||
| #include "build/build_config.h" | |||||
| #if defined(COMPILER_MSVC) | |||||
| // Macros for suppressing and disabling warnings on MSVC. | |||||
| // | |||||
| // Warning numbers are enumerated at: | |||||
| // http://msdn.microsoft.com/en-us/library/8x5x43k7(VS.80).aspx | |||||
| // | |||||
| // The warning pragma: | |||||
| // http://msdn.microsoft.com/en-us/library/2c8f766e(VS.80).aspx | |||||
| // | |||||
| // Using __pragma instead of #pragma inside macros: | |||||
| // http://msdn.microsoft.com/en-us/library/d9x1s805.aspx | |||||
| // MSVC_SUPPRESS_WARNING disables warning |n| for the remainder of the line and | |||||
| // for the next line of the source file. | |||||
| #define MSVC_SUPPRESS_WARNING(n) __pragma(warning(suppress:n)) | |||||
| // MSVC_PUSH_DISABLE_WARNING pushes |n| onto a stack of warnings to be disabled. | |||||
| // The warning remains disabled until popped by MSVC_POP_WARNING. | |||||
| #define MSVC_PUSH_DISABLE_WARNING(n) __pragma(warning(push)) \ | |||||
| __pragma(warning(disable:n)) | |||||
| // MSVC_PUSH_WARNING_LEVEL pushes |n| as the global warning level. The level | |||||
| // remains in effect until popped by MSVC_POP_WARNING(). Use 0 to disable all | |||||
| // warnings. | |||||
| #define MSVC_PUSH_WARNING_LEVEL(n) __pragma(warning(push, n)) | |||||
| // Pop effects of innermost MSVC_PUSH_* macro. | |||||
| #define MSVC_POP_WARNING() __pragma(warning(pop)) | |||||
| #define MSVC_DISABLE_OPTIMIZE() __pragma(optimize("", off)) | |||||
| #define MSVC_ENABLE_OPTIMIZE() __pragma(optimize("", on)) | |||||
| // Allows |this| to be passed as an argument in constructor initializer lists. | |||||
| // This uses push/pop instead of the seemingly simpler suppress feature to avoid | |||||
| // having the warning be disabled for more than just |code|. | |||||
| // | |||||
| // Example usage: | |||||
| // Foo::Foo() : x(NULL), ALLOW_THIS_IN_INITIALIZER_LIST(y(this)), z(3) {} | |||||
| // | |||||
| // Compiler warning C4355: 'this': used in base member initializer list: | |||||
| // http://msdn.microsoft.com/en-us/library/3c594ae3(VS.80).aspx | |||||
| #define ALLOW_THIS_IN_INITIALIZER_LIST(code) MSVC_PUSH_DISABLE_WARNING(4355) \ | |||||
| code \ | |||||
| MSVC_POP_WARNING() | |||||
| #else // Not MSVC | |||||
| #define MSVC_SUPPRESS_WARNING(n) | |||||
| #define MSVC_PUSH_DISABLE_WARNING(n) | |||||
| #define MSVC_PUSH_WARNING_LEVEL(n) | |||||
| #define MSVC_POP_WARNING() | |||||
| #define MSVC_DISABLE_OPTIMIZE() | |||||
| #define MSVC_ENABLE_OPTIMIZE() | |||||
| #define ALLOW_THIS_IN_INITIALIZER_LIST(code) code | |||||
| #endif // COMPILER_MSVC | |||||
| // Annotate a variable indicating it's ok if the variable is not used. | |||||
| // (Typically used to silence a compiler warning when the assignment | |||||
| // is important for some other reason.) | |||||
| // Use like: | |||||
| // int x ALLOW_UNUSED = ...; | |||||
| #if defined(COMPILER_GCC) | |||||
| #define ALLOW_UNUSED __attribute__((unused)) | |||||
| #else | |||||
| #define ALLOW_UNUSED | |||||
| #endif | |||||
| // Annotate a virtual method indicating it must be overriding a virtual | |||||
| // method in the parent class. | |||||
| // Use like: | |||||
| // virtual void foo() OVERRIDE; | |||||
| #if defined(COMPILER_MSVC) | |||||
| #define OVERRIDE override | |||||
| #elif defined(__clang__) | |||||
| #define OVERRIDE override | |||||
| #else | |||||
| #define OVERRIDE | |||||
| #endif | |||||
| // Annotate a function indicating the caller must examine the return value. | |||||
| // Use like: | |||||
| // int foo() WARN_UNUSED_RESULT; | |||||
| #if defined(COMPILER_GCC) | |||||
| #define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) | |||||
| #else | |||||
| #define WARN_UNUSED_RESULT | |||||
| #endif | |||||
| // Tell the compiler a function is using a printf-style format string. | |||||
| // |format_param| is the one-based index of the format string parameter; | |||||
| // |dots_param| is the one-based index of the "..." parameter. | |||||
| // For v*printf functions (which take a va_list), pass 0 for dots_param. | |||||
| // (This is undocumented but matches what the system C headers do.) | |||||
| #if defined(COMPILER_GCC) | |||||
| #define PRINTF_FORMAT(format_param, dots_param) \ | |||||
| __attribute__((format(printf, format_param, dots_param))) | |||||
| #else | |||||
| #define PRINTF_FORMAT(format_param, dots_param) | |||||
| #endif | |||||
| // WPRINTF_FORMAT is the same, but for wide format strings. | |||||
| // This doesn't appear to yet be implemented in any compiler. | |||||
| // See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38308 . | |||||
| #define WPRINTF_FORMAT(format_param, dots_param) | |||||
| // If available, it would look like: | |||||
| // __attribute__((format(wprintf, format_param, dots_param))) | |||||
| #endif // BASE_COMPILER_SPECIFIC_H_ | |||||
| @ -0,0 +1,44 @@ | |||||
| // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #include "base/lazy_instance.h" | |||||
| #include "base/at_exit.h" | |||||
| #include "base/atomicops.h" | |||||
| #include "base/basictypes.h" | |||||
| #include "base/threading/platform_thread.h" | |||||
| #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | |||||
| namespace base { | |||||
| bool LazyInstanceHelper::NeedsInstance() { | |||||
| // Try to create the instance, if we're the first, will go from EMPTY | |||||
| // to CREATING, otherwise we've already been beaten here. | |||||
| if (base::subtle::Acquire_CompareAndSwap( | |||||
| &state_, STATE_EMPTY, STATE_CREATING) == STATE_EMPTY) { | |||||
| // Caller must create instance | |||||
| return true; | |||||
| } else { | |||||
| // It's either in the process of being created, or already created. Spin. | |||||
| while (base::subtle::NoBarrier_Load(&state_) != STATE_CREATED) | |||||
| PlatformThread::YieldCurrentThread(); | |||||
| } | |||||
| // Someone else created the instance. | |||||
| return false; | |||||
| } | |||||
| void LazyInstanceHelper::CompleteInstance(void* instance, void (*dtor)(void*)) { | |||||
| // See the comment to the corresponding HAPPENS_AFTER in Pointer(). | |||||
| ANNOTATE_HAPPENS_BEFORE(&state_); | |||||
| // Instance is created, go from CREATING to CREATED. | |||||
| base::subtle::Release_Store(&state_, STATE_CREATED); | |||||
| // Make sure that the lazily instantiated object will get destroyed at exit. | |||||
| if (dtor) | |||||
| base::AtExitManager::RegisterCallback(dtor, instance); | |||||
| } | |||||
| } // namespace base | |||||
| @ -0,0 +1,164 @@ | |||||
| // Copyright (c) 2008 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| // The LazyInstance<Type, Traits> class manages a single instance of Type, | |||||
| // which will be lazily created on the first time it's accessed. This class is | |||||
| // useful for places you would normally use a function-level static, but you | |||||
| // need to have guaranteed thread-safety. The Type constructor will only ever | |||||
| // be called once, even if two threads are racing to create the object. Get() | |||||
| // and Pointer() will always return the same, completely initialized instance. | |||||
| // When the instance is constructed it is registered with AtExitManager. The | |||||
| // destructor will be called on program exit. | |||||
| // | |||||
| // LazyInstance is completely thread safe, assuming that you create it safely. | |||||
| // The class was designed to be POD initialized, so it shouldn't require a | |||||
| // static constructor. It really only makes sense to declare a LazyInstance as | |||||
| // a global variable using the base::LinkerInitialized constructor. | |||||
| // | |||||
| // LazyInstance is similar to Singleton, except it does not have the singleton | |||||
| // property. You can have multiple LazyInstance's of the same type, and each | |||||
| // will manage a unique instance. It also preallocates the space for Type, as | |||||
| // to avoid allocating the Type instance on the heap. This may help with the | |||||
| // performance of creating the instance, and reducing heap fragmentation. This | |||||
| // requires that Type be a complete type so we can determine the size. | |||||
| // | |||||
| // Example usage: | |||||
| // static LazyInstance<MyClass> my_instance(base::LINKER_INITIALIZED); | |||||
| // void SomeMethod() { | |||||
| // my_instance.Get().SomeMethod(); // MyClass::SomeMethod() | |||||
| // | |||||
| // MyClass* ptr = my_instance.Pointer(); | |||||
| // ptr->DoDoDo(); // MyClass::DoDoDo | |||||
| // } | |||||
| #ifndef BASE_LAZY_INSTANCE_H_ | |||||
| #define BASE_LAZY_INSTANCE_H_ | |||||
| #pragma once | |||||
| #include <new> // For placement new. | |||||
| #include "base/atomicops.h" | |||||
| #include "base/basictypes.h" | |||||
| #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | |||||
| #include "base/threading/thread_restrictions.h" | |||||
| namespace base { | |||||
| template <typename Type> | |||||
| struct DefaultLazyInstanceTraits { | |||||
| static const bool kAllowedToAccessOnNonjoinableThread = false; | |||||
| static Type* New(void* instance) { | |||||
| // Use placement new to initialize our instance in our preallocated space. | |||||
| // The parenthesis is very important here to force POD type initialization. | |||||
| return new (instance) Type(); | |||||
| } | |||||
| static void Delete(void* instance) { | |||||
| // Explicitly call the destructor. | |||||
| reinterpret_cast<Type*>(instance)->~Type(); | |||||
| } | |||||
| }; | |||||
| template <typename Type> | |||||
| struct LeakyLazyInstanceTraits { | |||||
| static const bool kAllowedToAccessOnNonjoinableThread = true; | |||||
| static Type* New(void* instance) { | |||||
| return DefaultLazyInstanceTraits<Type>::New(instance); | |||||
| } | |||||
| // Rather than define an empty Delete function, we make Delete itself | |||||
| // a null pointer. This allows us to completely sidestep registering | |||||
| // this object with an AtExitManager, which allows you to use | |||||
| // LeakyLazyInstanceTraits in contexts where you don't have an | |||||
| // AtExitManager. | |||||
| static void (*Delete)(void* instance); | |||||
| }; | |||||
| template <typename Type> | |||||
| void (*LeakyLazyInstanceTraits<Type>::Delete)(void* instance) = NULL; | |||||
| // We pull out some of the functionality into a non-templated base, so that we | |||||
| // can implement the more complicated pieces out of line in the .cc file. | |||||
| class LazyInstanceHelper { | |||||
| protected: | |||||
| enum { | |||||
| STATE_EMPTY = 0, | |||||
| STATE_CREATING = 1, | |||||
| STATE_CREATED = 2 | |||||
| }; | |||||
| explicit LazyInstanceHelper(LinkerInitialized /* x */) { /* state_ is 0 */ } | |||||
| // Declaring a destructor (even if it's empty) will cause MSVC to register a | |||||
| // static initializer to register the empty destructor with atexit(). | |||||
| // Check if instance needs to be created. If so return true otherwise | |||||
| // if another thread has beat us, wait for instance to be created and | |||||
| // return false. | |||||
| bool NeedsInstance(); | |||||
| // After creating an instance, call this to register the dtor to be called | |||||
| // at program exit and to update the state to STATE_CREATED. | |||||
| void CompleteInstance(void* instance, void (*dtor)(void*)); | |||||
| base::subtle::Atomic32 state_; | |||||
| private: | |||||
| DISALLOW_COPY_AND_ASSIGN(LazyInstanceHelper); | |||||
| }; | |||||
| template <typename Type, typename Traits = DefaultLazyInstanceTraits<Type> > | |||||
| class LazyInstance : public LazyInstanceHelper { | |||||
| public: | |||||
| explicit LazyInstance(LinkerInitialized x) : LazyInstanceHelper(x) { } | |||||
| // Declaring a destructor (even if it's empty) will cause MSVC to register a | |||||
| // static initializer to register the empty destructor with atexit(). | |||||
| Type& Get() { | |||||
| return *Pointer(); | |||||
| } | |||||
| Type* Pointer() { | |||||
| if (!Traits::kAllowedToAccessOnNonjoinableThread) | |||||
| base::ThreadRestrictions::AssertSingletonAllowed(); | |||||
| // We will hopefully have fast access when the instance is already created. | |||||
| if ((base::subtle::NoBarrier_Load(&state_) != STATE_CREATED) && | |||||
| NeedsInstance()) { | |||||
| // Create the instance in the space provided by |buf_|. | |||||
| instance_ = Traits::New(buf_); | |||||
| // Traits::Delete will be null for LeakyLazyInstannceTraits | |||||
| void (*dtor)(void*) = Traits::Delete; | |||||
| CompleteInstance(this, (dtor == NULL) ? NULL : OnExit); | |||||
| } | |||||
| // This annotation helps race detectors recognize correct lock-less | |||||
| // synchronization between different threads calling Pointer(). | |||||
| // We suggest dynamic race detection tool that "Traits::New" above | |||||
| // and CompleteInstance(...) happens before "return instance_" below. | |||||
| // See the corresponding HAPPENS_BEFORE in CompleteInstance(...). | |||||
| ANNOTATE_HAPPENS_AFTER(&state_); | |||||
| return instance_; | |||||
| } | |||||
| private: | |||||
| // Adapter function for use with AtExit. This should be called single | |||||
| // threaded, so don't use atomic operations. | |||||
| // Calling OnExit while the instance is in use by other threads is a mistake. | |||||
| static void OnExit(void* lazy_instance) { | |||||
| LazyInstance<Type, Traits>* me = | |||||
| reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance); | |||||
| Traits::Delete(me->instance_); | |||||
| me->instance_ = NULL; | |||||
| base::subtle::Release_Store(&me->state_, STATE_EMPTY); | |||||
| } | |||||
| int8 buf_[sizeof(Type)]; // Preallocate the space for the Type instance. | |||||
| Type *instance_; | |||||
| DISALLOW_COPY_AND_ASSIGN(LazyInstance); | |||||
| }; | |||||
| } // namespace base | |||||
| #endif // BASE_LAZY_INSTANCE_H_ | |||||
| @ -0,0 +1,36 @@ | |||||
| // Copyright (C) 2011 Google Inc. | |||||
| // | |||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| // you may not use this file except in compliance with the License. | |||||
| // You may obtain a copy of the License at | |||||
| // | |||||
| // http://www.apache.org/licenses/LICENSE-2.0 | |||||
| // | |||||
| // Unless required by applicable law or agreed to in writing, software | |||||
| // distributed under the License is distributed on an "AS IS" BASIS, | |||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| // See the License for the specific language governing permissions and | |||||
| // limitations under the License. | |||||
| // Author: Philippe Liard | |||||
| // This file does not come from Chromium. | |||||
| // It provides a minimalist implementation of common macros. | |||||
| #ifndef BASE_LOGGING_H_ | |||||
| # define BASE_LOGGING_H_ | |||||
| # include <cassert> | |||||
| # include <iostream> | |||||
| # define CHECK_EQ(X, Y) assert((X) == (Y)) | |||||
| # define DCHECK(X) assert(X) | |||||
| # define DCHECK_EQ(X, Y) CHECK_EQ((X), (Y)) | |||||
| # define NOTREACHED() std::cerr | |||||
| # define LOG(Level) std::cerr | |||||
| # define FATAL 1 | |||||
| #endif | |||||
| @ -0,0 +1,55 @@ | |||||
| // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #ifndef BASE_PORT_H_ | |||||
| #define BASE_PORT_H_ | |||||
| #pragma once | |||||
| #include <stdarg.h> | |||||
| #include "build/build_config.h" | |||||
| #ifdef COMPILER_MSVC | |||||
| #define GG_LONGLONG(x) x##I64 | |||||
| #define GG_ULONGLONG(x) x##UI64 | |||||
| #else | |||||
| #define GG_LONGLONG(x) x##LL | |||||
| #define GG_ULONGLONG(x) x##ULL | |||||
| #endif | |||||
| // Per C99 7.8.14, define __STDC_CONSTANT_MACROS before including <stdint.h> | |||||
| // to get the INTn_C and UINTn_C macros for integer constants. It's difficult | |||||
| // to guarantee any specific ordering of header includes, so it's difficult to | |||||
| // guarantee that the INTn_C macros can be defined by including <stdint.h> at | |||||
| // any specific point. Provide GG_INTn_C macros instead. | |||||
| #define GG_INT8_C(x) (x) | |||||
| #define GG_INT16_C(x) (x) | |||||
| #define GG_INT32_C(x) (x) | |||||
| #define GG_INT64_C(x) GG_LONGLONG(x) | |||||
| #define GG_UINT8_C(x) (x ## U) | |||||
| #define GG_UINT16_C(x) (x ## U) | |||||
| #define GG_UINT32_C(x) (x ## U) | |||||
| #define GG_UINT64_C(x) GG_ULONGLONG(x) | |||||
| // It's possible for functions that use a va_list, such as StringPrintf, to | |||||
| // invalidate the data in it upon use. The fix is to make a copy of the | |||||
| // structure before using it and use that copy instead. va_copy is provided | |||||
| // for this purpose. MSVC does not provide va_copy, so define an | |||||
| // implementation here. It is not guaranteed that assignment is a copy, so the | |||||
| // StringUtil.VariableArgsFunc unit test tests this capability. | |||||
| #if defined(COMPILER_GCC) | |||||
| #define GG_VA_COPY(a, b) (va_copy(a, b)) | |||||
| #elif defined(COMPILER_MSVC) | |||||
| #define GG_VA_COPY(a, b) (a = b) | |||||
| #endif | |||||
| // Define an OS-neutral wrapper for shared library entry points | |||||
| #if defined(OS_WIN) | |||||
| #define API_CALL __stdcall | |||||
| #else | |||||
| #define API_CALL | |||||
| #endif | |||||
| #endif // BASE_PORT_H_ | |||||
| @ -0,0 +1 @@ | |||||
| // Empty File. | |||||
| @ -0,0 +1,383 @@ | |||||
| // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| // Scopers help you manage ownership of a pointer, helping you easily manage the | |||||
| // a pointer within a scope, and automatically destroying the pointer at the | |||||
| // end of a scope. There are two main classes you will use, which correspond | |||||
| // to the operators new/delete and new[]/delete[]. | |||||
| // | |||||
| // Example usage (scoped_ptr): | |||||
| // { | |||||
| // scoped_ptr<Foo> foo(new Foo("wee")); | |||||
| // } // foo goes out of scope, releasing the pointer with it. | |||||
| // | |||||
| // { | |||||
| // scoped_ptr<Foo> foo; // No pointer managed. | |||||
| // foo.reset(new Foo("wee")); // Now a pointer is managed. | |||||
| // foo.reset(new Foo("wee2")); // Foo("wee") was destroyed. | |||||
| // foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed. | |||||
| // foo->Method(); // Foo::Method() called. | |||||
| // foo.get()->Method(); // Foo::Method() called. | |||||
| // SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer | |||||
| // // manages a pointer. | |||||
| // foo.reset(new Foo("wee4")); // foo manages a pointer again. | |||||
| // foo.reset(); // Foo("wee4") destroyed, foo no longer | |||||
| // // manages a pointer. | |||||
| // } // foo wasn't managing a pointer, so nothing was destroyed. | |||||
| // | |||||
| // Example usage (scoped_array): | |||||
| // { | |||||
| // scoped_array<Foo> foo(new Foo[100]); | |||||
| // foo.get()->Method(); // Foo::Method on the 0th element. | |||||
| // foo[10].Method(); // Foo::Method on the 10th element. | |||||
| // } | |||||
| #ifndef BASE_SCOPED_PTR_H_ | |||||
| #define BASE_SCOPED_PTR_H_ | |||||
| #pragma once | |||||
| // This is an implementation designed to match the anticipated future TR2 | |||||
| // implementation of the scoped_ptr class, and its closely-related brethren, | |||||
| // scoped_array, scoped_ptr_malloc. | |||||
| #include <assert.h> | |||||
| #include <stddef.h> | |||||
| #include <stdlib.h> | |||||
| #include "base/compiler_specific.h" | |||||
| // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T> | |||||
| // automatically deletes the pointer it holds (if any). | |||||
| // That is, scoped_ptr<T> owns the T object that it points to. | |||||
| // Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object. | |||||
| // Also like T*, scoped_ptr<T> is thread-compatible, and once you | |||||
| // dereference it, you get the threadsafety guarantees of T. | |||||
| // | |||||
| // The size of a scoped_ptr is small: | |||||
| // sizeof(scoped_ptr<C>) == sizeof(C*) | |||||
| template <class C> | |||||
| class scoped_ptr { | |||||
| public: | |||||
| // The element type | |||||
| typedef C element_type; | |||||
| // Constructor. Defaults to initializing with NULL. | |||||
| // There is no way to create an uninitialized scoped_ptr. | |||||
| // The input parameter must be allocated with new. | |||||
| explicit scoped_ptr(C* p = NULL) : ptr_(p) { } | |||||
| // Destructor. If there is a C object, delete it. | |||||
| // We don't need to test ptr_ == NULL because C++ does that for us. | |||||
| ~scoped_ptr() { | |||||
| enum { type_must_be_complete = sizeof(C) }; | |||||
| delete ptr_; | |||||
| } | |||||
| // Reset. Deletes the current owned object, if any. | |||||
| // Then takes ownership of a new object, if given. | |||||
| // this->reset(this->get()) works. | |||||
| void reset(C* p = NULL) { | |||||
| if (p != ptr_) { | |||||
| enum { type_must_be_complete = sizeof(C) }; | |||||
| delete ptr_; | |||||
| ptr_ = p; | |||||
| } | |||||
| } | |||||
| // Accessors to get the owned object. | |||||
| // operator* and operator-> will assert() if there is no current object. | |||||
| C& operator*() const { | |||||
| assert(ptr_ != NULL); | |||||
| return *ptr_; | |||||
| } | |||||
| C* operator->() const { | |||||
| assert(ptr_ != NULL); | |||||
| return ptr_; | |||||
| } | |||||
| C* get() const { return ptr_; } | |||||
| // Comparison operators. | |||||
| // These return whether two scoped_ptr refer to the same object, not just to | |||||
| // two different but equal objects. | |||||
| bool operator==(C* p) const { return ptr_ == p; } | |||||
| bool operator!=(C* p) const { return ptr_ != p; } | |||||
| // Swap two scoped pointers. | |||||
| void swap(scoped_ptr& p2) { | |||||
| C* tmp = ptr_; | |||||
| ptr_ = p2.ptr_; | |||||
| p2.ptr_ = tmp; | |||||
| } | |||||
| // Release a pointer. | |||||
| // The return value is the current pointer held by this object. | |||||
| // If this object holds a NULL pointer, the return value is NULL. | |||||
| // After this operation, this object will hold a NULL pointer, | |||||
| // and will not own the object any more. | |||||
| C* release() WARN_UNUSED_RESULT { | |||||
| C* retVal = ptr_; | |||||
| ptr_ = NULL; | |||||
| return retVal; | |||||
| } | |||||
| private: | |||||
| C* ptr_; | |||||
| // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't | |||||
| // make sense, and if C2 == C, it still doesn't make sense because you should | |||||
| // never have the same object owned by two different scoped_ptrs. | |||||
| template <class C2> bool operator==(scoped_ptr<C2> const& p2) const; | |||||
| template <class C2> bool operator!=(scoped_ptr<C2> const& p2) const; | |||||
| // Disallow evil constructors | |||||
| scoped_ptr(const scoped_ptr&); | |||||
| void operator=(const scoped_ptr&); | |||||
| }; | |||||
| // Free functions | |||||
| template <class C> | |||||
| void swap(scoped_ptr<C>& p1, scoped_ptr<C>& p2) { | |||||
| p1.swap(p2); | |||||
| } | |||||
| template <class C> | |||||
| bool operator==(C* p1, const scoped_ptr<C>& p2) { | |||||
| return p1 == p2.get(); | |||||
| } | |||||
| template <class C> | |||||
| bool operator!=(C* p1, const scoped_ptr<C>& p2) { | |||||
| return p1 != p2.get(); | |||||
| } | |||||
| // scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate | |||||
| // with new [] and the destructor deletes objects with delete []. | |||||
| // | |||||
| // As with scoped_ptr<C>, a scoped_array<C> either points to an object | |||||
| // or is NULL. A scoped_array<C> owns the object that it points to. | |||||
| // scoped_array<T> is thread-compatible, and once you index into it, | |||||
| // the returned objects have only the threadsafety guarantees of T. | |||||
| // | |||||
| // Size: sizeof(scoped_array<C>) == sizeof(C*) | |||||
| template <class C> | |||||
| class scoped_array { | |||||
| public: | |||||
| // The element type | |||||
| typedef C element_type; | |||||
| // Constructor. Defaults to intializing with NULL. | |||||
| // There is no way to create an uninitialized scoped_array. | |||||
| // The input parameter must be allocated with new []. | |||||
| explicit scoped_array(C* p = NULL) : array_(p) { } | |||||
| // Destructor. If there is a C object, delete it. | |||||
| // We don't need to test ptr_ == NULL because C++ does that for us. | |||||
| ~scoped_array() { | |||||
| enum { type_must_be_complete = sizeof(C) }; | |||||
| delete[] array_; | |||||
| } | |||||
| // Reset. Deletes the current owned object, if any. | |||||
| // Then takes ownership of a new object, if given. | |||||
| // this->reset(this->get()) works. | |||||
| void reset(C* p = NULL) { | |||||
| if (p != array_) { | |||||
| enum { type_must_be_complete = sizeof(C) }; | |||||
| delete[] array_; | |||||
| array_ = p; | |||||
| } | |||||
| } | |||||
| // Get one element of the current object. | |||||
| // Will assert() if there is no current object, or index i is negative. | |||||
| C& operator[](ptrdiff_t i) const { | |||||
| assert(i >= 0); | |||||
| assert(array_ != NULL); | |||||
| return array_[i]; | |||||
| } | |||||
| // Get a pointer to the zeroth element of the current object. | |||||
| // If there is no current object, return NULL. | |||||
| C* get() const { | |||||
| return array_; | |||||
| } | |||||
| // Comparison operators. | |||||
| // These return whether two scoped_array refer to the same object, not just to | |||||
| // two different but equal objects. | |||||
| bool operator==(C* p) const { return array_ == p; } | |||||
| bool operator!=(C* p) const { return array_ != p; } | |||||
| // Swap two scoped arrays. | |||||
| void swap(scoped_array& p2) { | |||||
| C* tmp = array_; | |||||
| array_ = p2.array_; | |||||
| p2.array_ = tmp; | |||||
| } | |||||
| // Release an array. | |||||
| // The return value is the current pointer held by this object. | |||||
| // If this object holds a NULL pointer, the return value is NULL. | |||||
| // After this operation, this object will hold a NULL pointer, | |||||
| // and will not own the object any more. | |||||
| C* release() WARN_UNUSED_RESULT { | |||||
| C* retVal = array_; | |||||
| array_ = NULL; | |||||
| return retVal; | |||||
| } | |||||
| private: | |||||
| C* array_; | |||||
| // Forbid comparison of different scoped_array types. | |||||
| template <class C2> bool operator==(scoped_array<C2> const& p2) const; | |||||
| template <class C2> bool operator!=(scoped_array<C2> const& p2) const; | |||||
| // Disallow evil constructors | |||||
| scoped_array(const scoped_array&); | |||||
| void operator=(const scoped_array&); | |||||
| }; | |||||
| // Free functions | |||||
| template <class C> | |||||
| void swap(scoped_array<C>& p1, scoped_array<C>& p2) { | |||||
| p1.swap(p2); | |||||
| } | |||||
| template <class C> | |||||
| bool operator==(C* p1, const scoped_array<C>& p2) { | |||||
| return p1 == p2.get(); | |||||
| } | |||||
| template <class C> | |||||
| bool operator!=(C* p1, const scoped_array<C>& p2) { | |||||
| return p1 != p2.get(); | |||||
| } | |||||
| // This class wraps the c library function free() in a class that can be | |||||
| // passed as a template argument to scoped_ptr_malloc below. | |||||
| class ScopedPtrMallocFree { | |||||
| public: | |||||
| inline void operator()(void* x) const { | |||||
| free(x); | |||||
| } | |||||
| }; | |||||
| // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a | |||||
| // second template argument, the functor used to free the object. | |||||
| template<class C, class FreeProc = ScopedPtrMallocFree> | |||||
| class scoped_ptr_malloc { | |||||
| public: | |||||
| // The element type | |||||
| typedef C element_type; | |||||
| // Constructor. Defaults to initializing with NULL. | |||||
| // There is no way to create an uninitialized scoped_ptr. | |||||
| // The input parameter must be allocated with an allocator that matches the | |||||
| // Free functor. For the default Free functor, this is malloc, calloc, or | |||||
| // realloc. | |||||
| explicit scoped_ptr_malloc(C* p = NULL): ptr_(p) {} | |||||
| // Destructor. If there is a C object, call the Free functor. | |||||
| ~scoped_ptr_malloc() { | |||||
| free_(ptr_); | |||||
| } | |||||
| // Reset. Calls the Free functor on the current owned object, if any. | |||||
| // Then takes ownership of a new object, if given. | |||||
| // this->reset(this->get()) works. | |||||
| void reset(C* p = NULL) { | |||||
| if (ptr_ != p) { | |||||
| free_(ptr_); | |||||
| ptr_ = p; | |||||
| } | |||||
| } | |||||
| // Get the current object. | |||||
| // operator* and operator-> will cause an assert() failure if there is | |||||
| // no current object. | |||||
| C& operator*() const { | |||||
| assert(ptr_ != NULL); | |||||
| return *ptr_; | |||||
| } | |||||
| C* operator->() const { | |||||
| assert(ptr_ != NULL); | |||||
| return ptr_; | |||||
| } | |||||
| C* get() const { | |||||
| return ptr_; | |||||
| } | |||||
| // Comparison operators. | |||||
| // These return whether a scoped_ptr_malloc and a plain pointer refer | |||||
| // to the same object, not just to two different but equal objects. | |||||
| // For compatibility with the boost-derived implementation, these | |||||
| // take non-const arguments. | |||||
| bool operator==(C* p) const { | |||||
| return ptr_ == p; | |||||
| } | |||||
| bool operator!=(C* p) const { | |||||
| return ptr_ != p; | |||||
| } | |||||
| // Swap two scoped pointers. | |||||
| void swap(scoped_ptr_malloc & b) { | |||||
| C* tmp = b.ptr_; | |||||
| b.ptr_ = ptr_; | |||||
| ptr_ = tmp; | |||||
| } | |||||
| // Release a pointer. | |||||
| // The return value is the current pointer held by this object. | |||||
| // If this object holds a NULL pointer, the return value is NULL. | |||||
| // After this operation, this object will hold a NULL pointer, | |||||
| // and will not own the object any more. | |||||
| C* release() WARN_UNUSED_RESULT { | |||||
| C* tmp = ptr_; | |||||
| ptr_ = NULL; | |||||
| return tmp; | |||||
| } | |||||
| private: | |||||
| C* ptr_; | |||||
| // no reason to use these: each scoped_ptr_malloc should have its own object | |||||
| template <class C2, class GP> | |||||
| bool operator==(scoped_ptr_malloc<C2, GP> const& p) const; | |||||
| template <class C2, class GP> | |||||
| bool operator!=(scoped_ptr_malloc<C2, GP> const& p) const; | |||||
| static FreeProc const free_; | |||||
| // Disallow evil constructors | |||||
| scoped_ptr_malloc(const scoped_ptr_malloc&); | |||||
| void operator=(const scoped_ptr_malloc&); | |||||
| }; | |||||
| template<class C, class FP> | |||||
| FP const scoped_ptr_malloc<C, FP>::free_ = FP(); | |||||
| template<class C, class FP> inline | |||||
| void swap(scoped_ptr_malloc<C, FP>& a, scoped_ptr_malloc<C, FP>& b) { | |||||
| a.swap(b); | |||||
| } | |||||
| template<class C, class FP> inline | |||||
| bool operator==(C* p, const scoped_ptr_malloc<C, FP>& b) { | |||||
| return p == b.get(); | |||||
| } | |||||
| template<class C, class FP> inline | |||||
| bool operator!=(C* p, const scoped_ptr_malloc<C, FP>& b) { | |||||
| return p != b.get(); | |||||
| } | |||||
| #endif // BASE_SCOPED_PTR_H_ | |||||
| @ -0,0 +1,271 @@ | |||||
| // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #ifndef BASE_SINGLETON_H_ | |||||
| #define BASE_SINGLETON_H_ | |||||
| #pragma once | |||||
| #include "base/at_exit.h" | |||||
| #include "base/atomicops.h" | |||||
| #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | |||||
| #include "base/threading/platform_thread.h" | |||||
| #include "base/threading/thread_restrictions.h" | |||||
| // Default traits for Singleton<Type>. Calls operator new and operator delete on | |||||
| // the object. Registers automatic deletion at process exit. | |||||
| // Overload if you need arguments or another memory allocation function. | |||||
| template<typename Type> | |||||
| struct DefaultSingletonTraits { | |||||
| // Allocates the object. | |||||
| static Type* New() { | |||||
| // The parenthesis is very important here; it forces POD type | |||||
| // initialization. | |||||
| return new Type(); | |||||
| } | |||||
| // Destroys the object. | |||||
| static void Delete(Type* x) { | |||||
| delete x; | |||||
| } | |||||
| // Set to true to automatically register deletion of the object on process | |||||
| // exit. See below for the required call that makes this happen. | |||||
| static const bool kRegisterAtExit = true; | |||||
| // Set to false to disallow access on a non-joinable thread. This is | |||||
| // different from kRegisterAtExit because StaticMemorySingletonTraits allows | |||||
| // access on non-joinable threads, and gracefully handles this. | |||||
| static const bool kAllowedToAccessOnNonjoinableThread = false; | |||||
| }; | |||||
| // Alternate traits for use with the Singleton<Type>. Identical to | |||||
| // DefaultSingletonTraits except that the Singleton will not be cleaned up | |||||
| // at exit. | |||||
| template<typename Type> | |||||
| struct LeakySingletonTraits : public DefaultSingletonTraits<Type> { | |||||
| static const bool kRegisterAtExit = false; | |||||
| static const bool kAllowedToAccessOnNonjoinableThread = true; | |||||
| }; | |||||
| // Alternate traits for use with the Singleton<Type>. Allocates memory | |||||
| // for the singleton instance from a static buffer. The singleton will | |||||
| // be cleaned up at exit, but can't be revived after destruction unless | |||||
| // the Resurrect() method is called. | |||||
| // | |||||
| // This is useful for a certain category of things, notably logging and | |||||
| // tracing, where the singleton instance is of a type carefully constructed to | |||||
| // be safe to access post-destruction. | |||||
| // In logging and tracing you'll typically get stray calls at odd times, like | |||||
| // during static destruction, thread teardown and the like, and there's a | |||||
| // termination race on the heap-based singleton - e.g. if one thread calls | |||||
| // get(), but then another thread initiates AtExit processing, the first thread | |||||
| // may call into an object residing in unallocated memory. If the instance is | |||||
| // allocated from the data segment, then this is survivable. | |||||
| // | |||||
| // The destructor is to deallocate system resources, in this case to unregister | |||||
| // a callback the system will invoke when logging levels change. Note that | |||||
| // this is also used in e.g. Chrome Frame, where you have to allow for the | |||||
| // possibility of loading briefly into someone else's process space, and | |||||
| // so leaking is not an option, as that would sabotage the state of your host | |||||
| // process once you've unloaded. | |||||
| template <typename Type> | |||||
| struct StaticMemorySingletonTraits { | |||||
| // WARNING: User has to deal with get() in the singleton class | |||||
| // this is traits for returning NULL. | |||||
| static Type* New() { | |||||
| if (base::subtle::NoBarrier_AtomicExchange(&dead_, 1)) | |||||
| return NULL; | |||||
| Type* ptr = reinterpret_cast<Type*>(buffer_); | |||||
| // We are protected by a memory barrier. | |||||
| new(ptr) Type(); | |||||
| return ptr; | |||||
| } | |||||
| static void Delete(Type* p) { | |||||
| base::subtle::NoBarrier_Store(&dead_, 1); | |||||
| base::subtle::MemoryBarrier(); | |||||
| if (p != NULL) | |||||
| p->Type::~Type(); | |||||
| } | |||||
| static const bool kRegisterAtExit = true; | |||||
| static const bool kAllowedToAccessOnNonjoinableThread = true; | |||||
| // Exposed for unittesting. | |||||
| static void Resurrect() { | |||||
| base::subtle::NoBarrier_Store(&dead_, 0); | |||||
| } | |||||
| private: | |||||
| static const size_t kBufferSize = (sizeof(Type) + | |||||
| sizeof(intptr_t) - 1) / sizeof(intptr_t); | |||||
| static intptr_t buffer_[kBufferSize]; | |||||
| // Signal the object was already deleted, so it is not revived. | |||||
| static base::subtle::Atomic32 dead_; | |||||
| }; | |||||
| template <typename Type> intptr_t | |||||
| StaticMemorySingletonTraits<Type>::buffer_[kBufferSize]; | |||||
| template <typename Type> base::subtle::Atomic32 | |||||
| StaticMemorySingletonTraits<Type>::dead_ = 0; | |||||
| // The Singleton<Type, Traits, DifferentiatingType> class manages a single | |||||
| // instance of Type which will be created on first use and will be destroyed at | |||||
| // normal process exit). The Trait::Delete function will not be called on | |||||
| // abnormal process exit. | |||||
| // | |||||
| // DifferentiatingType is used as a key to differentiate two different | |||||
| // singletons having the same memory allocation functions but serving a | |||||
| // different purpose. This is mainly used for Locks serving different purposes. | |||||
| // | |||||
| // Example usage: | |||||
| // | |||||
| // In your header: | |||||
| // #include "base/singleton.h" | |||||
| // class FooClass { | |||||
| // public: | |||||
| // static FooClass* GetInstance(); <-- See comment below on this. | |||||
| // void Bar() { ... } | |||||
| // private: | |||||
| // FooClass() { ... } | |||||
| // friend struct DefaultSingletonTraits<FooClass>; | |||||
| // | |||||
| // DISALLOW_COPY_AND_ASSIGN(FooClass); | |||||
| // }; | |||||
| // | |||||
| // In your source file: | |||||
| // FooClass* FooClass::GetInstance() { | |||||
| // return Singleton<FooClass>::get(); | |||||
| // } | |||||
| // | |||||
| // And to call methods on FooClass: | |||||
| // FooClass::GetInstance()->Bar(); | |||||
| // | |||||
| // NOTE: The method accessing Singleton<T>::get() has to be named as GetInstance | |||||
| // and it is important that FooClass::GetInstance() is not inlined in the | |||||
| // header. This makes sure that when source files from multiple targets include | |||||
| // this header they don't end up with different copies of the inlined code | |||||
| // creating multiple copies of the singleton. | |||||
| // | |||||
| // Singleton<> has no non-static members and doesn't need to actually be | |||||
| // instantiated. | |||||
| // | |||||
| // This class is itself thread-safe. The underlying Type must of course be | |||||
| // thread-safe if you want to use it concurrently. Two parameters may be tuned | |||||
| // depending on the user's requirements. | |||||
| // | |||||
| // Glossary: | |||||
| // RAE = kRegisterAtExit | |||||
| // | |||||
| // On every platform, if Traits::RAE is true, the singleton will be destroyed at | |||||
| // process exit. More precisely it uses base::AtExitManager which requires an | |||||
| // object of this type to be instantiated. AtExitManager mimics the semantics | |||||
| // of atexit() such as LIFO order but under Windows is safer to call. For more | |||||
| // information see at_exit.h. | |||||
| // | |||||
| // If Traits::RAE is false, the singleton will not be freed at process exit, | |||||
| // thus the singleton will be leaked if it is ever accessed. Traits::RAE | |||||
| // shouldn't be false unless absolutely necessary. Remember that the heap where | |||||
| // the object is allocated may be destroyed by the CRT anyway. | |||||
| // | |||||
| // Caveats: | |||||
| // (a) Every call to get(), operator->() and operator*() incurs some overhead | |||||
| // (16ns on my P4/2.8GHz) to check whether the object has already been | |||||
| // initialized. You may wish to cache the result of get(); it will not | |||||
| // change. | |||||
| // | |||||
| // (b) Your factory function must never throw an exception. This class is not | |||||
| // exception-safe. | |||||
| // | |||||
| template <typename Type, | |||||
| typename Traits = DefaultSingletonTraits<Type>, | |||||
| typename DifferentiatingType = Type> | |||||
| class Singleton { | |||||
| private: | |||||
| // Classes using the Singleton<T> pattern should declare a GetInstance() | |||||
| // method and call Singleton::get() from within that. | |||||
| friend Type* Type::GetInstance(); | |||||
| // This class is safe to be constructed and copy-constructed since it has no | |||||
| // member. | |||||
| // Return a pointer to the one true instance of the class. | |||||
| static Type* get() { | |||||
| if (!Traits::kAllowedToAccessOnNonjoinableThread) | |||||
| base::ThreadRestrictions::AssertSingletonAllowed(); | |||||
| // Our AtomicWord doubles as a spinlock, where a value of | |||||
| // kBeingCreatedMarker means the spinlock is being held for creation. | |||||
| static const base::subtle::AtomicWord kBeingCreatedMarker = 1; | |||||
| base::subtle::AtomicWord value = base::subtle::NoBarrier_Load(&instance_); | |||||
| if (value != 0 && value != kBeingCreatedMarker) { | |||||
| // See the corresponding HAPPENS_BEFORE below. | |||||
| ANNOTATE_HAPPENS_AFTER(&instance_); | |||||
| return reinterpret_cast<Type*>(value); | |||||
| } | |||||
| // Object isn't created yet, maybe we will get to create it, let's try... | |||||
| if (base::subtle::Acquire_CompareAndSwap(&instance_, | |||||
| 0, | |||||
| kBeingCreatedMarker) == 0) { | |||||
| // instance_ was NULL and is now kBeingCreatedMarker. Only one thread | |||||
| // will ever get here. Threads might be spinning on us, and they will | |||||
| // stop right after we do this store. | |||||
| Type* newval = Traits::New(); | |||||
| // This annotation helps race detectors recognize correct lock-less | |||||
| // synchronization between different threads calling get(). | |||||
| // See the corresponding HAPPENS_AFTER below and above. | |||||
| ANNOTATE_HAPPENS_BEFORE(&instance_); | |||||
| base::subtle::Release_Store( | |||||
| &instance_, reinterpret_cast<base::subtle::AtomicWord>(newval)); | |||||
| if (newval != NULL && Traits::kRegisterAtExit) | |||||
| base::AtExitManager::RegisterCallback(OnExit, NULL); | |||||
| return newval; | |||||
| } | |||||
| // We hit a race. Another thread beat us and either: | |||||
| // - Has the object in BeingCreated state | |||||
| // - Already has the object created... | |||||
| // We know value != NULL. It could be kBeingCreatedMarker, or a valid ptr. | |||||
| // Unless your constructor can be very time consuming, it is very unlikely | |||||
| // to hit this race. When it does, we just spin and yield the thread until | |||||
| // the object has been created. | |||||
| while (true) { | |||||
| value = base::subtle::NoBarrier_Load(&instance_); | |||||
| if (value != kBeingCreatedMarker) | |||||
| break; | |||||
| base::PlatformThread::YieldCurrentThread(); | |||||
| } | |||||
| // See the corresponding HAPPENS_BEFORE above. | |||||
| ANNOTATE_HAPPENS_AFTER(&instance_); | |||||
| return reinterpret_cast<Type*>(value); | |||||
| } | |||||
| // Adapter function for use with AtExit(). This should be called single | |||||
| // threaded, so don't use atomic operations. | |||||
| // Calling OnExit while singleton is in use by other threads is a mistake. | |||||
| static void OnExit(void* /* unused */) { | |||||
| // AtExit should only ever be register after the singleton instance was | |||||
| // created. We should only ever get here with a valid instance_ pointer. | |||||
| Traits::Delete( | |||||
| reinterpret_cast<Type*>(base::subtle::NoBarrier_Load(&instance_))); | |||||
| instance_ = 0; | |||||
| } | |||||
| static base::subtle::AtomicWord instance_; | |||||
| }; | |||||
| template <typename Type, typename Traits, typename DifferentiatingType> | |||||
| base::subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>:: | |||||
| instance_ = 0; | |||||
| #endif // BASE_SINGLETON_H_ | |||||
| @ -0,0 +1,41 @@ | |||||
| // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| // This file is used for debugging assertion support. The Lock class | |||||
| // is functionally a wrapper around the LockImpl class, so the only | |||||
| // real intelligence in the class is in the debugging logic. | |||||
| #if !defined(NDEBUG) | |||||
| #include "base/synchronization/lock.h" | |||||
| #include "base/logging.h" | |||||
| namespace base { | |||||
| Lock::Lock() : lock_() { | |||||
| owned_by_thread_ = false; | |||||
| owning_thread_id_ = static_cast<PlatformThreadId>(0); | |||||
| } | |||||
| void Lock::AssertAcquired() const { | |||||
| DCHECK(owned_by_thread_); | |||||
| DCHECK_EQ(owning_thread_id_, PlatformThread::CurrentId()); | |||||
| } | |||||
| void Lock::CheckHeldAndUnmark() { | |||||
| DCHECK(owned_by_thread_); | |||||
| DCHECK_EQ(owning_thread_id_, PlatformThread::CurrentId()); | |||||
| owned_by_thread_ = false; | |||||
| owning_thread_id_ = static_cast<PlatformThreadId>(0); | |||||
| } | |||||
| void Lock::CheckUnheldAndMark() { | |||||
| DCHECK(!owned_by_thread_); | |||||
| owned_by_thread_ = true; | |||||
| owning_thread_id_ = PlatformThread::CurrentId(); | |||||
| } | |||||
| } // namespace base | |||||
| #endif // NDEBUG | |||||
| @ -0,0 +1,131 @@ | |||||
| // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #ifndef BASE_SYNCHRONIZATION_LOCK_H_ | |||||
| #define BASE_SYNCHRONIZATION_LOCK_H_ | |||||
| #pragma once | |||||
| #include "base/synchronization/lock_impl.h" | |||||
| #include "base/threading/platform_thread.h" | |||||
| namespace base { | |||||
| // A convenient wrapper for an OS specific critical section. The only real | |||||
| // intelligence in this class is in debug mode for the support for the | |||||
| // AssertAcquired() method. | |||||
| class Lock { | |||||
| public: | |||||
| #if defined(NDEBUG) // Optimized wrapper implementation | |||||
| Lock() : lock_() {} | |||||
| ~Lock() {} | |||||
| void Acquire() { lock_.Lock(); } | |||||
| void Release() { lock_.Unlock(); } | |||||
| // If the lock is not held, take it and return true. If the lock is already | |||||
| // held by another thread, immediately return false. This must not be called | |||||
| // by a thread already holding the lock (what happens is undefined and an | |||||
| // assertion may fail). | |||||
| bool Try() { return lock_.Try(); } | |||||
| // Null implementation if not debug. | |||||
| void AssertAcquired() const {} | |||||
| #else | |||||
| Lock(); | |||||
| ~Lock() {} | |||||
| // NOTE: Although windows critical sections support recursive locks, we do not | |||||
| // allow this, and we will commonly fire a DCHECK() if a thread attempts to | |||||
| // acquire the lock a second time (while already holding it). | |||||
| void Acquire() { | |||||
| lock_.Lock(); | |||||
| CheckUnheldAndMark(); | |||||
| } | |||||
| void Release() { | |||||
| CheckHeldAndUnmark(); | |||||
| lock_.Unlock(); | |||||
| } | |||||
| bool Try() { | |||||
| bool rv = lock_.Try(); | |||||
| if (rv) { | |||||
| CheckUnheldAndMark(); | |||||
| } | |||||
| return rv; | |||||
| } | |||||
| void AssertAcquired() const; | |||||
| #endif // NDEBUG | |||||
| #if defined(OS_POSIX) | |||||
| // The posix implementation of ConditionVariable needs to be able | |||||
| // to see our lock and tweak our debugging counters, as it releases | |||||
| // and acquires locks inside of pthread_cond_{timed,}wait. | |||||
| // Windows doesn't need to do this as it calls the Lock::* methods. | |||||
| friend class ConditionVariable; | |||||
| #endif | |||||
| private: | |||||
| #if !defined(NDEBUG) | |||||
| // Members and routines taking care of locks assertions. | |||||
| // Note that this checks for recursive locks and allows them | |||||
| // if the variable is set. This is allowed by the underlying implementation | |||||
| // on windows but not on Posix, so we're doing unneeded checks on Posix. | |||||
| // It's worth it to share the code. | |||||
| void CheckHeldAndUnmark(); | |||||
| void CheckUnheldAndMark(); | |||||
| // All private data is implicitly protected by lock_. | |||||
| // Be VERY careful to only access members under that lock. | |||||
| // Determines validity of owning_thread_id_. Needed as we don't have | |||||
| // a null owning_thread_id_ value. | |||||
| bool owned_by_thread_; | |||||
| base::PlatformThreadId owning_thread_id_; | |||||
| #endif // NDEBUG | |||||
| // Platform specific underlying lock implementation. | |||||
| internal::LockImpl lock_; | |||||
| DISALLOW_COPY_AND_ASSIGN(Lock); | |||||
| }; | |||||
| // A helper class that acquires the given Lock while the AutoLock is in scope. | |||||
| class AutoLock { | |||||
| public: | |||||
| explicit AutoLock(Lock& lock) : lock_(lock) { | |||||
| lock_.Acquire(); | |||||
| } | |||||
| ~AutoLock() { | |||||
| lock_.AssertAcquired(); | |||||
| lock_.Release(); | |||||
| } | |||||
| private: | |||||
| Lock& lock_; | |||||
| DISALLOW_COPY_AND_ASSIGN(AutoLock); | |||||
| }; | |||||
| // AutoUnlock is a helper that will Release() the |lock| argument in the | |||||
| // constructor, and re-Acquire() it in the destructor. | |||||
| class AutoUnlock { | |||||
| public: | |||||
| explicit AutoUnlock(Lock& lock) : lock_(lock) { | |||||
| // We require our caller to have the lock. | |||||
| lock_.AssertAcquired(); | |||||
| lock_.Release(); | |||||
| } | |||||
| ~AutoUnlock() { | |||||
| lock_.Acquire(); | |||||
| } | |||||
| private: | |||||
| Lock& lock_; | |||||
| DISALLOW_COPY_AND_ASSIGN(AutoUnlock); | |||||
| }; | |||||
| } // namespace base | |||||
| #endif // BASE_SYNCHRONIZATION_LOCK_H_ | |||||
| @ -0,0 +1,63 @@ | |||||
| // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #ifndef BASE_SYNCHRONIZATION_LOCK_IMPL_H_ | |||||
| #define BASE_SYNCHRONIZATION_LOCK_IMPL_H_ | |||||
| #pragma once | |||||
| #include "build/build_config.h" | |||||
| #if defined(OS_WIN) | |||||
| #include <windows.h> | |||||
| #elif defined(OS_POSIX) | |||||
| #include <pthread.h> | |||||
| #endif | |||||
| #include "base/basictypes.h" | |||||
| namespace base { | |||||
| namespace internal { | |||||
| // This class implements the underlying platform-specific spin-lock mechanism | |||||
| // used for the Lock class. Most users should not use LockImpl directly, but | |||||
| // should instead use Lock. | |||||
| class LockImpl { | |||||
| public: | |||||
| #if defined(OS_WIN) | |||||
| typedef CRITICAL_SECTION OSLockType; | |||||
| #elif defined(OS_POSIX) | |||||
| typedef pthread_mutex_t OSLockType; | |||||
| #endif | |||||
| LockImpl(); | |||||
| ~LockImpl(); | |||||
| // If the lock is not held, take it and return true. If the lock is already | |||||
| // held by something else, immediately return false. | |||||
| bool Try(); | |||||
| // Take the lock, blocking until it is available if necessary. | |||||
| void Lock(); | |||||
| // Release the lock. This must only be called by the lock's holder: after | |||||
| // a successful call to Try, or a call to Lock. | |||||
| void Unlock(); | |||||
| // Return the native underlying lock. Not supported for Windows builds. | |||||
| // TODO(awalker): refactor lock and condition variables so that this is | |||||
| // unnecessary. | |||||
| #if !defined(OS_WIN) | |||||
| OSLockType* os_lock() { return &os_lock_; } | |||||
| #endif | |||||
| private: | |||||
| OSLockType os_lock_; | |||||
| DISALLOW_COPY_AND_ASSIGN(LockImpl); | |||||
| }; | |||||
| } // namespace internal | |||||
| } // namespace base | |||||
| #endif // BASE_SYNCHRONIZATION_LOCK_IMPL_H_ | |||||
| @ -0,0 +1,54 @@ | |||||
| // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #include "base/synchronization/lock_impl.h" | |||||
| #include <errno.h> | |||||
| #include "base/logging.h" | |||||
| namespace base { | |||||
| namespace internal { | |||||
| LockImpl::LockImpl() { | |||||
| #ifndef NDEBUG | |||||
| // In debug, setup attributes for lock error checking. | |||||
| pthread_mutexattr_t mta; | |||||
| int rv = pthread_mutexattr_init(&mta); | |||||
| DCHECK_EQ(rv, 0); | |||||
| rv = pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_ERRORCHECK); | |||||
| DCHECK_EQ(rv, 0); | |||||
| rv = pthread_mutex_init(&os_lock_, &mta); | |||||
| DCHECK_EQ(rv, 0); | |||||
| rv = pthread_mutexattr_destroy(&mta); | |||||
| DCHECK_EQ(rv, 0); | |||||
| #else | |||||
| // In release, go with the default lock attributes. | |||||
| pthread_mutex_init(&os_lock_, NULL); | |||||
| #endif | |||||
| } | |||||
| LockImpl::~LockImpl() { | |||||
| int rv = pthread_mutex_destroy(&os_lock_); | |||||
| DCHECK_EQ(rv, 0); | |||||
| } | |||||
| bool LockImpl::Try() { | |||||
| int rv = pthread_mutex_trylock(&os_lock_); | |||||
| DCHECK(rv == 0 || rv == EBUSY); | |||||
| return rv == 0; | |||||
| } | |||||
| void LockImpl::Lock() { | |||||
| int rv = pthread_mutex_lock(&os_lock_); | |||||
| DCHECK_EQ(rv, 0); | |||||
| } | |||||
| void LockImpl::Unlock() { | |||||
| int rv = pthread_mutex_unlock(&os_lock_); | |||||
| DCHECK_EQ(rv, 0); | |||||
| } | |||||
| } // namespace internal | |||||
| } // namespace base | |||||
| @ -0,0 +1,36 @@ | |||||
| // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #include "base/synchronization/lock_impl.h" | |||||
| namespace base { | |||||
| namespace internal { | |||||
| LockImpl::LockImpl() { | |||||
| // The second parameter is the spin count, for short-held locks it avoid the | |||||
| // contending thread from going to sleep which helps performance greatly. | |||||
| ::InitializeCriticalSectionAndSpinCount(&os_lock_, 2000); | |||||
| } | |||||
| LockImpl::~LockImpl() { | |||||
| ::DeleteCriticalSection(&os_lock_); | |||||
| } | |||||
| bool LockImpl::Try() { | |||||
| if (::TryEnterCriticalSection(&os_lock_) != FALSE) { | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| void LockImpl::Lock() { | |||||
| ::EnterCriticalSection(&os_lock_); | |||||
| } | |||||
| void LockImpl::Unlock() { | |||||
| ::LeaveCriticalSection(&os_lock_); | |||||
| } | |||||
| } // namespace internal | |||||
| } // namespace base | |||||
| @ -0,0 +1,170 @@ | |||||
| /* Copyright (c) 2008-2009, Google Inc. | |||||
| * All rights reserved. | |||||
| * | |||||
| * 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. | |||||
| * * Neither the name of Google Inc. nor the names of its | |||||
| * contributors may be used to endorse or promote products derived from | |||||
| * this software without specific prior written permission. | |||||
| * | |||||
| * 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 | |||||
| * OWNER 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. | |||||
| * | |||||
| * --- | |||||
| * Author: Kostya Serebryany | |||||
| */ | |||||
| #ifdef _MSC_VER | |||||
| # include <windows.h> | |||||
| #endif | |||||
| #ifdef __cplusplus | |||||
| # error "This file should be built as pure C to avoid name mangling" | |||||
| #endif | |||||
| #include <stdlib.h> | |||||
| #include <string.h> | |||||
| #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | |||||
| #ifdef __GNUC__ | |||||
| /* valgrind.h uses gcc extensions so it won't build with other compilers */ | |||||
| # include "base/third_party/valgrind/valgrind.h" | |||||
| #endif | |||||
| /* Each function is empty and called (via a macro) only in debug mode. | |||||
| The arguments are captured by dynamic tools at runtime. */ | |||||
| #if DYNAMIC_ANNOTATIONS_ENABLED == 1 | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockCreate)( | |||||
| const char *file, int line, const volatile void *lock){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockDestroy)( | |||||
| const char *file, int line, const volatile void *lock){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockAcquired)( | |||||
| const char *file, int line, const volatile void *lock, long is_w){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockReleased)( | |||||
| const char *file, int line, const volatile void *lock, long is_w){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierInit)( | |||||
| const char *file, int line, const volatile void *barrier, long count, | |||||
| long reinitialization_allowed) {} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitBefore)( | |||||
| const char *file, int line, const volatile void *barrier) {} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitAfter)( | |||||
| const char *file, int line, const volatile void *barrier) {} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierDestroy)( | |||||
| const char *file, int line, const volatile void *barrier) {} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarWait)( | |||||
| const char *file, int line, const volatile void *cv, | |||||
| const volatile void *lock){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignal)( | |||||
| const char *file, int line, const volatile void *cv){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignalAll)( | |||||
| const char *file, int line, const volatile void *cv){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotatePublishMemoryRange)( | |||||
| const char *file, int line, const volatile void *address, long size){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateUnpublishMemoryRange)( | |||||
| const char *file, int line, const volatile void *address, long size){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQCreate)( | |||||
| const char *file, int line, const volatile void *pcq){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQDestroy)( | |||||
| const char *file, int line, const volatile void *pcq){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQPut)( | |||||
| const char *file, int line, const volatile void *pcq){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQGet)( | |||||
| const char *file, int line, const volatile void *pcq){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateNewMemory)( | |||||
| const char *file, int line, const volatile void *mem, long size){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateExpectRace)( | |||||
| const char *file, int line, const volatile void *mem, | |||||
| const char *description){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushExpectedRaces)( | |||||
| const char *file, int line){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRace)( | |||||
| const char *file, int line, const volatile void *mem, | |||||
| const char *description){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRaceSized)( | |||||
| const char *file, int line, const volatile void *mem, long size, | |||||
| const char *description){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsUsedAsCondVar)( | |||||
| const char *file, int line, const volatile void *mu){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsNotPHB)( | |||||
| const char *file, int line, const volatile void *mu){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateTraceMemory)( | |||||
| const char *file, int line, const volatile void *arg){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateThreadName)( | |||||
| const char *file, int line, const char *name){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsBegin)( | |||||
| const char *file, int line){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsEnd)( | |||||
| const char *file, int line){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesBegin)( | |||||
| const char *file, int line){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesEnd)( | |||||
| const char *file, int line){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncBegin)( | |||||
| const char *file, int line){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncEnd)( | |||||
| const char *file, int line){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateEnableRaceDetection)( | |||||
| const char *file, int line, int enable){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateNoOp)( | |||||
| const char *file, int line, const volatile void *arg){} | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushState)( | |||||
| const char *file, int line){} | |||||
| #endif /* DYNAMIC_ANNOTATIONS_ENABLED == 1 */ | |||||
| #if DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND == 1 | |||||
| static int GetRunningOnValgrind(void) { | |||||
| #ifdef RUNNING_ON_VALGRIND | |||||
| if (RUNNING_ON_VALGRIND) return 1; | |||||
| #endif | |||||
| #ifndef _MSC_VER | |||||
| char *running_on_valgrind_str = getenv("RUNNING_ON_VALGRIND"); | |||||
| if (running_on_valgrind_str) { | |||||
| return strcmp(running_on_valgrind_str, "0") != 0; | |||||
| } | |||||
| #else | |||||
| /* Visual Studio issues warnings if we use getenv, | |||||
| * so we use GetEnvironmentVariableA instead. | |||||
| */ | |||||
| char value[100] = "1"; | |||||
| int res = GetEnvironmentVariableA("RUNNING_ON_VALGRIND", | |||||
| value, sizeof(value)); | |||||
| /* value will remain "1" if res == 0 or res >= sizeof(value). The latter | |||||
| * can happen only if the given value is long, in this case it can't be "0". | |||||
| */ | |||||
| if (res > 0 && strcmp(value, "0") != 0) | |||||
| return 1; | |||||
| #endif | |||||
| return 0; | |||||
| } | |||||
| /* See the comments in dynamic_annotations.h */ | |||||
| int RunningOnValgrind(void) { | |||||
| static volatile int running_on_valgrind = -1; | |||||
| /* C doesn't have thread-safe initialization of statics, and we | |||||
| don't want to depend on pthread_once here, so hack it. */ | |||||
| int local_running_on_valgrind = running_on_valgrind; | |||||
| if (local_running_on_valgrind == -1) | |||||
| running_on_valgrind = local_running_on_valgrind = GetRunningOnValgrind(); | |||||
| return local_running_on_valgrind; | |||||
| } | |||||
| #endif /* DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND == 1 */ | |||||
| @ -0,0 +1,590 @@ | |||||
| /* Copyright (c) 2008-2009, Google Inc. | |||||
| * All rights reserved. | |||||
| * | |||||
| * 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. | |||||
| * * Neither the name of Google Inc. nor the names of its | |||||
| * contributors may be used to endorse or promote products derived from | |||||
| * this software without specific prior written permission. | |||||
| * | |||||
| * 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 | |||||
| * OWNER 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. | |||||
| * | |||||
| * --- | |||||
| * Author: Kostya Serebryany | |||||
| */ | |||||
| /* This file defines dynamic annotations for use with dynamic analysis | |||||
| tool such as valgrind, PIN, etc. | |||||
| Dynamic annotation is a source code annotation that affects | |||||
| the generated code (that is, the annotation is not a comment). | |||||
| Each such annotation is attached to a particular | |||||
| instruction and/or to a particular object (address) in the program. | |||||
| The annotations that should be used by users are macros in all upper-case | |||||
| (e.g., ANNOTATE_NEW_MEMORY). | |||||
| Actual implementation of these macros may differ depending on the | |||||
| dynamic analysis tool being used. | |||||
| See http://code.google.com/p/data-race-test/ for more information. | |||||
| This file supports the following dynamic analysis tools: | |||||
| - None (DYNAMIC_ANNOTATIONS_ENABLED is not defined or zero). | |||||
| Macros are defined empty. | |||||
| - ThreadSanitizer, Helgrind, DRD (DYNAMIC_ANNOTATIONS_ENABLED is 1). | |||||
| Macros are defined as calls to non-inlinable empty functions | |||||
| that are intercepted by Valgrind. */ | |||||
| #ifndef __DYNAMIC_ANNOTATIONS_H__ | |||||
| #define __DYNAMIC_ANNOTATIONS_H__ | |||||
| #ifndef DYNAMIC_ANNOTATIONS_PREFIX | |||||
| # define DYNAMIC_ANNOTATIONS_PREFIX | |||||
| #endif | |||||
| #ifndef DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND | |||||
| # define DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND 1 | |||||
| #endif | |||||
| #ifdef DYNAMIC_ANNOTATIONS_WANT_ATTRIBUTE_WEAK | |||||
| # ifdef __GNUC__ | |||||
| # define DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK __attribute__((weak)) | |||||
| # else | |||||
| /* TODO(glider): for Windows support we may want to change this macro in order | |||||
| to prepend __declspec(selectany) to the annotations' declarations. */ | |||||
| # error weak annotations are not supported for your compiler | |||||
| # endif | |||||
| #else | |||||
| # define DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK | |||||
| #endif | |||||
| /* The following preprocessor magic prepends the value of | |||||
| DYNAMIC_ANNOTATIONS_PREFIX to annotation function names. */ | |||||
| #define DYNAMIC_ANNOTATIONS_GLUE0(A, B) A##B | |||||
| #define DYNAMIC_ANNOTATIONS_GLUE(A, B) DYNAMIC_ANNOTATIONS_GLUE0(A, B) | |||||
| #define DYNAMIC_ANNOTATIONS_NAME(name) \ | |||||
| DYNAMIC_ANNOTATIONS_GLUE(DYNAMIC_ANNOTATIONS_PREFIX, name) | |||||
| #ifndef DYNAMIC_ANNOTATIONS_ENABLED | |||||
| # define DYNAMIC_ANNOTATIONS_ENABLED 0 | |||||
| #endif | |||||
| #if DYNAMIC_ANNOTATIONS_ENABLED != 0 | |||||
| /* ------------------------------------------------------------- | |||||
| Annotations useful when implementing condition variables such as CondVar, | |||||
| using conditional critical sections (Await/LockWhen) and when constructing | |||||
| user-defined synchronization mechanisms. | |||||
| The annotations ANNOTATE_HAPPENS_BEFORE() and ANNOTATE_HAPPENS_AFTER() can | |||||
| be used to define happens-before arcs in user-defined synchronization | |||||
| mechanisms: the race detector will infer an arc from the former to the | |||||
| latter when they share the same argument pointer. | |||||
| Example 1 (reference counting): | |||||
| void Unref() { | |||||
| ANNOTATE_HAPPENS_BEFORE(&refcount_); | |||||
| if (AtomicDecrementByOne(&refcount_) == 0) { | |||||
| ANNOTATE_HAPPENS_AFTER(&refcount_); | |||||
| delete this; | |||||
| } | |||||
| } | |||||
| Example 2 (message queue): | |||||
| void MyQueue::Put(Type *e) { | |||||
| MutexLock lock(&mu_); | |||||
| ANNOTATE_HAPPENS_BEFORE(e); | |||||
| PutElementIntoMyQueue(e); | |||||
| } | |||||
| Type *MyQueue::Get() { | |||||
| MutexLock lock(&mu_); | |||||
| Type *e = GetElementFromMyQueue(); | |||||
| ANNOTATE_HAPPENS_AFTER(e); | |||||
| return e; | |||||
| } | |||||
| Note: when possible, please use the existing reference counting and message | |||||
| queue implementations instead of inventing new ones. */ | |||||
| /* Report that wait on the condition variable at address "cv" has succeeded | |||||
| and the lock at address "lock" is held. */ | |||||
| #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarWait)(__FILE__, __LINE__, cv, lock) | |||||
| /* Report that wait on the condition variable at "cv" has succeeded. Variant | |||||
| w/o lock. */ | |||||
| #define ANNOTATE_CONDVAR_WAIT(cv) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarWait)(__FILE__, __LINE__, cv, NULL) | |||||
| /* Report that we are about to signal on the condition variable at address | |||||
| "cv". */ | |||||
| #define ANNOTATE_CONDVAR_SIGNAL(cv) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignal)(__FILE__, __LINE__, cv) | |||||
| /* Report that we are about to signal_all on the condition variable at address | |||||
| "cv". */ | |||||
| #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignalAll)(__FILE__, __LINE__, cv) | |||||
| /* Annotations for user-defined synchronization mechanisms. */ | |||||
| #define ANNOTATE_HAPPENS_BEFORE(obj) ANNOTATE_CONDVAR_SIGNAL(obj) | |||||
| #define ANNOTATE_HAPPENS_AFTER(obj) ANNOTATE_CONDVAR_WAIT(obj) | |||||
| /* DEPRECATED. Don't use it. */ | |||||
| #define ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotatePublishMemoryRange)(__FILE__, __LINE__, \ | |||||
| pointer, size) | |||||
| /* DEPRECATED. Don't use it. */ | |||||
| #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(pointer, size) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateUnpublishMemoryRange)(__FILE__, __LINE__, \ | |||||
| pointer, size) | |||||
| /* DEPRECATED. Don't use it. */ | |||||
| #define ANNOTATE_SWAP_MEMORY_RANGE(pointer, size) \ | |||||
| do { \ | |||||
| ANNOTATE_UNPUBLISH_MEMORY_RANGE(pointer, size); \ | |||||
| ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size); \ | |||||
| } while (0) | |||||
| /* Instruct the tool to create a happens-before arc between mu->Unlock() and | |||||
| mu->Lock(). This annotation may slow down the race detector and hide real | |||||
| races. Normally it is used only when it would be difficult to annotate each | |||||
| of the mutex's critical sections individually using the annotations above. | |||||
| This annotation makes sense only for hybrid race detectors. For pure | |||||
| happens-before detectors this is a no-op. For more details see | |||||
| http://code.google.com/p/data-race-test/wiki/PureHappensBeforeVsHybrid . */ | |||||
| #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsUsedAsCondVar)(__FILE__, __LINE__, \ | |||||
| mu) | |||||
| /* Opposite to ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX. | |||||
| Instruct the tool to NOT create h-b arcs between Unlock and Lock, even in | |||||
| pure happens-before mode. For a hybrid mode this is a no-op. */ | |||||
| #define ANNOTATE_NOT_HAPPENS_BEFORE_MUTEX(mu) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsNotPHB)(__FILE__, __LINE__, mu) | |||||
| /* Deprecated. Use ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX. */ | |||||
| #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsUsedAsCondVar)(__FILE__, __LINE__, \ | |||||
| mu) | |||||
| /* ------------------------------------------------------------- | |||||
| Annotations useful when defining memory allocators, or when memory that | |||||
| was protected in one way starts to be protected in another. */ | |||||
| /* Report that a new memory at "address" of size "size" has been allocated. | |||||
| This might be used when the memory has been retrieved from a free list and | |||||
| is about to be reused, or when a the locking discipline for a variable | |||||
| changes. */ | |||||
| #define ANNOTATE_NEW_MEMORY(address, size) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateNewMemory)(__FILE__, __LINE__, address, \ | |||||
| size) | |||||
| /* ------------------------------------------------------------- | |||||
| Annotations useful when defining FIFO queues that transfer data between | |||||
| threads. */ | |||||
| /* Report that the producer-consumer queue (such as ProducerConsumerQueue) at | |||||
| address "pcq" has been created. The ANNOTATE_PCQ_* annotations | |||||
| should be used only for FIFO queues. For non-FIFO queues use | |||||
| ANNOTATE_HAPPENS_BEFORE (for put) and ANNOTATE_HAPPENS_AFTER (for get). */ | |||||
| #define ANNOTATE_PCQ_CREATE(pcq) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQCreate)(__FILE__, __LINE__, pcq) | |||||
| /* Report that the queue at address "pcq" is about to be destroyed. */ | |||||
| #define ANNOTATE_PCQ_DESTROY(pcq) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQDestroy)(__FILE__, __LINE__, pcq) | |||||
| /* Report that we are about to put an element into a FIFO queue at address | |||||
| "pcq". */ | |||||
| #define ANNOTATE_PCQ_PUT(pcq) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQPut)(__FILE__, __LINE__, pcq) | |||||
| /* Report that we've just got an element from a FIFO queue at address | |||||
| "pcq". */ | |||||
| #define ANNOTATE_PCQ_GET(pcq) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQGet)(__FILE__, __LINE__, pcq) | |||||
| /* ------------------------------------------------------------- | |||||
| Annotations that suppress errors. It is usually better to express the | |||||
| program's synchronization using the other annotations, but these can | |||||
| be used when all else fails. */ | |||||
| /* Report that we may have a benign race at "pointer", with size | |||||
| "sizeof(*(pointer))". "pointer" must be a non-void* pointer. Insert at the | |||||
| point where "pointer" has been allocated, preferably close to the point | |||||
| where the race happens. See also ANNOTATE_BENIGN_RACE_STATIC. */ | |||||
| #define ANNOTATE_BENIGN_RACE(pointer, description) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRaceSized)(__FILE__, __LINE__, \ | |||||
| pointer, sizeof(*(pointer)), description) | |||||
| /* Same as ANNOTATE_BENIGN_RACE(address, description), but applies to | |||||
| the memory range [address, address+size). */ | |||||
| #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRaceSized)(__FILE__, __LINE__, \ | |||||
| address, size, description) | |||||
| /* Request the analysis tool to ignore all reads in the current thread | |||||
| until ANNOTATE_IGNORE_READS_END is called. | |||||
| Useful to ignore intentional racey reads, while still checking | |||||
| other reads and all writes. | |||||
| See also ANNOTATE_UNPROTECTED_READ. */ | |||||
| #define ANNOTATE_IGNORE_READS_BEGIN() \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsBegin)(__FILE__, __LINE__) | |||||
| /* Stop ignoring reads. */ | |||||
| #define ANNOTATE_IGNORE_READS_END() \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsEnd)(__FILE__, __LINE__) | |||||
| /* Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. */ | |||||
| #define ANNOTATE_IGNORE_WRITES_BEGIN() \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesBegin)(__FILE__, __LINE__) | |||||
| /* Stop ignoring writes. */ | |||||
| #define ANNOTATE_IGNORE_WRITES_END() \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesEnd)(__FILE__, __LINE__) | |||||
| /* Start ignoring all memory accesses (reads and writes). */ | |||||
| #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ | |||||
| do {\ | |||||
| ANNOTATE_IGNORE_READS_BEGIN();\ | |||||
| ANNOTATE_IGNORE_WRITES_BEGIN();\ | |||||
| }while(0)\ | |||||
| /* Stop ignoring all memory accesses. */ | |||||
| #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ | |||||
| do {\ | |||||
| ANNOTATE_IGNORE_WRITES_END();\ | |||||
| ANNOTATE_IGNORE_READS_END();\ | |||||
| }while(0)\ | |||||
| /* Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore synchronization events: | |||||
| RWLOCK* and CONDVAR*. */ | |||||
| #define ANNOTATE_IGNORE_SYNC_BEGIN() \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncBegin)(__FILE__, __LINE__) | |||||
| /* Stop ignoring sync events. */ | |||||
| #define ANNOTATE_IGNORE_SYNC_END() \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncEnd)(__FILE__, __LINE__) | |||||
| /* Enable (enable!=0) or disable (enable==0) race detection for all threads. | |||||
| This annotation could be useful if you want to skip expensive race analysis | |||||
| during some period of program execution, e.g. during initialization. */ | |||||
| #define ANNOTATE_ENABLE_RACE_DETECTION(enable) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateEnableRaceDetection)(__FILE__, __LINE__, \ | |||||
| enable) | |||||
| /* ------------------------------------------------------------- | |||||
| Annotations useful for debugging. */ | |||||
| /* Request to trace every access to "address". */ | |||||
| #define ANNOTATE_TRACE_MEMORY(address) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateTraceMemory)(__FILE__, __LINE__, address) | |||||
| /* Report the current thread name to a race detector. */ | |||||
| #define ANNOTATE_THREAD_NAME(name) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateThreadName)(__FILE__, __LINE__, name) | |||||
| /* ------------------------------------------------------------- | |||||
| Annotations useful when implementing locks. They are not | |||||
| normally needed by modules that merely use locks. | |||||
| The "lock" argument is a pointer to the lock object. */ | |||||
| /* Report that a lock has been created at address "lock". */ | |||||
| #define ANNOTATE_RWLOCK_CREATE(lock) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockCreate)(__FILE__, __LINE__, lock) | |||||
| /* Report that the lock at address "lock" is about to be destroyed. */ | |||||
| #define ANNOTATE_RWLOCK_DESTROY(lock) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockDestroy)(__FILE__, __LINE__, lock) | |||||
| /* Report that the lock at address "lock" has been acquired. | |||||
| is_w=1 for writer lock, is_w=0 for reader lock. */ | |||||
| #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockAcquired)(__FILE__, __LINE__, lock, \ | |||||
| is_w) | |||||
| /* Report that the lock at address "lock" is about to be released. */ | |||||
| #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockReleased)(__FILE__, __LINE__, lock, \ | |||||
| is_w) | |||||
| /* ------------------------------------------------------------- | |||||
| Annotations useful when implementing barriers. They are not | |||||
| normally needed by modules that merely use barriers. | |||||
| The "barrier" argument is a pointer to the barrier object. */ | |||||
| /* Report that the "barrier" has been initialized with initial "count". | |||||
| If 'reinitialization_allowed' is true, initialization is allowed to happen | |||||
| multiple times w/o calling barrier_destroy() */ | |||||
| #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierInit)(__FILE__, __LINE__, barrier, \ | |||||
| count, reinitialization_allowed) | |||||
| /* Report that we are about to enter barrier_wait("barrier"). */ | |||||
| #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitBefore)(__FILE__, __LINE__, \ | |||||
| barrier) | |||||
| /* Report that we just exited barrier_wait("barrier"). */ | |||||
| #define ANNOTATE_BARRIER_WAIT_AFTER(barrier) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitAfter)(__FILE__, __LINE__, \ | |||||
| barrier) | |||||
| /* Report that the "barrier" has been destroyed. */ | |||||
| #define ANNOTATE_BARRIER_DESTROY(barrier) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierDestroy)(__FILE__, __LINE__, \ | |||||
| barrier) | |||||
| /* ------------------------------------------------------------- | |||||
| Annotations useful for testing race detectors. */ | |||||
| /* Report that we expect a race on the variable at "address". | |||||
| Use only in unit tests for a race detector. */ | |||||
| #define ANNOTATE_EXPECT_RACE(address, description) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateExpectRace)(__FILE__, __LINE__, address, \ | |||||
| description) | |||||
| #define ANNOTATE_FLUSH_EXPECTED_RACES() \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushExpectedRaces)(__FILE__, __LINE__) | |||||
| /* A no-op. Insert where you like to test the interceptors. */ | |||||
| #define ANNOTATE_NO_OP(arg) \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateNoOp)(__FILE__, __LINE__, arg) | |||||
| /* Force the race detector to flush its state. The actual effect depends on | |||||
| * the implementation of the detector. */ | |||||
| #define ANNOTATE_FLUSH_STATE() \ | |||||
| DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushState)(__FILE__, __LINE__) | |||||
| #else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ | |||||
| #define ANNOTATE_RWLOCK_CREATE(lock) /* empty */ | |||||
| #define ANNOTATE_RWLOCK_DESTROY(lock) /* empty */ | |||||
| #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */ | |||||
| #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */ | |||||
| #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) /* */ | |||||
| #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) /* empty */ | |||||
| #define ANNOTATE_BARRIER_WAIT_AFTER(barrier) /* empty */ | |||||
| #define ANNOTATE_BARRIER_DESTROY(barrier) /* empty */ | |||||
| #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) /* empty */ | |||||
| #define ANNOTATE_CONDVAR_WAIT(cv) /* empty */ | |||||
| #define ANNOTATE_CONDVAR_SIGNAL(cv) /* empty */ | |||||
| #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) /* empty */ | |||||
| #define ANNOTATE_HAPPENS_BEFORE(obj) /* empty */ | |||||
| #define ANNOTATE_HAPPENS_AFTER(obj) /* empty */ | |||||
| #define ANNOTATE_PUBLISH_MEMORY_RANGE(address, size) /* empty */ | |||||
| #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(address, size) /* empty */ | |||||
| #define ANNOTATE_SWAP_MEMORY_RANGE(address, size) /* empty */ | |||||
| #define ANNOTATE_PCQ_CREATE(pcq) /* empty */ | |||||
| #define ANNOTATE_PCQ_DESTROY(pcq) /* empty */ | |||||
| #define ANNOTATE_PCQ_PUT(pcq) /* empty */ | |||||
| #define ANNOTATE_PCQ_GET(pcq) /* empty */ | |||||
| #define ANNOTATE_NEW_MEMORY(address, size) /* empty */ | |||||
| #define ANNOTATE_EXPECT_RACE(address, description) /* empty */ | |||||
| #define ANNOTATE_FLUSH_EXPECTED_RACES(address, description) /* empty */ | |||||
| #define ANNOTATE_BENIGN_RACE(address, description) /* empty */ | |||||
| #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */ | |||||
| #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) /* empty */ | |||||
| #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) /* empty */ | |||||
| #define ANNOTATE_TRACE_MEMORY(arg) /* empty */ | |||||
| #define ANNOTATE_THREAD_NAME(name) /* empty */ | |||||
| #define ANNOTATE_IGNORE_READS_BEGIN() /* empty */ | |||||
| #define ANNOTATE_IGNORE_READS_END() /* empty */ | |||||
| #define ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */ | |||||
| #define ANNOTATE_IGNORE_WRITES_END() /* empty */ | |||||
| #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */ | |||||
| #define ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */ | |||||
| #define ANNOTATE_IGNORE_SYNC_BEGIN() /* empty */ | |||||
| #define ANNOTATE_IGNORE_SYNC_END() /* empty */ | |||||
| #define ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */ | |||||
| #define ANNOTATE_NO_OP(arg) /* empty */ | |||||
| #define ANNOTATE_FLUSH_STATE() /* empty */ | |||||
| #endif /* DYNAMIC_ANNOTATIONS_ENABLED */ | |||||
| /* Use the macros above rather than using these functions directly. */ | |||||
| #ifdef __cplusplus | |||||
| extern "C" { | |||||
| #endif | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockCreate)( | |||||
| const char *file, int line, | |||||
| const volatile void *lock) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockDestroy)( | |||||
| const char *file, int line, | |||||
| const volatile void *lock) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockAcquired)( | |||||
| const char *file, int line, | |||||
| const volatile void *lock, long is_w) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockReleased)( | |||||
| const char *file, int line, | |||||
| const volatile void *lock, long is_w) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierInit)( | |||||
| const char *file, int line, const volatile void *barrier, long count, | |||||
| long reinitialization_allowed) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitBefore)( | |||||
| const char *file, int line, | |||||
| const volatile void *barrier) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitAfter)( | |||||
| const char *file, int line, | |||||
| const volatile void *barrier) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierDestroy)( | |||||
| const char *file, int line, | |||||
| const volatile void *barrier) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarWait)( | |||||
| const char *file, int line, const volatile void *cv, | |||||
| const volatile void *lock) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignal)( | |||||
| const char *file, int line, | |||||
| const volatile void *cv) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignalAll)( | |||||
| const char *file, int line, | |||||
| const volatile void *cv) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotatePublishMemoryRange)( | |||||
| const char *file, int line, | |||||
| const volatile void *address, long size) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateUnpublishMemoryRange)( | |||||
| const char *file, int line, | |||||
| const volatile void *address, long size) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQCreate)( | |||||
| const char *file, int line, | |||||
| const volatile void *pcq) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQDestroy)( | |||||
| const char *file, int line, | |||||
| const volatile void *pcq) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQPut)( | |||||
| const char *file, int line, | |||||
| const volatile void *pcq) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQGet)( | |||||
| const char *file, int line, | |||||
| const volatile void *pcq) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateNewMemory)( | |||||
| const char *file, int line, | |||||
| const volatile void *mem, long size) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateExpectRace)( | |||||
| const char *file, int line, const volatile void *mem, | |||||
| const char *description) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushExpectedRaces)( | |||||
| const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRace)( | |||||
| const char *file, int line, const volatile void *mem, | |||||
| const char *description) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRaceSized)( | |||||
| const char *file, int line, const volatile void *mem, long size, | |||||
| const char *description) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsUsedAsCondVar)( | |||||
| const char *file, int line, | |||||
| const volatile void *mu) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsNotPHB)( | |||||
| const char *file, int line, | |||||
| const volatile void *mu) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateTraceMemory)( | |||||
| const char *file, int line, | |||||
| const volatile void *arg) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateThreadName)( | |||||
| const char *file, int line, | |||||
| const char *name) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsBegin)( | |||||
| const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsEnd)( | |||||
| const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesBegin)( | |||||
| const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesEnd)( | |||||
| const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncBegin)( | |||||
| const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncEnd)( | |||||
| const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateEnableRaceDetection)( | |||||
| const char *file, int line, int enable) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateNoOp)( | |||||
| const char *file, int line, | |||||
| const volatile void *arg) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| void DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushState)( | |||||
| const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; | |||||
| #if DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND == 1 | |||||
| /* Return non-zero value if running under valgrind. | |||||
| If "valgrind.h" is included into dynamic_annotations.c, | |||||
| the regular valgrind mechanism will be used. | |||||
| See http://valgrind.org/docs/manual/manual-core-adv.html about | |||||
| RUNNING_ON_VALGRIND and other valgrind "client requests". | |||||
| The file "valgrind.h" may be obtained by doing | |||||
| svn co svn://svn.valgrind.org/valgrind/trunk/include | |||||
| If for some reason you can't use "valgrind.h" or want to fake valgrind, | |||||
| there are two ways to make this function return non-zero: | |||||
| - Use environment variable: export RUNNING_ON_VALGRIND=1 | |||||
| - Make your tool intercept the function RunningOnValgrind() and | |||||
| change its return value. | |||||
| */ | |||||
| int RunningOnValgrind(void); | |||||
| #endif /* DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND == 1 */ | |||||
| #ifdef __cplusplus | |||||
| } | |||||
| #endif | |||||
| #if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus) | |||||
| /* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. | |||||
| Instead of doing | |||||
| ANNOTATE_IGNORE_READS_BEGIN(); | |||||
| ... = x; | |||||
| ANNOTATE_IGNORE_READS_END(); | |||||
| one can use | |||||
| ... = ANNOTATE_UNPROTECTED_READ(x); */ | |||||
| template <class T> | |||||
| inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) { | |||||
| ANNOTATE_IGNORE_READS_BEGIN(); | |||||
| T res = x; | |||||
| ANNOTATE_IGNORE_READS_END(); | |||||
| return res; | |||||
| } | |||||
| /* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */ | |||||
| #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ | |||||
| namespace { \ | |||||
| class static_var ## _annotator { \ | |||||
| public: \ | |||||
| static_var ## _annotator() { \ | |||||
| ANNOTATE_BENIGN_RACE_SIZED(&static_var, \ | |||||
| sizeof(static_var), \ | |||||
| # static_var ": " description); \ | |||||
| } \ | |||||
| }; \ | |||||
| static static_var ## _annotator the ## static_var ## _annotator;\ | |||||
| } | |||||
| #else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ | |||||
| #define ANNOTATE_UNPROTECTED_READ(x) (x) | |||||
| #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */ | |||||
| #endif /* DYNAMIC_ANNOTATIONS_ENABLED */ | |||||
| #endif /* __DYNAMIC_ANNOTATIONS_H__ */ | |||||
| @ -0,0 +1,99 @@ | |||||
| // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| // WARNING: You should *NOT* be using this class directly. PlatformThread is | |||||
| // the low-level platform-specific abstraction to the OS's threading interface. | |||||
| // You should instead be using a message-loop driven Thread, see thread.h. | |||||
| #ifndef BASE_THREADING_PLATFORM_THREAD_H_ | |||||
| #define BASE_THREADING_PLATFORM_THREAD_H_ | |||||
| #pragma once | |||||
| #include "base/basictypes.h" | |||||
| #include "build/build_config.h" | |||||
| #if defined(OS_WIN) | |||||
| #include <windows.h> | |||||
| #elif defined(OS_POSIX) | |||||
| #include <pthread.h> | |||||
| #if defined(OS_MACOSX) | |||||
| #include <mach/mach.h> | |||||
| #else // OS_POSIX && !OS_MACOSX | |||||
| #include <unistd.h> | |||||
| #endif | |||||
| #endif | |||||
| namespace base { | |||||
| // PlatformThreadHandle should not be assumed to be a numeric type, since the | |||||
| // standard intends to allow pthread_t to be a structure. This means you | |||||
| // should not initialize it to a value, like 0. If it's a member variable, the | |||||
| // constructor can safely "value initialize" using () in the initializer list. | |||||
| #if defined(OS_WIN) | |||||
| typedef DWORD PlatformThreadId; | |||||
| typedef void* PlatformThreadHandle; // HANDLE | |||||
| const PlatformThreadHandle kNullThreadHandle = NULL; | |||||
| #elif defined(OS_POSIX) | |||||
| typedef pthread_t PlatformThreadHandle; | |||||
| const PlatformThreadHandle kNullThreadHandle = 0; | |||||
| #if defined(OS_MACOSX) | |||||
| typedef mach_port_t PlatformThreadId; | |||||
| #else // OS_POSIX && !OS_MACOSX | |||||
| typedef pid_t PlatformThreadId; | |||||
| #endif | |||||
| #endif | |||||
| const PlatformThreadId kInvalidThreadId = 0; | |||||
| // A namespace for low-level thread functions. | |||||
| class PlatformThread { | |||||
| public: | |||||
| // Implement this interface to run code on a background thread. Your | |||||
| // ThreadMain method will be called on the newly created thread. | |||||
| class Delegate { | |||||
| public: | |||||
| virtual ~Delegate() {} | |||||
| virtual void ThreadMain() = 0; | |||||
| }; | |||||
| // Gets the current thread id, which may be useful for logging purposes. | |||||
| static PlatformThreadId CurrentId(); | |||||
| // Yield the current thread so another thread can be scheduled. | |||||
| static void YieldCurrentThread(); | |||||
| // Sleeps for the specified duration (units are milliseconds). | |||||
| static void Sleep(int duration_ms); | |||||
| // Sets the thread name visible to a debugger. This has no effect otherwise. | |||||
| static void SetName(const char* name); | |||||
| // Creates a new thread. The |stack_size| parameter can be 0 to indicate | |||||
| // that the default stack size should be used. Upon success, | |||||
| // |*thread_handle| will be assigned a handle to the newly created thread, | |||||
| // and |delegate|'s ThreadMain method will be executed on the newly created | |||||
| // thread. | |||||
| // NOTE: When you are done with the thread handle, you must call Join to | |||||
| // release system resources associated with the thread. You must ensure that | |||||
| // the Delegate object outlives the thread. | |||||
| static bool Create(size_t stack_size, Delegate* delegate, | |||||
| PlatformThreadHandle* thread_handle); | |||||
| // CreateNonJoinable() does the same thing as Create() except the thread | |||||
| // cannot be Join()'d. Therefore, it also does not output a | |||||
| // PlatformThreadHandle. | |||||
| static bool CreateNonJoinable(size_t stack_size, Delegate* delegate); | |||||
| // Joins with a thread created via the Create function. This function blocks | |||||
| // the caller until the designated thread exits. This will invalidate | |||||
| // |thread_handle|. | |||||
| static void Join(PlatformThreadHandle thread_handle); | |||||
| private: | |||||
| DISALLOW_IMPLICIT_CONSTRUCTORS(PlatformThread); | |||||
| }; | |||||
| } // namespace base | |||||
| #endif // BASE_THREADING_PLATFORM_THREAD_H_ | |||||
| @ -0,0 +1,225 @@ | |||||
| // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #include "base/threading/platform_thread.h" | |||||
| #include <errno.h> | |||||
| #include <sched.h> | |||||
| #include "base/logging.h" | |||||
| #include "base/safe_strerror_posix.h" | |||||
| #include "base/scoped_ptr.h" | |||||
| #include "base/threading/thread_restrictions.h" | |||||
| #if defined(OS_MACOSX) | |||||
| #include <mach/mach.h> | |||||
| #include <sys/resource.h> | |||||
| #include <algorithm> | |||||
| #endif | |||||
| #if defined(OS_LINUX) | |||||
| #include <dlfcn.h> | |||||
| #include <sys/prctl.h> | |||||
| #include <sys/syscall.h> | |||||
| #include <unistd.h> | |||||
| #endif | |||||
| #if defined(OS_NACL) | |||||
| #include <sys/nacl_syscalls.h> | |||||
| #endif | |||||
| namespace base { | |||||
| #if defined(OS_MACOSX) | |||||
| void InitThreading(); | |||||
| #endif | |||||
| namespace { | |||||
| struct ThreadParams { | |||||
| PlatformThread::Delegate* delegate; | |||||
| bool joinable; | |||||
| }; | |||||
| void* ThreadFunc(void* params) { | |||||
| ThreadParams* thread_params = static_cast<ThreadParams*>(params); | |||||
| PlatformThread::Delegate* delegate = thread_params->delegate; | |||||
| if (!thread_params->joinable) | |||||
| base::ThreadRestrictions::SetSingletonAllowed(false); | |||||
| delete thread_params; | |||||
| delegate->ThreadMain(); | |||||
| return NULL; | |||||
| } | |||||
| bool CreateThread(size_t stack_size, bool joinable, | |||||
| PlatformThread::Delegate* delegate, | |||||
| PlatformThreadHandle* thread_handle) { | |||||
| #if defined(OS_MACOSX) | |||||
| base::InitThreading(); | |||||
| #endif // OS_MACOSX | |||||
| bool success = false; | |||||
| pthread_attr_t attributes; | |||||
| pthread_attr_init(&attributes); | |||||
| // Pthreads are joinable by default, so only specify the detached attribute if | |||||
| // the thread should be non-joinable. | |||||
| if (!joinable) { | |||||
| pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED); | |||||
| } | |||||
| #if defined(OS_MACOSX) | |||||
| // The Mac OS X default for a pthread stack size is 512kB. | |||||
| // Libc-594.1.4/pthreads/pthread.c's pthread_attr_init uses | |||||
| // DEFAULT_STACK_SIZE for this purpose. | |||||
| // | |||||
| // 512kB isn't quite generous enough for some deeply recursive threads that | |||||
| // otherwise request the default stack size by specifying 0. Here, adopt | |||||
| // glibc's behavior as on Linux, which is to use the current stack size | |||||
| // limit (ulimit -s) as the default stack size. See | |||||
| // glibc-2.11.1/nptl/nptl-init.c's __pthread_initialize_minimal_internal. To | |||||
| // avoid setting the limit below the Mac OS X default or the minimum usable | |||||
| // stack size, these values are also considered. If any of these values | |||||
| // can't be determined, or if stack size is unlimited (ulimit -s unlimited), | |||||
| // stack_size is left at 0 to get the system default. | |||||
| // | |||||
| // Mac OS X normally only applies ulimit -s to the main thread stack. On | |||||
| // contemporary OS X and Linux systems alike, this value is generally 8MB | |||||
| // or in that neighborhood. | |||||
| if (stack_size == 0) { | |||||
| size_t default_stack_size; | |||||
| struct rlimit stack_rlimit; | |||||
| if (pthread_attr_getstacksize(&attributes, &default_stack_size) == 0 && | |||||
| getrlimit(RLIMIT_STACK, &stack_rlimit) == 0 && | |||||
| stack_rlimit.rlim_cur != RLIM_INFINITY) { | |||||
| stack_size = std::max(std::max(default_stack_size, | |||||
| static_cast<size_t>(PTHREAD_STACK_MIN)), | |||||
| static_cast<size_t>(stack_rlimit.rlim_cur)); | |||||
| } | |||||
| } | |||||
| #endif // OS_MACOSX | |||||
| if (stack_size > 0) | |||||
| pthread_attr_setstacksize(&attributes, stack_size); | |||||
| ThreadParams* params = new ThreadParams; | |||||
| params->delegate = delegate; | |||||
| params->joinable = joinable; | |||||
| success = !pthread_create(thread_handle, &attributes, ThreadFunc, params); | |||||
| pthread_attr_destroy(&attributes); | |||||
| if (!success) | |||||
| delete params; | |||||
| return success; | |||||
| } | |||||
| } // namespace | |||||
| // static | |||||
| PlatformThreadId PlatformThread::CurrentId() { | |||||
| // Pthreads doesn't have the concept of a thread ID, so we have to reach down | |||||
| // into the kernel. | |||||
| #if defined(OS_MACOSX) | |||||
| return mach_thread_self(); | |||||
| #elif defined(OS_LINUX) | |||||
| return syscall(__NR_gettid); | |||||
| #elif defined(OS_FREEBSD) | |||||
| // TODO(BSD): find a better thread ID | |||||
| return reinterpret_cast<int64>(pthread_self()); | |||||
| #elif defined(OS_NACL) | |||||
| return pthread_self(); | |||||
| #endif | |||||
| } | |||||
| // static | |||||
| void PlatformThread::YieldCurrentThread() { | |||||
| sched_yield(); | |||||
| } | |||||
| // static | |||||
| void PlatformThread::Sleep(int duration_ms) { | |||||
| struct timespec sleep_time, remaining; | |||||
| // Contains the portion of duration_ms >= 1 sec. | |||||
| sleep_time.tv_sec = duration_ms / 1000; | |||||
| duration_ms -= sleep_time.tv_sec * 1000; | |||||
| // Contains the portion of duration_ms < 1 sec. | |||||
| sleep_time.tv_nsec = duration_ms * 1000 * 1000; // nanoseconds. | |||||
| while (nanosleep(&sleep_time, &remaining) == -1 && errno == EINTR) | |||||
| sleep_time = remaining; | |||||
| } | |||||
| // Linux SetName is currently disabled, as we need to distinguish between | |||||
| // helper threads (where it's ok to make this call) and the main thread | |||||
| // (where making this call renames our process, causing tools like killall | |||||
| // to stop working). | |||||
| #if 0 && defined(OS_LINUX) | |||||
| // static | |||||
| void PlatformThread::SetName(const char* name) { | |||||
| // http://0pointer.de/blog/projects/name-your-threads.html | |||||
| // glibc recently added support for pthread_setname_np, but it's not | |||||
| // commonly available yet. So test for it at runtime. | |||||
| int (*dynamic_pthread_setname_np)(pthread_t, const char*); | |||||
| *reinterpret_cast<void**>(&dynamic_pthread_setname_np) = | |||||
| dlsym(RTLD_DEFAULT, "pthread_setname_np"); | |||||
| if (dynamic_pthread_setname_np) { | |||||
| // This limit comes from glibc, which gets it from the kernel | |||||
| // (TASK_COMM_LEN). | |||||
| const int kMaxNameLength = 15; | |||||
| std::string shortened_name = std::string(name).substr(0, kMaxNameLength); | |||||
| int err = dynamic_pthread_setname_np(pthread_self(), | |||||
| shortened_name.c_str()); | |||||
| if (err < 0) | |||||
| LOG(ERROR) << "pthread_setname_np: " << safe_strerror(err); | |||||
| } else { | |||||
| // Implementing this function without glibc is simple enough. (We | |||||
| // don't do the name length clipping as above because it will be | |||||
| // truncated by the callee (see TASK_COMM_LEN above).) | |||||
| int err = prctl(PR_SET_NAME, name); | |||||
| if (err < 0) | |||||
| PLOG(ERROR) << "prctl(PR_SET_NAME)"; | |||||
| } | |||||
| } | |||||
| #elif defined(OS_MACOSX) | |||||
| // Mac is implemented in platform_thread_mac.mm. | |||||
| #else | |||||
| // static | |||||
| void PlatformThread::SetName(const char* /* name */) { | |||||
| // Leave it unimplemented. | |||||
| // (This should be relatively simple to implement for the BSDs; I | |||||
| // just don't have one handy to test the code on.) | |||||
| } | |||||
| #endif // defined(OS_LINUX) | |||||
| // static | |||||
| bool PlatformThread::Create(size_t stack_size, Delegate* delegate, | |||||
| PlatformThreadHandle* thread_handle) { | |||||
| return CreateThread(stack_size, true /* joinable thread */, | |||||
| delegate, thread_handle); | |||||
| } | |||||
| // static | |||||
| bool PlatformThread::CreateNonJoinable(size_t stack_size, Delegate* delegate) { | |||||
| PlatformThreadHandle unused; | |||||
| bool result = CreateThread(stack_size, false /* non-joinable thread */, | |||||
| delegate, &unused); | |||||
| return result; | |||||
| } | |||||
| // static | |||||
| void PlatformThread::Join(PlatformThreadHandle thread_handle) { | |||||
| // Joining another thread may block the current thread for a long time, since | |||||
| // the thread referred to by |thread_handle| may still be running long-lived / | |||||
| // blocking tasks. | |||||
| base::ThreadRestrictions::AssertIOAllowed(); | |||||
| pthread_join(thread_handle, NULL); | |||||
| } | |||||
| } // namespace base | |||||
| @ -0,0 +1,147 @@ | |||||
| // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #include "base/threading/platform_thread.h" | |||||
| #include "base/logging.h" | |||||
| #include "base/threading/thread_restrictions.h" | |||||
| #include "base/win/windows_version.h" | |||||
| namespace base { | |||||
| namespace { | |||||
| // The information on how to set the thread name comes from | |||||
| // a MSDN article: http://msdn2.microsoft.com/en-us/library/xcb2z8hs.aspx | |||||
| const DWORD kVCThreadNameException = 0x406D1388; | |||||
| typedef struct tagTHREADNAME_INFO { | |||||
| DWORD dwType; // Must be 0x1000. | |||||
| LPCSTR szName; // Pointer to name (in user addr space). | |||||
| DWORD dwThreadID; // Thread ID (-1=caller thread). | |||||
| DWORD dwFlags; // Reserved for future use, must be zero. | |||||
| } THREADNAME_INFO; | |||||
| struct ThreadParams { | |||||
| PlatformThread::Delegate* delegate; | |||||
| bool joinable; | |||||
| }; | |||||
| DWORD __stdcall ThreadFunc(void* params) { | |||||
| ThreadParams* thread_params = static_cast<ThreadParams*>(params); | |||||
| PlatformThread::Delegate* delegate = thread_params->delegate; | |||||
| if (!thread_params->joinable) | |||||
| base::ThreadRestrictions::SetSingletonAllowed(false); | |||||
| delete thread_params; | |||||
| delegate->ThreadMain(); | |||||
| return NULL; | |||||
| } | |||||
| // CreateThreadInternal() matches PlatformThread::Create(), except that | |||||
| // |out_thread_handle| may be NULL, in which case a non-joinable thread is | |||||
| // created. | |||||
| bool CreateThreadInternal(size_t stack_size, | |||||
| PlatformThread::Delegate* delegate, | |||||
| PlatformThreadHandle* out_thread_handle) { | |||||
| PlatformThreadHandle thread_handle; | |||||
| unsigned int flags = 0; | |||||
| if (stack_size > 0 && base::win::GetVersion() >= base::win::VERSION_XP) { | |||||
| flags = STACK_SIZE_PARAM_IS_A_RESERVATION; | |||||
| } else { | |||||
| stack_size = 0; | |||||
| } | |||||
| ThreadParams* params = new ThreadParams; | |||||
| params->delegate = delegate; | |||||
| params->joinable = out_thread_handle != NULL; | |||||
| // Using CreateThread here vs _beginthreadex makes thread creation a bit | |||||
| // faster and doesn't require the loader lock to be available. Our code will | |||||
| // have to work running on CreateThread() threads anyway, since we run code | |||||
| // on the Windows thread pool, etc. For some background on the difference: | |||||
| // http://www.microsoft.com/msj/1099/win32/win321099.aspx | |||||
| thread_handle = CreateThread( | |||||
| NULL, stack_size, ThreadFunc, params, flags, NULL); | |||||
| if (!thread_handle) { | |||||
| delete params; | |||||
| return false; | |||||
| } | |||||
| if (out_thread_handle) | |||||
| *out_thread_handle = thread_handle; | |||||
| else | |||||
| CloseHandle(thread_handle); | |||||
| return true; | |||||
| } | |||||
| } // namespace | |||||
| // static | |||||
| PlatformThreadId PlatformThread::CurrentId() { | |||||
| return GetCurrentThreadId(); | |||||
| } | |||||
| // static | |||||
| void PlatformThread::YieldCurrentThread() { | |||||
| ::Sleep(0); | |||||
| } | |||||
| // static | |||||
| void PlatformThread::Sleep(int duration_ms) { | |||||
| ::Sleep(duration_ms); | |||||
| } | |||||
| // static | |||||
| void PlatformThread::SetName(const char* name) { | |||||
| // The debugger needs to be around to catch the name in the exception. If | |||||
| // there isn't a debugger, we are just needlessly throwing an exception. | |||||
| if (!::IsDebuggerPresent()) | |||||
| return; | |||||
| THREADNAME_INFO info; | |||||
| info.dwType = 0x1000; | |||||
| info.szName = name; | |||||
| info.dwThreadID = CurrentId(); | |||||
| info.dwFlags = 0; | |||||
| __try { | |||||
| RaiseException(kVCThreadNameException, 0, sizeof(info)/sizeof(DWORD), | |||||
| reinterpret_cast<DWORD_PTR*>(&info)); | |||||
| } __except(EXCEPTION_CONTINUE_EXECUTION) { | |||||
| } | |||||
| } | |||||
| // static | |||||
| bool PlatformThread::Create(size_t stack_size, Delegate* delegate, | |||||
| PlatformThreadHandle* thread_handle) { | |||||
| DCHECK(thread_handle); | |||||
| return CreateThreadInternal(stack_size, delegate, thread_handle); | |||||
| } | |||||
| // static | |||||
| bool PlatformThread::CreateNonJoinable(size_t stack_size, Delegate* delegate) { | |||||
| return CreateThreadInternal(stack_size, delegate, NULL); | |||||
| } | |||||
| // static | |||||
| void PlatformThread::Join(PlatformThreadHandle thread_handle) { | |||||
| DCHECK(thread_handle); | |||||
| // TODO(willchan): Enable this check once I can get it to work for Windows | |||||
| // shutdown. | |||||
| // Joining another thread may block the current thread for a long time, since | |||||
| // the thread referred to by |thread_handle| may still be running long-lived / | |||||
| // blocking tasks. | |||||
| #if 0 | |||||
| base::ThreadRestrictions::AssertIOAllowed(); | |||||
| #endif | |||||
| // Wait for the thread to exit. It should already have terminated but make | |||||
| // sure this assumption is valid. | |||||
| DWORD result = WaitForSingleObject(thread_handle, INFINITE); | |||||
| DCHECK_EQ(WAIT_OBJECT_0, result); | |||||
| CloseHandle(thread_handle); | |||||
| } | |||||
| } // namespace base | |||||
| @ -0,0 +1,127 @@ | |||||
| // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| // WARNING: Thread local storage is a bit tricky to get right. Please make | |||||
| // sure that this is really the proper solution for what you're trying to | |||||
| // achieve. Don't prematurely optimize, most likely you can just use a Lock. | |||||
| // | |||||
| // These classes implement a wrapper around the platform's TLS storage | |||||
| // mechanism. On construction, they will allocate a TLS slot, and free the | |||||
| // TLS slot on destruction. No memory management (creation or destruction) is | |||||
| // handled. This means for uses of ThreadLocalPointer, you must correctly | |||||
| // manage the memory yourself, these classes will not destroy the pointer for | |||||
| // you. There are no at-thread-exit actions taken by these classes. | |||||
| // | |||||
| // ThreadLocalPointer<Type> wraps a Type*. It performs no creation or | |||||
| // destruction, so memory management must be handled elsewhere. The first call | |||||
| // to Get() on a thread will return NULL. You can update the pointer with a | |||||
| // call to Set(). | |||||
| // | |||||
| // ThreadLocalBoolean wraps a bool. It will default to false if it has never | |||||
| // been set otherwise with Set(). | |||||
| // | |||||
| // Thread Safety: An instance of ThreadLocalStorage is completely thread safe | |||||
| // once it has been created. If you want to dynamically create an instance, | |||||
| // you must of course properly deal with safety and race conditions. This | |||||
| // means a function-level static initializer is generally inappropiate. | |||||
| // | |||||
| // Example usage: | |||||
| // // My class is logically attached to a single thread. We cache a pointer | |||||
| // // on the thread it was created on, so we can implement current(). | |||||
| // MyClass::MyClass() { | |||||
| // DCHECK(Singleton<ThreadLocalPointer<MyClass> >::get()->Get() == NULL); | |||||
| // Singleton<ThreadLocalPointer<MyClass> >::get()->Set(this); | |||||
| // } | |||||
| // | |||||
| // MyClass::~MyClass() { | |||||
| // DCHECK(Singleton<ThreadLocalPointer<MyClass> >::get()->Get() != NULL); | |||||
| // Singleton<ThreadLocalPointer<MyClass> >::get()->Set(NULL); | |||||
| // } | |||||
| // | |||||
| // // Return the current MyClass associated with the calling thread, can be | |||||
| // // NULL if there isn't a MyClass associated. | |||||
| // MyClass* MyClass::current() { | |||||
| // return Singleton<ThreadLocalPointer<MyClass> >::get()->Get(); | |||||
| // } | |||||
| #ifndef BASE_THREADING_THREAD_LOCAL_H_ | |||||
| #define BASE_THREADING_THREAD_LOCAL_H_ | |||||
| #pragma once | |||||
| #include "base/basictypes.h" | |||||
| #if defined(OS_POSIX) | |||||
| #include <pthread.h> | |||||
| #endif | |||||
| namespace base { | |||||
| namespace internal { | |||||
| // Helper functions that abstract the cross-platform APIs. Do not use directly. | |||||
| struct ThreadLocalPlatform { | |||||
| #if defined(OS_WIN) | |||||
| typedef unsigned long SlotType; | |||||
| #elif defined(OS_POSIX) | |||||
| typedef pthread_key_t SlotType; | |||||
| #endif | |||||
| static void AllocateSlot(SlotType& slot); | |||||
| static void FreeSlot(SlotType& slot); | |||||
| static void* GetValueFromSlot(SlotType& slot); | |||||
| static void SetValueInSlot(SlotType& slot, void* value); | |||||
| }; | |||||
| } // namespace internal | |||||
| template <typename Type> | |||||
| class ThreadLocalPointer { | |||||
| public: | |||||
| ThreadLocalPointer() : slot_() { | |||||
| internal::ThreadLocalPlatform::AllocateSlot(slot_); | |||||
| } | |||||
| ~ThreadLocalPointer() { | |||||
| internal::ThreadLocalPlatform::FreeSlot(slot_); | |||||
| } | |||||
| Type* Get() { | |||||
| return static_cast<Type*>( | |||||
| internal::ThreadLocalPlatform::GetValueFromSlot(slot_)); | |||||
| } | |||||
| void Set(Type* ptr) { | |||||
| internal::ThreadLocalPlatform::SetValueInSlot(slot_, ptr); | |||||
| } | |||||
| private: | |||||
| typedef internal::ThreadLocalPlatform::SlotType SlotType; | |||||
| SlotType slot_; | |||||
| DISALLOW_COPY_AND_ASSIGN(ThreadLocalPointer<Type>); | |||||
| }; | |||||
| class ThreadLocalBoolean { | |||||
| public: | |||||
| ThreadLocalBoolean() { } | |||||
| ~ThreadLocalBoolean() { } | |||||
| bool Get() { | |||||
| return tlp_.Get() != NULL; | |||||
| } | |||||
| void Set(bool val) { | |||||
| tlp_.Set(reinterpret_cast<void*>(val ? 1 : 0)); | |||||
| } | |||||
| private: | |||||
| ThreadLocalPointer<void> tlp_; | |||||
| DISALLOW_COPY_AND_ASSIGN(ThreadLocalBoolean); | |||||
| }; | |||||
| } // namespace base | |||||
| #endif // BASE_THREADING_THREAD_LOCAL_H_ | |||||
| @ -0,0 +1,40 @@ | |||||
| // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #include "base/threading/thread_local.h" | |||||
| #include <pthread.h> | |||||
| #include "base/logging.h" | |||||
| namespace base { | |||||
| namespace internal { | |||||
| // static | |||||
| void ThreadLocalPlatform::AllocateSlot(SlotType& slot) { | |||||
| int error = pthread_key_create(&slot, NULL); | |||||
| CHECK_EQ(error, 0); | |||||
| } | |||||
| // static | |||||
| void ThreadLocalPlatform::FreeSlot(SlotType& slot) { | |||||
| int error = pthread_key_delete(slot); | |||||
| DCHECK(error == 0); | |||||
| } | |||||
| // static | |||||
| void* ThreadLocalPlatform::GetValueFromSlot(SlotType& slot) { | |||||
| return pthread_getspecific(slot); | |||||
| } | |||||
| // static | |||||
| void ThreadLocalPlatform::SetValueInSlot(SlotType& slot, void* value) { | |||||
| int error = pthread_setspecific(slot, value); | |||||
| CHECK_EQ(error, 0); | |||||
| } | |||||
| } // namespace internal | |||||
| } // namespace base | |||||
| @ -0,0 +1,42 @@ | |||||
| // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #include "base/threading/thread_local.h" | |||||
| #include <windows.h> | |||||
| #include "base/logging.h" | |||||
| namespace base { | |||||
| namespace internal { | |||||
| // static | |||||
| void ThreadLocalPlatform::AllocateSlot(SlotType& slot) { | |||||
| slot = TlsAlloc(); | |||||
| CHECK_NE(slot, TLS_OUT_OF_INDEXES); | |||||
| } | |||||
| // static | |||||
| void ThreadLocalPlatform::FreeSlot(SlotType& slot) { | |||||
| if (!TlsFree(slot)) { | |||||
| NOTREACHED() << "Failed to deallocate tls slot with TlsFree()."; | |||||
| } | |||||
| } | |||||
| // static | |||||
| void* ThreadLocalPlatform::GetValueFromSlot(SlotType& slot) { | |||||
| return TlsGetValue(slot); | |||||
| } | |||||
| // static | |||||
| void ThreadLocalPlatform::SetValueInSlot(SlotType& slot, void* value) { | |||||
| if (!TlsSetValue(slot, value)) { | |||||
| LOG(FATAL) << "Failed to TlsSetValue()."; | |||||
| } | |||||
| } | |||||
| } // namespace internal | |||||
| } // namespace base | |||||
| @ -0,0 +1,63 @@ | |||||
| // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #include "base/threading/thread_restrictions.h" | |||||
| // This entire file is compiled out in Release mode. | |||||
| #ifndef NDEBUG | |||||
| #include "base/lazy_instance.h" | |||||
| #include "base/logging.h" | |||||
| #include "base/threading/thread_local.h" | |||||
| namespace base { | |||||
| namespace { | |||||
| LazyInstance<ThreadLocalBoolean, LeakyLazyInstanceTraits<ThreadLocalBoolean> > | |||||
| g_io_disallowed(LINKER_INITIALIZED); | |||||
| LazyInstance<ThreadLocalBoolean, LeakyLazyInstanceTraits<ThreadLocalBoolean> > | |||||
| g_singleton_disallowed(LINKER_INITIALIZED); | |||||
| } // anonymous namespace | |||||
| // static | |||||
| bool ThreadRestrictions::SetIOAllowed(bool allowed) { | |||||
| bool previous_disallowed = g_io_disallowed.Get().Get(); | |||||
| g_io_disallowed.Get().Set(!allowed); | |||||
| return !previous_disallowed; | |||||
| } | |||||
| // static | |||||
| void ThreadRestrictions::AssertIOAllowed() { | |||||
| if (g_io_disallowed.Get().Get()) { | |||||
| LOG(FATAL) << | |||||
| "Function marked as IO-only was called from a thread that " | |||||
| "disallows IO! If this thread really should be allowed to " | |||||
| "make IO calls, adjust the call to " | |||||
| "base::ThreadRestrictions::SetIOAllowed() in this thread's " | |||||
| "startup."; | |||||
| } | |||||
| } | |||||
| bool ThreadRestrictions::SetSingletonAllowed(bool allowed) { | |||||
| bool previous_disallowed = g_singleton_disallowed.Get().Get(); | |||||
| g_singleton_disallowed.Get().Set(!allowed); | |||||
| return !previous_disallowed; | |||||
| } | |||||
| // static | |||||
| void ThreadRestrictions::AssertSingletonAllowed() { | |||||
| if (g_singleton_disallowed.Get().Get()) { | |||||
| LOG(FATAL) << "LazyInstance/Singleton is not allowed to be used on this " | |||||
| << "thread. Most likely it's because this thread is not " | |||||
| << "joinable, so AtExitManager may have deleted the object " | |||||
| << "on shutdown, leading to a potential shutdown crash."; | |||||
| } | |||||
| } | |||||
| } // namespace base | |||||
| #endif // NDEBUG | |||||
| @ -0,0 +1,100 @@ | |||||
| // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |||||
| // Use of this source code is governed by a BSD-style license that can be | |||||
| // found in the LICENSE file. | |||||
| #ifndef BASE_THREADING_THREAD_RESTRICTIONS_H_ | |||||
| #define BASE_THREADING_THREAD_RESTRICTIONS_H_ | |||||
| #include "base/basictypes.h" | |||||
| namespace base { | |||||
| // Certain behavior is disallowed on certain threads. ThreadRestrictions helps | |||||
| // enforce these rules. Examples of such rules: | |||||
| // | |||||
| // * Do not do blocking IO (makes the thread janky) | |||||
| // * Do not access Singleton/LazyInstance (may lead to shutdown crashes) | |||||
| // | |||||
| // Here's more about how the protection works: | |||||
| // | |||||
| // 1) If a thread should not be allowed to make IO calls, mark it: | |||||
| // base::ThreadRestrictions::SetIOAllowed(false); | |||||
| // By default, threads *are* allowed to make IO calls. | |||||
| // In Chrome browser code, IO calls should be proxied to the File thread. | |||||
| // | |||||
| // 2) If a function makes a call that will go out to disk, check whether the | |||||
| // current thread is allowed: | |||||
| // base::ThreadRestrictions::AssertIOAllowed(); | |||||
| // | |||||
| // ThreadRestrictions does nothing in release builds; it is debug-only. | |||||
| // | |||||
| // Style tip: where should you put AssertIOAllowed checks? It's best | |||||
| // if you put them as close to the disk access as possible, at the | |||||
| // lowest level. This rule is simple to follow and helps catch all | |||||
| // callers. For example, if your function GoDoSomeBlockingDiskCall() | |||||
| // only calls other functions in Chrome and not fopen(), you should go | |||||
| // add the AssertIOAllowed checks in the helper functions. | |||||
| class ThreadRestrictions { | |||||
| public: | |||||
| // Constructing a ScopedAllowIO temporarily allows IO for the current | |||||
| // thread. Doing this is almost certainly always incorrect. | |||||
| class ScopedAllowIO { | |||||
| public: | |||||
| ScopedAllowIO() { previous_value_ = SetIOAllowed(true); } | |||||
| ~ScopedAllowIO() { SetIOAllowed(previous_value_); } | |||||
| private: | |||||
| // Whether IO is allowed when the ScopedAllowIO was constructed. | |||||
| bool previous_value_; | |||||
| DISALLOW_COPY_AND_ASSIGN(ScopedAllowIO); | |||||
| }; | |||||
| // Constructing a ScopedAllowSingleton temporarily allows accessing for the | |||||
| // current thread. Doing this is almost always incorrect. | |||||
| class ScopedAllowSingleton { | |||||
| public: | |||||
| ScopedAllowSingleton() { previous_value_ = SetSingletonAllowed(true); } | |||||
| ~ScopedAllowSingleton() { SetSingletonAllowed(previous_value_); } | |||||
| private: | |||||
| // Whether singleton use is allowed when the ScopedAllowSingleton was | |||||
| // constructed. | |||||
| bool previous_value_; | |||||
| DISALLOW_COPY_AND_ASSIGN(ScopedAllowSingleton); | |||||
| }; | |||||
| #ifndef NDEBUG | |||||
| // Set whether the current thread to make IO calls. | |||||
| // Threads start out in the *allowed* state. | |||||
| // Returns the previous value. | |||||
| static bool SetIOAllowed(bool allowed); | |||||
| // Check whether the current thread is allowed to make IO calls, | |||||
| // and DCHECK if not. See the block comment above the class for | |||||
| // a discussion of where to add these checks. | |||||
| static void AssertIOAllowed(); | |||||
| // Set whether the current thread can use singletons. Returns the previous | |||||
| // value. | |||||
| static bool SetSingletonAllowed(bool allowed); | |||||
| // Check whether the current thread is allowed to use singletons (Singleton / | |||||
| // LazyInstance). DCHECKs if not. | |||||
| static void AssertSingletonAllowed(); | |||||
| #else | |||||
| // In Release builds, inline the empty definitions of these functions so | |||||
| // that they can be compiled out. | |||||
| static bool SetIOAllowed(bool allowed) { return true; } | |||||
| static void AssertIOAllowed() {} | |||||
| static bool SetSingletonAllowed(bool allowed) { return true; } | |||||
| static void AssertSingletonAllowed() {} | |||||
| #endif | |||||
| private: | |||||
| DISALLOW_IMPLICIT_CONSTRUCTORS(ThreadRestrictions); | |||||
| }; | |||||
| } // namespace base | |||||
| #endif // BASE_THREADING_THREAD_RESTRICTIONS_H_ | |||||
| @ -0,0 +1,11 @@ | |||||
| #ifndef I18N_PHONENUMBERS_CONFIG_H_ | |||||
| # define I18N_PHONENUMBERS_CONFIG_H_ | |||||
| # ifdef __x86_64__ | |||||
| // Needed by atomicops | |||||
| # define ARCH_CPU_64_BITS | |||||
| # endif | |||||
| #endif | |||||
| @ -0,0 +1,220 @@ | |||||
| // Copyright (C) 2011 Google Inc. | |||||
| // | |||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| // you may not use this file except in compliance with the License. | |||||
| // You may obtain a copy of the License at | |||||
| // | |||||
| // http://www.apache.org/licenses/LICENSE-2.0 | |||||
| // | |||||
| // Unless required by applicable law or agreed to in writing, software | |||||
| // distributed under the License is distributed on an "AS IS" BASIS, | |||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| // See the License for the specific language governing permissions and | |||||
| // limitations under the License. | |||||
| // @author Shaopeng Jia | |||||
| // TODO(philip.liard): Remove this file and use the existing one available in | |||||
| // the SVN repository. | |||||
| package i18n.phonenumbers; | |||||
| message NumberFormat { | |||||
| // pattern is a regex that is used to match the national (significant) | |||||
| // number. For example, the pattern "(20)(\d{4})(\d{4})" will match number | |||||
| // "2070313000", which is the national (significant) number for Google London. | |||||
| // Note the presence of the parentheses, which are capturing groups what | |||||
| // specifies the grouping of numbers. | |||||
| required string pattern = 1; | |||||
| // format specifies how the national (significant) number matched by | |||||
| // pattern should be formatted. | |||||
| // Using the same example as above, format could contain "$1 $2 $3", | |||||
| // meaning that the number should be formatted as "20 7031 3000". | |||||
| // Each $x are replaced by the numbers captured by group x in the | |||||
| // regex specified by pattern. | |||||
| required string format = 2; | |||||
| // This field is a regex that is used to match a certain number of digits | |||||
| // at the beginning of the national (significant) number. When the match is | |||||
| // successful, the accompanying pattern and format should be used to format | |||||
| // this number. For example, if leading_digits="[1-3]|44", then all the | |||||
| // national numbers starting with 1, 2, 3 or 44 should be formatted using the | |||||
| // accompanying pattern and format. | |||||
| // | |||||
| // The first leadingDigitsPattern matches up to the first three digits of the | |||||
| // national (significant) number; the next one matches the first four digits, | |||||
| // then the first five and so on, until the leadingDigitsPattern can uniquely | |||||
| // identify one pattern and format to be used to format the number. | |||||
| // | |||||
| // In the case when only one formatting pattern exists, no | |||||
| // leading_digits_pattern is needed. | |||||
| repeated string leading_digits_pattern = 3; | |||||
| // This field specifies how the national prefix ($NP) together with the first | |||||
| // group ($FG) in the national significant number should be formatted in | |||||
| // the NATIONAL format when a national prefix exists for a certain country. | |||||
| // For example, when this field contains "($NP$FG)", a number from Beijing, | |||||
| // China (whose $NP = 0), which would by default be formatted without | |||||
| // national prefix as 10 1234 5678 in NATIONAL format, will instead be | |||||
| // formatted as (010) 1234 5678; to format it as (0)10 1234 5678, the field | |||||
| // would contain "($NP)$FG". Note $FG should always be present in this field, | |||||
| // but $NP can be omitted. For example, having "$FG" could indicate the | |||||
| // number should be formatted in NATIONAL format without the national prefix. | |||||
| // This is commonly used to override the rule from generalDesc. | |||||
| // | |||||
| // When this field is missing, a number will be formatted without national | |||||
| // prefix in NATIONAL format. This field does not affect how a number | |||||
| // is formatted in other formats, such as INTERNATIONAL. | |||||
| optional string national_prefix_formatting_rule = 4; | |||||
| // This field specifies how any carrier code ($CC) together with the first | |||||
| // group ($FG) in the national significant number should be formatted | |||||
| // when formatWithCarrierCode is called, if carrier codes are used for a | |||||
| // certain country. | |||||
| optional string domestic_carrier_code_formatting_rule = 5; | |||||
| } | |||||
| message PhoneNumberDesc { | |||||
| // The national_number_pattern is the pattern that a valid national | |||||
| // significant number would match. This specifies information such as its | |||||
| // total length and leading digits. | |||||
| optional string national_number_pattern = 2; | |||||
| // The possible_number_pattern represents what a potentially valid phone | |||||
| // number for this region may be written as. This is a superset of the | |||||
| // national_number_pattern above and includes numbers that have the area code | |||||
| // omitted. Typically the only restrictions here are in the number of digits. | |||||
| // This could be used to highlight tokens in a text that may be a phone | |||||
| // number, or to quickly prune numbers that could not possibly be a phone | |||||
| // number for this locale. | |||||
| optional string possible_number_pattern = 3; | |||||
| // An example national significant number for the specific type. It should | |||||
| // not contain any formatting information. | |||||
| optional string example_number = 6; | |||||
| } | |||||
| message PhoneMetadata { | |||||
| // The general_desc contains information which is a superset of descriptions | |||||
| // for all types of phone numbers. If any element is missing in the | |||||
| // description of a specific type in the XML file, the element will inherit | |||||
| // from its counterpart in the general_desc. Every locale is assumed to have | |||||
| // fixed line and mobile numbers - if these types are missing in the XML | |||||
| // file, they will inherit all fields from the general_desc. For all other | |||||
| // types, if the whole type is missing in the xml file, it will be given a | |||||
| // national_number_pattern of "NA" and a possible_number_pattern of "NA". | |||||
| required PhoneNumberDesc general_desc = 1; | |||||
| required PhoneNumberDesc fixed_line = 2; | |||||
| required PhoneNumberDesc mobile = 3; | |||||
| required PhoneNumberDesc toll_free = 4; | |||||
| required PhoneNumberDesc premium_rate = 5; | |||||
| required PhoneNumberDesc shared_cost = 6; | |||||
| required PhoneNumberDesc personal_number = 7; | |||||
| required PhoneNumberDesc voip = 8; | |||||
| required PhoneNumberDesc pager = 21; | |||||
| required PhoneNumberDesc uan = 25; | |||||
| // The rules here distinguish the numbers that are only able to be dialled | |||||
| // nationally. | |||||
| required PhoneNumberDesc no_international_dialling = 24; | |||||
| // The ISO 3166-1 alpha-2 representation of a country/region | |||||
| required string id = 9; | |||||
| // The country calling code that one would dial from overseas when trying to | |||||
| // dial a phone number in this country. For example, this would be "64" for | |||||
| // New Zealand. | |||||
| required int32 country_code = 10; | |||||
| // The international_prefix of country A is the number that needs to be | |||||
| // dialled from country A to another country (country B). This is followed | |||||
| // by the country code for country B. Note that some countries may have more | |||||
| // than one international prefix, and for those cases, a regular expression | |||||
| // matching the international prefixes will be stored in this field. | |||||
| required string international_prefix = 11; | |||||
| // If more than one international prefix is present, a preferred prefix can | |||||
| // be specified here for out-of-country formatting purposes. If this field is | |||||
| // not present, and multiple international prefixes are present, then "+" | |||||
| // will be used instead. | |||||
| optional string preferred_international_prefix = 17; | |||||
| // The national prefix of country A is the number that needs to be dialled | |||||
| // before the national significant number when dialling internally. This | |||||
| // would not be dialled when dialling internationally. For example, in New | |||||
| // Zealand, the number that would be locally dialled as 09 345 3456 would be | |||||
| // dialled from overseas as +64 9 345 3456. In this case, 0 is the national | |||||
| // prefix. | |||||
| optional string national_prefix = 12; | |||||
| // The preferred prefix when specifying an extension in this country. This is | |||||
| // used for formatting only, and if this is not specified, a suitable default | |||||
| // should be used instead. For example, if you wanted extensions to be | |||||
| // formatted in the following way: | |||||
| // 1 (365) 345 445 ext. 2345 | |||||
| // " ext. " should be the preferred extension prefix. | |||||
| optional string preferred_extn_prefix = 13; | |||||
| // This field is used for cases where the national prefix of a country | |||||
| // contains a carrier selection code, and is written in the form of a | |||||
| // regular expression. For example, to dial the number 2222-2222 in | |||||
| // Fortaleza, Brazil (area code 85) using the long distance carrier Oi | |||||
| // (selection code 31), one would dial 0 31 85 2222 2222. Assuming the | |||||
| // only other possible carrier selection code is 32, the field will | |||||
| // contain "03[12]". | |||||
| // | |||||
| // When it is missing from the XML file, this field inherits the value of | |||||
| // national_prefix, if that is present. | |||||
| optional string national_prefix_for_parsing = 15; | |||||
| // This field is only populated and used under very rare situations. | |||||
| // For example, mobile numbers in Argentina are written in two completely | |||||
| // different ways when dialed in-country and out-of-country | |||||
| // (e.g. 0343 15 555 1212 is exactly the same number as +54 9 343 555 1212). | |||||
| // This field is used together with national_prefix_for_parsing to transform | |||||
| // the number into a particular representation for storing in the phonenumber | |||||
| // proto buffer in those rare cases. | |||||
| optional string national_prefix_transform_rule = 16; | |||||
| // Specifies whether the mobile and fixed-line patterns are the same or not. | |||||
| // This is used to speed up determining phone number type in countries where | |||||
| // these two types of phone numbers can never be distinguished. | |||||
| optional bool same_mobile_and_fixed_line_pattern = 18 [default=false]; | |||||
| // Note that the number format here is used for formatting only, not parsing. | |||||
| // Hence all the varied ways a user *may* write a number need not be recorded | |||||
| // - just the ideal way we would like to format it for them. When this element | |||||
| // is absent, the national significant number will be formatted as a whole | |||||
| // without any formatting applied. | |||||
| repeated NumberFormat number_format = 19; | |||||
| // This field is populated only when the national significant number is | |||||
| // formatted differently when it forms part of the INTERNATIONAL format | |||||
| // and NATIONAL format. A case in point is mobile numbers in Argentina: | |||||
| // The number, which would be written in INTERNATIONAL format as | |||||
| // +54 9 343 555 1212, will be written as 0343 15 555 1212 for NATIONAL | |||||
| // format. In this case, the prefix 9 is inserted when dialling from | |||||
| // overseas, but otherwise the prefix 0 and the carrier selection code | |||||
| // 15 (inserted after the area code of 343) is used. | |||||
| repeated NumberFormat intl_number_format = 20; | |||||
| // This field is set when this country is considered to be the main country | |||||
| // for a calling code. It may not be set by more than one country with the | |||||
| // same calling code, and it should not be set by countries with a unique | |||||
| // calling code. This can be used to indicate that "GB" is the main country | |||||
| // for the calling code "44" for example, rather than Jersey or the Isle of | |||||
| // Man. | |||||
| optional bool main_country_for_code = 22 [default=false]; | |||||
| // This field is populated only for countries or regions that share a country | |||||
| // calling code. If a number matches this pattern, it could belong to this | |||||
| // region. This is not intended as a replacement for IsValidForRegion, and | |||||
| // does not mean the number must come from this region (for example, 800 | |||||
| // numbers are valid for all NANPA countries.) This field should be a regular | |||||
| // expression of the expected prefix match. | |||||
| optional string leading_digits = 23; | |||||
| } | |||||
| message PhoneMetadataCollection { | |||||
| repeated PhoneMetadata metadata = 1; | |||||
| } | |||||
| @ -0,0 +1,105 @@ | |||||
| // Copyright (C) 2011 Google Inc. | |||||
| // | |||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| // you may not use this file except in compliance with the License. | |||||
| // You may obtain a copy of the License at | |||||
| // | |||||
| // http://www.apache.org/licenses/LICENSE-2.0 | |||||
| // | |||||
| // Unless required by applicable law or agreed to in writing, software | |||||
| // distributed under the License is distributed on an "AS IS" BASIS, | |||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| // See the License for the specific language governing permissions and | |||||
| // limitations under the License. | |||||
| // @author Shaopeng Jia | |||||
| // TODO(philip.liard): Remove this file and use the existing one available in | |||||
| // the SVN repository. | |||||
| package i18n.phonenumbers; | |||||
| message PhoneNumber { | |||||
| // The country calling code for this number, as defined by the International Telecommunication Union | |||||
| // (ITU). Fox example, this would be 1 for NANPA countries, and 33 for France. | |||||
| required int32 country_code = 1; | |||||
| // National (significant) Number is defined in ITU Recommendation E.164. It is a | |||||
| // language/country-neutral representation of a phone number at a country level. For countries which | |||||
| // have the concept of Area Code, the National (significant) Number contains the area code. It | |||||
| // contains a maximum number of digits which equal to 15 - n, where n is the number of digits of the | |||||
| // country code. Take note that National (significant) Number does not contain National(trunk) | |||||
| // prefix. Obviously, as a uint64, it will never contain any formatting (hypens, spaces, | |||||
| // parentheses), nor any alphanumeric spellings. | |||||
| required uint64 national_number = 2; | |||||
| // Extension is not standardized in ITU recommendations, except for being defined as a series of | |||||
| // numbers with a maximum length of 40 digits. It is defined as a string here to accommodate for the | |||||
| // possible use of a leading zero in the extension (organizations have complete freedom to do so, | |||||
| // as there is no standard defined). However, only ASCII digits should be stored here. | |||||
| optional string extension = 3; | |||||
| // In some countries, the national (significant) number starts with a "0" without this being a | |||||
| // national prefix or trunk code of some kind. For example, the leading zero in the national | |||||
| // (significant) number of an Italian phone number indicates the number is a fixed-line number. | |||||
| // There have been plans to migrate fixed-line numbers to start with the digit two since December | |||||
| // 2000, but it has not happened yet. See http://en.wikipedia.org/wiki/%2B39 for more details. | |||||
| // | |||||
| // This field can be safely ignored (there is no need to set it) for most countries. Some limited | |||||
| // amount of countries behave like Italy - for these cases, if the leading zero of a number would be | |||||
| // retained even when dialling internationally, set this flag to true. | |||||
| // | |||||
| // Clients who use the parsing or conversion functionality of the i18n phone number libraries | |||||
| // (https://sites/intl-eng/team/emea/phone/telephone-number-utilities) will have this field set if | |||||
| // necessary automatically. | |||||
| optional bool italian_leading_zero = 4; | |||||
| // This field is used to store the raw input string containing phone numbers before it was | |||||
| // canonicalized by the library. For example, it could be used to store alphanumerical numbers | |||||
| // such as "1-800-GOOG-411". | |||||
| optional string raw_input = 5; | |||||
| // The source from which the country_code is derived. This is not set in the general parsing method, | |||||
| // but in the method that parses and keeps raw_input. New fields could be added upon request. | |||||
| enum CountryCodeSource { | |||||
| // The country_code is derived based on a phone number with a leading "+", e.g. the French | |||||
| // number "+33 (0)1 42 68 53 00". | |||||
| FROM_NUMBER_WITH_PLUS_SIGN = 1; | |||||
| // The country_code is derived based on a phone number with a leading IDD, e.g. the French | |||||
| // number "011 33 (0)1 42 68 53 00", as it is dialled from US. | |||||
| FROM_NUMBER_WITH_IDD = 5; | |||||
| // The country_code is derived based on a phone number without a leading "+", e.g. the French | |||||
| // number "33 (0)1 42 68 53 00" when defaultCountry is supplied as France. | |||||
| FROM_NUMBER_WITHOUT_PLUS_SIGN = 10; | |||||
| // The country_code is derived NOT based on the phone number itself, but from the defaultCountry | |||||
| // parameter provided in the parsing function by the clients. This happens mostly for numbers | |||||
| // written in the national format (without country code). For example, this would be set when | |||||
| // parsing the French number "(0)1 42 68 53 00", when defaultCountry is supplied as France. | |||||
| FROM_DEFAULT_COUNTRY = 20; | |||||
| } | |||||
| // The source from which the country_code is derived. | |||||
| optional CountryCodeSource country_code_source = 6; | |||||
| } | |||||
| // Examples | |||||
| // | |||||
| // Google MTV, +1 650-253-0000, (650) 253-0000 | |||||
| // country_code: 1 | |||||
| // national_number: 6502530000 | |||||
| // | |||||
| // Google Paris, +33 (0)1 42 68 53 00, 01 42 68 53 00 | |||||
| // country_code: 33 | |||||
| // national_number: 142685300 | |||||
| // | |||||
| // Google Beijing, +86-10-62503000, (010) 62503000 | |||||
| // country_code: 86 | |||||
| // national_number: 1062503000 | |||||
| // | |||||
| // Google Italy, +39 02-36618 300, 02-36618 300 | |||||
| // country_code: 39 | |||||
| // national_number: 236618300 | |||||
| // italian_leading_zero: true | |||||
| @ -0,0 +1 @@ | |||||
| // TODO | |||||
| @ -0,0 +1 @@ | |||||
| // TODO | |||||
| @ -0,0 +1 @@ | |||||
| // TODO | |||||
| @ -0,0 +1,7 @@ | |||||
| #include <gtest/gtest.h> | |||||
| int main(int argc, char** argv) { | |||||
| ::testing::InitGoogleTest(&argc, argv); | |||||
| return RUN_ALL_TESTS(); | |||||
| } | |||||
| @ -0,0 +1 @@ | |||||
| These files come from lib9 (http://code.google.com/p/go/source/browse). | |||||
| @ -0,0 +1,351 @@ | |||||
| /* | |||||
| * The authors of this software are Rob Pike and Ken Thompson. | |||||
| * Copyright (c) 2002 by Lucent Technologies. | |||||
| * Portions Copyright (c) 2009 The Go Authors. All rights reserved. | |||||
| * Permission to use, copy, modify, and distribute this software for any | |||||
| * purpose without fee is hereby granted, provided that this entire notice | |||||
| * is included in all copies of any software which is or includes a copy | |||||
| * or modification of this software and in all copies of the supporting | |||||
| * documentation for such software. | |||||
| * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED | |||||
| * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY | |||||
| * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY | |||||
| * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. | |||||
| */ | |||||
| #include <stdarg.h> | |||||
| #include <string.h> | |||||
| #include "utf.h" | |||||
| #include "utfdef.h" | |||||
| enum | |||||
| { | |||||
| Bit1 = 7, | |||||
| Bitx = 6, | |||||
| Bit2 = 5, | |||||
| Bit3 = 4, | |||||
| Bit4 = 3, | |||||
| Bit5 = 2, | |||||
| T1 = ((1<<(Bit1+1))-1) ^ 0xFF, /* 0000 0000 */ | |||||
| Tx = ((1<<(Bitx+1))-1) ^ 0xFF, /* 1000 0000 */ | |||||
| T2 = ((1<<(Bit2+1))-1) ^ 0xFF, /* 1100 0000 */ | |||||
| T3 = ((1<<(Bit3+1))-1) ^ 0xFF, /* 1110 0000 */ | |||||
| T4 = ((1<<(Bit4+1))-1) ^ 0xFF, /* 1111 0000 */ | |||||
| T5 = ((1<<(Bit5+1))-1) ^ 0xFF, /* 1111 1000 */ | |||||
| Rune1 = (1<<(Bit1+0*Bitx))-1, /* 0000 0000 0111 1111 */ | |||||
| Rune2 = (1<<(Bit2+1*Bitx))-1, /* 0000 0111 1111 1111 */ | |||||
| Rune3 = (1<<(Bit3+2*Bitx))-1, /* 1111 1111 1111 1111 */ | |||||
| Rune4 = (1<<(Bit4+3*Bitx))-1, | |||||
| /* 0001 1111 1111 1111 1111 1111 */ | |||||
| Maskx = (1<<Bitx)-1, /* 0011 1111 */ | |||||
| Testx = Maskx ^ 0xFF, /* 1100 0000 */ | |||||
| Bad = Runeerror, | |||||
| }; | |||||
| /* | |||||
| * Modified by Wei-Hwa Huang, Google Inc., on 2004-09-24 | |||||
| * This is a slower but "safe" version of the old chartorune | |||||
| * that works on strings that are not necessarily null-terminated. | |||||
| * | |||||
| * If you know for sure that your string is null-terminated, | |||||
| * chartorune will be a bit faster. | |||||
| * | |||||
| * It is guaranteed not to attempt to access "length" | |||||
| * past the incoming pointer. This is to avoid | |||||
| * possible access violations. If the string appears to be | |||||
| * well-formed but incomplete (i.e., to get the whole Rune | |||||
| * we'd need to read past str+length) then we'll set the Rune | |||||
| * to Bad and return 0. | |||||
| * | |||||
| * Note that if we have decoding problems for other | |||||
| * reasons, we return 1 instead of 0. | |||||
| */ | |||||
| int | |||||
| charntorune(Rune *rune, const char *str, int length) | |||||
| { | |||||
| int c, c1, c2, c3; | |||||
| long l; | |||||
| /* When we're not allowed to read anything */ | |||||
| if(length <= 0) { | |||||
| goto badlen; | |||||
| } | |||||
| /* | |||||
| * one character sequence (7-bit value) | |||||
| * 00000-0007F => T1 | |||||
| */ | |||||
| c = *(uchar*)str; | |||||
| if(c < Tx) { | |||||
| *rune = c; | |||||
| return 1; | |||||
| } | |||||
| // If we can't read more than one character we must stop | |||||
| if(length <= 1) { | |||||
| goto badlen; | |||||
| } | |||||
| /* | |||||
| * two character sequence (11-bit value) | |||||
| * 0080-07FF => T2 Tx | |||||
| */ | |||||
| c1 = *(uchar*)(str+1) ^ Tx; | |||||
| if(c1 & Testx) | |||||
| goto bad; | |||||
| if(c < T3) { | |||||
| if(c < T2) | |||||
| goto bad; | |||||
| l = ((c << Bitx) | c1) & Rune2; | |||||
| if(l <= Rune1) | |||||
| goto bad; | |||||
| *rune = l; | |||||
| return 2; | |||||
| } | |||||
| // If we can't read more than two characters we must stop | |||||
| if(length <= 2) { | |||||
| goto badlen; | |||||
| } | |||||
| /* | |||||
| * three character sequence (16-bit value) | |||||
| * 0800-FFFF => T3 Tx Tx | |||||
| */ | |||||
| c2 = *(uchar*)(str+2) ^ Tx; | |||||
| if(c2 & Testx) | |||||
| goto bad; | |||||
| if(c < T4) { | |||||
| l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3; | |||||
| if(l <= Rune2) | |||||
| goto bad; | |||||
| *rune = l; | |||||
| return 3; | |||||
| } | |||||
| if (length <= 3) | |||||
| goto badlen; | |||||
| /* | |||||
| * four character sequence (21-bit value) | |||||
| * 10000-1FFFFF => T4 Tx Tx Tx | |||||
| */ | |||||
| c3 = *(uchar*)(str+3) ^ Tx; | |||||
| if (c3 & Testx) | |||||
| goto bad; | |||||
| if (c < T5) { | |||||
| l = ((((((c << Bitx) | c1) << Bitx) | c2) << Bitx) | c3) & Rune4; | |||||
| if (l <= Rune3) | |||||
| goto bad; | |||||
| *rune = l; | |||||
| return 4; | |||||
| } | |||||
| // Support for 5-byte or longer UTF-8 would go here, but | |||||
| // since we don't have that, we'll just fall through to bad. | |||||
| /* | |||||
| * bad decoding | |||||
| */ | |||||
| bad: | |||||
| *rune = Bad; | |||||
| return 1; | |||||
| badlen: | |||||
| *rune = Bad; | |||||
| return 0; | |||||
| } | |||||
| /* | |||||
| * This is the older "unsafe" version, which works fine on | |||||
| * null-terminated strings. | |||||
| */ | |||||
| int | |||||
| chartorune(Rune *rune, const char *str) | |||||
| { | |||||
| int c, c1, c2, c3; | |||||
| long l; | |||||
| /* | |||||
| * one character sequence | |||||
| * 00000-0007F => T1 | |||||
| */ | |||||
| c = *(uchar*)str; | |||||
| if(c < Tx) { | |||||
| *rune = c; | |||||
| return 1; | |||||
| } | |||||
| /* | |||||
| * two character sequence | |||||
| * 0080-07FF => T2 Tx | |||||
| */ | |||||
| c1 = *(uchar*)(str+1) ^ Tx; | |||||
| if(c1 & Testx) | |||||
| goto bad; | |||||
| if(c < T3) { | |||||
| if(c < T2) | |||||
| goto bad; | |||||
| l = ((c << Bitx) | c1) & Rune2; | |||||
| if(l <= Rune1) | |||||
| goto bad; | |||||
| *rune = l; | |||||
| return 2; | |||||
| } | |||||
| /* | |||||
| * three character sequence | |||||
| * 0800-FFFF => T3 Tx Tx | |||||
| */ | |||||
| c2 = *(uchar*)(str+2) ^ Tx; | |||||
| if(c2 & Testx) | |||||
| goto bad; | |||||
| if(c < T4) { | |||||
| l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3; | |||||
| if(l <= Rune2) | |||||
| goto bad; | |||||
| *rune = l; | |||||
| return 3; | |||||
| } | |||||
| /* | |||||
| * four character sequence (21-bit value) | |||||
| * 10000-1FFFFF => T4 Tx Tx Tx | |||||
| */ | |||||
| c3 = *(uchar*)(str+3) ^ Tx; | |||||
| if (c3 & Testx) | |||||
| goto bad; | |||||
| if (c < T5) { | |||||
| l = ((((((c << Bitx) | c1) << Bitx) | c2) << Bitx) | c3) & Rune4; | |||||
| if (l <= Rune3) | |||||
| goto bad; | |||||
| *rune = l; | |||||
| return 4; | |||||
| } | |||||
| /* | |||||
| * Support for 5-byte or longer UTF-8 would go here, but | |||||
| * since we don't have that, we'll just fall through to bad. | |||||
| */ | |||||
| /* | |||||
| * bad decoding | |||||
| */ | |||||
| bad: | |||||
| *rune = Bad; | |||||
| return 1; | |||||
| } | |||||
| int | |||||
| isvalidcharntorune(const char* str, int length, Rune* rune, int* consumed) { | |||||
| *consumed = charntorune(rune, str, length); | |||||
| return *rune != Runeerror || *consumed == 3; | |||||
| } | |||||
| int | |||||
| runetochar(char *str, const Rune *rune) | |||||
| { | |||||
| /* Runes are signed, so convert to unsigned for range check. */ | |||||
| unsigned long c; | |||||
| /* | |||||
| * one character sequence | |||||
| * 00000-0007F => 00-7F | |||||
| */ | |||||
| c = *rune; | |||||
| if(c <= Rune1) { | |||||
| str[0] = c; | |||||
| return 1; | |||||
| } | |||||
| /* | |||||
| * two character sequence | |||||
| * 0080-07FF => T2 Tx | |||||
| */ | |||||
| if(c <= Rune2) { | |||||
| str[0] = T2 | (c >> 1*Bitx); | |||||
| str[1] = Tx | (c & Maskx); | |||||
| return 2; | |||||
| } | |||||
| /* | |||||
| * If the Rune is out of range, convert it to the error rune. | |||||
| * Do this test here because the error rune encodes to three bytes. | |||||
| * Doing it earlier would duplicate work, since an out of range | |||||
| * Rune wouldn't have fit in one or two bytes. | |||||
| */ | |||||
| if (c > Runemax) | |||||
| c = Runeerror; | |||||
| /* | |||||
| * three character sequence | |||||
| * 0800-FFFF => T3 Tx Tx | |||||
| */ | |||||
| if (c <= Rune3) { | |||||
| str[0] = T3 | (c >> 2*Bitx); | |||||
| str[1] = Tx | ((c >> 1*Bitx) & Maskx); | |||||
| str[2] = Tx | (c & Maskx); | |||||
| return 3; | |||||
| } | |||||
| /* | |||||
| * four character sequence (21-bit value) | |||||
| * 10000-1FFFFF => T4 Tx Tx Tx | |||||
| */ | |||||
| str[0] = T4 | (c >> 3*Bitx); | |||||
| str[1] = Tx | ((c >> 2*Bitx) & Maskx); | |||||
| str[2] = Tx | ((c >> 1*Bitx) & Maskx); | |||||
| str[3] = Tx | (c & Maskx); | |||||
| return 4; | |||||
| } | |||||
| int | |||||
| runelen(Rune rune) | |||||
| { | |||||
| char str[10]; | |||||
| return runetochar(str, &rune); | |||||
| } | |||||
| int | |||||
| runenlen(const Rune *r, int nrune) | |||||
| { | |||||
| int nb, c; | |||||
| nb = 0; | |||||
| while(nrune--) { | |||||
| c = *r++; | |||||
| if (c <= Rune1) | |||||
| nb++; | |||||
| else if (c <= Rune2) | |||||
| nb += 2; | |||||
| else if (c <= Rune3) | |||||
| nb += 3; | |||||
| else /* assert(c <= Rune4) */ | |||||
| nb += 4; | |||||
| } | |||||
| return nb; | |||||
| } | |||||
| int | |||||
| fullrune(const char *str, int n) | |||||
| { | |||||
| if (n > 0) { | |||||
| int c = *(uchar*)str; | |||||
| if (c < Tx) | |||||
| return 1; | |||||
| if (n > 1) { | |||||
| if (c < T3) | |||||
| return 1; | |||||
| if (n > 2) { | |||||
| if (c < T4 || n > 3) | |||||
| return 1; | |||||
| } | |||||
| } | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| @ -0,0 +1,242 @@ | |||||
| /* | |||||
| * The authors of this software are Rob Pike and Ken Thompson. | |||||
| * Copyright (c) 1998-2002 by Lucent Technologies. | |||||
| * Portions Copyright (c) 2009 The Go Authors. All rights reserved. | |||||
| * Permission to use, copy, modify, and distribute this software for any | |||||
| * purpose without fee is hereby granted, provided that this entire notice | |||||
| * is included in all copies of any software which is or includes a copy | |||||
| * or modification of this software and in all copies of the supporting | |||||
| * documentation for such software. | |||||
| * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED | |||||
| * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY | |||||
| * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY | |||||
| * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. | |||||
| */ | |||||
| #ifndef _UTFH_ | |||||
| #define _UTFH_ 1 | |||||
| #include <stdint.h> | |||||
| typedef unsigned int Rune; /* Code-point values in Unicode 4.0 are 21 bits wide.*/ | |||||
| enum | |||||
| { | |||||
| UTFmax = 4, /* maximum bytes per rune */ | |||||
| Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | |||||
| Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | |||||
| Runeerror = 0xFFFD, /* decoding error in UTF */ | |||||
| Runemax = 0x10FFFF, /* maximum rune value */ | |||||
| }; | |||||
| #ifdef __cplusplus | |||||
| extern "C" { | |||||
| #endif | |||||
| /* | |||||
| * rune routines | |||||
| */ | |||||
| /* | |||||
| * These routines were written by Rob Pike and Ken Thompson | |||||
| * and first appeared in Plan 9. | |||||
| * SEE ALSO | |||||
| * utf (7) | |||||
| * tcs (1) | |||||
| */ | |||||
| // runetochar copies (encodes) one rune, pointed to by r, to at most | |||||
| // UTFmax bytes starting at s and returns the number of bytes generated. | |||||
| int runetochar(char* s, const Rune* r); | |||||
| // chartorune copies (decodes) at most UTFmax bytes starting at s to | |||||
| // one rune, pointed to by r, and returns the number of bytes consumed. | |||||
| // If the input is not exactly in UTF format, chartorune will set *r | |||||
| // to Runeerror and return 1. | |||||
| // | |||||
| // Note: There is no special case for a "null-terminated" string. A | |||||
| // string whose first byte has the value 0 is the UTF8 encoding of the | |||||
| // Unicode value 0 (i.e., ASCII NULL). A byte value of 0 is illegal | |||||
| // anywhere else in a UTF sequence. | |||||
| int chartorune(Rune* r, const char* s); | |||||
| // charntorune is like chartorune, except that it will access at most | |||||
| // n bytes of s. If the UTF sequence is incomplete within n bytes, | |||||
| // charntorune will set *r to Runeerror and return 0. If it is complete | |||||
| // but not in UTF format, it will set *r to Runeerror and return 1. | |||||
| // | |||||
| // Added 2004-09-24 by Wei-Hwa Huang | |||||
| int charntorune(Rune* r, const char* s, int n); | |||||
| // isvalidcharntorune(str, n, r, consumed) | |||||
| // is a convenience function that calls "*consumed = charntorune(r, str, n)" | |||||
| // and returns an int (logically boolean) indicating whether the first | |||||
| // n bytes of str was a valid and complete UTF sequence. | |||||
| int isvalidcharntorune(const char* str, int n, Rune* r, int* consumed); | |||||
| // runelen returns the number of bytes required to convert r into UTF. | |||||
| int runelen(Rune r); | |||||
| // runenlen returns the number of bytes required to convert the n | |||||
| // runes pointed to by r into UTF. | |||||
| int runenlen(const Rune* r, int n); | |||||
| // fullrune returns 1 if the string s of length n is long enough to be | |||||
| // decoded by chartorune, and 0 otherwise. This does not guarantee | |||||
| // that the string contains a legal UTF encoding. This routine is used | |||||
| // by programs that obtain input one byte at a time and need to know | |||||
| // when a full rune has arrived. | |||||
| int fullrune(const char* s, int n); | |||||
| // The following routines are analogous to the corresponding string | |||||
| // routines with "utf" substituted for "str", and "rune" substituted | |||||
| // for "chr". | |||||
| // utflen returns the number of runes that are represented by the UTF | |||||
| // string s. (cf. strlen) | |||||
| int utflen(const char* s); | |||||
| // utfnlen returns the number of complete runes that are represented | |||||
| // by the first n bytes of the UTF string s. If the last few bytes of | |||||
| // the string contain an incompletely coded rune, utfnlen will not | |||||
| // count them; in this way, it differs from utflen, which includes | |||||
| // every byte of the string. (cf. strnlen) | |||||
| int utfnlen(const char* s, long n); | |||||
| // utfrune returns a pointer to the first occurrence of rune r in the | |||||
| // UTF string s, or 0 if r does not occur in the string. The NULL | |||||
| // byte terminating a string is considered to be part of the string s. | |||||
| // (cf. strchr) | |||||
| /*const*/ char* utfrune(const char* s, Rune r); | |||||
| // utfrrune returns a pointer to the last occurrence of rune r in the | |||||
| // UTF string s, or 0 if r does not occur in the string. The NULL | |||||
| // byte terminating a string is considered to be part of the string s. | |||||
| // (cf. strrchr) | |||||
| /*const*/ char* utfrrune(const char* s, Rune r); | |||||
| // utfutf returns a pointer to the first occurrence of the UTF string | |||||
| // s2 as a UTF substring of s1, or 0 if there is none. If s2 is the | |||||
| // null string, utfutf returns s1. (cf. strstr) | |||||
| const char* utfutf(const char* s1, const char* s2); | |||||
| // utfecpy copies UTF sequences until a null sequence has been copied, | |||||
| // but writes no sequences beyond es1. If any sequences are copied, | |||||
| // s1 is terminated by a null sequence, and a pointer to that sequence | |||||
| // is returned. Otherwise, the original s1 is returned. (cf. strecpy) | |||||
| char* utfecpy(char *s1, char *es1, const char *s2); | |||||
| // These functions are rune-string analogues of the corresponding | |||||
| // functions in strcat (3). | |||||
| // | |||||
| // These routines first appeared in Plan 9. | |||||
| // SEE ALSO | |||||
| // memmove (3) | |||||
| // rune (3) | |||||
| // strcat (2) | |||||
| // | |||||
| // BUGS: The outcome of overlapping moves varies among implementations. | |||||
| Rune* runestrcat(Rune* s1, const Rune* s2); | |||||
| Rune* runestrncat(Rune* s1, const Rune* s2, long n); | |||||
| const Rune* runestrchr(const Rune* s, Rune c); | |||||
| int runestrcmp(const Rune* s1, const Rune* s2); | |||||
| int runestrncmp(const Rune* s1, const Rune* s2, long n); | |||||
| Rune* runestrcpy(Rune* s1, const Rune* s2); | |||||
| Rune* runestrncpy(Rune* s1, const Rune* s2, long n); | |||||
| Rune* runestrecpy(Rune* s1, Rune* es1, const Rune* s2); | |||||
| Rune* runestrdup(const Rune* s); | |||||
| const Rune* runestrrchr(const Rune* s, Rune c); | |||||
| long runestrlen(const Rune* s); | |||||
| const Rune* runestrstr(const Rune* s1, const Rune* s2); | |||||
| // The following routines test types and modify cases for Unicode | |||||
| // characters. Unicode defines some characters as letters and | |||||
| // specifies three cases: upper, lower, and title. Mappings among the | |||||
| // cases are also defined, although they are not exhaustive: some | |||||
| // upper case letters have no lower case mapping, and so on. Unicode | |||||
| // also defines several character properties, a subset of which are | |||||
| // checked by these routines. These routines are based on Unicode | |||||
| // version 3.0.0. | |||||
| // | |||||
| // NOTE: The routines are implemented in C, so the boolean functions | |||||
| // (e.g., isupperrune) return 0 for false and 1 for true. | |||||
| // | |||||
| // | |||||
| // toupperrune, tolowerrune, and totitlerune are the Unicode case | |||||
| // mappings. These routines return the character unchanged if it has | |||||
| // no defined mapping. | |||||
| Rune toupperrune(Rune r); | |||||
| Rune tolowerrune(Rune r); | |||||
| Rune totitlerune(Rune r); | |||||
| // isupperrune tests for upper case characters, including Unicode | |||||
| // upper case letters and targets of the toupper mapping. islowerrune | |||||
| // and istitlerune are defined analogously. | |||||
| int isupperrune(Rune r); | |||||
| int islowerrune(Rune r); | |||||
| int istitlerune(Rune r); | |||||
| // isalpharune tests for Unicode letters; this includes ideographs in | |||||
| // addition to alphabetic characters. | |||||
| int isalpharune(Rune r); | |||||
| // isdigitrune tests for digits. Non-digit numbers, such as Roman | |||||
| // numerals, are not included. | |||||
| int isdigitrune(Rune r); | |||||
| // isspacerune tests for whitespace characters, including "C" locale | |||||
| // whitespace, Unicode defined whitespace, and the "zero-width | |||||
| // non-break space" character. | |||||
| int isspacerune(Rune r); | |||||
| // (The comments in this file were copied from the manpage files rune.3, | |||||
| // isalpharune.3, and runestrcat.3. Some formatting changes were also made | |||||
| // to conform to Google style. /JRM 11/11/05) | |||||
| #ifdef __cplusplus | |||||
| } | |||||
| #endif | |||||
| #endif | |||||
| @ -0,0 +1,28 @@ | |||||
| /* | |||||
| * The authors of this software are Rob Pike and Ken Thompson. | |||||
| * Copyright (c) 1998-2002 by Lucent Technologies. | |||||
| * Permission to use, copy, modify, and distribute this software for any | |||||
| * purpose without fee is hereby granted, provided that this entire notice | |||||
| * is included in all copies of any software which is or includes a copy | |||||
| * or modification of this software and in all copies of the supporting | |||||
| * documentation for such software. | |||||
| * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED | |||||
| * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY | |||||
| * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY | |||||
| * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. | |||||
| */ | |||||
| #define uchar _utfuchar | |||||
| #define ushort _utfushort | |||||
| #define uint _utfuint | |||||
| #define ulong _utfulong | |||||
| #define vlong _utfvlong | |||||
| #define uvlong _utfuvlong | |||||
| typedef unsigned char uchar; | |||||
| typedef unsigned short ushort; | |||||
| typedef unsigned int uint; | |||||
| typedef unsigned long ulong; | |||||
| #define nelem(x) (sizeof(x)/sizeof((x)[0])) | |||||
| #define nil ((void*)0) | |||||