Added preliminary support for chained mutex calls.

This commit is contained in:
Nicholas Sinnott-Armstrong 2008-09-15 18:45:05 -04:00 committed by Christian Thaeter
parent 16d2fcf2e9
commit 7d86367909
3 changed files with 60 additions and 1 deletions

View file

@ -60,6 +60,39 @@ LUMIERA_ERROR_DECLARE (MUTEX_DESTROY);
} \
}))
/**
* Mutual exclusion chainbuilder section.
* Usage: LUMIERA_MUTEX_SECTION(a){LUMIERA_MUTEX_SECTION_CHAIN(a,b){run();}}
* calls lock(a); lock(b); unlock(a); run(); unlock(b);
* This macro should only be used inside LUMIERA_MUTEX_SECTION and should be
* called on the correct mutexes, period.
*/
#define LUMIERA_MUTEX_SECTION_CHAIN(nobugflag, mtxa, mtxb) \
for (lumiera_mutexacquirer NOBUG_CLEANUP(lumiera_mutexacquirer_ensureunlocked) lumiera_mutex_section_ = {(LumieraMutex)1}; \
lumiera_mutex_section_.mutex;) \
for ( \
({ \
lumiera_mutex_section_.mutex = (mtxb); \
NOBUG_RESOURCE_HANDLE_INIT (lumiera_mutex_section_.rh); \
RESOURCE_ENTER (nobugflag, (mtxb)->rh, "acquire mutex", &lumiera_mutex_section_, \
NOBUG_RESOURCE_EXCLUSIVE, lumiera_mutex_section_.rh); \
if (pthread_mutex_lock (&(mtxb)->mutex)) LUMIERA_DIE (MUTEX_LOCK); \
if (mtxa) \
{ \
pthread_mutex_unlock (&mtxa->mutex); \
mtxa = NULL; \
RESOURCE_LEAVE(nobugflag, mtxa.rh); \
} \
}); \
lumiera_mutex_section_.mutex; \
({ \
if (lumiera_mutex_section_.mutex) \
{ \
pthread_mutex_unlock (&lumiera_mutex_section_.mutex->mutex); \
lumiera_mutex_section_.mutex = NULL; \
RESOURCE_LEAVE(nobugflag, lumiera_mutex_section_.rh); \
} \
}))
/**
* Mutex.

View file

@ -18,6 +18,12 @@ out: inner mutex locked section
END
TEST "chained mutex section" chainedmutexsection <<END
out: outer mutex locked section
out: inner but not outer mutex locked section
END
TEST "rwlock section" rwlocksection <<END
out: write locked section 1
out: read locked section 2

View file

@ -82,10 +82,30 @@ TEST ("nestedmutexsection")
}
lumiera_mutex_destroy (&n, &NOBUG_FLAG(NOBUG_ON));
lumiera_mutex_destroy (&m, &NOBUG_FLAG(NOBUG_ON));
lumiera_mutex_destroy (&m, &NOBUG_FLAG(NOBUG_ON));
}
TEST ("chainedmutexsection")
{
lumiera_mutex m;
lumiera_mutex_init (&m, "m_mutexsection", &NOBUG_FLAG(NOBUG_ON));
lumiera_mutex n;
lumiera_mutex_init (&n, "n_mutexsection", &NOBUG_FLAG(NOBUG_ON));
LUMIERA_MUTEX_SECTION (NOBUG_ON, &m)
{
printf ("outer mutex locked section\n");
LUMIERA_MUTEX_SECTION_CHAIN (NOBUG_ON, &m, &n)
{
printf ("inner but not outer mutex locked section\n");
}
}
lumiera_mutex_destroy (&n, &NOBUG_FLAG(NOBUG_ON));
lumiera_mutex_destroy (&m, &NOBUG_FLAG(NOBUG_ON));
}
TEST ("rwlocksection")
{