|
Boost : |
From: Michael Glassford (glassfordm_at_[hidden])
Date: 2004-03-22 09:13:54
For what it's worth, the version of Boost.Thread in the thread_dev
branch of CVS already uses a critical section when possible. As time
allows, I'm planning to review the code in the thread_dev branch, ask
for comments, finish anything that isn't finished, and move it to the
main branch piece by piece. I'm currently doing this (very slowly, I'm
afraid) for the thread_specific_ptr and related classes.
Mike
Adal Chiriliuc wrote:
> Hello.
>
> try_mutex uses a Mutex instead of a CRITICAL_SECTION because on
> Windows 9x and Me it's impossible to try the aquisition of a
> CRITICAL_SECTION.
>
> On Windows NT/2000/XP this is possible, using the function
> TryEnterCriticalSection.
>
> So I suggest this: choose at runtime what syncronization primitive
to
> use based on the running OS. CRITICAL_SECTIONS are much faster and
> since Windows NT is gradually replacing Windows 9x systems I think
it
> is good to use this feature.
>
> A sketch follows.
>
> ---------- mutex.cpp -----------
>
> namespace
> {
> bool g_Init = false;
> bool g_UseTryCritical;
> TryCriticalProcType g_TryCritical;
>
> void TryCriticalInit()
> {
> g_Init = true;
> g_UseTryCritical = false;
> get windows version;
> if (!windows nt)
> return;
> lib = load library (kernel32.dll);
> g_TryCritical = get proc address (lib, TryEnterCriticalSection);
> g_UseTryCritical = true;
> }
>
> }
>
> try_mutex::try_mutex()
> {
> if (!g_Init)
> TryCriticalInit();
> if (g_UseTryCritical)
> {
> try
> {
> m_mutex = reinterpret_cast<void*>(new CRITICAL_SECTION);
> }
> catch (...)
> {
> }
> }
> else
> {
> m_mutex = reinterpret_cast<void*>(CreateMutex(0, 0, 0));
> }
> if (!m_mutex)
> throw thread_resource_error();
> if (g_UseTryCritical)
>
>
InitializeCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(m_mutex
));
> }
>
> bool try_mutex::do_trylock()
> {
> if (g_UseTryCritical)
> {
> return
> g_TryCritical(reinterpret_cast<LPCRITICAL_SECTION>(m_mutex)) !=
> 0; } else
> {
> unsigned int res = 0;
> res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_mutex),
> 0); assert(res != WAIT_FAILED && res != WAIT_ABANDONED);
> return res == WAIT_OBJECT_0;
> }
> }
>
> ---------- mutex.cpp -----------
>
> There is only one potential problem:
> if (!g_Init)
> TryCriticalInit();
> might not be thread safe.
>
> Something like a thread safe singleton might be needed.
> Or maybe we could use InterlockedExchange & co.
>
> I'm not sure if timed_mutex could also benefit from this.
>
> In the docs you should explain what joining means. I worked a lot
with
> threads in the past, but I've never heard of such a concept. I had
to
> look through the source codes to understand what join means. Many
> Win32 developers will not know of concepts not covered by the
Platform
> SDK. You do explain that conditions are some sort of events, but you
> use joining in sample code without explaining what it does.
>
> Regards,
> Adal Chiriliuc
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk