-
Notifications
You must be signed in to change notification settings - Fork 485
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Basic implementation of threaded traces
The very simple implementation improves performance of tracing by about 3x.
- Loading branch information
Showing
6 changed files
with
418 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
/************************************************************************** | ||
* | ||
* Copyright 1999-2006 Brian Paul | ||
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. | ||
* All Rights Reserved. | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a | ||
* copy of this software and associated documentation files (the "Software"), | ||
* to deal in the Software without restriction, including without limitation | ||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
* and/or sell copies of the Software, and to permit persons to whom the | ||
* Software is furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included | ||
* in all copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | ||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
* | ||
**************************************************************************/ | ||
|
||
|
||
/** | ||
* @file | ||
* | ||
* Thread, mutex, condition variable. | ||
*/ | ||
|
||
|
||
#ifndef OS_THREAD_H_ | ||
#define OS_THREAD_H_ | ||
|
||
namespace OS { | ||
|
||
#if defined _WIN32 | ||
#include <windows.h> | ||
typedef HANDLE Thread; | ||
typedef CRITICAL_SECTION Mutex; | ||
typedef CONDITION_VARIABLE Condvar; | ||
#else | ||
#include <pthread.h> /* POSIX threads headers */ | ||
#include <stdio.h> /* for perror() */ | ||
#include <signal.h> | ||
typedef pthread_t Thread; | ||
typedef pthread_mutex_t Mutex; | ||
typedef pthread_cond_t Condvar; | ||
#endif | ||
|
||
#if defined _WIN32 | ||
#define THREAD_ROUTINE( name, param ) \ | ||
void * WINAPI name( void *param ) | ||
|
||
static inline Thread ThreadCreate(void *(WINAPI * routine)(void *), | ||
void *param) | ||
{ | ||
DWORD id; | ||
return CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) routine, | ||
param, 0, &id); | ||
} | ||
|
||
static inline int ThreadWait(Thread thread) | ||
{ | ||
if (WaitForSingleObject(thread, INFINITE) == WAIT_OBJECT_0) | ||
return 0; | ||
return -1; | ||
} | ||
|
||
static inline int ThreadDestroy(Thread thread) | ||
{ | ||
if (CloseHandle(thread)) | ||
return 0; | ||
return -1; | ||
} | ||
|
||
/* http://locklessinc.com/articles/pthreads_on_windows/ */ | ||
#define MutexStatic(mutex) \ | ||
static Mutex mutex = {(PCRITICAL_SECTION_DEBUG)-1, -1, 0, 0, 0, 0} | ||
|
||
#define MutexInit(mutex) \ | ||
InitializeCriticalSection(&mutex) | ||
|
||
#define MutexDestroy(mutex) \ | ||
DeleteCriticalSection(&mutex) | ||
|
||
#define MutexLock(mutex) \ | ||
EnterCriticalSection(&mutex) | ||
|
||
#define MutexUnlock(mutex) \ | ||
LeaveCriticalSection(&mutex) | ||
|
||
/* CONDITION_VARIABLE is only available on newer versions of Windows | ||
* (Server 2008/Vista or later). | ||
* http://msdn.microsoft.com/en-us/library/ms682052(VS.85).aspx | ||
*/ | ||
|
||
#define CondvarStatic(cond) \ | ||
/*static*/ Condvar cond = CONDITION_VARIABLE_INIT | ||
|
||
#define CondvarInit(cond) \ | ||
InitializeConditionVariable(&(cond)) | ||
|
||
#define CondvarDestroy(cond) \ | ||
(void) cond /* nothing to do */ | ||
|
||
#define CondvarWait(cond, mutex) \ | ||
SleepConditionVariableCS(&(cond), &(mutex), INFINITE) | ||
|
||
#define CondvarSignal(cond) \ | ||
WakeConditionVariable(&(cond)) | ||
|
||
#define CondvarBroadcast(cond) \ | ||
WakeAllConditionVariable(&(cond)) | ||
|
||
#else | ||
|
||
#define THREAD_ROUTINE( name, param ) \ | ||
void *name( void *param ) | ||
|
||
static inline Thread ThreadCreate(void *(* routine)( void *), | ||
void *param) | ||
{ | ||
Thread thread; | ||
sigset_t saved_set, new_set; | ||
int ret; | ||
|
||
sigfillset(&new_set); | ||
pthread_sigmask(SIG_SETMASK, &new_set, &saved_set); | ||
ret = pthread_create( &thread, NULL, routine, param ); | ||
pthread_sigmask(SIG_SETMASK, &saved_set, NULL); | ||
if (ret) | ||
return 0; | ||
return thread; | ||
} | ||
|
||
static inline int ThreadWait(Thread thread) | ||
{ | ||
return pthread_join(thread, NULL); | ||
} | ||
|
||
static inline int ThreadDestroy(Thread thread) | ||
{ | ||
return pthread_detach(thread); | ||
} | ||
|
||
#define MutexStatic(mutex) \ | ||
static Mutex mutex = PTHREAD_MUTEX_INITIALIZER | ||
|
||
#define MutexInit(mutex) \ | ||
(void) pthread_mutex_init(&(mutex), NULL) | ||
|
||
#define MutexDestroy(mutex) \ | ||
pthread_mutex_destroy(&(mutex)) | ||
|
||
#define MutexLock(mutex) \ | ||
(void) pthread_mutex_lock(&(mutex)) | ||
|
||
#define MutexUnlock(mutex) \ | ||
(void) pthread_mutex_unlock(&(mutex)) | ||
|
||
#define CondvarStatic(mutex) \ | ||
static Condvar mutex = PTHREAD_COND_INITIALIZER | ||
|
||
#define CondvarInit(cond) \ | ||
pthread_cond_init(&(cond), NULL) | ||
|
||
#define CondvarDestroy(cond) \ | ||
pthread_cond_destroy(&(cond)) | ||
|
||
#define CondvarWait(cond, mutex) \ | ||
pthread_cond_wait(&(cond), &(mutex)) | ||
|
||
#define CondvarSignal(cond) \ | ||
pthread_cond_signal(&(cond)) | ||
|
||
#define CondvarBroadcast(cond) \ | ||
pthread_cond_broadcast(&(cond)) | ||
|
||
#endif | ||
|
||
|
||
} | ||
|
||
#endif /* OS_THREAD_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
#include <string.h> | ||
#include <assert.h> | ||
|
||
#include "ringbuffer.hpp" | ||
|
||
using namespace OS; | ||
|
||
Ringbuffer::Ringbuffer(long size) | ||
: m_size(size) | ||
{ | ||
m_buffer = new char[m_size]; | ||
m_writePtr = m_buffer; | ||
m_readPtr = m_buffer; | ||
|
||
MutexInit(m_mutex); | ||
} | ||
|
||
Ringbuffer::~Ringbuffer() | ||
{ | ||
MutexDestroy(m_mutex); | ||
delete [] m_buffer; | ||
} | ||
|
||
long Ringbuffer::size() const | ||
{ | ||
return m_size; | ||
} | ||
|
||
int Ringbuffer::sizeToWrite() const | ||
{ | ||
if (m_writePtr > m_readPtr) { | ||
return m_size - (m_writePtr - m_readPtr); | ||
} else if (m_writePtr == m_readPtr) { | ||
return m_size - (m_writePtr - m_buffer); | ||
} else { | ||
return m_readPtr - m_writePtr; | ||
} | ||
} | ||
|
||
int Ringbuffer::sizeToRead() const | ||
{ | ||
return m_size - sizeToWrite(); | ||
} | ||
|
||
void Ringbuffer::write(char *buffer, int size) | ||
{ | ||
if (size >= this->size()) { | ||
assert(0); | ||
return; | ||
} | ||
MutexLock(m_mutex); | ||
memcpy(m_writePtr, buffer, size); | ||
m_writePtr += size; | ||
MutexUnlock(m_mutex); | ||
} | ||
|
||
void Ringbuffer::read(char *buffer, int size) | ||
{ | ||
MutexLock(m_mutex); | ||
memcpy(buffer, m_readPtr, size); | ||
m_readPtr += size; | ||
MutexUnlock(m_mutex); | ||
} | ||
|
||
void OS::Ringbuffer::reset() | ||
{ | ||
m_writePtr = m_buffer; | ||
m_readPtr = m_buffer; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#ifndef OS_RINGBUFFER_HPP | ||
#define OS_RINGBUFFER_HPP | ||
|
||
#include "os_thread.hpp" | ||
|
||
namespace OS { | ||
|
||
class Ringbuffer | ||
{ | ||
public: | ||
Ringbuffer(long size = 32 * 1024 * 1024); | ||
~Ringbuffer(); | ||
|
||
long size() const; | ||
|
||
int sizeToWrite() const; | ||
int sizeToRead() const; | ||
|
||
void write(char *buffer, int size); | ||
void read(char *buffer, int size); | ||
|
||
void reset(); | ||
|
||
private: | ||
char *m_buffer; | ||
long m_size; | ||
|
||
char *m_writePtr; | ||
char *m_readPtr; | ||
|
||
OS::Mutex m_mutex; | ||
}; | ||
|
||
} | ||
|
||
#endif |
Oops, something went wrong.