Support for Signal calls.

Merge in RedPhone

// FREEBIE
This commit is contained in:
Moxie Marlinspike
2015-09-09 13:54:29 -07:00
parent 3d4ae60d81
commit d83a3d71bc
2585 changed files with 803492 additions and 45 deletions

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ALIGNED_MALLOC_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ALIGNED_MALLOC_H_
// The functions declared here
// 1) Allocates block of aligned memory.
// 2) Re-calculates a pointer such that it is aligned to a higher or equal
// address.
// Note: alignment must be a power of two. The alignment is in bytes.
#include <stddef.h>
namespace webrtc {
// Returns a pointer to the first boundry of |alignment| bytes following the
// address of |ptr|.
// Note that there is no guarantee that the memory in question is available.
// |ptr| has no requirements other than it can't be NULL.
void* GetRightAlign(const void* ptr, size_t alignment);
// Allocates memory of |size| bytes aligned on an |alignment| boundry.
// The return value is a pointer to the memory. Note that the memory must
// be de-allocated using AlignedFree.
void* AlignedMalloc(size_t size, size_t alignment);
// De-allocates memory created using the AlignedMalloc() API.
void AlignedFree(void* mem_block);
// Templated versions to facilitate usage of aligned malloc without casting
// to and from void*.
template<typename T>
T* GetRightAlign(const T* ptr, size_t alignment) {
return reinterpret_cast<T*>(GetRightAlign(reinterpret_cast<const void*>(ptr),
alignment));
}
template<typename T>
T* AlignedMalloc(size_t size, size_t alignment) {
return reinterpret_cast<T*>(AlignedMalloc(size, alignment));
}
// Deleter for use with scoped_ptr. E.g., use as
// scoped_ptr<Foo, AlignedFreeDeleter> foo;
struct AlignedFreeDeleter {
inline void operator()(void* ptr) const {
AlignedFree(ptr);
}
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ALIGNED_MALLOC_H_

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ASM_DEFINES_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ASM_DEFINES_H_
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
// Define the macros used in ARM assembly code, so that for Mac or iOS builds
// we add leading underscores for the function names.
#ifdef __APPLE__
.macro GLOBAL_FUNCTION name
.global _\name
.endm
.macro DEFINE_FUNCTION name
_\name:
.endm
.macro CALL_FUNCTION name
bl _\name
.endm
.macro GLOBAL_LABEL name
.global _\name
.endm
#else
.macro GLOBAL_FUNCTION name
.global \name
.endm
.macro DEFINE_FUNCTION name
\name:
.endm
.macro CALL_FUNCTION name
bl \name
.endm
.macro GLOBAL_LABEL name
.global \name
.endm
#endif
// With Apple's clang compiler, for instructions ldrb, strh, etc.,
// the condition code is after the width specifier. Here we define
// only the ones that are actually used in the assembly files.
#if (defined __llvm__) && (defined __APPLE__)
.macro streqh reg1, reg2, num
strheq \reg1, \reg2, \num
.endm
#endif
.text
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ASM_DEFINES_H_

View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Atomic, system independent 32-bit integer. Unless you know what you're
// doing, use locks instead! :-)
//
// Note: assumes 32-bit (or higher) system
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ATOMIC32_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ATOMIC32_H_
#include <stddef.h>
#include "webrtc/base/constructormagic.h"
#include "webrtc/common_types.h"
namespace webrtc {
// 32 bit atomic variable. Note that this class relies on the compiler to
// align the 32 bit value correctly (on a 32 bit boundary), so as long as you're
// not doing things like reinterpret_cast over some custom allocated memory
// without being careful with alignment, you should be fine.
class Atomic32 {
public:
Atomic32(int32_t initial_value = 0);
~Atomic32();
// Prefix operator!
int32_t operator++();
int32_t operator--();
int32_t operator+=(int32_t value);
int32_t operator-=(int32_t value);
// Sets the value atomically to new_value if the value equals compare value.
// The function returns true if the exchange happened.
bool CompareExchange(int32_t new_value, int32_t compare_value);
int32_t Value() {
return *this += 0;
}
private:
// Disable the + and - operator since it's unclear what these operations
// should do.
Atomic32 operator+(const Atomic32& other);
Atomic32 operator-(const Atomic32& other);
// Checks if |_value| is 32bit aligned.
inline bool Is32bitAligned() const {
return (reinterpret_cast<ptrdiff_t>(&value_) & 3) == 0;
}
DISALLOW_COPY_AND_ASSIGN(Atomic32);
int32_t value_;
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ATOMIC32_H_

View File

@@ -0,0 +1,85 @@
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CLOCK_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CLOCK_H_
#include "webrtc/system_wrappers/interface/rw_lock_wrapper.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
#include "webrtc/typedefs.h"
namespace webrtc {
// January 1970, in NTP seconds.
const uint32_t kNtpJan1970 = 2208988800UL;
// Magic NTP fractional unit.
const double kMagicNtpFractionalUnit = 4.294967296E+9;
// A clock interface that allows reading of absolute and relative timestamps.
class Clock {
public:
virtual ~Clock() {}
// Return a timestamp in milliseconds relative to some arbitrary source; the
// source is fixed for this clock.
virtual int64_t TimeInMilliseconds() const = 0;
// Return a timestamp in microseconds relative to some arbitrary source; the
// source is fixed for this clock.
virtual int64_t TimeInMicroseconds() const = 0;
// Retrieve an NTP absolute timestamp in seconds and fractions of a second.
virtual void CurrentNtp(uint32_t& seconds, uint32_t& fractions) const = 0;
// Retrieve an NTP absolute timestamp in milliseconds.
virtual int64_t CurrentNtpInMilliseconds() const = 0;
// Converts an NTP timestamp to a millisecond timestamp.
static int64_t NtpToMs(uint32_t seconds, uint32_t fractions);
// Returns an instance of the real-time system clock implementation.
static Clock* GetRealTimeClock();
};
class SimulatedClock : public Clock {
public:
explicit SimulatedClock(int64_t initial_time_us);
virtual ~SimulatedClock();
// Return a timestamp in milliseconds relative to some arbitrary source; the
// source is fixed for this clock.
virtual int64_t TimeInMilliseconds() const OVERRIDE;
// Return a timestamp in microseconds relative to some arbitrary source; the
// source is fixed for this clock.
virtual int64_t TimeInMicroseconds() const OVERRIDE;
// Retrieve an NTP absolute timestamp in milliseconds.
virtual void CurrentNtp(uint32_t& seconds,
uint32_t& fractions) const OVERRIDE;
// Converts an NTP timestamp to a millisecond timestamp.
virtual int64_t CurrentNtpInMilliseconds() const OVERRIDE;
// Advance the simulated clock with a given number of milliseconds or
// microseconds.
void AdvanceTimeMilliseconds(int64_t milliseconds);
void AdvanceTimeMicroseconds(int64_t microseconds);
private:
int64_t time_us_;
scoped_ptr<RWLockWrapper> lock_;
};
}; // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CLOCK_H_

View File

@@ -0,0 +1,90 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Borrowed from Chromium's src/base/macros.h.
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
// 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.
// TODO(ajm): Hack to avoid multiple definitions until the base/ of webrtc and
// libjingle are merged.
#if !defined(COMPILE_ASSERT)
#if __cplusplus >= 201103L
// Under C++11, just use static_assert.
#define COMPILE_ASSERT(expr, msg) static_assert(expr, #msg)
#else
template <bool>
struct CompileAssert {
};
#define COMPILE_ASSERT(expr, msg) \
typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
#endif // __cplusplus >= 201103L
#endif // !defined(COMPILE_ASSERT)
// 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 outer 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.
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_

View File

@@ -0,0 +1,22 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
// Only use this for C files. For C++, use compile_assert.h.
//
// Use this macro to verify at compile time that certain restrictions are met.
// The argument is the boolean expression to evaluate.
// Example:
// COMPILE_ASSERT(sizeof(foo) < 128);
#define COMPILE_ASSERT(expression) switch (0) {case 0: case expression:;}
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CONDITION_VARIABLE_WRAPPER_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CONDITION_VARIABLE_WRAPPER_H_
namespace webrtc {
class CriticalSectionWrapper;
class ConditionVariableWrapper {
public:
// Factory method, constructor disabled.
static ConditionVariableWrapper* CreateConditionVariable();
virtual ~ConditionVariableWrapper() {}
// Calling thread will atomically release crit_sect and wait until next
// some other thread calls Wake() or WakeAll().
virtual void SleepCS(CriticalSectionWrapper& crit_sect) = 0;
// Same as above but with a timeout.
virtual bool SleepCS(CriticalSectionWrapper& crit_sect,
unsigned long max_time_in_ms) = 0;
// Wakes one thread calling SleepCS().
virtual void Wake() = 0;
// Wakes all threads calling SleepCS().
virtual void WakeAll() = 0;
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CONDITION_VARIABLE_WRAPPER_H_

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_FEATURES_WRAPPER_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_FEATURES_WRAPPER_H_
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
#include "webrtc/typedefs.h"
// List of features in x86.
typedef enum {
kSSE2,
kSSE3
} CPUFeature;
// List of features in ARM.
enum {
kCPUFeatureARMv7 = (1 << 0),
kCPUFeatureVFPv3 = (1 << 1),
kCPUFeatureNEON = (1 << 2),
kCPUFeatureLDREXSTREX = (1 << 3)
};
typedef int (*WebRtc_CPUInfo)(CPUFeature feature);
// Returns true if the CPU supports the feature.
extern WebRtc_CPUInfo WebRtc_GetCPUInfo;
// No CPU feature is available => straight C path.
extern WebRtc_CPUInfo WebRtc_GetCPUInfoNoASM;
// Return the features in an ARM device.
// It detects the features in the hardware platform, and returns supported
// values in the above enum definition as a bitmask.
extern uint64_t WebRtc_GetCPUFeaturesARM(void);
#if defined(__cplusplus) || defined(c_plusplus)
} // extern "C"
#endif
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_FEATURES_WRAPPER_H_

View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_INFO_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_INFO_H_
#include "webrtc/typedefs.h"
namespace webrtc {
class CpuInfo {
public:
static uint32_t DetectNumberOfCores();
private:
CpuInfo() {}
static uint32_t number_of_cores_;
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_INFO_H_

View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_
// If the critical section is heavily contended it may be beneficial to use
// read/write locks instead.
#include "webrtc/common_types.h"
#include "webrtc/system_wrappers/interface/thread_annotations.h"
namespace webrtc {
class LOCKABLE CriticalSectionWrapper {
public:
// Factory method, constructor disabled
static CriticalSectionWrapper* CreateCriticalSection();
virtual ~CriticalSectionWrapper() {}
// Tries to grab lock, beginning of a critical section. Will wait for the
// lock to become available if the grab failed.
virtual void Enter() EXCLUSIVE_LOCK_FUNCTION() = 0;
// Returns a grabbed lock, end of critical section.
virtual void Leave() UNLOCK_FUNCTION() = 0;
};
// RAII extension of the critical section. Prevents Enter/Leave mismatches and
// provides more compact critical section syntax.
class SCOPED_LOCKABLE CriticalSectionScoped {
public:
explicit CriticalSectionScoped(CriticalSectionWrapper* critsec)
EXCLUSIVE_LOCK_FUNCTION(critsec)
: ptr_crit_sec_(critsec) {
ptr_crit_sec_->Enter();
}
~CriticalSectionScoped() UNLOCK_FUNCTION() { ptr_crit_sec_->Leave(); }
private:
CriticalSectionWrapper* ptr_crit_sec_;
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_

View File

@@ -0,0 +1,119 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// This singleton can be used for logging data for offline processing. Data
// logged with it can conveniently be parsed and processed with e.g. Matlab.
//
// Following is an example of the log file format, starting with the header
// row at line 1, and the data rows following.
// col1,col2,col3,multi-value-col4[3],,,col5
// 123,10.2,-243,1,2,3,100
// 241,12.3,233,1,2,3,200
// 13,16.4,-13,1,2,3,300
//
// As can be seen in the example, a multi-value-column is specified with the
// name followed the number of elements it contains. This followed by
// number of elements - 1 empty columns.
//
// Without multi-value-columns this format can be natively by Matlab. With
// multi-value-columns a small Matlab script is needed, available at
// trunk/tools/matlab/parseLog.m.
//
// Table names and column names are case sensitive.
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_H_
#include <string>
#include "webrtc/system_wrappers/interface/data_log_impl.h"
namespace webrtc {
class DataLog {
public:
// Creates a log which uses a separate thread (referred to as the file
// writer thread) for writing log rows to file.
//
// Calls to this function after the log object has been created will only
// increment the reference counter.
static int CreateLog();
// Decrements the reference counter and deletes the log when the counter
// reaches 0. Should be called equal number of times as successful calls to
// CreateLog or memory leak will occur.
static void ReturnLog();
// Combines the string table_name and the integer table_id into a new string
// table_name + _ + table_id. The new string will be lower-case.
static std::string Combine(const std::string& table_name, int table_id);
// Adds a new table, with the name table_name, and creates the file, with the
// name table_name + ".txt", to which the table will be written.
// table_name is treated in a case sensitive way.
static int AddTable(const std::string& table_name);
// Adds a new column to a table. The column will be a multi-value-column
// if multi_value_length is greater than 1.
// table_name and column_name are treated in a case sensitive way.
static int AddColumn(const std::string& table_name,
const std::string& column_name,
int multi_value_length);
// Inserts a single value into a table with name table_name at the column with
// name column_name.
// Note that the ValueContainer makes use of the copy constructor,
// operator= and operator<< of the type T, and that the template type must
// implement a deep copy copy constructor and operator=.
// Copy constructor and operator= must not be disabled for the type T.
// table_name and column_name are treated in a case sensitive way.
template<class T>
static int InsertCell(const std::string& table_name,
const std::string& column_name,
T value) {
DataLogImpl* data_log = DataLogImpl::StaticInstance();
if (data_log == NULL)
return -1;
return data_log->InsertCell(
table_name,
column_name,
new ValueContainer<T>(value));
}
// Inserts an array of values into a table with name table_name at the
// column specified by column_name, which must be a multi-value-column.
// Note that the MultiValueContainer makes use of the copy constructor,
// operator= and operator<< of the type T, and that the template type
// must implement a deep copy copy constructor and operator=.
// Copy constructor and operator= must not be disabled for the type T.
// table_name and column_name are treated in a case sensitive way.
template<class T>
static int InsertCell(const std::string& table_name,
const std::string& column_name,
const T* array,
int length) {
DataLogImpl* data_log = DataLogImpl::StaticInstance();
if (data_log == NULL)
return -1;
return data_log->InsertCell(
table_name,
column_name,
new MultiValueContainer<T>(array, length));
}
// For the table with name table_name: Writes the current row to file.
// Starts a new empty row.
// table_name is treated in a case-sensitive way.
static int NextRow(const std::string& table_name);
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_H_

View File

@@ -0,0 +1,85 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// This is a pure C wrapper of the DataLog class. The functions are directly
// mapped here except for InsertCell as C does not support templates.
// See data_log.h for a description of the functions.
#ifndef SRC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_C_H_
#define SRC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_C_H_
#include <stddef.h> // size_t
#include "webrtc/typedefs.h"
#ifdef __cplusplus
extern "C" {
#endif
// All char* parameters in this file are expected to be null-terminated
// character sequences.
int WebRtcDataLog_CreateLog();
void WebRtcDataLog_ReturnLog();
char* WebRtcDataLog_Combine(char* combined_name, size_t combined_len,
const char* table_name, int table_id);
int WebRtcDataLog_AddTable(const char* table_name);
int WebRtcDataLog_AddColumn(const char* table_name, const char* column_name,
int multi_value_length);
int WebRtcDataLog_InsertCell_int(const char* table_name,
const char* column_name,
int value);
int WebRtcDataLog_InsertArray_int(const char* table_name,
const char* column_name,
const int* values,
int length);
int WebRtcDataLog_InsertCell_float(const char* table_name,
const char* column_name,
float value);
int WebRtcDataLog_InsertArray_float(const char* table_name,
const char* column_name,
const float* values,
int length);
int WebRtcDataLog_InsertCell_double(const char* table_name,
const char* column_name,
double value);
int WebRtcDataLog_InsertArray_double(const char* table_name,
const char* column_name,
const double* values,
int length);
int WebRtcDataLog_InsertCell_int32(const char* table_name,
const char* column_name,
int32_t value);
int WebRtcDataLog_InsertArray_int32(const char* table_name,
const char* column_name,
const int32_t* values,
int length);
int WebRtcDataLog_InsertCell_uint32(const char* table_name,
const char* column_name,
uint32_t value);
int WebRtcDataLog_InsertArray_uint32(const char* table_name,
const char* column_name,
const uint32_t* values,
int length);
int WebRtcDataLog_InsertCell_int64(const char* table_name,
const char* column_name,
int64_t value);
int WebRtcDataLog_InsertArray_int64(const char* table_name,
const char* column_name,
const int64_t* values,
int length);
int WebRtcDataLog_NextRow(const char* table_name);
#ifdef __cplusplus
} // end of extern "C"
#endif
#endif // SRC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_C_H_ // NOLINT

View File

@@ -0,0 +1,155 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// This file contains the helper classes for the DataLog APIs. See data_log.h
// for the APIs.
//
// These classes are helper classes used for logging data for offline
// processing. Data logged with these classes can conveniently be parsed and
// processed with e.g. Matlab.
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_IMPL_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_IMPL_H_
#include <map>
#include <sstream>
#include <string>
#include <vector>
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
#include "webrtc/typedefs.h"
namespace webrtc {
class CriticalSectionWrapper;
class EventWrapper;
class LogTable;
class RWLockWrapper;
class ThreadWrapper;
// All container classes need to implement a ToString-function to be
// writable to file. Enforce this via the Container interface.
class Container {
public:
virtual ~Container() {}
virtual void ToString(std::string* container_string) const = 0;
};
template<class T>
class ValueContainer : public Container {
public:
explicit ValueContainer(T data) : data_(data) {}
virtual void ToString(std::string* container_string) const {
*container_string = "";
std::stringstream ss;
ss << data_ << ",";
ss >> *container_string;
}
private:
T data_;
};
template<class T>
class MultiValueContainer : public Container {
public:
MultiValueContainer(const T* data, int length)
: data_(data, data + length) {
}
virtual void ToString(std::string* container_string) const {
*container_string = "";
std::stringstream ss;
for (size_t i = 0; i < data_.size(); ++i)
ss << data_[i] << ",";
*container_string += ss.str();
}
private:
std::vector<T> data_;
};
class DataLogImpl {
public:
~DataLogImpl();
// The implementation of the CreateLog() method declared in data_log.h.
// See data_log.h for a description.
static int CreateLog();
// The implementation of the StaticInstance() method declared in data_log.h.
// See data_log.h for a description.
static DataLogImpl* StaticInstance();
// The implementation of the ReturnLog() method declared in data_log.h. See
// data_log.h for a description.
static void ReturnLog();
// The implementation of the AddTable() method declared in data_log.h. See
// data_log.h for a description.
int AddTable(const std::string& table_name);
// The implementation of the AddColumn() method declared in data_log.h. See
// data_log.h for a description.
int AddColumn(const std::string& table_name,
const std::string& column_name,
int multi_value_length);
// Inserts a Container into a table with name table_name at the column
// with name column_name.
// column_name is treated in a case sensitive way.
int InsertCell(const std::string& table_name,
const std::string& column_name,
const Container* value_container);
// The implementation of the NextRow() method declared in data_log.h. See
// data_log.h for a description.
int NextRow(const std::string& table_name);
private:
DataLogImpl();
// Initializes the DataLogImpl object, allocates and starts the
// thread file_writer_thread_.
int Init();
// Write all complete rows in every table to file.
// This function should only be called by the file_writer_thread_ if that
// thread is running to avoid race conditions.
void Flush();
// Run() is called by the thread file_writer_thread_.
static bool Run(void* obj);
// This function writes data to file. Note, it blocks if there is no data
// that should be written to file availble. Flush is the non-blocking
// version of this function.
void Process();
// Stops the continuous calling of Process().
void StopThread();
// Collection of tables indexed by the table name as std::string.
typedef std::map<std::string, LogTable*> TableMap;
typedef webrtc::scoped_ptr<CriticalSectionWrapper> CritSectScopedPtr;
static CritSectScopedPtr crit_sect_;
static DataLogImpl* instance_;
int counter_;
TableMap tables_;
EventWrapper* flush_event_;
ThreadWrapper* file_writer_thread_;
RWLockWrapper* tables_lock_;
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_IMPL_H_

View File

@@ -0,0 +1,73 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// This file defines the interface for event tracing in WebRTC.
//
// Event log handlers are set through SetupEventTracer(). User of this API will
// provide two function pointers to handle event tracing calls.
//
// * GetCategoryEnabledPtr
// Event tracing system calls this function to determine if a particular
// event category is enabled.
//
// * AddTraceEventPtr
// Adds a tracing event. It is the user's responsibility to log the data
// provided.
//
// Parameters for the above two functions are described in trace_event.h.
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_EVENT_TRACER_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_EVENT_TRACER_H_
#include "webrtc/common_types.h"
namespace webrtc {
typedef const unsigned char* (*GetCategoryEnabledPtr)(const char* name);
typedef void (*AddTraceEventPtr)(char phase,
const unsigned char* category_enabled,
const char* name,
unsigned long long id,
int num_args,
const char** arg_names,
const unsigned char* arg_types,
const unsigned long long* arg_values,
unsigned char flags);
// User of WebRTC can call this method to setup event tracing.
//
// This method must be called before any WebRTC methods. Functions
// provided should be thread-safe.
WEBRTC_DLLEXPORT void SetupEventTracer(
GetCategoryEnabledPtr get_category_enabled_ptr,
AddTraceEventPtr add_trace_event_ptr);
// This class defines interface for the event tracing system to call
// internally. Do not call these methods directly.
class EventTracer {
public:
static const unsigned char* GetCategoryEnabled(
const char* name);
static void AddTraceEvent(
char phase,
const unsigned char* category_enabled,
const char* name,
unsigned long long id,
int num_args,
const char** arg_names,
const unsigned char* arg_types,
const unsigned long long* arg_values,
unsigned char flags);
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_EVENT_TRACER_H_

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_EVENT_WRAPPER_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_EVENT_WRAPPER_H_
namespace webrtc {
enum EventTypeWrapper {
kEventSignaled = 1,
kEventError = 2,
kEventTimeout = 3
};
#define WEBRTC_EVENT_10_SEC 10000
#define WEBRTC_EVENT_INFINITE 0xffffffff
class EventWrapper {
public:
// Factory method. Constructor disabled.
static EventWrapper* Create();
virtual ~EventWrapper() {}
// Releases threads who are calling Wait() and has started waiting. Please
// note that a thread calling Wait() will not start waiting immediately.
// assumptions to the contrary is a very common source of issues in
// multithreaded programming.
// Set is sticky in the sense that it will release at least one thread
// either immediately or some time in the future.
virtual bool Set() = 0;
// Prevents future Wait() calls from finishing without a new Set() call.
virtual bool Reset() = 0;
// Puts the calling thread into a wait state. The thread may be released
// by a Set() call depending on if other threads are waiting and if so on
// timing. The thread that was released will call Reset() before leaving
// preventing more threads from being released. If multiple threads
// are waiting for the same Set(), only one (random) thread is guaranteed to
// be released. It is possible that multiple (random) threads are released
// Depending on timing.
virtual EventTypeWrapper Wait(unsigned long max_time) = 0;
// Starts a timer that will call a non-sticky version of Set() either once
// or periodically. If the timer is periodic it ensures that there is no
// drift over time relative to the system clock.
virtual bool StartTimer(bool periodic, unsigned long time) = 0;
virtual bool StopTimer() = 0;
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_EVENT_WRAPPER_H_

View File

@@ -0,0 +1,70 @@
//
// Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
//
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_FIELD_TRIAL_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_FIELD_TRIAL_H_
#include <string>
#include "webrtc/common_types.h"
// Field trials allow webrtc clients (such as Chrome) to turn on feature code
// in binaries out in the field and gather information with that.
//
// WebRTC clients MUST provide an implementation of:
//
// std::string webrtc::field_trial::FindFullName(const std::string& trial).
//
// Or link with a default one provided in:
//
// system_wrappers/source/system_wrappers.gyp:field_trial_default
//
//
// They are designed to wire up directly to chrome field trials and to speed up
// developers by reducing the need to wire APIs to control whether a feature is
// on/off. E.g. to experiment with a new method that could lead to a different
// trade-off between CPU/bandwidth:
//
// 1 - Develop the feature with default behaviour off:
//
// if (FieldTrial::FindFullName("WebRTCExperimenMethod2") == "Enabled")
// method2();
// else
// method1();
//
// 2 - Once the changes are rolled to chrome, the new code path can be
// controlled as normal chrome field trials.
//
// 3 - Evaluate the new feature and clean the code paths.
//
// Notes:
// - NOT every feature is a candidate to be controlled by this mechanism as
// it may require negotation between involved parties (e.g. SDP).
//
// TODO(andresp): since chrome --force-fieldtrials does not marks the trial
// as active it does not gets propaged to renderer process. For now one
// needs to push a config with start_active:true or run a local finch
// server.
//
// TODO(andresp): find out how to get bots to run tests with trials enabled.
namespace webrtc {
namespace field_trial {
// Returns the group name chosen for the named trial, or the empty string
// if the trial does not exists.
//
// Note: To keep things tidy append all the trial names with WebRTC.
std::string FindFullName(const std::string& name);
} // namespace field_trial
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_FIELD_TRIAL_H_

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_FILE_WRAPPER_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_FILE_WRAPPER_H_
#include <stddef.h>
#include <stdio.h>
#include "webrtc/common_types.h"
#include "webrtc/typedefs.h"
// Implementation of an InStream and OutStream that can read (exclusive) or
// write from/to a file.
namespace webrtc {
class FileWrapper : public InStream, public OutStream {
public:
static const size_t kMaxFileNameSize = 1024;
// Factory method. Constructor disabled.
static FileWrapper* Create();
// Returns true if a file has been opened.
virtual bool Open() const = 0;
// Opens a file in read or write mode, decided by the read_only parameter.
virtual int OpenFile(const char* file_name_utf8,
bool read_only,
bool loop = false,
bool text = false) = 0;
// Initializes the wrapper from an existing handle. |read_only| must match in
// the mode the file was opened in. If |manage_file| is true, the wrapper
// takes ownership of |handle| and closes it in CloseFile().
virtual int OpenFromFileHandle(FILE* handle,
bool manage_file,
bool read_only,
bool loop = false) = 0;
virtual int CloseFile() = 0;
// Limits the file size to |bytes|. Writing will fail after the cap
// is hit. Pass zero to use an unlimited size.
virtual int SetMaxFileSize(size_t bytes) = 0;
// Flush any pending writes.
virtual int Flush() = 0;
// Returns the opened file's name in |file_name_utf8|. Provide the size of
// the buffer in bytes in |size|. The name will be truncated if |size| is
// too small.
virtual int FileName(char* file_name_utf8,
size_t size) const = 0;
// Write |format| to the opened file. Arguments are taken in the same manner
// as printf. That is, supply a format string containing text and
// specifiers. Returns the number of characters written or -1 on error.
virtual int WriteText(const char* format, ...) = 0;
// Inherited from Instream.
// Reads |length| bytes from file to |buf|. Returns the number of bytes read
// or -1 on error.
virtual int Read(void* buf, int length) = 0;
// Inherited from OutStream.
// Writes |length| bytes from |buf| to file. The actual writing may happen
// some time later. Call Flush() to force a write.
virtual bool Write(const void* buf, int length) = 0;
// Inherited from both Instream and OutStream.
// Rewinds the file to the start. Only available when OpenFile() has been
// called with |loop| == true or |readOnly| == true.
virtual int Rewind() = 0;
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_FILE_WRAPPER_H_

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Various inline functions and macros to fix compilation of 32 bit target
// on MSVC with /Wp64 flag enabled.
// The original code can be found here:
// http://src.chromium.org/svn/trunk/src/base/fix_wp64.h
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_FIX_INTERLOCKED_EXCHANGE_POINTER_WINDOWS_H_
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_FIX_INTERLOCKED_EXCHANGE_POINTER_WINDOWS_H_
#include <windows.h>
// Platform SDK fixes when building with /Wp64 for a 32 bits target.
#if !defined(_WIN64) && defined(_Wp64)
#ifdef InterlockedExchangePointer
#undef InterlockedExchangePointer
// The problem is that the macro provided for InterlockedExchangePointer() is
// doing a (LONG) C-style cast that triggers invariably the warning C4312 when
// building on 32 bits.
inline void* InterlockedExchangePointer(void* volatile* target, void* value) {
return reinterpret_cast<void*>(static_cast<LONG_PTR>(InterlockedExchange(
reinterpret_cast<volatile LONG*>(target),
static_cast<LONG>(reinterpret_cast<LONG_PTR>(value)))));
}
#endif // #ifdef InterlockedExchangePointer
#endif // #if !defined(_WIN64) && defined(_Wp64)
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_FIX_INTERLOCKED_EXCHANGE_POINTER_WINDOWS_H_

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LOGCAT_TRACE_CONTEXT_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LOGCAT_TRACE_CONTEXT_H_
#include "webrtc/system_wrappers/interface/trace.h"
#ifndef ANDROID
#error This file only makes sense to include on Android!
#endif
namespace webrtc {
// Scoped helper class for directing Traces to Android's logcat facility. While
// this object lives, Trace output will be sent to logcat.
class LogcatTraceContext : public webrtc::TraceCallback {
public:
LogcatTraceContext();
virtual ~LogcatTraceContext();
// TraceCallback impl.
virtual void Print(TraceLevel level, const char* message, int length);
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LOGCAT_TRACE_CONTEXT_H_

View File

@@ -0,0 +1,161 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// This is a highly stripped-down version of libjingle's talk/base/logging.h.
// It is a thin wrapper around WEBRTC_TRACE, maintaining the libjingle log
// semantics to ease a transition to that format.
// NOTE: LS_INFO maps to a new trace level which should be reserved for
// infrequent, non-verbose logs. The other levels below kTraceWarning have been
// rendered essentially useless due to their verbosity. Carefully consider the
// impact of adding a new LS_INFO log. If it will be logged at anything
// approaching a frame or packet frequency, use LS_VERBOSE if necessary, or
// preferably, do not log at all.
// LOG(...) an ostream target that can be used to send formatted
// output to a variety of logging targets, such as debugger console, stderr,
// file, or any StreamInterface.
// The severity level passed as the first argument to the LOGging
// functions is used as a filter, to limit the verbosity of the logging.
// Static members of LogMessage documented below are used to control the
// verbosity and target of the output.
// There are several variations on the LOG macro which facilitate logging
// of common error conditions, detailed below.
// LOG(sev) logs the given stream at severity "sev", which must be a
// compile-time constant of the LoggingSeverity type, without the namespace
// prefix.
// LOG_V(sev) Like LOG(), but sev is a run-time variable of the LoggingSeverity
// type (basically, it just doesn't prepend the namespace).
// LOG_F(sev) Like LOG(), but includes the name of the current function.
// Additional helper macros added by WebRTC:
// LOG_API is a shortcut for API call logging. Pass in the input parameters of
// the method. For example:
// Foo(int bar, int baz) {
// LOG_API2(bar, baz);
// }
//
// LOG_FERR is a shortcut for logging a failed function call. For example:
// if (!Foo(bar)) {
// LOG_FERR1(LS_WARNING, Foo, bar);
// }
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LOGGING_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LOGGING_H_
#include <sstream>
namespace webrtc {
//////////////////////////////////////////////////////////////////////
// Note that the non-standard LoggingSeverity aliases exist because they are
// still in broad use. The meanings of the levels are:
// LS_SENSITIVE: Information which should only be logged with the consent
// of the user, due to privacy concerns.
// LS_VERBOSE: This level is for data which we do not want to appear in the
// normal debug log, but should appear in diagnostic logs.
// LS_INFO: Chatty level used in debugging for all sorts of things, the default
// in debug builds.
// LS_WARNING: Something that may warrant investigation.
// LS_ERROR: Something that should not have occurred.
enum LoggingSeverity {
LS_SENSITIVE, LS_VERBOSE, LS_INFO, LS_WARNING, LS_ERROR
};
class LogMessage {
public:
LogMessage(const char* file, int line, LoggingSeverity sev);
~LogMessage();
static bool Loggable(LoggingSeverity sev);
std::ostream& stream() { return print_stream_; }
private:
// The ostream that buffers the formatted message before output
std::ostringstream print_stream_;
// The severity level of this message
LoggingSeverity severity_;
};
//////////////////////////////////////////////////////////////////////
// Macros which automatically disable logging when WEBRTC_LOGGING == 0
//////////////////////////////////////////////////////////////////////
#ifndef LOG
// The following non-obvious technique for implementation of a
// conditional log stream was stolen from google3/base/logging.h.
// This class is used to explicitly ignore values in the conditional
// logging macros. This avoids compiler warnings like "value computed
// is not used" and "statement has no effect".
class LogMessageVoidify {
public:
LogMessageVoidify() { }
// This has to be an operator with a precedence lower than << but
// higher than ?:
void operator&(std::ostream&) { }
};
#if defined(WEBRTC_RESTRICT_LOGGING)
// This should compile away logs matching the following condition.
#define RESTRICT_LOGGING_PRECONDITION(sev) \
sev < webrtc::LS_INFO ? (void) 0 :
#else
#define RESTRICT_LOGGING_PRECONDITION(sev)
#endif
#define LOG_SEVERITY_PRECONDITION(sev) \
RESTRICT_LOGGING_PRECONDITION(sev) !(webrtc::LogMessage::Loggable(sev)) \
? (void) 0 \
: webrtc::LogMessageVoidify() &
#define LOG(sev) \
LOG_SEVERITY_PRECONDITION(webrtc::sev) \
webrtc::LogMessage(__FILE__, __LINE__, webrtc::sev).stream()
// The _V version is for when a variable is passed in. It doesn't do the
// namespace concatination.
#define LOG_V(sev) \
LOG_SEVERITY_PRECONDITION(sev) \
webrtc::LogMessage(__FILE__, __LINE__, sev).stream()
// The _F version prefixes the message with the current function name.
#if (defined(__GNUC__) && defined(_DEBUG)) || defined(WANT_PRETTY_LOG_F)
#define LOG_F(sev) LOG(sev) << __PRETTY_FUNCTION__ << ": "
#else
#define LOG_F(sev) LOG(sev) << __FUNCTION__ << ": "
#endif
#define LOG_API0() LOG_F(LS_VERBOSE)
#define LOG_API1(v1) LOG_API0() << #v1 << "=" << v1
#define LOG_API2(v1, v2) LOG_API1(v1) \
<< ", " << #v2 << "=" << v2
#define LOG_API3(v1, v2, v3) LOG_API2(v1, v2) \
<< ", " << #v3 << "=" << v3
#define LOG_FERR0(sev, func) LOG(sev) << #func << " failed"
#define LOG_FERR1(sev, func, v1) LOG_FERR0(sev, func) \
<< ": " << #v1 << "=" << v1
#define LOG_FERR2(sev, func, v1, v2) LOG_FERR1(sev, func, v1) \
<< ", " << #v2 << "=" << v2
#define LOG_FERR3(sev, func, v1, v2, v3) LOG_FERR2(sev, func, v1, v2) \
<< ", " << #v3 << "=" << v3
#define LOG_FERR4(sev, func, v1, v2, v3, v4) LOG_FERR3(sev, func, v1, v2, v3) \
<< ", " << #v4 << "=" << v4
#endif // LOG
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LOGGING_H_

View File

@@ -0,0 +1,82 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef SYSTEM_WRAPPERS_INTERFACE_REF_COUNT_H_
#define SYSTEM_WRAPPERS_INTERFACE_REF_COUNT_H_
#include "webrtc/system_wrappers/interface/atomic32.h"
namespace webrtc {
// This class can be used for instantiating
// reference counted objects.
// int32_t AddRef() and int32_t Release().
// Usage:
// RefCountImpl<T>* implementation = new RefCountImpl<T>(p);
//
// Example:
// class MyInterface {
// public:
// virtual void DoSomething() = 0;
// virtual int32_t AddRef() = 0;
// virtual int32_t Release() = 0:
// private:
// virtual ~MyInterface(){};
// }
// class MyImplementation : public MyInterface {
// public:
// virtual DoSomething() { printf("hello"); };
// };
// MyImplementation* CreateMyImplementation() {
// RefCountImpl<MyImplementation>* implementation =
// new RefCountImpl<MyImplementation>();
// return implementation;
// }
template <class T>
class RefCountImpl : public T {
public:
RefCountImpl() : ref_count_(0) {}
template<typename P>
explicit RefCountImpl(P p) : T(p), ref_count_(0) {}
template<typename P1, typename P2>
RefCountImpl(P1 p1, P2 p2) : T(p1, p2), ref_count_(0) {}
template<typename P1, typename P2, typename P3>
RefCountImpl(P1 p1, P2 p2, P3 p3) : T(p1, p2, p3), ref_count_(0) {}
template<typename P1, typename P2, typename P3, typename P4>
RefCountImpl(P1 p1, P2 p2, P3 p3, P4 p4) : T(p1, p2, p3, p4), ref_count_(0) {}
template<typename P1, typename P2, typename P3, typename P4, typename P5>
RefCountImpl(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
: T(p1, p2, p3, p4, p5), ref_count_(0) {}
virtual int32_t AddRef() {
return ++ref_count_;
}
virtual int32_t Release() {
int32_t ref_count;
ref_count = --ref_count_;
if (ref_count == 0)
delete this;
return ref_count;
}
protected:
Atomic32 ref_count_;
};
} // namespace webrtc
#endif // SYSTEM_WRAPPERS_INTERFACE_REF_COUNT_H_

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef SYSTEM_WRAPPERS_INTERFACE_RTP_TO_NTP_H_
#define SYSTEM_WRAPPERS_INTERFACE_RTP_TO_NTP_H_
#include <list>
#include "webrtc/typedefs.h"
namespace webrtc {
struct RtcpMeasurement {
RtcpMeasurement();
RtcpMeasurement(uint32_t ntp_secs, uint32_t ntp_frac, uint32_t timestamp);
uint32_t ntp_secs;
uint32_t ntp_frac;
uint32_t rtp_timestamp;
};
typedef std::list<RtcpMeasurement> RtcpList;
// Updates |rtcp_list| with timestamps from the latest RTCP SR.
// |new_rtcp_sr| will be set to true if these are the timestamps which have
// never be added to |rtcp_list|.
bool UpdateRtcpList(uint32_t ntp_secs,
uint32_t ntp_frac,
uint32_t rtp_timestamp,
RtcpList* rtcp_list,
bool* new_rtcp_sr);
// Converts an RTP timestamp to the NTP domain in milliseconds using two
// (RTP timestamp, NTP timestamp) pairs.
bool RtpToNtpMs(int64_t rtp_timestamp, const RtcpList& rtcp,
int64_t* timestamp_in_ms);
// Returns 1 there has been a forward wrap around, 0 if there has been no wrap
// around and -1 if there has been a backwards wrap around (i.e. reordering).
int CheckForWrapArounds(uint32_t rtp_timestamp, uint32_t rtcp_rtp_timestamp);
} // namespace webrtc
#endif // SYSTEM_WRAPPERS_INTERFACE_RTP_TO_NTP_H_

View File

@@ -0,0 +1,68 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_RW_LOCK_WRAPPER_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_RW_LOCK_WRAPPER_H_
#include "webrtc/system_wrappers/interface/thread_annotations.h"
// Note, Windows pre-Vista version of RW locks are not supported natively. For
// these OSs regular critical sections have been used to approximate RW lock
// functionality and will therefore have worse performance.
namespace webrtc {
class LOCKABLE RWLockWrapper {
public:
static RWLockWrapper* CreateRWLock();
virtual ~RWLockWrapper() {}
virtual void AcquireLockExclusive() EXCLUSIVE_LOCK_FUNCTION() = 0;
virtual void ReleaseLockExclusive() UNLOCK_FUNCTION() = 0;
virtual void AcquireLockShared() SHARED_LOCK_FUNCTION() = 0;
virtual void ReleaseLockShared() UNLOCK_FUNCTION() = 0;
};
// RAII extensions of the RW lock. Prevents Acquire/Release missmatches and
// provides more compact locking syntax.
class SCOPED_LOCKABLE ReadLockScoped {
public:
ReadLockScoped(RWLockWrapper& rw_lock) SHARED_LOCK_FUNCTION(rw_lock)
: rw_lock_(rw_lock) {
rw_lock_.AcquireLockShared();
}
~ReadLockScoped() UNLOCK_FUNCTION() {
rw_lock_.ReleaseLockShared();
}
private:
RWLockWrapper& rw_lock_;
};
class SCOPED_LOCKABLE WriteLockScoped {
public:
WriteLockScoped(RWLockWrapper& rw_lock) EXCLUSIVE_LOCK_FUNCTION(rw_lock)
: rw_lock_(rw_lock) {
rw_lock_.AcquireLockExclusive();
}
~WriteLockScoped() UNLOCK_FUNCTION() {
rw_lock_.ReleaseLockExclusive();
}
private:
RWLockWrapper& rw_lock_;
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_RW_LOCK_WRAPPER_H_

View File

@@ -0,0 +1,566 @@
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Borrowed from Chromium's src/base/memory/scoped_ptr.h.
// 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<T>):
// {
// 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_ptr<T[]>):
// {
// scoped_ptr<Foo[]> foo(new Foo[100]);
// foo.get()->Method(); // Foo::Method on the 0th element.
// foo[10].Method(); // Foo::Method on the 10th element.
// }
//
// These scopers also implement part of the functionality of C++11 unique_ptr
// in that they are "movable but not copyable." You can use the scopers in
// the parameter and return types of functions to signify ownership transfer
// in to and out of a function. When calling a function that has a scoper
// as the argument type, it must be called with the result of an analogous
// scoper's Pass() function or another function that generates a temporary;
// passing by copy will NOT work. Here is an example using scoped_ptr:
//
// void TakesOwnership(scoped_ptr<Foo> arg) {
// // Do something with arg
// }
// scoped_ptr<Foo> CreateFoo() {
// // No need for calling Pass() because we are constructing a temporary
// // for the return value.
// return scoped_ptr<Foo>(new Foo("new"));
// }
// scoped_ptr<Foo> PassThru(scoped_ptr<Foo> arg) {
// return arg.Pass();
// }
//
// {
// scoped_ptr<Foo> ptr(new Foo("yay")); // ptr manages Foo("yay").
// TakesOwnership(ptr.Pass()); // ptr no longer owns Foo("yay").
// scoped_ptr<Foo> ptr2 = CreateFoo(); // ptr2 owns the return Foo.
// scoped_ptr<Foo> ptr3 = // ptr3 now owns what was in ptr2.
// PassThru(ptr2.Pass()); // ptr2 is correspondingly NULL.
// }
//
// Notice that if you do not call Pass() when returning from PassThru(), or
// when invoking TakesOwnership(), the code will not compile because scopers
// are not copyable; they only implement move semantics which require calling
// the Pass() function to signify a destructive transfer of state. CreateFoo()
// is different though because we are constructing a temporary on the return
// line and thus can avoid needing to call Pass().
//
// Pass() properly handles upcast in initialization, i.e. you can use a
// scoped_ptr<Child> to initialize a scoped_ptr<Parent>:
//
// scoped_ptr<Foo> foo(new Foo());
// scoped_ptr<FooParent> parent(foo.Pass());
//
// PassAs<>() should be used to upcast return value in return statement:
//
// scoped_ptr<Foo> CreateFoo() {
// scoped_ptr<FooChild> result(new FooChild());
// return result.PassAs<Foo>();
// }
//
// Note that PassAs<>() is implemented only for scoped_ptr<T>, but not for
// scoped_ptr<T[]>. This is because casting array pointers may not be safe.
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_PTR_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_PTR_H_
// This is an implementation designed to match the anticipated future TR2
// implementation of the scoped_ptr class.
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <algorithm> // For std::swap().
#include "webrtc/base/constructormagic.h"
#include "webrtc/system_wrappers/interface/compile_assert.h"
#include "webrtc/system_wrappers/interface/template_util.h"
#include "webrtc/system_wrappers/source/move.h"
#include "webrtc/typedefs.h"
namespace webrtc {
// Function object which deletes its parameter, which must be a pointer.
// If C is an array type, invokes 'delete[]' on the parameter; otherwise,
// invokes 'delete'. The default deleter for scoped_ptr<T>.
template <class T>
struct DefaultDeleter {
DefaultDeleter() {}
template <typename U> DefaultDeleter(const DefaultDeleter<U>& other) {
// IMPLEMENTATION NOTE: C++11 20.7.1.1.2p2 only provides this constructor
// if U* is implicitly convertible to T* and U is not an array type.
//
// Correct implementation should use SFINAE to disable this
// constructor. However, since there are no other 1-argument constructors,
// using a COMPILE_ASSERT() based on is_convertible<> and requiring
// complete types is simpler and will cause compile failures for equivalent
// misuses.
//
// Note, the is_convertible<U*, T*> check also ensures that U is not an
// array. T is guaranteed to be a non-array, so any U* where U is an array
// cannot convert to T*.
enum { T_must_be_complete = sizeof(T) };
enum { U_must_be_complete = sizeof(U) };
COMPILE_ASSERT((webrtc::is_convertible<U*, T*>::value),
U_ptr_must_implicitly_convert_to_T_ptr);
}
inline void operator()(T* ptr) const {
enum { type_must_be_complete = sizeof(T) };
delete ptr;
}
};
// Specialization of DefaultDeleter for array types.
template <class T>
struct DefaultDeleter<T[]> {
inline void operator()(T* ptr) const {
enum { type_must_be_complete = sizeof(T) };
delete[] ptr;
}
private:
// Disable this operator for any U != T because it is undefined to execute
// an array delete when the static type of the array mismatches the dynamic
// type.
//
// References:
// C++98 [expr.delete]p3
// http://cplusplus.github.com/LWG/lwg-defects.html#938
template <typename U> void operator()(U* array) const;
};
template <class T, int n>
struct DefaultDeleter<T[n]> {
// Never allow someone to declare something like scoped_ptr<int[10]>.
COMPILE_ASSERT(sizeof(T) == -1, do_not_use_array_with_size_as_type);
};
// Function object which invokes 'free' on its parameter, which must be
// a pointer. Can be used to store malloc-allocated pointers in scoped_ptr:
//
// scoped_ptr<int, webrtc::FreeDeleter> foo_ptr(
// static_cast<int*>(malloc(sizeof(int))));
struct FreeDeleter {
inline void operator()(void* ptr) const {
free(ptr);
}
};
namespace internal {
// Minimal implementation of the core logic of scoped_ptr, suitable for
// reuse in both scoped_ptr and its specializations.
template <class T, class D>
class scoped_ptr_impl {
public:
explicit scoped_ptr_impl(T* p) : data_(p) { }
// Initializer for deleters that have data parameters.
scoped_ptr_impl(T* p, const D& d) : data_(p, d) {}
// Templated constructor that destructively takes the value from another
// scoped_ptr_impl.
template <typename U, typename V>
scoped_ptr_impl(scoped_ptr_impl<U, V>* other)
: data_(other->release(), other->get_deleter()) {
// We do not support move-only deleters. We could modify our move
// emulation to have webrtc::subtle::move() and webrtc::subtle::forward()
// functions that are imperfect emulations of their C++11 equivalents,
// but until there's a requirement, just assume deleters are copyable.
}
template <typename U, typename V>
void TakeState(scoped_ptr_impl<U, V>* other) {
// See comment in templated constructor above regarding lack of support
// for move-only deleters.
reset(other->release());
get_deleter() = other->get_deleter();
}
~scoped_ptr_impl() {
if (data_.ptr != NULL) {
// Not using get_deleter() saves one function call in non-optimized
// builds.
static_cast<D&>(data_)(data_.ptr);
}
}
void reset(T* p) {
// This is a self-reset, which is no longer allowed: http://crbug.com/162971
if (p != NULL && p == data_.ptr)
abort();
// Note that running data_.ptr = p can lead to undefined behavior if
// get_deleter()(get()) deletes this. In order to pevent this, reset()
// should update the stored pointer before deleting its old value.
//
// However, changing reset() to use that behavior may cause current code to
// break in unexpected ways. If the destruction of the owned object
// dereferences the scoped_ptr when it is destroyed by a call to reset(),
// then it will incorrectly dispatch calls to |p| rather than the original
// value of |data_.ptr|.
//
// During the transition period, set the stored pointer to NULL while
// deleting the object. Eventually, this safety check will be removed to
// prevent the scenario initially described from occuring and
// http://crbug.com/176091 can be closed.
T* old = data_.ptr;
data_.ptr = NULL;
if (old != NULL)
static_cast<D&>(data_)(old);
data_.ptr = p;
}
T* get() const { return data_.ptr; }
D& get_deleter() { return data_; }
const D& get_deleter() const { return data_; }
void swap(scoped_ptr_impl& p2) {
// Standard swap idiom: 'using std::swap' ensures that std::swap is
// present in the overload set, but we call swap unqualified so that
// any more-specific overloads can be used, if available.
using std::swap;
swap(static_cast<D&>(data_), static_cast<D&>(p2.data_));
swap(data_.ptr, p2.data_.ptr);
}
T* release() {
T* old_ptr = data_.ptr;
data_.ptr = NULL;
return old_ptr;
}
private:
// Needed to allow type-converting constructor.
template <typename U, typename V> friend class scoped_ptr_impl;
// Use the empty base class optimization to allow us to have a D
// member, while avoiding any space overhead for it when D is an
// empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good
// discussion of this technique.
struct Data : public D {
explicit Data(T* ptr_in) : ptr(ptr_in) {}
Data(T* ptr_in, const D& other) : D(other), ptr(ptr_in) {}
T* ptr;
};
Data data_;
DISALLOW_COPY_AND_ASSIGN(scoped_ptr_impl);
};
} // namespace internal
// 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 thread safety guarantees of T.
//
// The size of scoped_ptr is small. On most compilers, when using the
// DefaultDeleter, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters will
// increase the size proportional to whatever state they need to have. See
// comments inside scoped_ptr_impl<> for details.
//
// Current implementation targets having a strict subset of C++11's
// unique_ptr<> features. Known deficiencies include not supporting move-only
// deleteres, function pointers as deleters, and deleters with reference
// types.
template <class T, class D = webrtc::DefaultDeleter<T> >
class scoped_ptr {
WEBRTC_MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue)
public:
// The element and deleter types.
typedef T element_type;
typedef D deleter_type;
// Constructor. Defaults to initializing with NULL.
scoped_ptr() : impl_(NULL) { }
// Constructor. Takes ownership of p.
explicit scoped_ptr(element_type* p) : impl_(p) { }
// Constructor. Allows initialization of a stateful deleter.
scoped_ptr(element_type* p, const D& d) : impl_(p, d) { }
// Constructor. Allows construction from a scoped_ptr rvalue for a
// convertible type and deleter.
//
// IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct
// from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor
// has different post-conditions if D is a reference type. Since this
// implementation does not support deleters with reference type,
// we do not need a separate move constructor allowing us to avoid one
// use of SFINAE. You only need to care about this if you modify the
// implementation of scoped_ptr.
template <typename U, typename V>
scoped_ptr(scoped_ptr<U, V> other) : impl_(&other.impl_) {
COMPILE_ASSERT(!webrtc::is_array<U>::value, U_cannot_be_an_array);
}
// Constructor. Move constructor for C++03 move emulation of this type.
scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { }
// operator=. Allows assignment from a scoped_ptr rvalue for a convertible
// type and deleter.
//
// IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from
// the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated
// form has different requirements on for move-only Deleters. Since this
// implementation does not support move-only Deleters, we do not need a
// separate move assignment operator allowing us to avoid one use of SFINAE.
// You only need to care about this if you modify the implementation of
// scoped_ptr.
template <typename U, typename V>
scoped_ptr& operator=(scoped_ptr<U, V> rhs) {
COMPILE_ASSERT(!webrtc::is_array<U>::value, U_cannot_be_an_array);
impl_.TakeState(&rhs.impl_);
return *this;
}
// Reset. Deletes the currently owned object, if any.
// Then takes ownership of a new object, if given.
void reset(element_type* p = NULL) { impl_.reset(p); }
// Accessors to get the owned object.
// operator* and operator-> will assert() if there is no current object.
element_type& operator*() const {
assert(impl_.get() != NULL);
return *impl_.get();
}
element_type* operator->() const {
assert(impl_.get() != NULL);
return impl_.get();
}
element_type* get() const { return impl_.get(); }
// Access to the deleter.
deleter_type& get_deleter() { return impl_.get_deleter(); }
const deleter_type& get_deleter() const { return impl_.get_deleter(); }
// Allow scoped_ptr<element_type> to be used in boolean expressions, but not
// implicitly convertible to a real bool (which is dangerous).
//
// Note that this trick is only safe when the == and != operators
// are declared explicitly, as otherwise "scoped_ptr1 ==
// scoped_ptr2" will compile but do the wrong thing (i.e., convert
// to Testable and then do the comparison).
private:
typedef webrtc::internal::scoped_ptr_impl<element_type, deleter_type>
scoped_ptr::*Testable;
public:
operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; }
// Comparison operators.
// These return whether two scoped_ptr refer to the same object, not just to
// two different but equal objects.
bool operator==(const element_type* p) const { return impl_.get() == p; }
bool operator!=(const element_type* p) const { return impl_.get() != p; }
// Swap two scoped pointers.
void swap(scoped_ptr& p2) {
impl_.swap(p2.impl_);
}
// 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.
element_type* release() WARN_UNUSED_RESULT {
return impl_.release();
}
// C++98 doesn't support functions templates with default parameters which
// makes it hard to write a PassAs() that understands converting the deleter
// while preserving simple calling semantics.
//
// Until there is a use case for PassAs() with custom deleters, just ignore
// the custom deleter.
template <typename PassAsType>
scoped_ptr<PassAsType> PassAs() {
return scoped_ptr<PassAsType>(Pass());
}
private:
// Needed to reach into |impl_| in the constructor.
template <typename U, typename V> friend class scoped_ptr;
webrtc::internal::scoped_ptr_impl<element_type, deleter_type> impl_;
// Forbidden for API compatibility with std::unique_ptr.
explicit scoped_ptr(int disallow_construction_from_null);
// Forbid comparison of scoped_ptr types. If U != T, it totally
// doesn't make sense, and if U == T, it still doesn't make sense
// because you should never have the same object owned by two different
// scoped_ptrs.
template <class U> bool operator==(scoped_ptr<U> const& p2) const;
template <class U> bool operator!=(scoped_ptr<U> const& p2) const;
};
template <class T, class D>
class scoped_ptr<T[], D> {
WEBRTC_MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue)
public:
// The element and deleter types.
typedef T element_type;
typedef D deleter_type;
// Constructor. Defaults to initializing with NULL.
scoped_ptr() : impl_(NULL) { }
// Constructor. Stores the given array. Note that the argument's type
// must exactly match T*. In particular:
// - it cannot be a pointer to a type derived from T, because it is
// inherently unsafe in the general case to access an array through a
// pointer whose dynamic type does not match its static type (eg., if
// T and the derived types had different sizes access would be
// incorrectly calculated). Deletion is also always undefined
// (C++98 [expr.delete]p3). If you're doing this, fix your code.
// - it cannot be NULL, because NULL is an integral expression, not a
// pointer to T. Use the no-argument version instead of explicitly
// passing NULL.
// - it cannot be const-qualified differently from T per unique_ptr spec
// (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting
// to work around this may use implicit_cast<const T*>().
// However, because of the first bullet in this comment, users MUST
// NOT use implicit_cast<Base*>() to upcast the static type of the array.
explicit scoped_ptr(element_type* array) : impl_(array) { }
// Constructor. Move constructor for C++03 move emulation of this type.
scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { }
// operator=. Move operator= for C++03 move emulation of this type.
scoped_ptr& operator=(RValue rhs) {
impl_.TakeState(&rhs.object->impl_);
return *this;
}
// Reset. Deletes the currently owned array, if any.
// Then takes ownership of a new object, if given.
void reset(element_type* array = NULL) { impl_.reset(array); }
// Accessors to get the owned array.
element_type& operator[](size_t i) const {
assert(impl_.get() != NULL);
return impl_.get()[i];
}
element_type* get() const { return impl_.get(); }
// Access to the deleter.
deleter_type& get_deleter() { return impl_.get_deleter(); }
const deleter_type& get_deleter() const { return impl_.get_deleter(); }
// Allow scoped_ptr<element_type> to be used in boolean expressions, but not
// implicitly convertible to a real bool (which is dangerous).
private:
typedef webrtc::internal::scoped_ptr_impl<element_type, deleter_type>
scoped_ptr::*Testable;
public:
operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; }
// Comparison operators.
// These return whether two scoped_ptr refer to the same object, not just to
// two different but equal objects.
bool operator==(element_type* array) const { return impl_.get() == array; }
bool operator!=(element_type* array) const { return impl_.get() != array; }
// Swap two scoped pointers.
void swap(scoped_ptr& p2) {
impl_.swap(p2.impl_);
}
// 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.
element_type* release() WARN_UNUSED_RESULT {
return impl_.release();
}
private:
// Force element_type to be a complete type.
enum { type_must_be_complete = sizeof(element_type) };
// Actually hold the data.
webrtc::internal::scoped_ptr_impl<element_type, deleter_type> impl_;
// Disable initialization from any type other than element_type*, by
// providing a constructor that matches such an initialization, but is
// private and has no definition. This is disabled because it is not safe to
// call delete[] on an array whose static type does not match its dynamic
// type.
template <typename U> explicit scoped_ptr(U* array);
explicit scoped_ptr(int disallow_construction_from_null);
// Disable reset() from any type other than element_type*, for the same
// reasons as the constructor above.
template <typename U> void reset(U* array);
void reset(int disallow_reset_from_null);
// Forbid comparison of scoped_ptr types. If U != T, it totally
// doesn't make sense, and if U == T, it still doesn't make sense
// because you should never have the same object owned by two different
// scoped_ptrs.
template <class U> bool operator==(scoped_ptr<U> const& p2) const;
template <class U> bool operator!=(scoped_ptr<U> const& p2) const;
};
} // namespace webrtc
// Free functions
template <class T, class D>
void swap(webrtc::scoped_ptr<T, D>& p1, webrtc::scoped_ptr<T, D>& p2) {
p1.swap(p2);
}
template <class T, class D>
bool operator==(T* p1, const webrtc::scoped_ptr<T, D>& p2) {
return p1 == p2.get();
}
template <class T, class D>
bool operator!=(T* p1, const webrtc::scoped_ptr<T, D>& p2) {
return p1 != p2.get();
}
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_PTR_H_

View File

@@ -0,0 +1,144 @@
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef SYSTEM_WRAPPERS_INTERFACE_SCOPED_REFPTR_H_
#define SYSTEM_WRAPPERS_INTERFACE_SCOPED_REFPTR_H_
#include <stddef.h>
namespace webrtc {
// Extracted from Chromium's src/base/memory/ref_counted.h.
//
// A smart pointer class for reference counted objects. Use this class instead
// of calling AddRef and Release manually on a reference counted object to
// avoid common memory leaks caused by forgetting to Release an object
// reference. Sample usage:
//
// class MyFoo : public RefCounted<MyFoo> {
// ...
// };
//
// void some_function() {
// scoped_refptr<MyFoo> foo = new MyFoo();
// foo->Method(param);
// // |foo| is released when this function returns
// }
//
// void some_other_function() {
// scoped_refptr<MyFoo> foo = new MyFoo();
// ...
// foo = NULL; // explicitly releases |foo|
// ...
// if (foo)
// foo->Method(param);
// }
//
// The above examples show how scoped_refptr<T> acts like a pointer to T.
// Given two scoped_refptr<T> classes, it is also possible to exchange
// references between the two objects, like so:
//
// {
// scoped_refptr<MyFoo> a = new MyFoo();
// scoped_refptr<MyFoo> b;
//
// b.swap(a);
// // now, |b| references the MyFoo object, and |a| references NULL.
// }
//
// To make both |a| and |b| in the above example reference the same MyFoo
// object, simply use the assignment operator:
//
// {
// scoped_refptr<MyFoo> a = new MyFoo();
// scoped_refptr<MyFoo> b;
//
// b = a;
// // now, |a| and |b| each own a reference to the same MyFoo object.
// }
//
template <class T>
class scoped_refptr {
public:
scoped_refptr() : ptr_(NULL) {
}
scoped_refptr(T* p) : ptr_(p) {
if (ptr_)
ptr_->AddRef();
}
scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
if (ptr_)
ptr_->AddRef();
}
template <typename U>
scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
if (ptr_)
ptr_->AddRef();
}
~scoped_refptr() {
if (ptr_)
ptr_->Release();
}
T* get() const { return ptr_; }
operator T*() const { return ptr_; }
T* operator->() const { return ptr_; }
// 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.
T* release() {
T* retVal = ptr_;
ptr_ = NULL;
return retVal;
}
scoped_refptr<T>& operator=(T* p) {
// AddRef first so that self assignment should work
if (p)
p->AddRef();
if (ptr_ )
ptr_->Release();
ptr_ = p;
return *this;
}
scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
return *this = r.ptr_;
}
template <typename U>
scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
return *this = r.get();
}
void swap(T** pp) {
T* p = ptr_;
ptr_ = *pp;
*pp = p;
}
void swap(scoped_refptr<T>& r) {
swap(&r.ptr_);
}
protected:
T* ptr_;
};
} // namespace webrtc
#endif // SYSTEM_WRAPPERS_INTERFACE_SCOPED_REFPTR_H_

View File

@@ -0,0 +1,149 @@
/*
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Borrowed from Chromium's src/base/memory/scoped_vector.h.
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_VECTOR_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_VECTOR_H_
#include <assert.h>
#include <algorithm>
#include <vector>
#include "webrtc/system_wrappers/interface/stl_util.h"
#include "webrtc/system_wrappers/source/move.h"
namespace webrtc {
// ScopedVector wraps a vector deleting the elements from its
// destructor.
template <class T>
class ScopedVector {
WEBRTC_MOVE_ONLY_TYPE_FOR_CPP_03(ScopedVector, RValue)
public:
typedef typename std::vector<T*>::allocator_type allocator_type;
typedef typename std::vector<T*>::size_type size_type;
typedef typename std::vector<T*>::difference_type difference_type;
typedef typename std::vector<T*>::pointer pointer;
typedef typename std::vector<T*>::const_pointer const_pointer;
typedef typename std::vector<T*>::reference reference;
typedef typename std::vector<T*>::const_reference const_reference;
typedef typename std::vector<T*>::value_type value_type;
typedef typename std::vector<T*>::iterator iterator;
typedef typename std::vector<T*>::const_iterator const_iterator;
typedef typename std::vector<T*>::reverse_iterator reverse_iterator;
typedef typename std::vector<T*>::const_reverse_iterator
const_reverse_iterator;
ScopedVector() {}
~ScopedVector() { clear(); }
ScopedVector(RValue other) { swap(*other.object); }
ScopedVector& operator=(RValue rhs) {
swap(*rhs.object);
return *this;
}
reference operator[](size_t index) { return v_[index]; }
const_reference operator[](size_t index) const { return v_[index]; }
bool empty() const { return v_.empty(); }
size_t size() const { return v_.size(); }
reverse_iterator rbegin() { return v_.rbegin(); }
const_reverse_iterator rbegin() const { return v_.rbegin(); }
reverse_iterator rend() { return v_.rend(); }
const_reverse_iterator rend() const { return v_.rend(); }
iterator begin() { return v_.begin(); }
const_iterator begin() const { return v_.begin(); }
iterator end() { return v_.end(); }
const_iterator end() const { return v_.end(); }
const_reference front() const { return v_.front(); }
reference front() { return v_.front(); }
const_reference back() const { return v_.back(); }
reference back() { return v_.back(); }
void push_back(T* elem) { v_.push_back(elem); }
void pop_back() {
assert(!empty());
delete v_.back();
v_.pop_back();
}
std::vector<T*>& get() { return v_; }
const std::vector<T*>& get() const { return v_; }
void swap(std::vector<T*>& other) { v_.swap(other); }
void swap(ScopedVector<T>& other) { v_.swap(other.v_); }
void release(std::vector<T*>* out) {
out->swap(v_);
v_.clear();
}
void reserve(size_t capacity) { v_.reserve(capacity); }
// Resize, deleting elements in the disappearing range if we are shrinking.
void resize(size_t new_size) {
if (v_.size() > new_size)
STLDeleteContainerPointers(v_.begin() + new_size, v_.end());
v_.resize(new_size);
}
template<typename InputIterator>
void assign(InputIterator begin, InputIterator end) {
v_.assign(begin, end);
}
void clear() { STLDeleteElements(&v_); }
// Like |clear()|, but doesn't delete any elements.
void weak_clear() { v_.clear(); }
// Lets the ScopedVector take ownership of |x|.
iterator insert(iterator position, T* x) {
return v_.insert(position, x);
}
// Lets the ScopedVector take ownership of elements in [first,last).
template<typename InputIterator>
void insert(iterator position, InputIterator first, InputIterator last) {
v_.insert(position, first, last);
}
iterator erase(iterator position) {
delete *position;
return v_.erase(position);
}
iterator erase(iterator first, iterator last) {
STLDeleteContainerPointers(first, last);
return v_.erase(first, last);
}
// Like |erase()|, but doesn't delete the element at |position|.
iterator weak_erase(iterator position) {
return v_.erase(position);
}
// Like |erase()|, but doesn't delete the elements in [first, last).
iterator weak_erase(iterator first, iterator last) {
return v_.erase(first, last);
}
private:
std::vector<T*> v_;
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_VECTOR_H_

View File

@@ -0,0 +1,24 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// An OS-independent sleep function.
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SLEEP_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SLEEP_H_
namespace webrtc {
// This function sleeps for the specified number of milliseconds.
// It may return early if the thread is woken by some other event,
// such as the delivery of a signal on Unix.
void SleepMs(int msecs);
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SLEEP_H_

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Generic unstable sorting routines.
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SORT_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SORT_H_
#include "webrtc/common_types.h"
#include "webrtc/typedefs.h"
namespace webrtc {
enum Type {
TYPE_Word8,
TYPE_UWord8,
TYPE_Word16,
TYPE_UWord16,
TYPE_Word32,
TYPE_UWord32,
TYPE_Word64,
TYPE_UWord64,
TYPE_Float32,
TYPE_Float64
};
// Sorts intrinsic data types.
//
// data [in/out] A pointer to an array of intrinsic type.
// Upon return it will be sorted in ascending order.
// num_of_elements The number of elements in the array.
// data_type Enum corresponding to the type of the array.
//
// returns 0 on success, -1 on failure.
int32_t Sort(void* data, uint32_t num_of_elements, Type data_type);
// Sorts arbitrary data types. This requires an array of intrinsically typed
// key values which will be used to sort the data array. There must be a
// one-to-one correspondence between data elements and key elements, with
// corresponding elements sharing the same position in their respective
// arrays.
//
// data [in/out] A pointer to an array of arbitrary type.
// Upon return it will be sorted in ascending order.
// key [in] A pointer to an array of keys used to sort the
// data array.
// num_of_elements The number of elements in the arrays.
// size_of_element The size, in bytes, of the data array.
// key_type Enum corresponding to the type of the key array.
//
// returns 0 on success, -1 on failure.
//
int32_t KeySort(void* data, void* key, uint32_t num_of_elements,
uint32_t size_of_element, Type key_type);
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SORT_H_

View File

@@ -0,0 +1,153 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STATIC_INSTANCE_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STATIC_INSTANCE_H_
#include <assert.h>
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#ifdef _WIN32
#include "webrtc/system_wrappers/interface/fix_interlocked_exchange_pointer_win.h"
#endif
namespace webrtc {
enum CountOperation {
kRelease,
kAddRef,
kAddRefNoCreate
};
enum CreateOperation {
kInstanceExists,
kCreate,
kDestroy
};
template <class T>
// Construct On First Use idiom. Avoids
// "static initialization order fiasco".
static T* GetStaticInstance(CountOperation count_operation) {
// TODO (hellner): use atomic wrapper instead.
static volatile long instance_count = 0;
static T* volatile instance = NULL;
CreateOperation state = kInstanceExists;
#ifndef _WIN32
// This memory is staticly allocated once. The application does not try to
// free this memory. This approach is taken to avoid issues with
// destruction order for statically allocated memory. The memory will be
// reclaimed by the OS and memory leak tools will not recognize memory
// reachable from statics leaked so no noise is added by doing this.
static CriticalSectionWrapper* crit_sect(
CriticalSectionWrapper::CreateCriticalSection());
CriticalSectionScoped lock(crit_sect);
if (count_operation ==
kAddRefNoCreate && instance_count == 0) {
return NULL;
}
if (count_operation ==
kAddRef ||
count_operation == kAddRefNoCreate) {
instance_count++;
if (instance_count == 1) {
state = kCreate;
}
} else {
instance_count--;
if (instance_count == 0) {
state = kDestroy;
}
}
if (state == kCreate) {
instance = T::CreateInstance();
} else if (state == kDestroy) {
T* old_instance = instance;
instance = NULL;
// The state will not change past this point. Release the critical
// section while deleting the object in case it would be blocking on
// access back to this object. (This is the case for the tracing class
// since the thread owned by the tracing class also traces).
// TODO(hellner): this is a bit out of place but here goes, de-couple
// thread implementation with trace implementation.
crit_sect->Leave();
if (old_instance) {
delete old_instance;
}
// Re-acquire the lock since the scoped critical section will release
// it.
crit_sect->Enter();
return NULL;
}
#else // _WIN32
if (count_operation ==
kAddRefNoCreate && instance_count == 0) {
return NULL;
}
if (count_operation == kAddRefNoCreate) {
if (1 == InterlockedIncrement(&instance_count)) {
// The instance has been destroyed by some other thread. Rollback.
InterlockedDecrement(&instance_count);
assert(false);
return NULL;
}
// Sanity to catch corrupt state.
if (instance == NULL) {
assert(false);
InterlockedDecrement(&instance_count);
return NULL;
}
} else if (count_operation == kAddRef) {
if (instance_count == 0) {
state = kCreate;
} else {
if (1 == InterlockedIncrement(&instance_count)) {
// InterlockedDecrement because reference count should not be
// updated just yet (that's done when the instance is created).
InterlockedDecrement(&instance_count);
state = kCreate;
}
}
} else {
int new_value = InterlockedDecrement(&instance_count);
if (new_value == 0) {
state = kDestroy;
}
}
if (state == kCreate) {
// Create instance and let whichever thread finishes first assign its
// local copy to the global instance. All other threads reclaim their
// local copy.
T* new_instance = T::CreateInstance();
if (1 == InterlockedIncrement(&instance_count)) {
InterlockedExchangePointer(reinterpret_cast<void * volatile*>(&instance),
new_instance);
} else {
InterlockedDecrement(&instance_count);
if (new_instance) {
delete static_cast<T*>(new_instance);
}
}
} else if (state == kDestroy) {
T* old_value = static_cast<T*>(InterlockedExchangePointer(
reinterpret_cast<void * volatile*>(&instance), NULL));
if (old_value) {
delete static_cast<T*>(old_value);
}
return NULL;
}
#endif // #ifndef _WIN32
return instance;
}
} // namspace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STATIC_INSTANCE_H_

View File

@@ -0,0 +1,265 @@
/*
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Borrowed from Chromium's src/base/stl_util.h.
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STL_UTIL_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STL_UTIL_H_
#include <assert.h>
#include <algorithm>
#include <functional>
#include <iterator>
#include <string>
#include <vector>
namespace webrtc {
// Clears internal memory of an STL object.
// STL clear()/reserve(0) does not always free internal memory allocated
// This function uses swap/destructor to ensure the internal memory is freed.
template<class T>
void STLClearObject(T* obj) {
T tmp;
tmp.swap(*obj);
// Sometimes "T tmp" allocates objects with memory (arena implementation?).
// Hence using additional reserve(0) even if it doesn't always work.
obj->reserve(0);
}
// For a range within a container of pointers, calls delete (non-array version)
// on these pointers.
// NOTE: for these three functions, we could just implement a DeleteObject
// functor and then call for_each() on the range and functor, but this
// requires us to pull in all of algorithm.h, which seems expensive.
// For hash_[multi]set, it is important that this deletes behind the iterator
// because the hash_set may call the hash function on the iterator when it is
// advanced, which could result in the hash function trying to deference a
// stale pointer.
template <class ForwardIterator>
void STLDeleteContainerPointers(ForwardIterator begin, ForwardIterator end) {
while (begin != end) {
ForwardIterator temp = begin;
++begin;
delete *temp;
}
}
// For a range within a container of pairs, calls delete (non-array version) on
// BOTH items in the pairs.
// NOTE: Like STLDeleteContainerPointers, it is important that this deletes
// behind the iterator because if both the key and value are deleted, the
// container may call the hash function on the iterator when it is advanced,
// which could result in the hash function trying to dereference a stale
// pointer.
template <class ForwardIterator>
void STLDeleteContainerPairPointers(ForwardIterator begin,
ForwardIterator end) {
while (begin != end) {
ForwardIterator temp = begin;
++begin;
delete temp->first;
delete temp->second;
}
}
// For a range within a container of pairs, calls delete (non-array version) on
// the FIRST item in the pairs.
// NOTE: Like STLDeleteContainerPointers, deleting behind the iterator.
template <class ForwardIterator>
void STLDeleteContainerPairFirstPointers(ForwardIterator begin,
ForwardIterator end) {
while (begin != end) {
ForwardIterator temp = begin;
++begin;
delete temp->first;
}
}
// For a range within a container of pairs, calls delete.
// NOTE: Like STLDeleteContainerPointers, deleting behind the iterator.
// Deleting the value does not always invalidate the iterator, but it may
// do so if the key is a pointer into the value object.
template <class ForwardIterator>
void STLDeleteContainerPairSecondPointers(ForwardIterator begin,
ForwardIterator end) {
while (begin != end) {
ForwardIterator temp = begin;
++begin;
delete temp->second;
}
}
// To treat a possibly-empty vector as an array, use these functions.
// If you know the array will never be empty, you can use &*v.begin()
// directly, but that is undefined behaviour if |v| is empty.
template<typename T>
inline T* vector_as_array(std::vector<T>* v) {
return v->empty() ? NULL : &*v->begin();
}
template<typename T>
inline const T* vector_as_array(const std::vector<T>* v) {
return v->empty() ? NULL : &*v->begin();
}
// Return a mutable char* pointing to a string's internal buffer,
// which may not be null-terminated. Writing through this pointer will
// modify the string.
//
// string_as_array(&str)[i] is valid for 0 <= i < str.size() until the
// next call to a string method that invalidates iterators.
//
// As of 2006-04, there is no standard-blessed way of getting a
// mutable reference to a string's internal buffer. However, issue 530
// (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#530)
// proposes this as the method. According to Matt Austern, this should
// already work on all current implementations.
inline char* string_as_array(std::string* str) {
// DO NOT USE const_cast<char*>(str->data())
return str->empty() ? NULL : &*str->begin();
}
// The following functions are useful for cleaning up STL containers whose
// elements point to allocated memory.
// STLDeleteElements() deletes all the elements in an STL container and clears
// the container. This function is suitable for use with a vector, set,
// hash_set, or any other STL container which defines sensible begin(), end(),
// and clear() methods.
//
// If container is NULL, this function is a no-op.
//
// As an alternative to calling STLDeleteElements() directly, consider
// STLElementDeleter (defined below), which ensures that your container's
// elements are deleted when the STLElementDeleter goes out of scope.
template <class T>
void STLDeleteElements(T* container) {
if (!container)
return;
STLDeleteContainerPointers(container->begin(), container->end());
container->clear();
}
// Given an STL container consisting of (key, value) pairs, STLDeleteValues
// deletes all the "value" components and clears the container. Does nothing
// in the case it's given a NULL pointer.
template <class T>
void STLDeleteValues(T* container) {
if (!container)
return;
for (typename T::iterator i(container->begin()); i != container->end(); ++i)
delete i->second;
container->clear();
}
// The following classes provide a convenient way to delete all elements or
// values from STL containers when they goes out of scope. This greatly
// simplifies code that creates temporary objects and has multiple return
// statements. Example:
//
// vector<MyProto *> tmp_proto;
// STLElementDeleter<vector<MyProto *> > d(&tmp_proto);
// if (...) return false;
// ...
// return success;
// Given a pointer to an STL container this class will delete all the element
// pointers when it goes out of scope.
template<class T>
class STLElementDeleter {
public:
STLElementDeleter<T>(T* container) : container_(container) {}
~STLElementDeleter<T>() { STLDeleteElements(container_); }
private:
T* container_;
};
// Given a pointer to an STL container this class will delete all the value
// pointers when it goes out of scope.
template<class T>
class STLValueDeleter {
public:
STLValueDeleter<T>(T* container) : container_(container) {}
~STLValueDeleter<T>() { STLDeleteValues(container_); }
private:
T* container_;
};
// Test to see if a set, map, hash_set or hash_map contains a particular key.
// Returns true if the key is in the collection.
template <typename Collection, typename Key>
bool ContainsKey(const Collection& collection, const Key& key) {
return collection.find(key) != collection.end();
}
// Returns true if the container is sorted.
template <typename Container>
bool STLIsSorted(const Container& cont) {
// Note: Use reverse iterator on container to ensure we only require
// value_type to implement operator<.
return std::adjacent_find(cont.rbegin(), cont.rend(),
std::less<typename Container::value_type>())
== cont.rend();
}
// Returns a new ResultType containing the difference of two sorted containers.
template <typename ResultType, typename Arg1, typename Arg2>
ResultType STLSetDifference(const Arg1& a1, const Arg2& a2) {
assert(STLIsSorted(a1));
assert(STLIsSorted(a2));
ResultType difference;
std::set_difference(a1.begin(), a1.end(),
a2.begin(), a2.end(),
std::inserter(difference, difference.end()));
return difference;
}
// Returns a new ResultType containing the union of two sorted containers.
template <typename ResultType, typename Arg1, typename Arg2>
ResultType STLSetUnion(const Arg1& a1, const Arg2& a2) {
assert(STLIsSorted(a1));
assert(STLIsSorted(a2));
ResultType result;
std::set_union(a1.begin(), a1.end(),
a2.begin(), a2.end(),
std::inserter(result, result.end()));
return result;
}
// Returns a new ResultType containing the intersection of two sorted
// containers.
template <typename ResultType, typename Arg1, typename Arg2>
ResultType STLSetIntersection(const Arg1& a1, const Arg2& a2) {
assert(STLIsSorted(a1));
assert(STLIsSorted(a2));
ResultType result;
std::set_intersection(a1.begin(), a1.end(),
a2.begin(), a2.end(),
std::inserter(result, result.end()));
return result;
}
// Returns true if the sorted container |a1| contains all elements of the sorted
// container |a2|.
template <typename Arg1, typename Arg2>
bool STLIncludes(const Arg1& a1, const Arg2& a2) {
assert(STLIsSorted(a1));
assert(STLIsSorted(a2));
return std::includes(a1.begin(), a1.end(),
a2.begin(), a2.end());
}
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STL_UTIL_H_

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Modified from the Chromium original:
// src/base/strings/stringize_macros.h
// This file defines preprocessor macros for stringizing preprocessor
// symbols (or their output) and manipulating preprocessor symbols
// that define strings.
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STRINGIZE_MACROS_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STRINGIZE_MACROS_H_
// This is not very useful as it does not expand defined symbols if
// called directly. Use its counterpart without the _NO_EXPANSION
// suffix, below.
#define STRINGIZE_NO_EXPANSION(x) #x
// Use this to quote the provided parameter, first expanding it if it
// is a preprocessor symbol.
//
// For example, if:
// #define A FOO
// #define B(x) myobj->FunctionCall(x)
//
// Then:
// STRINGIZE(A) produces "FOO"
// STRINGIZE(B(y)) produces "myobj->FunctionCall(y)"
#define STRINGIZE(x) STRINGIZE_NO_EXPANSION(x)
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STRINGIZE_MACROS_H_

View File

@@ -0,0 +1,114 @@
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Borrowed from Chromium's src/base/template_util.h.
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TEMPLATE_UTIL_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TEMPLATE_UTIL_H_
#include <stddef.h> // For size_t.
namespace webrtc {
// Template definitions from tr1.
template<class T, T v>
struct integral_constant {
static const T value = v;
typedef T value_type;
typedef integral_constant<T, v> type;
};
template <class T, T v> const T integral_constant<T, v>::value;
typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;
template <class T> struct is_pointer : false_type {};
template <class T> struct is_pointer<T*> : true_type {};
template <class T, class U> struct is_same : public false_type {};
template <class T> struct is_same<T, T> : true_type {};
template<class> struct is_array : public false_type {};
template<class T, size_t n> struct is_array<T[n]> : public true_type {};
template<class T> struct is_array<T[]> : public true_type {};
template <class T> struct is_non_const_reference : false_type {};
template <class T> struct is_non_const_reference<T&> : true_type {};
template <class T> struct is_non_const_reference<const T&> : false_type {};
template <class T> struct is_void : false_type {};
template <> struct is_void<void> : true_type {};
namespace internal {
// Types YesType and NoType are guaranteed such that sizeof(YesType) <
// sizeof(NoType).
typedef char YesType;
struct NoType {
YesType dummy[2];
};
// This class is an implementation detail for is_convertible, and you
// don't need to know how it works to use is_convertible. For those
// who care: we declare two different functions, one whose argument is
// of type To and one with a variadic argument list. We give them
// return types of different size, so we can use sizeof to trick the
// compiler into telling us which function it would have chosen if we
// had called it with an argument of type From. See Alexandrescu's
// _Modern C++ Design_ for more details on this sort of trick.
struct ConvertHelper {
template <typename To>
static YesType Test(To);
template <typename To>
static NoType Test(...);
template <typename From>
static From& Create();
};
// Used to determine if a type is a struct/union/class. Inspired by Boost's
// is_class type_trait implementation.
struct IsClassHelper {
template <typename C>
static YesType Test(void(C::*)(void));
template <typename C>
static NoType Test(...);
};
} // namespace internal
// Inherits from true_type if From is convertible to To, false_type otherwise.
//
// Note that if the type is convertible, this will be a true_type REGARDLESS
// of whether or not the conversion would emit a warning.
template <typename From, typename To>
struct is_convertible
: integral_constant<bool,
sizeof(internal::ConvertHelper::Test<To>(
internal::ConvertHelper::Create<From>())) ==
sizeof(internal::YesType)> {
};
template <typename T>
struct is_class
: integral_constant<bool,
sizeof(internal::IsClassHelper::Test<T>(0)) ==
sizeof(internal::YesType)> {
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TEMPLATE_UTIL_H_

View File

@@ -0,0 +1,99 @@
//
// Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
//
// Borrowed from
// https://code.google.com/p/gperftools/source/browse/src/base/thread_annotations.h
// but adapted for clang attributes instead of the gcc.
//
// This header file contains the macro definitions for thread safety
// annotations that allow the developers to document the locking policies
// of their multi-threaded code. The annotations can also help program
// analysis tools to identify potential thread safety issues.
#ifndef BASE_THREAD_ANNOTATIONS_H_
#define BASE_THREAD_ANNOTATIONS_H_
#if defined(__clang__) && (!defined(SWIG))
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
#else
#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
#endif
// Document if a shared variable/field needs to be protected by a lock.
// GUARDED_BY allows the user to specify a particular lock that should be
// held when accessing the annotated variable, while GUARDED_VAR only
// indicates a shared variable should be guarded (by any lock). GUARDED_VAR
// is primarily used when the client cannot express the name of the lock.
#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
#define GUARDED_VAR THREAD_ANNOTATION_ATTRIBUTE__(guarded)
// Document if the memory location pointed to by a pointer should be guarded
// by a lock when dereferencing the pointer. Similar to GUARDED_VAR,
// PT_GUARDED_VAR is primarily used when the client cannot express the name
// of the lock. Note that a pointer variable to a shared memory location
// could itself be a shared variable. For example, if a shared global pointer
// q, which is guarded by mu1, points to a shared memory location that is
// guarded by mu2, q should be annotated as follows:
// int *q GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(point_to_guarded_by(x))
#define PT_GUARDED_VAR THREAD_ANNOTATION_ATTRIBUTE__(point_to_guarded)
// Document the acquisition order between locks that can be held
// simultaneously by a thread. For any two locks that need to be annotated
// to establish an acquisition order, only one of them needs the annotation.
// (i.e. You don't have to annotate both locks with both ACQUIRED_AFTER
// and ACQUIRED_BEFORE.)
#define ACQUIRED_AFTER(x) THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(x))
#define ACQUIRED_BEFORE(x) THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(x))
// The following three annotations document the lock requirements for
// functions/methods.
// Document if a function expects certain locks to be held before it is called
#define EXCLUSIVE_LOCKS_REQUIRED(...) \
THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__))
#define SHARED_LOCKS_REQUIRED(...) \
THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__))
// Document the locks acquired in the body of the function. These locks
// cannot be held when calling this function (as google3's Mutex locks are
// non-reentrant).
#define LOCKS_EXCLUDED(x) THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(x))
// Document the lock the annotated function returns without acquiring it.
#define LOCK_RETURNED(x) THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
// Document if a class/type is a lockable type (such as the Mutex class).
#define LOCKABLE THREAD_ANNOTATION_ATTRIBUTE__(lockable)
// Document if a class is a scoped lockable type (such as the MutexLock class).
#define SCOPED_LOCKABLE THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
// The following annotations specify lock and unlock primitives.
#define EXCLUSIVE_LOCK_FUNCTION(...) \
THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
#define SHARED_LOCK_FUNCTION(...) \
THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__))
#define EXCLUSIVE_TRYLOCK_FUNCTION(...) \
THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
#define SHARED_TRYLOCK_FUNCTION(...) \
THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__))
#define UNLOCK_FUNCTION(...) \
THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
// An escape hatch for thread safety analysis to ignore the annotated function.
#define NO_THREAD_SAFETY_ANALYSIS \
THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
#endif // BASE_THREAD_ANNOTATIONS_H_

View File

@@ -0,0 +1,92 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// System independant wrapper for spawning threads
// Note: the spawned thread will loop over the callback function until stopped.
// Note: The callback function is expected to return every 2 seconds or more
// often.
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_THREAD_WRAPPER_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_THREAD_WRAPPER_H_
#include "webrtc/common_types.h"
#include "webrtc/typedefs.h"
namespace webrtc {
// Object that will be passed by the spawned thread when it enters the callback
// function.
#define ThreadObj void*
// Callback function that the spawned thread will enter once spawned.
// A return value of false is interpreted as that the function has no
// more work to do and that the thread can be released.
typedef bool(*ThreadRunFunction)(ThreadObj);
enum ThreadPriority {
kLowPriority = 1,
kNormalPriority = 2,
kHighPriority = 3,
kHighestPriority = 4,
kRealtimePriority = 5
};
class ThreadWrapper {
public:
enum {kThreadMaxNameLength = 64};
virtual ~ThreadWrapper() {};
// Factory method. Constructor disabled.
//
// func Pointer to a, by user, specified callback function.
// obj Object associated with the thread. Passed in the callback
// function.
// prio Thread priority. May require root/admin rights.
// thread_name NULL terminated thread name, will be visable in the Windows
// debugger.
static ThreadWrapper* CreateThread(ThreadRunFunction func,
ThreadObj obj,
ThreadPriority prio = kNormalPriority,
const char* thread_name = 0);
// Get the current thread's kernel thread ID.
static uint32_t GetThreadId();
// Non blocking termination of the spawned thread. Note that it is not safe
// to delete this class until the spawned thread has been reclaimed.
virtual void SetNotAlive() = 0;
// Tries to spawns a thread and returns true if that was successful.
// Additionally, it tries to set thread priority according to the priority
// from when CreateThread was called. However, failure to set priority will
// not result in a false return value.
// TODO(henrike): add a function for polling whether priority was set or
// not.
virtual bool Start(unsigned int& id) = 0;
// Sets the threads CPU affinity. CPUs are listed 0 - (number of CPUs - 1).
// The numbers in processor_numbers specify which CPUs are allowed to run the
// thread. processor_numbers should not contain any duplicates and elements
// should be lower than (number of CPUs - 1). amount_of_processors should be
// equal to the number of processors listed in processor_numbers.
virtual bool SetAffinity(const int* processor_numbers,
const unsigned int amount_of_processors);
// Stops the spawned thread and waits for it to be reclaimed with a timeout
// of two seconds. Will return false if the thread was not reclaimed.
// Multiple tries to Stop are allowed (e.g. to wait longer than 2 seconds).
// It's ok to call Stop() even if the spawned thread has been reclaimed.
virtual bool Stop() = 0;
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_THREAD_WRAPPER_H_

View File

@@ -0,0 +1,298 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// System independant wrapper for polling elapsed time in ms and us.
// The implementation works in the tick domain which can be mapped over to the
// time domain.
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_
#if _WIN32
// Note: The Windows header must always be included before mmsystem.h
#include <windows.h>
#include <mmsystem.h>
#elif WEBRTC_LINUX
#include <time.h>
#elif WEBRTC_MAC
#include <mach/mach_time.h>
#include <string.h>
#else
#include <sys/time.h>
#include <time.h>
#endif
#include "webrtc/typedefs.h"
namespace webrtc {
class TickInterval;
// Class representing the current time.
class TickTime {
public:
TickTime();
explicit TickTime(int64_t ticks);
// Current time in the tick domain.
static TickTime Now();
// Now in the time domain in ms.
static int64_t MillisecondTimestamp();
// Now in the time domain in us.
static int64_t MicrosecondTimestamp();
// Returns the number of ticks in the tick domain.
int64_t Ticks() const;
static int64_t MillisecondsToTicks(const int64_t ms);
static int64_t TicksToMilliseconds(const int64_t ticks);
// Returns a TickTime that is ticks later than the passed TickTime.
friend TickTime operator+(const TickTime lhs, const int64_t ticks);
TickTime& operator+=(const int64_t& ticks);
// Returns a TickInterval that is the difference in ticks beween rhs and lhs.
friend TickInterval operator-(const TickTime& lhs, const TickTime& rhs);
// Call to engage the fake clock. This is useful for tests since relying on
// a real clock often makes the test flaky.
static void UseFakeClock(int64_t start_millisecond);
// Advance the fake clock. Must be called after UseFakeClock.
static void AdvanceFakeClock(int64_t milliseconds);
private:
static int64_t QueryOsForTicks();
static bool use_fake_clock_;
static int64_t fake_ticks_;
int64_t ticks_;
};
// Represents a time delta in ticks.
class TickInterval {
public:
TickInterval();
int64_t Milliseconds() const;
int64_t Microseconds() const;
// Returns the sum of two TickIntervals as a TickInterval.
friend TickInterval operator+(const TickInterval& lhs,
const TickInterval& rhs);
TickInterval& operator+=(const TickInterval& rhs);
// Returns a TickInterval corresponding to rhs - lhs.
friend TickInterval operator-(const TickInterval& lhs,
const TickInterval& rhs);
TickInterval& operator-=(const TickInterval& rhs);
friend bool operator>(const TickInterval& lhs, const TickInterval& rhs);
friend bool operator<=(const TickInterval& lhs, const TickInterval& rhs);
friend bool operator<(const TickInterval& lhs, const TickInterval& rhs);
friend bool operator>=(const TickInterval& lhs, const TickInterval& rhs);
private:
explicit TickInterval(int64_t interval);
friend class TickTime;
friend TickInterval operator-(const TickTime& lhs, const TickTime& rhs);
private:
int64_t interval_;
};
inline TickInterval operator+(const TickInterval& lhs,
const TickInterval& rhs) {
return TickInterval(lhs.interval_ + rhs.interval_);
}
inline TickInterval operator-(const TickInterval& lhs,
const TickInterval& rhs) {
return TickInterval(lhs.interval_ - rhs.interval_);
}
inline TickInterval operator-(const TickTime& lhs, const TickTime& rhs) {
return TickInterval(lhs.ticks_ - rhs.ticks_);
}
inline TickTime operator+(const TickTime lhs, const int64_t ticks) {
TickTime time = lhs;
time.ticks_ += ticks;
return time;
}
inline bool operator>(const TickInterval& lhs, const TickInterval& rhs) {
return lhs.interval_ > rhs.interval_;
}
inline bool operator<=(const TickInterval& lhs, const TickInterval& rhs) {
return lhs.interval_ <= rhs.interval_;
}
inline bool operator<(const TickInterval& lhs, const TickInterval& rhs) {
return lhs.interval_ <= rhs.interval_;
}
inline bool operator>=(const TickInterval& lhs, const TickInterval& rhs) {
return lhs.interval_ >= rhs.interval_;
}
inline TickTime::TickTime()
: ticks_(0) {
}
inline TickTime::TickTime(int64_t ticks)
: ticks_(ticks) {
}
inline TickTime TickTime::Now() {
if (use_fake_clock_)
return TickTime(fake_ticks_);
else
return TickTime(QueryOsForTicks());
}
inline int64_t TickTime::MillisecondTimestamp() {
int64_t ticks = TickTime::Now().Ticks();
#if _WIN32
#ifdef USE_QUERY_PERFORMANCE_COUNTER
LARGE_INTEGER qpfreq;
QueryPerformanceFrequency(&qpfreq);
return (ticks * 1000) / qpfreq.QuadPart;
#else
return ticks;
#endif
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
return ticks / 1000000LL;
#else
return ticks / 1000LL;
#endif
}
inline int64_t TickTime::MicrosecondTimestamp() {
int64_t ticks = TickTime::Now().Ticks();
#if _WIN32
#ifdef USE_QUERY_PERFORMANCE_COUNTER
LARGE_INTEGER qpfreq;
QueryPerformanceFrequency(&qpfreq);
return (ticks * 1000) / (qpfreq.QuadPart / 1000);
#else
return ticks * 1000LL;
#endif
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
return ticks / 1000LL;
#else
return ticks;
#endif
}
inline int64_t TickTime::Ticks() const {
return ticks_;
}
inline int64_t TickTime::MillisecondsToTicks(const int64_t ms) {
#if _WIN32
#ifdef USE_QUERY_PERFORMANCE_COUNTER
LARGE_INTEGER qpfreq;
QueryPerformanceFrequency(&qpfreq);
return (qpfreq.QuadPart * ms) / 1000;
#else
return ms;
#endif
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
return ms * 1000000LL;
#else
return ms * 1000LL;
#endif
}
inline int64_t TickTime::TicksToMilliseconds(const int64_t ticks) {
#if _WIN32
#ifdef USE_QUERY_PERFORMANCE_COUNTER
LARGE_INTEGER qpfreq;
QueryPerformanceFrequency(&qpfreq);
return (ticks * 1000) / qpfreq.QuadPart;
#else
return ticks;
#endif
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
return ticks / 1000000LL;
#else
return ticks / 1000LL;
#endif
}
inline TickTime& TickTime::operator+=(const int64_t& ticks) {
ticks_ += ticks;
return *this;
}
inline TickInterval::TickInterval() : interval_(0) {
}
inline TickInterval::TickInterval(const int64_t interval)
: interval_(interval) {
}
inline int64_t TickInterval::Milliseconds() const {
#if _WIN32
#ifdef USE_QUERY_PERFORMANCE_COUNTER
LARGE_INTEGER qpfreq;
QueryPerformanceFrequency(&qpfreq);
return (interval_ * 1000) / qpfreq.QuadPart;
#else
// interval_ is in ms
return interval_;
#endif
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
// interval_ is in ns
return interval_ / 1000000;
#else
// interval_ is usecs
return interval_ / 1000;
#endif
}
inline int64_t TickInterval::Microseconds() const {
#if _WIN32
#ifdef USE_QUERY_PERFORMANCE_COUNTER
LARGE_INTEGER qpfreq;
QueryPerformanceFrequency(&qpfreq);
return (interval_ * 1000000) / qpfreq.QuadPart;
#else
// interval_ is in ms
return interval_ * 1000LL;
#endif
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
// interval_ is in ns
return interval_ / 1000;
#else
// interval_ is usecs
return interval_;
#endif
}
inline TickInterval& TickInterval::operator+=(const TickInterval& rhs) {
interval_ += rhs.interval_;
return *this;
}
inline TickInterval& TickInterval::operator-=(const TickInterval& rhs) {
interval_ -= rhs.interval_;
return *this;
}
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_

View File

@@ -0,0 +1,56 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef SYSTEM_WRAPPERS_INTERFACE_TIMESTAMP_EXTRAPOLATOR_H_
#define SYSTEM_WRAPPERS_INTERFACE_TIMESTAMP_EXTRAPOLATOR_H_
#include "webrtc/system_wrappers/interface/rw_lock_wrapper.h"
#include "webrtc/typedefs.h"
namespace webrtc
{
class TimestampExtrapolator
{
public:
explicit TimestampExtrapolator(int64_t start_ms);
~TimestampExtrapolator();
void Update(int64_t tMs, uint32_t ts90khz);
int64_t ExtrapolateLocalTime(uint32_t timestamp90khz);
void Reset(int64_t start_ms);
private:
void CheckForWrapArounds(uint32_t ts90khz);
bool DelayChangeDetection(double error);
RWLockWrapper* _rwLock;
double _w[2];
double _P[2][2];
int64_t _startMs;
int64_t _prevMs;
uint32_t _firstTimestamp;
int32_t _wrapArounds;
int64_t _prevUnwrappedTimestamp;
int64_t _prevWrapTimestamp;
const double _lambda;
bool _firstAfterReset;
uint32_t _packetCount;
const uint32_t _startUpFilterDelayInPackets;
double _detectorAccumulatorPos;
double _detectorAccumulatorNeg;
const double _alarmThreshold;
const double _accDrift;
const double _accMaxError;
const double _P11;
};
} // namespace webrtc
#endif // SYSTEM_WRAPPERS_INTERFACE_TIMESTAMP_EXTRAPOLATOR_H_

View File

@@ -0,0 +1,92 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*
* System independent wrapper for logging runtime information to file.
* Note: All log messages will be written to the same trace file.
* Note: If too many messages are written to file there will be a build up of
* messages. Apply filtering to avoid that.
*/
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TRACE_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TRACE_H_
#include "webrtc/common_types.h"
#include "webrtc/typedefs.h"
namespace webrtc {
#if defined(WEBRTC_RESTRICT_LOGGING)
// Disable all TRACE macros. The LOG macro is still functional.
#define WEBRTC_TRACE true ? (void) 0 : Trace::Add
#else
#define WEBRTC_TRACE Trace::Add
#endif
class Trace {
public:
// The length of the trace text preceeding the log message.
static const int kBoilerplateLength;
// The position of the timestamp text within a trace.
static const int kTimestampPosition;
// The length of the timestamp (without "delta" field).
static const int kTimestampLength;
// Increments the reference count to the trace.
static void CreateTrace();
// Decrements the reference count to the trace.
static void ReturnTrace();
// Note: any instance that writes to the trace file should increment and
// decrement the reference count on construction and destruction,
// respectively.
// Specifies what type of messages should be written to the trace file. The
// filter parameter is a bitmask where each message type is enumerated by the
// TraceLevel enumerator. TODO(hellner): why is the TraceLevel enumerator not
// defined in this file?
static void set_level_filter(uint32_t filter) { level_filter_ = filter; }
// Returns what type of messages are written to the trace file.
static uint32_t level_filter() { return level_filter_; }
// Sets the file name. If add_file_counter is false the same file will be
// reused when it fills up. If it's true a new file with incremented name
// will be used.
static int32_t SetTraceFile(const char* file_name,
const bool add_file_counter = false);
// Returns the name of the file that the trace is currently writing to.
static int32_t TraceFile(char file_name[1024]);
// Registers callback to receive trace messages.
// TODO(hellner): Why not use OutStream instead? Why is TraceCallback not
// defined in this file?
static int32_t SetTraceCallback(TraceCallback* callback);
// Adds a trace message for writing to file. The message is put in a queue
// for writing to file whenever possible for performance reasons. I.e. there
// is a crash it is possible that the last, vital logs are not logged yet.
// level is the type of message to log. If that type of messages is
// filtered it will not be written to file. module is an identifier for what
// part of the code the message is coming.
// id is an identifier that should be unique for that set of classes that
// are associated (e.g. all instances owned by an engine).
// msg and the ellipsis are the same as e.g. sprintf.
// TODO(hellner) Why is TraceModule not defined in this file?
static void Add(const TraceLevel level,
const TraceModule module,
const int32_t id,
const char* msg, ...);
private:
static uint32_t level_filter_;
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TRACE_H_

View File

@@ -0,0 +1,912 @@
// Copyright (c) 2012 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 under third_party_mods/chromium or at:
// http://src.chromium.org/svn/trunk/src/LICENSE
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TRACE_EVENT_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TRACE_EVENT_H_
#include <string>
#include "webrtc/system_wrappers/interface/event_tracer.h"
#if defined(TRACE_EVENT0)
#error "Another copy of trace_event.h has already been included."
#endif
// Extracted from Chromium's src/base/debug/trace_event.h.
// This header is designed to give you trace_event macros without specifying
// how the events actually get collected and stored. If you need to expose trace
// event to some other universe, you can copy-and-paste this file,
// implement the TRACE_EVENT_API macros, and do any other necessary fixup for
// the target platform. The end result is that multiple libraries can funnel
// events through to a shared trace event collector.
// Trace events are for tracking application performance and resource usage.
// Macros are provided to track:
// Begin and end of function calls
// Counters
//
// Events are issued against categories. Whereas LOG's
// categories are statically defined, TRACE categories are created
// implicitly with a string. For example:
// TRACE_EVENT_INSTANT0("MY_SUBSYSTEM", "SomeImportantEvent")
//
// Events can be INSTANT, or can be pairs of BEGIN and END in the same scope:
// TRACE_EVENT_BEGIN0("MY_SUBSYSTEM", "SomethingCostly")
// doSomethingCostly()
// TRACE_EVENT_END0("MY_SUBSYSTEM", "SomethingCostly")
// Note: our tools can't always determine the correct BEGIN/END pairs unless
// these are used in the same scope. Use ASYNC_BEGIN/ASYNC_END macros if you
// need them to be in separate scopes.
//
// A common use case is to trace entire function scopes. This
// issues a trace BEGIN and END automatically:
// void doSomethingCostly() {
// TRACE_EVENT0("MY_SUBSYSTEM", "doSomethingCostly");
// ...
// }
//
// Additional parameters can be associated with an event:
// void doSomethingCostly2(int howMuch) {
// TRACE_EVENT1("MY_SUBSYSTEM", "doSomethingCostly",
// "howMuch", howMuch);
// ...
// }
//
// The trace system will automatically add to this information the
// current process id, thread id, and a timestamp in microseconds.
//
// To trace an asynchronous procedure such as an IPC send/receive, use
// ASYNC_BEGIN and ASYNC_END:
// [single threaded sender code]
// static int send_count = 0;
// ++send_count;
// TRACE_EVENT_ASYNC_BEGIN0("ipc", "message", send_count);
// Send(new MyMessage(send_count));
// [receive code]
// void OnMyMessage(send_count) {
// TRACE_EVENT_ASYNC_END0("ipc", "message", send_count);
// }
// The third parameter is a unique ID to match ASYNC_BEGIN/ASYNC_END pairs.
// ASYNC_BEGIN and ASYNC_END can occur on any thread of any traced process.
// Pointers can be used for the ID parameter, and they will be mangled
// internally so that the same pointer on two different processes will not
// match. For example:
// class MyTracedClass {
// public:
// MyTracedClass() {
// TRACE_EVENT_ASYNC_BEGIN0("category", "MyTracedClass", this);
// }
// ~MyTracedClass() {
// TRACE_EVENT_ASYNC_END0("category", "MyTracedClass", this);
// }
// }
//
// Trace event also supports counters, which is a way to track a quantity
// as it varies over time. Counters are created with the following macro:
// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter", g_myCounterValue);
//
// Counters are process-specific. The macro itself can be issued from any
// thread, however.
//
// Sometimes, you want to track two counters at once. You can do this with two
// counter macros:
// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter0", g_myCounterValue[0]);
// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter1", g_myCounterValue[1]);
// Or you can do it with a combined macro:
// TRACE_COUNTER2("MY_SUBSYSTEM", "myCounter",
// "bytesPinned", g_myCounterValue[0],
// "bytesAllocated", g_myCounterValue[1]);
// This indicates to the tracing UI that these counters should be displayed
// in a single graph, as a summed area chart.
//
// Since counters are in a global namespace, you may want to disembiguate with a
// unique ID, by using the TRACE_COUNTER_ID* variations.
//
// By default, trace collection is compiled in, but turned off at runtime.
// Collecting trace data is the responsibility of the embedding
// application. In Chrome's case, navigating to about:tracing will turn on
// tracing and display data collected across all active processes.
//
//
// Memory scoping note:
// Tracing copies the pointers, not the string content, of the strings passed
// in for category, name, and arg_names. Thus, the following code will
// cause problems:
// char* str = strdup("impprtantName");
// TRACE_EVENT_INSTANT0("SUBSYSTEM", str); // BAD!
// free(str); // Trace system now has dangling pointer
//
// To avoid this issue with the |name| and |arg_name| parameters, use the
// TRACE_EVENT_COPY_XXX overloads of the macros at additional runtime overhead.
// Notes: The category must always be in a long-lived char* (i.e. static const).
// The |arg_values|, when used, are always deep copied with the _COPY
// macros.
//
// When are string argument values copied:
// const char* arg_values are only referenced by default:
// TRACE_EVENT1("category", "name",
// "arg1", "literal string is only referenced");
// Use TRACE_STR_COPY to force copying of a const char*:
// TRACE_EVENT1("category", "name",
// "arg1", TRACE_STR_COPY("string will be copied"));
// std::string arg_values are always copied:
// TRACE_EVENT1("category", "name",
// "arg1", std::string("string will be copied"));
//
//
// Thread Safety:
// Thread safety is provided by methods defined in event_tracer.h. See the file
// for details.
// By default, const char* argument values are assumed to have long-lived scope
// and will not be copied. Use this macro to force a const char* to be copied.
#define TRACE_STR_COPY(str) \
webrtc::trace_event_internal::TraceStringWithCopy(str)
// By default, uint64 ID argument values are not mangled with the Process ID in
// TRACE_EVENT_ASYNC macros. Use this macro to force Process ID mangling.
#define TRACE_ID_MANGLE(id) \
webrtc::trace_event_internal::TraceID::ForceMangle(id)
// Records a pair of begin and end events called "name" for the current
// scope, with 0, 1 or 2 associated arguments. If the category is not
// enabled, then this does nothing.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
#define TRACE_EVENT0(category, name) \
INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name)
#define TRACE_EVENT1(category, name, arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val)
#define TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, arg2_val) \
INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val, \
arg2_name, arg2_val)
// Same as TRACE_EVENT except that they are not included in official builds.
#ifdef OFFICIAL_BUILD
#define UNSHIPPED_TRACE_EVENT0(category, name) (void)0
#define UNSHIPPED_TRACE_EVENT1(category, name, arg1_name, arg1_val) (void)0
#define UNSHIPPED_TRACE_EVENT2(category, name, arg1_name, arg1_val, \
arg2_name, arg2_val) (void)0
#define UNSHIPPED_TRACE_EVENT_INSTANT0(category, name) (void)0
#define UNSHIPPED_TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val) \
(void)0
#define UNSHIPPED_TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \
arg2_name, arg2_val) (void)0
#else
#define UNSHIPPED_TRACE_EVENT0(category, name) \
TRACE_EVENT0(category, name)
#define UNSHIPPED_TRACE_EVENT1(category, name, arg1_name, arg1_val) \
TRACE_EVENT1(category, name, arg1_name, arg1_val)
#define UNSHIPPED_TRACE_EVENT2(category, name, arg1_name, arg1_val, \
arg2_name, arg2_val) \
TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, arg2_val)
#define UNSHIPPED_TRACE_EVENT_INSTANT0(category, name) \
TRACE_EVENT_INSTANT0(category, name)
#define UNSHIPPED_TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val) \
TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val)
#define UNSHIPPED_TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \
arg2_name, arg2_val) \
TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \
arg2_name, arg2_val)
#endif
// Records a single event called "name" immediately, with 0, 1 or 2
// associated arguments. If the category is not enabled, then this
// does nothing.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
#define TRACE_EVENT_INSTANT0(category, name) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
category, name, TRACE_EVENT_FLAG_NONE)
#define TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
#define TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \
arg2_name, arg2_val) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
arg2_name, arg2_val)
#define TRACE_EVENT_COPY_INSTANT0(category, name) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
category, name, TRACE_EVENT_FLAG_COPY)
#define TRACE_EVENT_COPY_INSTANT1(category, name, arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
#define TRACE_EVENT_COPY_INSTANT2(category, name, arg1_name, arg1_val, \
arg2_name, arg2_val) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
arg2_name, arg2_val)
// Records a single BEGIN event called "name" immediately, with 0, 1 or 2
// associated arguments. If the category is not enabled, then this
// does nothing.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
#define TRACE_EVENT_BEGIN0(category, name) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
category, name, TRACE_EVENT_FLAG_NONE)
#define TRACE_EVENT_BEGIN1(category, name, arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
#define TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, \
arg2_name, arg2_val) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
arg2_name, arg2_val)
#define TRACE_EVENT_COPY_BEGIN0(category, name) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
category, name, TRACE_EVENT_FLAG_COPY)
#define TRACE_EVENT_COPY_BEGIN1(category, name, arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
#define TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val, \
arg2_name, arg2_val) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
arg2_name, arg2_val)
// Records a single END event for "name" immediately. If the category
// is not enabled, then this does nothing.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
#define TRACE_EVENT_END0(category, name) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
category, name, TRACE_EVENT_FLAG_NONE)
#define TRACE_EVENT_END1(category, name, arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
#define TRACE_EVENT_END2(category, name, arg1_name, arg1_val, \
arg2_name, arg2_val) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
arg2_name, arg2_val)
#define TRACE_EVENT_COPY_END0(category, name) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
category, name, TRACE_EVENT_FLAG_COPY)
#define TRACE_EVENT_COPY_END1(category, name, arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
#define TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, \
arg2_name, arg2_val) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
arg2_name, arg2_val)
// Records the value of a counter called "name" immediately. Value
// must be representable as a 32 bit integer.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
#define TRACE_COUNTER1(category, name, value) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
category, name, TRACE_EVENT_FLAG_NONE, \
"value", static_cast<int>(value))
#define TRACE_COPY_COUNTER1(category, name, value) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
category, name, TRACE_EVENT_FLAG_COPY, \
"value", static_cast<int>(value))
// Records the values of a multi-parted counter called "name" immediately.
// The UI will treat value1 and value2 as parts of a whole, displaying their
// values as a stacked-bar chart.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
#define TRACE_COUNTER2(category, name, value1_name, value1_val, \
value2_name, value2_val) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
category, name, TRACE_EVENT_FLAG_NONE, \
value1_name, static_cast<int>(value1_val), \
value2_name, static_cast<int>(value2_val))
#define TRACE_COPY_COUNTER2(category, name, value1_name, value1_val, \
value2_name, value2_val) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
category, name, TRACE_EVENT_FLAG_COPY, \
value1_name, static_cast<int>(value1_val), \
value2_name, static_cast<int>(value2_val))
// Records the value of a counter called "name" immediately. Value
// must be representable as a 32 bit integer.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
// - |id| is used to disambiguate counters with the same name. It must either
// be a pointer or an integer value up to 64 bits. If it's a pointer, the bits
// will be xored with a hash of the process ID so that the same pointer on
// two different processes will not collide.
#define TRACE_COUNTER_ID1(category, name, id, value) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
category, name, id, TRACE_EVENT_FLAG_NONE, \
"value", static_cast<int>(value))
#define TRACE_COPY_COUNTER_ID1(category, name, id, value) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
category, name, id, TRACE_EVENT_FLAG_COPY, \
"value", static_cast<int>(value))
// Records the values of a multi-parted counter called "name" immediately.
// The UI will treat value1 and value2 as parts of a whole, displaying their
// values as a stacked-bar chart.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
// - |id| is used to disambiguate counters with the same name. It must either
// be a pointer or an integer value up to 64 bits. If it's a pointer, the bits
// will be xored with a hash of the process ID so that the same pointer on
// two different processes will not collide.
#define TRACE_COUNTER_ID2(category, name, id, value1_name, value1_val, \
value2_name, value2_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
category, name, id, TRACE_EVENT_FLAG_NONE, \
value1_name, static_cast<int>(value1_val), \
value2_name, static_cast<int>(value2_val))
#define TRACE_COPY_COUNTER_ID2(category, name, id, value1_name, value1_val, \
value2_name, value2_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
category, name, id, TRACE_EVENT_FLAG_COPY, \
value1_name, static_cast<int>(value1_val), \
value2_name, static_cast<int>(value2_val))
// Records a single ASYNC_BEGIN event called "name" immediately, with 0, 1 or 2
// associated arguments. If the category is not enabled, then this
// does nothing.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
// - |id| is used to match the ASYNC_BEGIN event with the ASYNC_END event. ASYNC
// events are considered to match if their category, name and id values all
// match. |id| must either be a pointer or an integer value up to 64 bits. If
// it's a pointer, the bits will be xored with a hash of the process ID so
// that the same pointer on two different processes will not collide.
// An asynchronous operation can consist of multiple phases. The first phase is
// defined by the ASYNC_BEGIN calls. Additional phases can be defined using the
// ASYNC_STEP macros. When the operation completes, call ASYNC_END.
// An ASYNC trace typically occur on a single thread (if not, they will only be
// drawn on the thread defined in the ASYNC_BEGIN event), but all events in that
// operation must use the same |name| and |id|. Each event can have its own
// args.
#define TRACE_EVENT_ASYNC_BEGIN0(category, name, id) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
category, name, id, TRACE_EVENT_FLAG_NONE)
#define TRACE_EVENT_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
#define TRACE_EVENT_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \
arg2_name, arg2_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
category, name, id, TRACE_EVENT_FLAG_NONE, \
arg1_name, arg1_val, arg2_name, arg2_val)
#define TRACE_EVENT_COPY_ASYNC_BEGIN0(category, name, id) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
category, name, id, TRACE_EVENT_FLAG_COPY)
#define TRACE_EVENT_COPY_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
category, name, id, TRACE_EVENT_FLAG_COPY, \
arg1_name, arg1_val)
#define TRACE_EVENT_COPY_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \
arg2_name, arg2_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
category, name, id, TRACE_EVENT_FLAG_COPY, \
arg1_name, arg1_val, arg2_name, arg2_val)
// Records a single ASYNC_STEP event for |step| immediately. If the category
// is not enabled, then this does nothing. The |name| and |id| must match the
// ASYNC_BEGIN event above. The |step| param identifies this step within the
// async event. This should be called at the beginning of the next phase of an
// asynchronous operation.
#define TRACE_EVENT_ASYNC_STEP0(category, name, id, step) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
category, name, id, TRACE_EVENT_FLAG_NONE, "step", step)
#define TRACE_EVENT_ASYNC_STEP1(category, name, id, step, \
arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
category, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \
arg1_name, arg1_val)
#define TRACE_EVENT_COPY_ASYNC_STEP0(category, name, id, step) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
category, name, id, TRACE_EVENT_FLAG_COPY, "step", step)
#define TRACE_EVENT_COPY_ASYNC_STEP1(category, name, id, step, \
arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
category, name, id, TRACE_EVENT_FLAG_COPY, "step", step, \
arg1_name, arg1_val)
// Records a single ASYNC_END event for "name" immediately. If the category
// is not enabled, then this does nothing.
#define TRACE_EVENT_ASYNC_END0(category, name, id) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
category, name, id, TRACE_EVENT_FLAG_NONE)
#define TRACE_EVENT_ASYNC_END1(category, name, id, arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
#define TRACE_EVENT_ASYNC_END2(category, name, id, arg1_name, arg1_val, \
arg2_name, arg2_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
category, name, id, TRACE_EVENT_FLAG_NONE, \
arg1_name, arg1_val, arg2_name, arg2_val)
#define TRACE_EVENT_COPY_ASYNC_END0(category, name, id) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
category, name, id, TRACE_EVENT_FLAG_COPY)
#define TRACE_EVENT_COPY_ASYNC_END1(category, name, id, arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
category, name, id, TRACE_EVENT_FLAG_COPY, \
arg1_name, arg1_val)
#define TRACE_EVENT_COPY_ASYNC_END2(category, name, id, arg1_name, arg1_val, \
arg2_name, arg2_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
category, name, id, TRACE_EVENT_FLAG_COPY, \
arg1_name, arg1_val, arg2_name, arg2_val)
// Records a single FLOW_BEGIN event called "name" immediately, with 0, 1 or 2
// associated arguments. If the category is not enabled, then this
// does nothing.
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
// - |id| is used to match the FLOW_BEGIN event with the FLOW_END event. FLOW
// events are considered to match if their category, name and id values all
// match. |id| must either be a pointer or an integer value up to 64 bits. If
// it's a pointer, the bits will be xored with a hash of the process ID so
// that the same pointer on two different processes will not collide.
// FLOW events are different from ASYNC events in how they are drawn by the
// tracing UI. A FLOW defines asynchronous data flow, such as posting a task
// (FLOW_BEGIN) and later executing that task (FLOW_END). Expect FLOWs to be
// drawn as lines or arrows from FLOW_BEGIN scopes to FLOW_END scopes. Similar
// to ASYNC, a FLOW can consist of multiple phases. The first phase is defined
// by the FLOW_BEGIN calls. Additional phases can be defined using the FLOW_STEP
// macros. When the operation completes, call FLOW_END. An async operation can
// span threads and processes, but all events in that operation must use the
// same |name| and |id|. Each event can have its own args.
#define TRACE_EVENT_FLOW_BEGIN0(category, name, id) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
category, name, id, TRACE_EVENT_FLAG_NONE)
#define TRACE_EVENT_FLOW_BEGIN1(category, name, id, arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
#define TRACE_EVENT_FLOW_BEGIN2(category, name, id, arg1_name, arg1_val, \
arg2_name, arg2_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
category, name, id, TRACE_EVENT_FLAG_NONE, \
arg1_name, arg1_val, arg2_name, arg2_val)
#define TRACE_EVENT_COPY_FLOW_BEGIN0(category, name, id) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
category, name, id, TRACE_EVENT_FLAG_COPY)
#define TRACE_EVENT_COPY_FLOW_BEGIN1(category, name, id, arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
category, name, id, TRACE_EVENT_FLAG_COPY, \
arg1_name, arg1_val)
#define TRACE_EVENT_COPY_FLOW_BEGIN2(category, name, id, arg1_name, arg1_val, \
arg2_name, arg2_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
category, name, id, TRACE_EVENT_FLAG_COPY, \
arg1_name, arg1_val, arg2_name, arg2_val)
// Records a single FLOW_STEP event for |step| immediately. If the category
// is not enabled, then this does nothing. The |name| and |id| must match the
// FLOW_BEGIN event above. The |step| param identifies this step within the
// async event. This should be called at the beginning of the next phase of an
// asynchronous operation.
#define TRACE_EVENT_FLOW_STEP0(category, name, id, step) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \
category, name, id, TRACE_EVENT_FLAG_NONE, "step", step)
#define TRACE_EVENT_FLOW_STEP1(category, name, id, step, \
arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \
category, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \
arg1_name, arg1_val)
#define TRACE_EVENT_COPY_FLOW_STEP0(category, name, id, step) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \
category, name, id, TRACE_EVENT_FLAG_COPY, "step", step)
#define TRACE_EVENT_COPY_FLOW_STEP1(category, name, id, step, \
arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \
category, name, id, TRACE_EVENT_FLAG_COPY, "step", step, \
arg1_name, arg1_val)
// Records a single FLOW_END event for "name" immediately. If the category
// is not enabled, then this does nothing.
#define TRACE_EVENT_FLOW_END0(category, name, id) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
category, name, id, TRACE_EVENT_FLAG_NONE)
#define TRACE_EVENT_FLOW_END1(category, name, id, arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
#define TRACE_EVENT_FLOW_END2(category, name, id, arg1_name, arg1_val, \
arg2_name, arg2_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
category, name, id, TRACE_EVENT_FLAG_NONE, \
arg1_name, arg1_val, arg2_name, arg2_val)
#define TRACE_EVENT_COPY_FLOW_END0(category, name, id) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
category, name, id, TRACE_EVENT_FLAG_COPY)
#define TRACE_EVENT_COPY_FLOW_END1(category, name, id, arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
category, name, id, TRACE_EVENT_FLAG_COPY, \
arg1_name, arg1_val)
#define TRACE_EVENT_COPY_FLOW_END2(category, name, id, arg1_name, arg1_val, \
arg2_name, arg2_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
category, name, id, TRACE_EVENT_FLAG_COPY, \
arg1_name, arg1_val, arg2_name, arg2_val)
////////////////////////////////////////////////////////////////////////////////
// Implementation specific tracing API definitions.
// Get a pointer to the enabled state of the given trace category. Only
// long-lived literal strings should be given as the category name. The returned
// pointer can be held permanently in a local static for example. If the
// unsigned char is non-zero, tracing is enabled. If tracing is enabled,
// TRACE_EVENT_API_ADD_TRACE_EVENT can be called. It's OK if tracing is disabled
// between the load of the tracing state and the call to
// TRACE_EVENT_API_ADD_TRACE_EVENT, because this flag only provides an early out
// for best performance when tracing is disabled.
// const unsigned char*
// TRACE_EVENT_API_GET_CATEGORY_ENABLED(const char* category_name)
#define TRACE_EVENT_API_GET_CATEGORY_ENABLED \
webrtc::EventTracer::GetCategoryEnabled
// Add a trace event to the platform tracing system.
// void TRACE_EVENT_API_ADD_TRACE_EVENT(
// char phase,
// const unsigned char* category_enabled,
// const char* name,
// unsigned long long id,
// int num_args,
// const char** arg_names,
// const unsigned char* arg_types,
// const unsigned long long* arg_values,
// unsigned char flags)
#define TRACE_EVENT_API_ADD_TRACE_EVENT webrtc::EventTracer::AddTraceEvent
////////////////////////////////////////////////////////////////////////////////
// Implementation detail: trace event macros create temporary variables
// to keep instrumentation overhead low. These macros give each temporary
// variable a unique name based on the line number to prevent name collissions.
#define INTERNAL_TRACE_EVENT_UID3(a,b) \
trace_event_unique_##a##b
#define INTERNAL_TRACE_EVENT_UID2(a,b) \
INTERNAL_TRACE_EVENT_UID3(a,b)
#define INTERNAL_TRACE_EVENT_UID(name_prefix) \
INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__)
// Implementation detail: internal macro to create static category.
#define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category) \
static const unsigned char* INTERNAL_TRACE_EVENT_UID(catstatic) = 0; \
if (!INTERNAL_TRACE_EVENT_UID(catstatic)) { \
INTERNAL_TRACE_EVENT_UID(catstatic) = \
TRACE_EVENT_API_GET_CATEGORY_ENABLED(category); \
}
// Implementation detail: internal macro to create static category and add
// event if the category is enabled.
#define INTERNAL_TRACE_EVENT_ADD(phase, category, name, flags, ...) \
do { \
INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \
webrtc::trace_event_internal::AddTraceEvent( \
phase, INTERNAL_TRACE_EVENT_UID(catstatic), name, \
webrtc::trace_event_internal::kNoEventId, flags, ##__VA_ARGS__); \
} \
} while (0)
// Implementation detail: internal macro to create static category and add begin
// event if the category is enabled. Also adds the end event when the scope
// ends.
#define INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, ...) \
INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
webrtc::trace_event_internal::TraceEndOnScopeClose \
INTERNAL_TRACE_EVENT_UID(profileScope); \
if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \
webrtc::trace_event_internal::AddTraceEvent( \
TRACE_EVENT_PHASE_BEGIN, \
INTERNAL_TRACE_EVENT_UID(catstatic), \
name, webrtc::trace_event_internal::kNoEventId, \
TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \
INTERNAL_TRACE_EVENT_UID(profileScope).Initialize( \
INTERNAL_TRACE_EVENT_UID(catstatic), name); \
}
// Implementation detail: internal macro to create static category and add
// event if the category is enabled.
#define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category, name, id, flags, \
...) \
do { \
INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \
unsigned char trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID; \
webrtc::trace_event_internal::TraceID trace_event_trace_id( \
id, &trace_event_flags); \
webrtc::trace_event_internal::AddTraceEvent( \
phase, INTERNAL_TRACE_EVENT_UID(catstatic), \
name, trace_event_trace_id.data(), trace_event_flags, \
##__VA_ARGS__); \
} \
} while (0)
// Notes regarding the following definitions:
// New values can be added and propagated to third party libraries, but existing
// definitions must never be changed, because third party libraries may use old
// definitions.
// Phase indicates the nature of an event entry. E.g. part of a begin/end pair.
#define TRACE_EVENT_PHASE_BEGIN ('B')
#define TRACE_EVENT_PHASE_END ('E')
#define TRACE_EVENT_PHASE_INSTANT ('I')
#define TRACE_EVENT_PHASE_ASYNC_BEGIN ('S')
#define TRACE_EVENT_PHASE_ASYNC_STEP ('T')
#define TRACE_EVENT_PHASE_ASYNC_END ('F')
#define TRACE_EVENT_PHASE_FLOW_BEGIN ('s')
#define TRACE_EVENT_PHASE_FLOW_STEP ('t')
#define TRACE_EVENT_PHASE_FLOW_END ('f')
#define TRACE_EVENT_PHASE_METADATA ('M')
#define TRACE_EVENT_PHASE_COUNTER ('C')
// Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT.
#define TRACE_EVENT_FLAG_NONE (static_cast<unsigned char>(0))
#define TRACE_EVENT_FLAG_COPY (static_cast<unsigned char>(1 << 0))
#define TRACE_EVENT_FLAG_HAS_ID (static_cast<unsigned char>(1 << 1))
#define TRACE_EVENT_FLAG_MANGLE_ID (static_cast<unsigned char>(1 << 2))
// Type values for identifying types in the TraceValue union.
#define TRACE_VALUE_TYPE_BOOL (static_cast<unsigned char>(1))
#define TRACE_VALUE_TYPE_UINT (static_cast<unsigned char>(2))
#define TRACE_VALUE_TYPE_INT (static_cast<unsigned char>(3))
#define TRACE_VALUE_TYPE_DOUBLE (static_cast<unsigned char>(4))
#define TRACE_VALUE_TYPE_POINTER (static_cast<unsigned char>(5))
#define TRACE_VALUE_TYPE_STRING (static_cast<unsigned char>(6))
#define TRACE_VALUE_TYPE_COPY_STRING (static_cast<unsigned char>(7))
namespace webrtc {
namespace trace_event_internal {
// Specify these values when the corresponding argument of AddTraceEvent is not
// used.
const int kZeroNumArgs = 0;
const unsigned long long kNoEventId = 0;
// TraceID encapsulates an ID that can either be an integer or pointer. Pointers
// are mangled with the Process ID so that they are unlikely to collide when the
// same pointer is used on different processes.
class TraceID {
public:
class ForceMangle {
public:
explicit ForceMangle(unsigned long long id) : data_(id) {}
explicit ForceMangle(unsigned long id) : data_(id) {}
explicit ForceMangle(unsigned int id) : data_(id) {}
explicit ForceMangle(unsigned short id) : data_(id) {}
explicit ForceMangle(unsigned char id) : data_(id) {}
explicit ForceMangle(long long id)
: data_(static_cast<unsigned long long>(id)) {}
explicit ForceMangle(long id)
: data_(static_cast<unsigned long long>(id)) {}
explicit ForceMangle(int id)
: data_(static_cast<unsigned long long>(id)) {}
explicit ForceMangle(short id)
: data_(static_cast<unsigned long long>(id)) {}
explicit ForceMangle(signed char id)
: data_(static_cast<unsigned long long>(id)) {}
unsigned long long data() const { return data_; }
private:
unsigned long long data_;
};
explicit TraceID(const void* id, unsigned char* flags)
: data_(static_cast<unsigned long long>(
reinterpret_cast<unsigned long>(id))) {
*flags |= TRACE_EVENT_FLAG_MANGLE_ID;
}
explicit TraceID(ForceMangle id, unsigned char* flags) : data_(id.data()) {
*flags |= TRACE_EVENT_FLAG_MANGLE_ID;
}
explicit TraceID(unsigned long long id, unsigned char* flags)
: data_(id) { (void)flags; }
explicit TraceID(unsigned long id, unsigned char* flags)
: data_(id) { (void)flags; }
explicit TraceID(unsigned int id, unsigned char* flags)
: data_(id) { (void)flags; }
explicit TraceID(unsigned short id, unsigned char* flags)
: data_(id) { (void)flags; }
explicit TraceID(unsigned char id, unsigned char* flags)
: data_(id) { (void)flags; }
explicit TraceID(long long id, unsigned char* flags)
: data_(static_cast<unsigned long long>(id)) { (void)flags; }
explicit TraceID(long id, unsigned char* flags)
: data_(static_cast<unsigned long long>(id)) { (void)flags; }
explicit TraceID(int id, unsigned char* flags)
: data_(static_cast<unsigned long long>(id)) { (void)flags; }
explicit TraceID(short id, unsigned char* flags)
: data_(static_cast<unsigned long long>(id)) { (void)flags; }
explicit TraceID(signed char id, unsigned char* flags)
: data_(static_cast<unsigned long long>(id)) { (void)flags; }
unsigned long long data() const { return data_; }
private:
unsigned long long data_;
};
// Simple union to store various types as unsigned long long.
union TraceValueUnion {
bool as_bool;
unsigned long long as_uint;
long long as_int;
double as_double;
const void* as_pointer;
const char* as_string;
};
// Simple container for const char* that should be copied instead of retained.
class TraceStringWithCopy {
public:
explicit TraceStringWithCopy(const char* str) : str_(str) {}
operator const char* () const { return str_; }
private:
const char* str_;
};
// Define SetTraceValue for each allowed type. It stores the type and
// value in the return arguments. This allows this API to avoid declaring any
// structures so that it is portable to third_party libraries.
#define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, \
union_member, \
value_type_id) \
static inline void SetTraceValue(actual_type arg, \
unsigned char* type, \
unsigned long long* value) { \
TraceValueUnion type_value; \
type_value.union_member = arg; \
*type = value_type_id; \
*value = type_value.as_uint; \
}
// Simpler form for int types that can be safely casted.
#define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, \
value_type_id) \
static inline void SetTraceValue(actual_type arg, \
unsigned char* type, \
unsigned long long* value) { \
*type = value_type_id; \
*value = static_cast<unsigned long long>(arg); \
}
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long long, TRACE_VALUE_TYPE_UINT)
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long, TRACE_VALUE_TYPE_UINT)
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned int, TRACE_VALUE_TYPE_UINT)
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned short, TRACE_VALUE_TYPE_UINT)
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned char, TRACE_VALUE_TYPE_UINT)
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long long, TRACE_VALUE_TYPE_INT)
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long, TRACE_VALUE_TYPE_INT)
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT)
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(short, TRACE_VALUE_TYPE_INT)
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT)
INTERNAL_DECLARE_SET_TRACE_VALUE(bool, as_bool, TRACE_VALUE_TYPE_BOOL)
INTERNAL_DECLARE_SET_TRACE_VALUE(double, as_double, TRACE_VALUE_TYPE_DOUBLE)
INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, as_pointer,
TRACE_VALUE_TYPE_POINTER)
INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, as_string,
TRACE_VALUE_TYPE_STRING)
INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy&, as_string,
TRACE_VALUE_TYPE_COPY_STRING)
#undef INTERNAL_DECLARE_SET_TRACE_VALUE
#undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT
// std::string version of SetTraceValue so that trace arguments can be strings.
static inline void SetTraceValue(const std::string& arg,
unsigned char* type,
unsigned long long* value) {
TraceValueUnion type_value;
type_value.as_string = arg.c_str();
*type = TRACE_VALUE_TYPE_COPY_STRING;
*value = type_value.as_uint;
}
// These AddTraceEvent template functions are defined here instead of in the
// macro, because the arg_values could be temporary objects, such as
// std::string. In order to store pointers to the internal c_str and pass
// through to the tracing API, the arg_values must live throughout
// these procedures.
static inline void AddTraceEvent(char phase,
const unsigned char* category_enabled,
const char* name,
unsigned long long id,
unsigned char flags) {
TRACE_EVENT_API_ADD_TRACE_EVENT(
phase, category_enabled, name, id,
kZeroNumArgs, NULL, NULL, NULL,
flags);
}
template<class ARG1_TYPE>
static inline void AddTraceEvent(char phase,
const unsigned char* category_enabled,
const char* name,
unsigned long long id,
unsigned char flags,
const char* arg1_name,
const ARG1_TYPE& arg1_val) {
const int num_args = 1;
unsigned char arg_types[1];
unsigned long long arg_values[1];
SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]);
TRACE_EVENT_API_ADD_TRACE_EVENT(
phase, category_enabled, name, id,
num_args, &arg1_name, arg_types, arg_values,
flags);
}
template<class ARG1_TYPE, class ARG2_TYPE>
static inline void AddTraceEvent(char phase,
const unsigned char* category_enabled,
const char* name,
unsigned long long id,
unsigned char flags,
const char* arg1_name,
const ARG1_TYPE& arg1_val,
const char* arg2_name,
const ARG2_TYPE& arg2_val) {
const int num_args = 2;
const char* arg_names[2] = { arg1_name, arg2_name };
unsigned char arg_types[2];
unsigned long long arg_values[2];
SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]);
SetTraceValue(arg2_val, &arg_types[1], &arg_values[1]);
TRACE_EVENT_API_ADD_TRACE_EVENT(
phase, category_enabled, name, id,
num_args, arg_names, arg_types, arg_values,
flags);
}
// Used by TRACE_EVENTx macro. Do not use directly.
class TraceEndOnScopeClose {
public:
// Note: members of data_ intentionally left uninitialized. See Initialize.
TraceEndOnScopeClose() : p_data_(NULL) {}
~TraceEndOnScopeClose() {
if (p_data_)
AddEventIfEnabled();
}
void Initialize(const unsigned char* category_enabled,
const char* name) {
data_.category_enabled = category_enabled;
data_.name = name;
p_data_ = &data_;
}
private:
// Add the end event if the category is still enabled.
void AddEventIfEnabled() {
// Only called when p_data_ is non-null.
if (*p_data_->category_enabled) {
TRACE_EVENT_API_ADD_TRACE_EVENT(
TRACE_EVENT_PHASE_END,
p_data_->category_enabled,
p_data_->name, kNoEventId,
kZeroNumArgs, NULL, NULL, NULL,
TRACE_EVENT_FLAG_NONE);
}
}
// This Data struct workaround is to avoid initializing all the members
// in Data during construction of this object, since this object is always
// constructed, even when tracing is disabled. If the members of Data were
// members of this class instead, compiler warnings occur about potential
// uninitialized accesses.
struct Data {
const unsigned char* category_enabled;
const char* name;
};
Data* p_data_;
Data data_;
};
} // namespace trace_event_internal
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TRACE_EVENT_H_

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Conversion functions for UTF-8 and UTF-16 strings on Windows.
// Duplicated from talk/base/win32.h.
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_UTF_UTIL_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_UTF_UTIL_H_
#ifdef WIN32
#include <windows.h>
#include <string>
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
namespace webrtc {
inline std::wstring ToUtf16(const char* utf8, size_t len) {
int len16 = ::MultiByteToWideChar(CP_UTF8, 0, utf8, static_cast<int>(len),
NULL, 0);
scoped_ptr<wchar_t[]> ws(new wchar_t[len16]);
::MultiByteToWideChar(CP_UTF8, 0, utf8, static_cast<int>(len), ws.get(),
len16);
return std::wstring(ws.get(), len16);
}
inline std::wstring ToUtf16(const std::string& str) {
return ToUtf16(str.data(), str.length());
}
inline std::string ToUtf8(const wchar_t* wide, size_t len) {
int len8 = ::WideCharToMultiByte(CP_UTF8, 0, wide, static_cast<int>(len),
NULL, 0, NULL, NULL);
scoped_ptr<char[]> ns(new char[len8]);
::WideCharToMultiByte(CP_UTF8, 0, wide, static_cast<int>(len), ns.get(), len8,
NULL, NULL);
return std::string(ns.get(), len8);
}
inline std::string ToUtf8(const wchar_t* wide) {
return ToUtf8(wide, wcslen(wide));
}
inline std::string ToUtf8(const std::wstring& wstr) {
return ToUtf8(wstr.data(), wstr.length());
}
} // namespace webrtc
#endif // WIN32
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_UTF_UTIL_H_