logog
logger optimized for games
Porting logog

Porting logog should be a straightforward affair, if you follow these guidelines.

First of all, you'll need to choose a flavor of operating system for your platform. Nearly all OSes will fall into one of two flavors: POSIX-like and Windows-like. platform.hpp tries to detect the local OS and compile for it; you may need to change the detection logic for your new platform. You'll need to set either LOGOG_FLAVOR_POSIX or LOGOG_FLAVOR_WINDOWS before loading platform.hpp.

The files containing platform dependent code are as follows.

  • platform.hpp. In addition to detecting the build flavor, platform.hpp also sets some macros for STL usage. All STL calls are routed through the macros in platform.hpp. As of this writing, the STL templates are available in tr1; you may need to tweak this if you're depending on a C++x11 compiler.
#define LOGOG_HASH std::tr1::hash
#ifdef LOGOG_HAS_UNORDERED_MAP
#ifdef LOGOG_USE_TR1
#include <tr1/unordered_map>
#else
#include <unordered_map>
#endif // LOGOG_USE_TR1
#ifdef _GLIBCXX_UNORDERED_MAP
#define LOGOG_UNORDERED_MAP std::unordered_map
#else // _GLIBCXX_UNORDERED_MAP
#define LOGOG_UNORDERED_MAP std::tr1::unordered_map
#endif // _GLIBCXX_UNORDERED_MAP
#else // LOGOG_HAS_UNORDERED_MAP
#include <hash_map>
#define LOGOG_UNORDERED_MAP std::hash_map
#endif // LOGOG_HAS_UNORDERED_MAP
#define LOGOG_INTERNAL_FAILURE abort();
/* ----------------------------------------------- */
/* Here's the stuff that's pretty standard in STL by now. */
#define LOGOG_PAIR std::pair
#include <list>
#define LOGOG_LIST std::list
#include <vector>
#define LOGOG_VECTOR std::vector
#include <set>
#define LOGOG_SET std::set
#define LOGOG_EQUAL_TO std::equal_to
  • mutex.hpp. You'll need to write macros for your own LOGOG_MUTEX_* calls:
#ifndef LOGOG_MUTEX
#ifdef LOGOG_FLAVOR_WINDOWS
#define LOGOG_MUTEX(x) CRITICAL_SECTION (x);
#define LOGOG_MUTEX_INIT(x) InitializeCriticalSection (x)
#define LOGOG_MUTEX_DELETE(x) DeleteCriticalSection (x)
#define LOGOG_MUTEX_LOCK(x) EnterCriticalSection (x)
#define LOGOG_MUTEX_UNLOCK(x) LeaveCriticalSection (x)
#define LOGOG_MUTEX_CTOR(x)
#endif // LOGOG_FLAVOR_WINDOWS
#ifdef LOGOG_FLAVOR_POSIX
#define LOGOG_MUTEX(x) pthread_mutex_t (x);
#define LOGOG_MUTEX_INIT(x) pthread_mutex_init(x, 0)
#define LOGOG_MUTEX_DELETE(x) pthread_mutex_destroy (x)
#define LOGOG_MUTEX_LOCK(x) pthread_mutex_lock (x)
#define LOGOG_MUTEX_UNLOCK(x) pthread_mutex_unlock (x)
#define LOGOG_MUTEX_CTOR(x)
#endif // LOGOG_FLAVOR_POSIX
#endif // LOGOG_MUTEX
#ifndef LOGOG_MUTEX
#error You need to define mutex macros for your platform; please see mutex.hpp
#endif
  • thread.hpp. Write macros for LOGOG_THREAD, LOGOG_THREAD_CREATE and LOGOG_THREAD_JOIN. Since logog does not actually initiate multiple threads, this step can technically be skipped; however, unless threads are implemented for a target platform, the unit tests will fail.
#ifndef LOGOG_THREAD
#if defined(LOGOG_FLAVOR_WINDOWS)
#include <process.h>
typedef unsigned int (WINAPI * __logog_pThreadFn)(void *);
/* 64-bit versions of Windows use 32-bit handles for interoperability. When
* sharing a handle between 32-bit and 64-bit applications, only the lower
* 32 bits are significant, so it is safe to truncate the handle (when passing
* it from 64-bit to 32-bit) or sign-extend the handle (when passing it from
* 32-bit to 64-bit)."
* source: https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203%28v=vs.85%29.aspx
*/
#define LOGOG_THREAD HANDLE
#define LOGOG_THREAD_CREATE(handle, attr, pStartFn, arg) \
(int)((*handle=(HANDLE) _beginthreadex (NULL, /* security */ \
0, /* stack size */ \
(__logog_pThreadFn)pStartFn, /* start address */ \
arg, /* pv argument */ \
0, /* init flag */ \
NULL /*thread addr */ ))==NULL)
#define LOGOG_THREAD_JOIN( thread ) \
( (WaitForSingleObject(( thread ),INFINITE)!=WAIT_OBJECT_0) \
|| !CloseHandle(thread) \
)
#define LOGOG_THREAD_SELF (LOGOG_THREAD)((size_t)GetCurrentThreadId())
#endif // defined(LOGOG_FLAVOR_WINDOWS)
#if defined(LOGOG_FLAVOR_POSIX)
#define LOGOG_THREAD \
pthread_t
#define LOGOG_THREAD_CREATE(handle, attr, pStartFn, arg) \
pthread_create(handle, attr, pStartFn, arg)
#define LOGOG_THREAD_JOIN(thread) \
pthread_join(thread, NULL)
#define LOGOG_THREAD_SELF \
pthread_self()
#endif
#endif // LOGOG_THREAD
#ifndef LOGOG_THREAD
#error You need to define mutex macros for your platform; please see mutex.hpp
#endif
  • timer.hpp. Add code for the Timer initializer and the Get() function.
{
#ifdef LOGOG_FLAVOR_WINDOWS
LARGE_INTEGER liTime;
QueryPerformanceCounter( &liTime );
double dusec;
dusec =( liTime.QuadPart / m_fTicksPerMicrosecond );
return ( dusec / 1000000.0f ) - m_fStartTime;
#endif
#ifdef LOGOG_FLAVOR_POSIX
#ifdef LOGOG_TARGET_PS3
LOGOG_PS3_GET_TIME;
#else // LOGOG_TARGET_PS3
// General Posix implementation
timeval tv;
gettimeofday( &tv, 0 );
return ((double) (tv.tv_sec) + ((double)(tv.tv_usec ) / 1000000.0 ) - m_fStartTime);
#endif // LOGOG_TARGET_PS3
#endif
}

Lastly, verify that unittest.cpp compiles and executes with a zero return code.