Fix tracing_mutex_assert() by tracking the thread ID of the lock owner and

behave properly when the mutex is held by another thread.


git-svn-id: svn://svn.code.sf.net/p/libkqueue/code/trunk@514 fb4e3144-bc1c-4b72-a658-5bcd248dd7f7
This commit is contained in:
mheily 2011-05-22 00:57:44 +00:00
parent 54cafd9c68
commit 140343f197
2 changed files with 31 additions and 1 deletions

View File

@ -92,26 +92,35 @@ extern char *KQUEUE_DEBUG_IDENT;
typedef struct {
pthread_mutex_t mtx_lock;
int mtx_status;
int mtx_owner;
} tracing_mutex_t;
# define tracing_mutex_init(mtx, attr) do { \
pthread_mutex_init(&(mtx)->mtx_lock, (attr)); \
(mtx)->mtx_status = MTX_UNLOCKED; \
(mtx)->mtx_owner = -1; \
} while (0)
# define tracing_mutex_destroy(mtx) pthread_mutex_destroy(&(mtx)->mtx_lock)
# define tracing_mutex_assert(x,y) assert((x)->mtx_status == (y))
# define tracing_mutex_assert(x,y) do { \
if ((y) == MTX_UNLOCKED) \
assert((x)->mtx_status == MTX_UNLOCKED || (x)->mtx_owner != THREAD_ID); \
else if ((y) == MTX_LOCKED) \
assert((x)->mtx_status == MTX_LOCKED); \
} while (0)
# define tracing_mutex_lock(x) do { \
dbg_printf("waiting for %s", #x); \
pthread_mutex_lock(&((x)->mtx_lock)); \
dbg_printf("locked %s", #x); \
(x)->mtx_owner = THREAD_ID; \
(x)->mtx_status = MTX_LOCKED; \
} while (0)
# define tracing_mutex_unlock(x) do { \
(x)->mtx_status = MTX_UNLOCKED; \
(x)->mtx_owner = -1; \
pthread_mutex_unlock(&((x)->mtx_lock)); \
dbg_printf("unlocked %s", # x); \
} while (0)

View File

@ -14,6 +14,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <err.h>
#include <pthread.h>
#include "../src/common/private.h"
int DEBUG_KQUEUE = 1;
@ -23,11 +25,20 @@ struct foo {
tracing_mutex_t foo_lock;
};
void *test_assertion(void *_x)
{
struct foo *x = (struct foo *) _x;
tracing_mutex_assert(&x->foo_lock, MTX_UNLOCKED);
pthread_exit(NULL);
}
/*
* Test the lockstat.h API
*/
int main() {
struct foo x;
pthread_t tid;
void *rv;
tracing_mutex_init(&x.foo_lock, NULL);
tracing_mutex_lock(&x.foo_lock);
@ -35,6 +46,16 @@ int main() {
tracing_mutex_unlock(&x.foo_lock);
tracing_mutex_assert(&x.foo_lock, MTX_UNLOCKED);
/*
* Ensure that the assert() function works when there
* are multiple threads contenting for the mutex.
*/
tracing_mutex_lock(&x.foo_lock);
if (pthread_create(&tid, NULL, test_assertion, &x) != 0)
err(1, "pthread_create");
pthread_join(tid, &rv);
tracing_mutex_unlock(&x.foo_lock);
puts("+OK");
return (0);
}