mirror of
https://github.com/darlinghq/darling-libkqueue.git
synced 2024-11-23 11:49:50 +00:00
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:
parent
54cafd9c68
commit
140343f197
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user