| @ -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) | |||