mirror of
https://github.com/boostorg/thread.git
synced 2026-02-15 01:22:08 +00:00
obsolete code
[SVN r33672]
This commit is contained in:
@@ -1,8 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#define TARGET_CARBON 1
|
||||
@@ -1,66 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#include "delivery_man.hpp"
|
||||
|
||||
#include "os.hpp"
|
||||
#include "execution_context.hpp"
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
delivery_man::delivery_man():
|
||||
m_pPackage(NULL),
|
||||
m_pSemaphore(kInvalidID),
|
||||
m_bPackageWaiting(false)
|
||||
{
|
||||
assert(at_st());
|
||||
|
||||
OSStatus lStatus = MPCreateSemaphore(1UL, 0UL, &m_pSemaphore);
|
||||
// TODO - throw on error here
|
||||
assert(lStatus == noErr);
|
||||
}
|
||||
|
||||
delivery_man::~delivery_man()
|
||||
{
|
||||
assert(m_bPackageWaiting == false);
|
||||
|
||||
OSStatus lStatus = MPDeleteSemaphore(m_pSemaphore);
|
||||
assert(lStatus == noErr);
|
||||
}
|
||||
|
||||
|
||||
void delivery_man::accept_deliveries()
|
||||
{
|
||||
if(m_bPackageWaiting)
|
||||
{
|
||||
assert(m_pPackage != NULL);
|
||||
m_pPackage->accept();
|
||||
m_pPackage = NULL;
|
||||
m_bPackageWaiting = false;
|
||||
|
||||
// signal to the thread making the call that we're done
|
||||
OSStatus lStatus = MPSignalSemaphore(m_pSemaphore);
|
||||
assert(lStatus == noErr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
@@ -1,84 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#ifndef BOOST_DELIVERY_MAN_MJM012402_HPP
|
||||
#define BOOST_DELIVERY_MAN_MJM012402_HPP
|
||||
|
||||
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
#include "package.hpp"
|
||||
|
||||
#include <Multiprocessing.h>
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
// class delivery_man is intended to move boost::function objects from MP tasks to
|
||||
// other execution contexts (such as deferred task time or system task time).
|
||||
|
||||
class delivery_man: private noncopyable
|
||||
{
|
||||
public:
|
||||
delivery_man();
|
||||
~delivery_man();
|
||||
|
||||
public:
|
||||
template<class R>
|
||||
R deliver(function<R> &rFunctor);
|
||||
|
||||
void accept_deliveries();
|
||||
|
||||
private:
|
||||
base_package *m_pPackage;
|
||||
mutex m_oMutex;
|
||||
MPSemaphoreID m_pSemaphore;
|
||||
bool m_bPackageWaiting;
|
||||
};
|
||||
|
||||
|
||||
template<class R>
|
||||
R delivery_man::deliver(function<R> &rFunctor)
|
||||
{
|
||||
assert(at_mp());
|
||||
|
||||
// lock our mutex
|
||||
mutex::scoped_lock oLock(m_oMutex);
|
||||
|
||||
// create a package and save it
|
||||
package<R> oPackage(rFunctor);
|
||||
m_pPackage = &oPackage;
|
||||
m_bPackageWaiting = true;
|
||||
|
||||
// wait on the semaphore
|
||||
OSStatus lStatus = MPWaitOnSemaphore(m_pSemaphore, kDurationForever);
|
||||
assert(lStatus == noErr);
|
||||
|
||||
return(oPackage.return_value());
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_DELIVERY_MAN_MJM012402_HPP
|
||||
@@ -1,93 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#include "dt_scheduler.hpp"
|
||||
|
||||
#include "ot_context.hpp"
|
||||
|
||||
|
||||
#include <boost/thread/detail/singleton.hpp>
|
||||
|
||||
#include <OpenTransportProtocol.h>
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
const OTTimeout k_ulTimerTaskDelay = 1UL;
|
||||
|
||||
|
||||
dt_scheduler::dt_scheduler():
|
||||
m_bReschedule(false),
|
||||
m_uppTask(NULL),
|
||||
m_lTask(0UL)
|
||||
{
|
||||
using ::boost::detail::thread::singleton;
|
||||
|
||||
ot_context &rContext(singleton<ot_context>::instance());
|
||||
|
||||
m_uppTask = NewOTProcessUPP(task_entry);
|
||||
m_lTask = OTCreateTimerTaskInContext(m_uppTask, this, rContext.get_context());
|
||||
}
|
||||
|
||||
dt_scheduler::~dt_scheduler()
|
||||
{
|
||||
OTDestroyTimerTask(m_lTask);
|
||||
m_lTask = 0UL;
|
||||
DisposeOTProcessUPP(m_uppTask);
|
||||
m_uppTask = NULL;
|
||||
}
|
||||
|
||||
|
||||
void dt_scheduler::start_polling()
|
||||
{
|
||||
m_bReschedule = true;
|
||||
schedule_task();
|
||||
}
|
||||
|
||||
void dt_scheduler::stop_polling()
|
||||
{
|
||||
m_bReschedule = false;
|
||||
}
|
||||
|
||||
|
||||
void dt_scheduler::schedule_task()
|
||||
{
|
||||
if(m_bReschedule)
|
||||
{
|
||||
OTScheduleTimerTask(m_lTask, k_ulTimerTaskDelay);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*static*/ pascal void dt_scheduler::task_entry(void *pRefCon)
|
||||
{
|
||||
dt_scheduler *pThis = reinterpret_cast<dt_scheduler *>(pRefCon);
|
||||
assert(pThis != NULL);
|
||||
pThis->task();
|
||||
}
|
||||
|
||||
void dt_scheduler::task()
|
||||
{
|
||||
periodic_function();
|
||||
schedule_task();
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
@@ -1,63 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#ifndef BOOST_DT_SCHEDULER_MJM012402_HPP
|
||||
#define BOOST_DT_SCHEDULER_MJM012402_HPP
|
||||
|
||||
|
||||
#include "periodical.hpp"
|
||||
|
||||
#include <OpenTransport.h>
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
// class dt_scheduler calls its pure-virtual periodic_function method periodically at
|
||||
// deferred task time. This is generally 1kHz under Mac OS 9.
|
||||
|
||||
class dt_scheduler
|
||||
{
|
||||
public:
|
||||
dt_scheduler();
|
||||
virtual ~dt_scheduler();
|
||||
|
||||
protected:
|
||||
void start_polling();
|
||||
void stop_polling();
|
||||
|
||||
private:
|
||||
virtual void periodic_function() = 0;
|
||||
|
||||
private:
|
||||
void schedule_task();
|
||||
static pascal void task_entry(void *pRefCon);
|
||||
void task();
|
||||
|
||||
private:
|
||||
bool m_bReschedule;
|
||||
OTProcessUPP m_uppTask;
|
||||
long m_lTask;
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_DT_SCHEDULER_MJM012402_HPP
|
||||
@@ -1,60 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#include <Debugging.h>
|
||||
#include <Multiprocessing.h>
|
||||
|
||||
#include "execution_context.hpp"
|
||||
#include "init.hpp"
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
|
||||
execution_context_t execution_context()
|
||||
{
|
||||
// make sure that MP services are available the first time through
|
||||
static bool bIgnored = detail::thread_init();
|
||||
|
||||
// first check if we're an MP task
|
||||
if(MPTaskIsPreemptive(kInvalidID))
|
||||
{
|
||||
return(k_eExecutionContextMPTask);
|
||||
}
|
||||
|
||||
#if TARGET_CARBON
|
||||
// Carbon has TaskLevel
|
||||
UInt32 ulLevel = TaskLevel();
|
||||
|
||||
if(ulLevel == 0UL)
|
||||
{
|
||||
return(k_eExecutionContextSystemTask);
|
||||
}
|
||||
|
||||
if(ulLevel & kInDeferredTaskMask)
|
||||
{
|
||||
return(k_eExecutionContextDeferredTask);
|
||||
}
|
||||
|
||||
return(k_eExecutionContextOther);
|
||||
#else
|
||||
// this can be implemented using TaskLevel if you don't mind linking against
|
||||
// DebugLib (and therefore breaking Mac OS 8.6 support), or CurrentExecutionLevel.
|
||||
# error execution_context unimplimented
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
@@ -1,47 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#ifndef BOOST_EXECUTION_CONTEXT_MJM012402_HPP
|
||||
#define BOOST_EXECUTION_CONTEXT_MJM012402_HPP
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
|
||||
// utility functions for figuring out what context your code is executing in.
|
||||
// Bear in mind that at_mp and in_blue are the only functions guarenteed by
|
||||
// Apple to work. There is simply no way of being sure that you will not get
|
||||
// false readings about task level at interrupt time in blue.
|
||||
|
||||
typedef enum {
|
||||
k_eExecutionContextSystemTask,
|
||||
k_eExecutionContextDeferredTask,
|
||||
k_eExecutionContextMPTask,
|
||||
k_eExecutionContextOther
|
||||
} execution_context_t;
|
||||
|
||||
execution_context_t execution_context();
|
||||
|
||||
inline bool at_st()
|
||||
{ return(execution_context() == k_eExecutionContextSystemTask); }
|
||||
|
||||
inline bool at_mp()
|
||||
{ return(execution_context() == k_eExecutionContextMPTask); }
|
||||
inline bool in_blue()
|
||||
{ return(!at_mp()); }
|
||||
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_EXECUTION_CONTEXT_MJM012402_HPP
|
||||
@@ -1,58 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#include "init.hpp"
|
||||
|
||||
#include "remote_call_manager.hpp"
|
||||
|
||||
|
||||
#include <boost/thread/detail/singleton.hpp>
|
||||
|
||||
#include <Multiprocessing.h>
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
// force these to get called by the end of static initialization time.
|
||||
static bool g_bInitialized = (thread_init() && create_singletons());
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool thread_init()
|
||||
{
|
||||
static bool bResult = MPLibraryIsLoaded();
|
||||
|
||||
return(bResult);
|
||||
}
|
||||
|
||||
bool create_singletons()
|
||||
{
|
||||
using ::boost::detail::thread::singleton;
|
||||
|
||||
singleton<remote_call_manager>::instance();
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
@@ -1,34 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#ifndef BOOST_INIT_MJM012402_HPP
|
||||
#define BOOST_INIT_MJM012402_HPP
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
bool thread_init();
|
||||
bool create_singletons();
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_INIT_MJM012402_HPP
|
||||
@@ -1,24 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
|
||||
#include <MacTypes.h>
|
||||
|
||||
#include "remote_calls.hpp"
|
||||
|
||||
// this function will be called when an assertion fails. We redirect the assertion
|
||||
// to DebugStr (MacsBug under Mac OS 1.x-9.x, Console under Mac OS X).
|
||||
void __assertion_failed(char const *pszAssertion, char const *pszFile, int nLine)
|
||||
{
|
||||
using std::snprintf;
|
||||
unsigned char strlDebug[sizeof(Str255) + 1];
|
||||
char *pszDebug = reinterpret_cast<char *>(&strlDebug[1]);
|
||||
strlDebug[0] = snprintf(pszDebug, sizeof(Str255), "assertion failed: \"%s\", %s, line %d", pszAssertion, pszFile, nLine);
|
||||
boost::threads::mac::dt_remote_call(DebugStr, static_cast<ConstStringPtr>(strlDebug));
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
//
|
||||
// includes
|
||||
//
|
||||
|
||||
#include <abort_exit.h>
|
||||
#include <console.h>
|
||||
#include <console_io.h>
|
||||
#include <misc_io.h>
|
||||
#include <SIOUX.h>
|
||||
|
||||
#include "remote_calls.hpp"
|
||||
|
||||
|
||||
//
|
||||
// using declarations
|
||||
//
|
||||
|
||||
using std::__file_handle;
|
||||
using std::__idle_proc;
|
||||
using std::__io_error;
|
||||
using std::__no_io_error;
|
||||
using std::size_t;
|
||||
|
||||
using boost::threads::mac::st_remote_call;
|
||||
|
||||
|
||||
//
|
||||
// prototypes
|
||||
//
|
||||
|
||||
static bool check_console();
|
||||
static int do_read_console(__file_handle ulHandle, unsigned char *pBuffer, size_t *pCount, __idle_proc pfnIdleProc);
|
||||
static int do_write_console(__file_handle ulHandle, unsigned char *pBuffer, size_t *pCount, __idle_proc pfnIdleProc);
|
||||
|
||||
|
||||
//
|
||||
// MSL function replacements
|
||||
//
|
||||
|
||||
// these two functions are called by cin and cout, respectively, as well as by (all?)
|
||||
// other functions in MSL that do console I/O. All that they do is as the remote
|
||||
// call manager to ensure that their guts are called at system task time.
|
||||
int __read_console(__file_handle handle, unsigned char * buffer, size_t * count, __idle_proc idle_proc)
|
||||
{
|
||||
return(st_remote_call(do_read_console, handle, buffer, count, idle_proc));
|
||||
}
|
||||
|
||||
int __write_console(__file_handle handle, unsigned char * buffer, size_t * count, __idle_proc idle_proc)
|
||||
{
|
||||
return(st_remote_call(do_write_console, handle, buffer, count, idle_proc));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
|
||||
static bool check_console()
|
||||
{
|
||||
static bool s_bHaveConsole(false);
|
||||
static bool s_bWontHaveConsole(false);
|
||||
|
||||
if(s_bHaveConsole)
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
|
||||
if(s_bWontHaveConsole == false)
|
||||
{
|
||||
__stdio_atexit();
|
||||
|
||||
if(InstallConsole(0) != 0)
|
||||
{
|
||||
s_bWontHaveConsole = true;
|
||||
return(false);
|
||||
}
|
||||
__console_exit = RemoveConsole;
|
||||
s_bHaveConsole = true;
|
||||
return(true);
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
int do_read_console(__file_handle /*ulHandle*/, unsigned char *pBuffer, size_t *pCount, __idle_proc /*pfnIdleProc*/)
|
||||
{
|
||||
assert(pCount != NULL);
|
||||
assert(pBuffer != NULL || *pCount == 0UL);
|
||||
|
||||
if(check_console() == false)
|
||||
{
|
||||
return(__io_error);
|
||||
}
|
||||
std::fflush(stdout);
|
||||
long lCount = ReadCharsFromConsole(reinterpret_cast<char *>(pBuffer), static_cast<long>(*pCount));
|
||||
*pCount = static_cast<size_t>(lCount);
|
||||
if(lCount == -1L)
|
||||
{
|
||||
return(__io_error);
|
||||
}
|
||||
|
||||
return(__no_io_error);
|
||||
}
|
||||
|
||||
int do_write_console(__file_handle /*ulHandle*/, unsigned char *pBuffer, size_t *pCount, __idle_proc /*pfnIdleProc*/)
|
||||
{
|
||||
if(check_console() == false)
|
||||
{
|
||||
return(__io_error);
|
||||
}
|
||||
|
||||
long lCount = WriteCharsToConsole(reinterpret_cast<char *>(pBuffer), static_cast<long>(*pCount));
|
||||
*pCount = static_cast<size_t>(lCount);
|
||||
if(lCount == -1L)
|
||||
{
|
||||
return(__io_error);
|
||||
}
|
||||
|
||||
return(__no_io_error);
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
//
|
||||
// includes
|
||||
//
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <Multiprocessing.h>
|
||||
|
||||
|
||||
//
|
||||
// using declarations
|
||||
//
|
||||
|
||||
using std::size_t;
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
//
|
||||
// prototypes
|
||||
//
|
||||
|
||||
void *malloc(size_t ulSize);
|
||||
void free(void *pBlock);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// MSL function replacements
|
||||
//
|
||||
|
||||
// all allocation/deallocation currently goes through MPAllocateAligned/MPFree. This
|
||||
// solution is sub-optimal at best, but will have to do for now.
|
||||
void *malloc(size_t ulSize)
|
||||
{
|
||||
static bool bIgnored = MPLibraryIsLoaded();
|
||||
return(MPAllocateAligned(ulSize, kMPAllocateDefaultAligned, 0UL));
|
||||
}
|
||||
|
||||
void free(void *pBlock)
|
||||
{
|
||||
if(pBlock == NULL) return;
|
||||
MPFree(pBlock);
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
//
|
||||
// includes
|
||||
//
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <Multiprocessing.h>
|
||||
|
||||
|
||||
//
|
||||
// using declarations
|
||||
//
|
||||
|
||||
using std::size_t;
|
||||
using std::bad_alloc;
|
||||
using std::nothrow_t;
|
||||
using std::nothrow;
|
||||
|
||||
|
||||
//
|
||||
// local utility functions
|
||||
//
|
||||
|
||||
// all allocation/deallocation currently goes through MPAllocateAligned/MPFree. This
|
||||
// solution is sub-optimal at best, but will have to do for now.
|
||||
inline static void *allocate(size_t ulSize, const nothrow_t &)
|
||||
{
|
||||
static bool bIgnored = MPLibraryIsLoaded();
|
||||
return(MPAllocateAligned(ulSize, kMPAllocateDefaultAligned, 0UL));
|
||||
}
|
||||
|
||||
inline static void *allocate(size_t ulSize)
|
||||
{
|
||||
void *pBlock = allocate(ulSize, nothrow);
|
||||
if(pBlock == NULL)
|
||||
throw(bad_alloc());
|
||||
return(pBlock);
|
||||
}
|
||||
|
||||
inline static void deallocate(void *pBlock)
|
||||
{
|
||||
if(pBlock == NULL) return;
|
||||
MPFree(pBlock);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// global operators
|
||||
//
|
||||
|
||||
void *operator new(size_t ulSize)
|
||||
{
|
||||
return(allocate(ulSize));
|
||||
}
|
||||
|
||||
void *operator new[](size_t ulSize)
|
||||
{
|
||||
return(allocate(ulSize));
|
||||
}
|
||||
|
||||
|
||||
void *operator new(size_t ulSize, const nothrow_t &rNoThrow)
|
||||
{
|
||||
return(allocate(ulSize, rNoThrow));
|
||||
}
|
||||
|
||||
void *operator new[](size_t ulSize, const nothrow_t &rNoThrow)
|
||||
{
|
||||
return(allocate(ulSize, rNoThrow));
|
||||
}
|
||||
|
||||
|
||||
void operator delete(void *pBlock)
|
||||
{
|
||||
deallocate(pBlock);
|
||||
}
|
||||
|
||||
void operator delete[](void *pBlock)
|
||||
{
|
||||
deallocate(pBlock);
|
||||
}
|
||||
|
||||
|
||||
void operator delete(void *pBlock, const nothrow_t &)
|
||||
{
|
||||
deallocate(pBlock);
|
||||
}
|
||||
|
||||
void operator delete[](void *pBlock, const nothrow_t &)
|
||||
{
|
||||
deallocate(pBlock);
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#include <cassert>
|
||||
// we include timesize.mac.h to get whether or not __TIMESIZE_DOUBLE__ is
|
||||
// defined. This is not safe, given that __TIMESIZE_DOUBLE__ affects MSL
|
||||
// at MSL's compile time, not ours, so be forgiving if you have changed it
|
||||
// since you have built MSL.
|
||||
#include <timesize.mac.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <boost/thread/detail/force_cast.hpp>
|
||||
#include <boost/thread/xtime.hpp>
|
||||
|
||||
#include "execution_context.hpp"
|
||||
|
||||
#include <DriverServices.h>
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
clock_t __get_clock();
|
||||
time_t __get_time();
|
||||
int __to_gm_time(time_t *pTime);
|
||||
int __is_dst();
|
||||
}
|
||||
|
||||
|
||||
static inline uint64_t get_nanoseconds()
|
||||
{
|
||||
using boost::detail::thread::force_cast;
|
||||
return(force_cast<uint64_t>(AbsoluteToNanoseconds(UpTime())));
|
||||
}
|
||||
|
||||
|
||||
#ifdef __TIMESIZE_DOUBLE__
|
||||
|
||||
// return number of microseconds since startup as a double
|
||||
clock_t __get_clock()
|
||||
{
|
||||
static const double k_dNanosecondsPerMicrosecond(1000.0);
|
||||
|
||||
return(get_nanoseconds() / k_dNanosecondsPerMicrosecond);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// return number of ticks (60th of a second) since startup as a long
|
||||
clock_t __get_clock()
|
||||
{
|
||||
static const uint64_t k_ullTicksPerSecond(60ULL);
|
||||
static const uint64_t k_ullNanosecondsPerSecond(1000ULL * 1000ULL * 1000ULL);
|
||||
static const uint64_t k_ullNanosecondsPerTick(k_ullNanosecondsPerSecond / k_ullTicksPerSecond);
|
||||
|
||||
return(get_nanoseconds() / k_ullNanosecondsPerTick);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// return number of seconds elapsed since Jan 1, 1970
|
||||
time_t __get_time()
|
||||
{
|
||||
boost::xtime sTime;
|
||||
int nType = boost::xtime_get(&sTime, boost::TIME_UTC);
|
||||
assert(nType == boost::TIME_UTC);
|
||||
return(static_cast<time_t>(sTime.sec));
|
||||
}
|
||||
|
||||
|
||||
static inline MachineLocation &read_location()
|
||||
{
|
||||
static MachineLocation s_sLocation;
|
||||
assert(boost::threads::mac::at_st());
|
||||
ReadLocation(&s_sLocation);
|
||||
return(s_sLocation);
|
||||
}
|
||||
|
||||
static inline MachineLocation &get_location()
|
||||
{
|
||||
static MachineLocation &s_rLocation(read_location());
|
||||
return(s_rLocation);
|
||||
}
|
||||
|
||||
|
||||
// force the machine location to be cached at static initlialization
|
||||
static MachineLocation &g_rIgnored(get_location());
|
||||
|
||||
static inline long calculate_delta()
|
||||
{
|
||||
MachineLocation &rLocation(get_location());
|
||||
|
||||
// gmtDelta is a 24-bit, signed integer. We need to strip out the lower 24 bits,
|
||||
// then sign-extend what we have.
|
||||
long lDelta = rLocation.u.gmtDelta & 0x00ffffffL;
|
||||
if((lDelta & 0x00800000L) != 0L)
|
||||
{
|
||||
lDelta |= 0xFF000000;
|
||||
}
|
||||
return(lDelta);
|
||||
}
|
||||
|
||||
static inline bool check_if_location_is_broken()
|
||||
{
|
||||
MachineLocation &rLocation(get_location());
|
||||
if(rLocation.latitude == 0 && rLocation.longitude == 0 && rLocation.u.gmtDelta == 0)
|
||||
return(true);
|
||||
return(false);
|
||||
}
|
||||
|
||||
static inline bool location_is_broken()
|
||||
{
|
||||
static bool s_bLocationIsBroken(check_if_location_is_broken());
|
||||
return(s_bLocationIsBroken);
|
||||
}
|
||||
|
||||
|
||||
// translate time to GMT
|
||||
int __to_gm_time(time_t *pTime)
|
||||
{
|
||||
if(location_is_broken())
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
static long s_lDelta(calculate_delta());
|
||||
*pTime -= s_lDelta;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static inline bool is_daylight_savings_time()
|
||||
{
|
||||
MachineLocation &rLocation(get_location());
|
||||
return(rLocation.u.dlsDelta != 0);
|
||||
}
|
||||
|
||||
// check if we're in daylight savings time
|
||||
int __is_dst()
|
||||
{
|
||||
if(location_is_broken())
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
static bool bIsDaylightSavingsTime(is_daylight_savings_time());
|
||||
return(static_cast<int>(bIsDaylightSavingsTime));
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#include "os.hpp"
|
||||
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <Gestalt.h>
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace os {
|
||||
|
||||
|
||||
// read the OS version from Gestalt
|
||||
static inline long get_version()
|
||||
{
|
||||
long lVersion;
|
||||
OSErr nErr = Gestalt(gestaltSystemVersion, &lVersion);
|
||||
assert(nErr == noErr);
|
||||
return(lVersion);
|
||||
}
|
||||
|
||||
|
||||
// check if we're running under Mac OS X and cache that information
|
||||
bool x()
|
||||
{
|
||||
static bool bX = (version() >= 0x1000);
|
||||
return(bX);
|
||||
}
|
||||
|
||||
|
||||
// read the OS version and cache it
|
||||
long version()
|
||||
{
|
||||
static long lVersion = get_version();
|
||||
return(lVersion);
|
||||
}
|
||||
|
||||
|
||||
} // namespace os
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
@@ -1,37 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#ifndef BOOST_OS_MJM012402_HPP
|
||||
#define BOOST_OS_MJM012402_HPP
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace os {
|
||||
|
||||
|
||||
// functions to determine the OS environment. With namespaces, you get a cute call:
|
||||
// mac::os::x
|
||||
|
||||
bool x();
|
||||
long version();
|
||||
|
||||
|
||||
} // namespace os
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_OS_MJM012402_HPP
|
||||
@@ -1,46 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#include "ot_context.hpp"
|
||||
|
||||
#include "execution_context.hpp"
|
||||
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
ot_context::ot_context()
|
||||
{
|
||||
assert(at_st());
|
||||
|
||||
OSStatus lStatus = InitOpenTransportInContext(0UL, &m_pContext);
|
||||
// TODO - throw on error
|
||||
assert(lStatus == noErr);
|
||||
}
|
||||
|
||||
ot_context::~ot_context()
|
||||
{
|
||||
CloseOpenTransportInContext(m_pContext);
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
@@ -1,58 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#ifndef BOOST_OT_CONTEXT_MJM012402_HPP
|
||||
#define BOOST_OT_CONTEXT_MJM012402_HPP
|
||||
|
||||
|
||||
#include <OpenTransport.h>
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
// class ot_context is intended to be used only as a singleton. All that this class
|
||||
// does is ask OpenTransport to create him an OTClientContextPtr, and then doles
|
||||
// this out to anyone who wants it. ot_context should only be instantiated at
|
||||
// system task time.
|
||||
|
||||
class ot_context: private noncopyable
|
||||
{
|
||||
protected:
|
||||
ot_context();
|
||||
~ot_context();
|
||||
|
||||
public:
|
||||
OTClientContextPtr get_context();
|
||||
|
||||
private:
|
||||
OTClientContextPtr m_pContext;
|
||||
};
|
||||
|
||||
|
||||
inline OTClientContextPtr ot_context::get_context()
|
||||
{ return(m_pContext); }
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_OT_CONTEXT_MJM012402_HPP
|
||||
@@ -1,76 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#ifndef BOOST_PACKAGE_MJM012402_HPP
|
||||
#define BOOST_PACKAGE_MJM012402_HPP
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
class base_package: private noncopyable
|
||||
{
|
||||
public:
|
||||
virtual void accept() = 0;
|
||||
};
|
||||
|
||||
template<class R>
|
||||
class package: public base_package
|
||||
{
|
||||
public:
|
||||
inline package(function<R> &rFunctor):
|
||||
m_rFunctor(rFunctor)
|
||||
{ /* no-op */ }
|
||||
inline ~package()
|
||||
{ /* no-op */ }
|
||||
|
||||
virtual void accept()
|
||||
{ m_oR = m_rFunctor(); }
|
||||
inline R return_value()
|
||||
{ return(m_oR); }
|
||||
|
||||
private:
|
||||
function<R> &m_rFunctor;
|
||||
R m_oR;
|
||||
};
|
||||
|
||||
template<>
|
||||
class package<void>: public base_package
|
||||
{
|
||||
public:
|
||||
inline package(function<void> &rFunctor):
|
||||
m_rFunctor(rFunctor)
|
||||
{ /* no-op */ }
|
||||
inline ~package()
|
||||
{ /* no-op */ }
|
||||
|
||||
virtual void accept()
|
||||
{ m_rFunctor(); }
|
||||
inline void return_value()
|
||||
{ return; }
|
||||
|
||||
private:
|
||||
function<void> &m_rFunctor;
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_PACKAGE_MJM012402_HPP
|
||||
@@ -1,97 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#ifndef BOOST_PERIODICAL_MJM012402_HPP
|
||||
#define BOOST_PERIODICAL_MJM012402_HPP
|
||||
|
||||
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
// class periodical inherits from its template parameter, which should follow the
|
||||
// pattern set by classes dt_scheduler and st_scheduler. periodical knows how to
|
||||
// call a boost::function, where the xx_scheduler classes only know to to call a
|
||||
// member periodically.
|
||||
|
||||
template<class Scheduler>
|
||||
class periodical: private noncopyable, private Scheduler
|
||||
{
|
||||
public:
|
||||
periodical(function<void> &rFunction);
|
||||
~periodical();
|
||||
|
||||
public:
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
protected:
|
||||
virtual void periodic_function();
|
||||
|
||||
private:
|
||||
function<void> m_oFunction;
|
||||
};
|
||||
|
||||
|
||||
template<class Scheduler>
|
||||
periodical<Scheduler>::periodical(function<void> &rFunction):
|
||||
m_oFunction(rFunction)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
template<class Scheduler>
|
||||
periodical<Scheduler>::~periodical()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
template<class Scheduler>
|
||||
void periodical<Scheduler>::start()
|
||||
{
|
||||
start_polling();
|
||||
}
|
||||
|
||||
template<class Scheduler>
|
||||
void periodical<Scheduler>::stop()
|
||||
{
|
||||
stop_polling();
|
||||
}
|
||||
|
||||
|
||||
template<class Scheduler>
|
||||
inline void periodical<Scheduler>::periodic_function()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_oFunction();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_PERIODICAL_MJM012402_HPP
|
||||
@@ -1,9 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#define NDEBUG
|
||||
#define TARGET_CARBON 1
|
||||
@@ -1,48 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#include "remote_call_manager.hpp"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
using detail::delivery_man;
|
||||
|
||||
|
||||
remote_call_manager::remote_call_manager():
|
||||
m_oDTDeliveryMan(),
|
||||
m_oSTDeliveryMan(),
|
||||
m_oDTFunction(bind(&delivery_man::accept_deliveries, &m_oDTDeliveryMan)),
|
||||
m_oSTFunction(bind(&delivery_man::accept_deliveries, &m_oSTDeliveryMan)),
|
||||
m_oDTPeriodical(m_oDTFunction),
|
||||
m_oSTPeriodical(m_oSTFunction)
|
||||
{
|
||||
m_oDTPeriodical.start();
|
||||
m_oSTPeriodical.start();
|
||||
}
|
||||
|
||||
remote_call_manager::~remote_call_manager()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
@@ -1,102 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#ifndef BOOST_REMOTE_CALL_MANAGER_MJM012402_HPP
|
||||
#define BOOST_REMOTE_CALL_MANAGER_MJM012402_HPP
|
||||
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
#include "delivery_man.hpp"
|
||||
#include "dt_scheduler.hpp"
|
||||
#include "periodical.hpp"
|
||||
#include "execution_context.hpp"
|
||||
#include "st_scheduler.hpp"
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
// class remote_call_manager is used by the remote call functions (dt_remote_call and
|
||||
// st_remote_call) to execute functions in non-MP contexts.
|
||||
|
||||
class remote_call_manager: private noncopyable
|
||||
{
|
||||
protected:
|
||||
remote_call_manager();
|
||||
~remote_call_manager();
|
||||
|
||||
public:
|
||||
template<class R>
|
||||
R execute_at_dt(function<R> &rFunctor);
|
||||
template<class R>
|
||||
R execute_at_st(function<R> &rFunctor);
|
||||
|
||||
private:
|
||||
template<class R>
|
||||
static R execute_now(function<R> &rFunctor);
|
||||
|
||||
private:
|
||||
delivery_man m_oDTDeliveryMan;
|
||||
delivery_man m_oSTDeliveryMan;
|
||||
function<void> m_oDTFunction;
|
||||
function<void> m_oSTFunction;
|
||||
periodical<dt_scheduler> m_oDTPeriodical;
|
||||
periodical<st_scheduler> m_oSTPeriodical;
|
||||
};
|
||||
|
||||
|
||||
template<class R>
|
||||
/*static*/ inline R remote_call_manager::execute_now(function<R> &rFunctor)
|
||||
{
|
||||
return(rFunctor());
|
||||
}
|
||||
template<>
|
||||
/*static*/ inline void remote_call_manager::execute_now<void>(function<void> &rFunctor)
|
||||
{
|
||||
rFunctor();
|
||||
}
|
||||
|
||||
|
||||
template<class R>
|
||||
inline R remote_call_manager::execute_at_dt(function<R> &rFunctor)
|
||||
{
|
||||
if(at_mp())
|
||||
{
|
||||
return(m_oDTDeliveryMan.deliver(rFunctor));
|
||||
}
|
||||
return(execute_now(rFunctor));
|
||||
}
|
||||
|
||||
template<class R>
|
||||
inline R remote_call_manager::execute_at_st(function<R> &rFunctor)
|
||||
{
|
||||
if(at_mp())
|
||||
{
|
||||
return(m_oSTDeliveryMan.deliver(rFunctor));
|
||||
}
|
||||
assert(at_st());
|
||||
return(execute_now(rFunctor));
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_REMOTE_CALL_MANAGER_MJM012402_HPP
|
||||
@@ -1,157 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#ifndef BOOST_REMOTE_CALLS_MJM012402_HPP
|
||||
#define BOOST_REMOTE_CALLS_MJM012402_HPP
|
||||
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include "remote_call_manager.hpp"
|
||||
#include <boost/thread/detail/singleton.hpp>
|
||||
|
||||
|
||||
// this file contains macros to generate functions with the signatures:
|
||||
// ReturnType st_remote_call([pascal] ReturnType (*pfnFunction)(
|
||||
// [Argument1Type[, Argument2Type[...]]])
|
||||
// [, Argument1Type oArgument1[, Argument2Type oArgument2[...]]])
|
||||
// and
|
||||
// ReturnType dt_remote_call([pascal] ReturnType (*pfnFunction)(
|
||||
// [Argument1Type[, Argument2Type[...]]])
|
||||
// [, Argument1Type oArgument1[, Argument2Type oArgument2[...]]])
|
||||
// in other words, identical to the function pointer versions of boost::bind, but
|
||||
// with the return type returned. The purpose of these functions is to be able to
|
||||
// request that a function be called at system task time or deferred task time, then
|
||||
// sleep until it is called, and finally get back its return value.
|
||||
|
||||
#define BOOST_REMOTE_CALL_CLASS_LIST_0
|
||||
#define BOOST_REMOTE_CALL_CLASS_LIST_1 BOOST_REMOTE_CALL_CLASS_LIST_0, class A1
|
||||
#define BOOST_REMOTE_CALL_CLASS_LIST_2 BOOST_REMOTE_CALL_CLASS_LIST_1, class A2
|
||||
#define BOOST_REMOTE_CALL_CLASS_LIST_3 BOOST_REMOTE_CALL_CLASS_LIST_2, class A3
|
||||
#define BOOST_REMOTE_CALL_CLASS_LIST_4 BOOST_REMOTE_CALL_CLASS_LIST_3, class A4
|
||||
#define BOOST_REMOTE_CALL_CLASS_LIST_5 BOOST_REMOTE_CALL_CLASS_LIST_4, class A5
|
||||
#define BOOST_REMOTE_CALL_CLASS_LIST_6 BOOST_REMOTE_CALL_CLASS_LIST_5, class A6
|
||||
#define BOOST_REMOTE_CALL_CLASS_LIST_7 BOOST_REMOTE_CALL_CLASS_LIST_6, class A7
|
||||
#define BOOST_REMOTE_CALL_CLASS_LIST_8 BOOST_REMOTE_CALL_CLASS_LIST_7, class A8
|
||||
#define BOOST_REMOTE_CALL_CLASS_LIST_9 BOOST_REMOTE_CALL_CLASS_LIST_8, class A9
|
||||
|
||||
|
||||
#define BOOST_REMOTE_CALL_ARGUMENT_LIST_0
|
||||
#define BOOST_REMOTE_CALL_ARGUMENT_LIST_1 BOOST_REMOTE_CALL_ARGUMENT_LIST_0 A1 oA1
|
||||
#define BOOST_REMOTE_CALL_ARGUMENT_LIST_2 BOOST_REMOTE_CALL_ARGUMENT_LIST_1, A2 oA2
|
||||
#define BOOST_REMOTE_CALL_ARGUMENT_LIST_3 BOOST_REMOTE_CALL_ARGUMENT_LIST_2, A3 oA3
|
||||
#define BOOST_REMOTE_CALL_ARGUMENT_LIST_4 BOOST_REMOTE_CALL_ARGUMENT_LIST_3, A4 oA4
|
||||
#define BOOST_REMOTE_CALL_ARGUMENT_LIST_5 BOOST_REMOTE_CALL_ARGUMENT_LIST_4, A5 oA5
|
||||
#define BOOST_REMOTE_CALL_ARGUMENT_LIST_6 BOOST_REMOTE_CALL_ARGUMENT_LIST_5, A6 oA6
|
||||
#define BOOST_REMOTE_CALL_ARGUMENT_LIST_7 BOOST_REMOTE_CALL_ARGUMENT_LIST_6, A7 oA7
|
||||
#define BOOST_REMOTE_CALL_ARGUMENT_LIST_8 BOOST_REMOTE_CALL_ARGUMENT_LIST_7, A8 oA8
|
||||
#define BOOST_REMOTE_CALL_ARGUMENT_LIST_9 BOOST_REMOTE_CALL_ARGUMENT_LIST_8, A9 oA9
|
||||
|
||||
|
||||
#define BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_0
|
||||
#define BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_1 BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_0, oA1
|
||||
#define BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_2 BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_1, oA2
|
||||
#define BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_3 BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_2, oA3
|
||||
#define BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_4 BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_3, oA4
|
||||
#define BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_5 BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_4, oA5
|
||||
#define BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_6 BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_5, oA6
|
||||
#define BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_7 BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_6, oA7
|
||||
#define BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_8 BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_7, oA8
|
||||
#define BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_9 BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_8, oA9
|
||||
|
||||
|
||||
#define BOOST_REMOTE_CALL_COMMA_0
|
||||
#define BOOST_REMOTE_CALL_COMMA_1 ,
|
||||
#define BOOST_REMOTE_CALL_COMMA_2 ,
|
||||
#define BOOST_REMOTE_CALL_COMMA_3 ,
|
||||
#define BOOST_REMOTE_CALL_COMMA_4 ,
|
||||
#define BOOST_REMOTE_CALL_COMMA_5 ,
|
||||
#define BOOST_REMOTE_CALL_COMMA_6 ,
|
||||
#define BOOST_REMOTE_CALL_COMMA_7 ,
|
||||
#define BOOST_REMOTE_CALL_COMMA_8 ,
|
||||
#define BOOST_REMOTE_CALL_COMMA_9 ,
|
||||
|
||||
|
||||
// this is the macro that ties it all together. From here, we generate all forms of
|
||||
// dt_remote_call and st_remote_call.
|
||||
|
||||
#define BOOST_REMOTE_CALL(context, stack, n) \
|
||||
template<class R BOOST_REMOTE_CALL_CLASS_LIST_ ## n> \
|
||||
inline R context ## _remote_call(stack R (*pfnF)( \
|
||||
BOOST_REMOTE_CALL_ARGUMENT_LIST_ ## n) \
|
||||
BOOST_REMOTE_CALL_COMMA_ ## n \
|
||||
BOOST_REMOTE_CALL_ARGUMENT_LIST_ ## n) \
|
||||
{ \
|
||||
using ::boost::detail::thread::singleton; \
|
||||
using detail::remote_call_manager; \
|
||||
function<R> oFunc(bind(pfnF BOOST_REMOTE_CALL_FUNCTION_ARGUMENT_LIST_ ## n)); \
|
||||
remote_call_manager &rManager(singleton<remote_call_manager>::instance()); \
|
||||
return(rManager.execute_at_ ## context(oFunc)); \
|
||||
}
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
|
||||
BOOST_REMOTE_CALL(st, , 0)
|
||||
BOOST_REMOTE_CALL(st, , 1)
|
||||
BOOST_REMOTE_CALL(st, , 2)
|
||||
BOOST_REMOTE_CALL(st, , 3)
|
||||
BOOST_REMOTE_CALL(st, , 4)
|
||||
BOOST_REMOTE_CALL(st, , 5)
|
||||
BOOST_REMOTE_CALL(st, , 6)
|
||||
BOOST_REMOTE_CALL(st, , 7)
|
||||
BOOST_REMOTE_CALL(st, , 8)
|
||||
BOOST_REMOTE_CALL(st, , 9)
|
||||
|
||||
BOOST_REMOTE_CALL(dt, , 0)
|
||||
BOOST_REMOTE_CALL(dt, , 1)
|
||||
BOOST_REMOTE_CALL(dt, , 2)
|
||||
BOOST_REMOTE_CALL(dt, , 3)
|
||||
BOOST_REMOTE_CALL(dt, , 4)
|
||||
BOOST_REMOTE_CALL(dt, , 5)
|
||||
BOOST_REMOTE_CALL(dt, , 6)
|
||||
BOOST_REMOTE_CALL(dt, , 7)
|
||||
BOOST_REMOTE_CALL(dt, , 8)
|
||||
BOOST_REMOTE_CALL(dt, , 9)
|
||||
|
||||
|
||||
BOOST_REMOTE_CALL(st, pascal, 0)
|
||||
BOOST_REMOTE_CALL(st, pascal, 1)
|
||||
BOOST_REMOTE_CALL(st, pascal, 2)
|
||||
BOOST_REMOTE_CALL(st, pascal, 3)
|
||||
BOOST_REMOTE_CALL(st, pascal, 4)
|
||||
BOOST_REMOTE_CALL(st, pascal, 5)
|
||||
BOOST_REMOTE_CALL(st, pascal, 6)
|
||||
BOOST_REMOTE_CALL(st, pascal, 7)
|
||||
BOOST_REMOTE_CALL(st, pascal, 8)
|
||||
BOOST_REMOTE_CALL(st, pascal, 9)
|
||||
|
||||
BOOST_REMOTE_CALL(dt, pascal, 0)
|
||||
BOOST_REMOTE_CALL(dt, pascal, 1)
|
||||
BOOST_REMOTE_CALL(dt, pascal, 2)
|
||||
BOOST_REMOTE_CALL(dt, pascal, 3)
|
||||
BOOST_REMOTE_CALL(dt, pascal, 4)
|
||||
BOOST_REMOTE_CALL(dt, pascal, 5)
|
||||
BOOST_REMOTE_CALL(dt, pascal, 6)
|
||||
BOOST_REMOTE_CALL(dt, pascal, 7)
|
||||
BOOST_REMOTE_CALL(dt, pascal, 8)
|
||||
BOOST_REMOTE_CALL(dt, pascal, 9)
|
||||
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_REMOTE_CALLS_MJM012402_HPP
|
||||
210
src/mac/safe.cpp
210
src/mac/safe.cpp
@@ -1,210 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#include <DriverServices.h>
|
||||
#include <Events.h>
|
||||
#include <Multiprocessing.h>
|
||||
#include <Threads.h>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/function.hpp>
|
||||
|
||||
#include <boost/thread/detail/force_cast.hpp>
|
||||
#include <limits>
|
||||
#include "execution_context.hpp"
|
||||
|
||||
|
||||
using boost::detail::thread::force_cast;
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
static OSStatus safe_wait(function<OSStatus, Duration> &rFunction, Duration lDuration);
|
||||
|
||||
|
||||
// we call WNE to allow tasks that own the resource the blue is waiting on system
|
||||
// task time, in case they are blocked on an ST remote call (or a memory allocation
|
||||
// for that matter).
|
||||
static void idle()
|
||||
{
|
||||
if(at_st())
|
||||
{
|
||||
EventRecord sEvent;
|
||||
bool bEvent = WaitNextEvent(0U, &sEvent, 0UL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
OSStatus safe_wait_on_semaphore(MPSemaphoreID pSemaphoreID, Duration lDuration)
|
||||
{
|
||||
function<OSStatus, Duration> oWaitOnSemaphore;
|
||||
oWaitOnSemaphore = bind(MPWaitOnSemaphore, pSemaphoreID, _1);
|
||||
return(safe_wait(oWaitOnSemaphore, lDuration));
|
||||
}
|
||||
|
||||
|
||||
OSStatus safe_enter_critical_region(MPCriticalRegionID pCriticalRegionID, Duration lDuration, MPCriticalRegionID pCriticalRegionCriticalRegionID/* = kInvalidID*/)
|
||||
{
|
||||
if(pCriticalRegionCriticalRegionID != kInvalidID)
|
||||
{
|
||||
if(at_mp())
|
||||
{
|
||||
// enter the critical region's critical region
|
||||
OSStatus lStatus = noErr;
|
||||
AbsoluteTime sExpiration;
|
||||
if(lDuration != kDurationImmediate && lDuration != kDurationForever)
|
||||
{
|
||||
sExpiration = AddDurationToAbsolute(lDuration, UpTime());
|
||||
}
|
||||
lStatus = MPEnterCriticalRegion(pCriticalRegionCriticalRegionID, lDuration);
|
||||
assert(lStatus == noErr || lStatus == kMPTimeoutErr);
|
||||
if(lStatus == noErr)
|
||||
{
|
||||
// calculate a new duration
|
||||
if(lDuration != kDurationImmediate && lDuration != kDurationForever)
|
||||
{
|
||||
// check if we have any time left
|
||||
AbsoluteTime sUpTime(UpTime());
|
||||
if(force_cast<uint64_t>(sExpiration) > force_cast<uint64_t>(sUpTime))
|
||||
{
|
||||
// reset our duration to our remaining time
|
||||
lDuration = AbsoluteDeltaToDuration(sExpiration, sUpTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
// no time left
|
||||
lDuration = kDurationImmediate;
|
||||
}
|
||||
}
|
||||
// if we entered the critical region, exit it again
|
||||
lStatus = MPExitCriticalRegion(pCriticalRegionCriticalRegionID);
|
||||
assert(lStatus == noErr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise, give up
|
||||
return(lStatus);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we're at system task time, try to enter the critical region's critical
|
||||
// region until we succeed. MP tasks will block on this until we let it go.
|
||||
OSStatus lStatus;
|
||||
do
|
||||
{
|
||||
lStatus = MPEnterCriticalRegion(pCriticalRegionCriticalRegionID, kDurationImmediate);
|
||||
} while(lStatus == kMPTimeoutErr);
|
||||
assert(lStatus == noErr);
|
||||
}
|
||||
}
|
||||
|
||||
// try to enter the critical region
|
||||
function<OSStatus, Duration> oEnterCriticalRegion;
|
||||
oEnterCriticalRegion = bind(MPEnterCriticalRegion, pCriticalRegionID, _1);
|
||||
OSStatus lStatus = safe_wait(oEnterCriticalRegion, lDuration);
|
||||
|
||||
// if we entered the critical region's critical region to get the critical region,
|
||||
// exit the critical region's critical region.
|
||||
if(pCriticalRegionCriticalRegionID != kInvalidID && at_mp() == false)
|
||||
{
|
||||
lStatus = MPExitCriticalRegion(pCriticalRegionCriticalRegionID);
|
||||
assert(lStatus == noErr);
|
||||
}
|
||||
return(lStatus);
|
||||
}
|
||||
|
||||
OSStatus safe_wait_on_queue(MPQueueID pQueueID, void **pParam1, void **pParam2, void **pParam3, Duration lDuration)
|
||||
{
|
||||
function<OSStatus, Duration> oWaitOnQueue;
|
||||
oWaitOnQueue = bind(MPWaitOnQueue, pQueueID, pParam1, pParam2, pParam3, _1);
|
||||
return(safe_wait(oWaitOnQueue, lDuration));
|
||||
}
|
||||
|
||||
OSStatus safe_delay_until(AbsoluteTime *pWakeUpTime)
|
||||
{
|
||||
if(execution_context() == k_eExecutionContextMPTask)
|
||||
{
|
||||
return(MPDelayUntil(pWakeUpTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t ullWakeUpTime = force_cast<uint64_t>(*pWakeUpTime);
|
||||
|
||||
while(force_cast<uint64_t>(UpTime()) < ullWakeUpTime)
|
||||
{
|
||||
idle();
|
||||
}
|
||||
|
||||
return(noErr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
OSStatus safe_wait(function<OSStatus, Duration> &rFunction, Duration lDuration)
|
||||
{
|
||||
if(execution_context() == k_eExecutionContextMPTask)
|
||||
{
|
||||
return(rFunction(lDuration));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t ullExpiration = 0ULL;
|
||||
|
||||
// get the expiration time in UpTime units
|
||||
if(lDuration == kDurationForever)
|
||||
{
|
||||
ullExpiration = (::std::numeric_limits<uint64_t>::max)();
|
||||
}
|
||||
else if(lDuration == kDurationImmediate)
|
||||
{
|
||||
ullExpiration = force_cast<uint64_t>(UpTime());
|
||||
}
|
||||
else
|
||||
{
|
||||
AbsoluteTime sExpiration = AddDurationToAbsolute(lDuration, UpTime());
|
||||
ullExpiration = force_cast<uint64_t>(sExpiration);
|
||||
}
|
||||
|
||||
OSStatus lStatus;
|
||||
bool bExpired = false;
|
||||
|
||||
do
|
||||
{
|
||||
lStatus = rFunction(kDurationImmediate);
|
||||
// mm - "if" #if 0'd out to allow task time to threads blocked on I/O
|
||||
#if 0
|
||||
if(lStatus == kMPTimeoutErr)
|
||||
#endif
|
||||
{
|
||||
idle();
|
||||
}
|
||||
if(lDuration != kDurationForever)
|
||||
{
|
||||
bExpired = (force_cast<uint64_t>(UpTime()) < ullExpiration);
|
||||
}
|
||||
} while(lStatus == kMPTimeoutErr && bExpired == false);
|
||||
|
||||
return(lStatus);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
@@ -1,41 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#ifndef BOOST_SAFE_MJM012402_HPP
|
||||
#define BOOST_SAFE_MJM012402_HPP
|
||||
|
||||
|
||||
#include <Multiprocessing.h>
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
// these functions are used to wain in an execution context-independent manor. All of these
|
||||
// functions are both MP- and ST-safe.
|
||||
|
||||
OSStatus safe_wait_on_semaphore(MPSemaphoreID pSemaphoreID, Duration lDuration);
|
||||
OSStatus safe_enter_critical_region(MPCriticalRegionID pCriticalRegionID, Duration lDuration, MPCriticalRegionID pCriticalRegionCriticalRegionID = kInvalidID);
|
||||
OSStatus safe_wait_on_queue(MPQueueID pQueueID, void **pParam1, void **pParam2, void **pParam3, Duration lDuration);
|
||||
OSStatus safe_delay_until(AbsoluteTime *pWakeUpTime);
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_SAFE_MJM012402_HPP
|
||||
@@ -1,47 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#include "scoped_critical_region.hpp"
|
||||
|
||||
#include "init.hpp"
|
||||
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
scoped_critical_region::scoped_critical_region():
|
||||
m_pCriticalRegionID(kInvalidID)
|
||||
{
|
||||
static bool bIgnored = thread_init();
|
||||
OSStatus lStatus = MPCreateCriticalRegion(&m_pCriticalRegionID);
|
||||
if(lStatus != noErr || m_pCriticalRegionID == kInvalidID)
|
||||
throw(thread_resource_error());
|
||||
}
|
||||
|
||||
scoped_critical_region::~scoped_critical_region()
|
||||
{
|
||||
OSStatus lStatus = MPDeleteCriticalRegion(m_pCriticalRegionID);
|
||||
assert(lStatus == noErr);
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
@@ -1,63 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#ifndef BOOST_SCOPED_CRITICAL_REGION_MJM012402_HPP
|
||||
#define BOOST_SCOPED_CRITICAL_REGION_MJM012402_HPP
|
||||
|
||||
|
||||
#include <boost/thread/exceptions.hpp>
|
||||
|
||||
#include <Multiprocessing.h>
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
// class scoped_critical_region probably needs a new name. Although the current name
|
||||
// is accurate, it can be read to mean that a critical region is entered for the
|
||||
// current scope. In reality, a critical region is _created_ for the current scope.
|
||||
// This class is intended as a replacement for MPCriticalRegionID that will
|
||||
// automatically create and dispose of itself.
|
||||
|
||||
class scoped_critical_region
|
||||
{
|
||||
public:
|
||||
scoped_critical_region();
|
||||
~scoped_critical_region();
|
||||
|
||||
public:
|
||||
operator const MPCriticalRegionID &() const;
|
||||
const MPCriticalRegionID &get() const;
|
||||
|
||||
private:
|
||||
MPCriticalRegionID m_pCriticalRegionID;
|
||||
};
|
||||
|
||||
|
||||
// these are inlined for speed.
|
||||
inline scoped_critical_region::operator const MPCriticalRegionID &() const
|
||||
{ return(m_pCriticalRegionID); }
|
||||
inline const MPCriticalRegionID &scoped_critical_region::get() const
|
||||
{ return(m_pCriticalRegionID); }
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_SCOPED_CRITICAL_REGION_MJM012402_HPP
|
||||
@@ -1,85 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#include "st_scheduler.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
#if TARGET_CARBON
|
||||
|
||||
st_scheduler::st_scheduler():
|
||||
m_uppTask(NULL),
|
||||
m_pTimer(NULL)
|
||||
{
|
||||
m_uppTask = NewEventLoopTimerUPP(task_entry);
|
||||
// TODO - throw on error
|
||||
assert(m_uppTask != NULL);
|
||||
}
|
||||
|
||||
st_scheduler::~st_scheduler()
|
||||
{
|
||||
DisposeEventLoopTimerUPP(m_uppTask);
|
||||
m_uppTask = NULL;
|
||||
}
|
||||
|
||||
|
||||
void st_scheduler::start_polling()
|
||||
{
|
||||
assert(m_pTimer == NULL);
|
||||
OSStatus lStatus = InstallEventLoopTimer(GetMainEventLoop(),
|
||||
0 * kEventDurationSecond,
|
||||
kEventDurationMillisecond,
|
||||
m_uppTask,
|
||||
this,
|
||||
&m_pTimer);
|
||||
// TODO - throw on error
|
||||
assert(lStatus == noErr);
|
||||
}
|
||||
|
||||
void st_scheduler::stop_polling()
|
||||
{
|
||||
assert(m_pTimer != NULL);
|
||||
OSStatus lStatus = RemoveEventLoopTimer(m_pTimer);
|
||||
assert(lStatus == noErr);
|
||||
m_pTimer = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*static*/ pascal void st_scheduler::task_entry(EventLoopTimerRef /*pTimer*/, void *pRefCon)
|
||||
{
|
||||
st_scheduler *pThis = reinterpret_cast<st_scheduler *>(pRefCon);
|
||||
assert(pThis != NULL);
|
||||
pThis->task();
|
||||
}
|
||||
|
||||
void st_scheduler::task()
|
||||
{
|
||||
periodic_function();
|
||||
}
|
||||
|
||||
#else
|
||||
# error st_scheduler unimplemented!
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
@@ -1,67 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#ifndef BOOST_ST_SCHEDULER_MJM012402_HPP
|
||||
#define BOOST_ST_SCHEDULER_MJM012402_HPP
|
||||
|
||||
|
||||
#include <CarbonEvents.h>
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
// class st_scheduler calls its pure-virtual periodic_function method periodically at
|
||||
// system task time. This is generally 40Hz under Mac OS 9.
|
||||
|
||||
class st_scheduler
|
||||
{
|
||||
public:
|
||||
st_scheduler();
|
||||
virtual ~st_scheduler();
|
||||
|
||||
protected:
|
||||
void start_polling();
|
||||
void stop_polling();
|
||||
|
||||
private:
|
||||
virtual void periodic_function() = 0;
|
||||
|
||||
#if TARGET_CARBON
|
||||
// use event loop timers under Carbon
|
||||
private:
|
||||
static pascal void task_entry(EventLoopTimerRef pTimer, void *pRefCon);
|
||||
void task();
|
||||
|
||||
private:
|
||||
EventLoopTimerUPP m_uppTask;
|
||||
EventLoopTimerRef m_pTimer;
|
||||
#else
|
||||
// this can be implemented using OT system tasks. This would be mostly a copy-and-
|
||||
// paste of the dt_scheduler code, replacing DeferredTask with SystemTask and DT
|
||||
// with ST.
|
||||
# error st_scheduler unimplemented!
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_ST_SCHEDULER_MJM012402_HPP
|
||||
@@ -1,56 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#include "thread_cleanup.hpp"
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
TaskStorageIndex g_ulIndex(0UL);
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
void do_thread_startup()
|
||||
{
|
||||
if(g_ulIndex == 0UL)
|
||||
{
|
||||
OSStatus lStatus = MPAllocateTaskStorageIndex(&g_ulIndex);
|
||||
assert(lStatus == noErr);
|
||||
}
|
||||
set_thread_cleanup_task(NULL);
|
||||
}
|
||||
|
||||
void do_thread_cleanup()
|
||||
{
|
||||
void (*pfnTask)() = MPGetTaskValue(g_ulIndex)
|
||||
}
|
||||
|
||||
|
||||
void set_thread_cleanup_task(void (*pfnTask)())
|
||||
{
|
||||
lStatus = MPSetTaskValue(g_ulIndex, reinterpret_cast<TaskStorageValue>(pfnTask));
|
||||
assert(lStatus == noErr);
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
@@ -1,36 +0,0 @@
|
||||
// (C) Copyright Mac Murrett 2001.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for most recent version.
|
||||
|
||||
#ifndef BOOST_THREAD_CLEANUP_MJM012402_HPP
|
||||
#define BOOST_THREAD_CLEANUP_MJM012402_HPP
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace threads {
|
||||
|
||||
namespace mac {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
void do_thread_startup();
|
||||
void do_thread_cleanup();
|
||||
|
||||
void set_thread_cleanup_task();
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mac
|
||||
|
||||
} // namespace threads
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_THREAD_CLEANUP_MJM012402_HPP
|
||||
Reference in New Issue
Block a user