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 {
|
typedef struct {
|
||||||
pthread_mutex_t mtx_lock;
|
pthread_mutex_t mtx_lock;
|
||||||
int mtx_status;
|
int mtx_status;
|
||||||
|
int mtx_owner;
|
||||||
} tracing_mutex_t;
|
} tracing_mutex_t;
|
||||||
|
|
||||||
# define tracing_mutex_init(mtx, attr) do { \
|
# define tracing_mutex_init(mtx, attr) do { \
|
||||||
pthread_mutex_init(&(mtx)->mtx_lock, (attr)); \
|
pthread_mutex_init(&(mtx)->mtx_lock, (attr)); \
|
||||||
(mtx)->mtx_status = MTX_UNLOCKED; \
|
(mtx)->mtx_status = MTX_UNLOCKED; \
|
||||||
|
(mtx)->mtx_owner = -1; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
# define tracing_mutex_destroy(mtx) pthread_mutex_destroy(&(mtx)->mtx_lock)
|
# 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 { \
|
# define tracing_mutex_lock(x) do { \
|
||||||
dbg_printf("waiting for %s", #x); \
|
dbg_printf("waiting for %s", #x); \
|
||||||
pthread_mutex_lock(&((x)->mtx_lock)); \
|
pthread_mutex_lock(&((x)->mtx_lock)); \
|
||||||
dbg_printf("locked %s", #x); \
|
dbg_printf("locked %s", #x); \
|
||||||
|
(x)->mtx_owner = THREAD_ID; \
|
||||||
(x)->mtx_status = MTX_LOCKED; \
|
(x)->mtx_status = MTX_LOCKED; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
# define tracing_mutex_unlock(x) do { \
|
# define tracing_mutex_unlock(x) do { \
|
||||||
(x)->mtx_status = MTX_UNLOCKED; \
|
(x)->mtx_status = MTX_UNLOCKED; \
|
||||||
|
(x)->mtx_owner = -1; \
|
||||||
pthread_mutex_unlock(&((x)->mtx_lock)); \
|
pthread_mutex_unlock(&((x)->mtx_lock)); \
|
||||||
dbg_printf("unlocked %s", # x); \
|
dbg_printf("unlocked %s", # x); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include "../src/common/private.h"
|
#include "../src/common/private.h"
|
||||||
|
|
||||||
int DEBUG_KQUEUE = 1;
|
int DEBUG_KQUEUE = 1;
|
||||||
@ -23,11 +25,20 @@ struct foo {
|
|||||||
tracing_mutex_t foo_lock;
|
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
|
* Test the lockstat.h API
|
||||||
*/
|
*/
|
||||||
int main() {
|
int main() {
|
||||||
struct foo x;
|
struct foo x;
|
||||||
|
pthread_t tid;
|
||||||
|
void *rv;
|
||||||
|
|
||||||
tracing_mutex_init(&x.foo_lock, NULL);
|
tracing_mutex_init(&x.foo_lock, NULL);
|
||||||
tracing_mutex_lock(&x.foo_lock);
|
tracing_mutex_lock(&x.foo_lock);
|
||||||
@ -35,6 +46,16 @@ int main() {
|
|||||||
tracing_mutex_unlock(&x.foo_lock);
|
tracing_mutex_unlock(&x.foo_lock);
|
||||||
tracing_mutex_assert(&x.foo_lock, MTX_UNLOCKED);
|
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");
|
puts("+OK");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user