lkml.org 
[lkml]   [2013]   [May]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH v4 3/9] liblockdep: Add public headers for pthread_mutex_t implementation
    On Wed, May 15, 2013 at 11:15:35PM -0400, Sasha Levin wrote:
    > These headers provide the same API as their pthread mutex
    > counterparts.
    >
    > The design here is to allow to easily switch to liblockdep lock
    > validation just by adding a "liblockdep_" to pthread_mutex_*()
    > calls, which means that it's easy to integrate liblockdep into
    > existing codebases.
    >
    > Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
    > ---
    > tools/lib/lockdep/include/liblockdep/common.h | 42 ++++++++++++++++
    > tools/lib/lockdep/include/liblockdep/mutex.h | 70 +++++++++++++++++++++++++++
    > 2 files changed, 112 insertions(+)
    > create mode 100644 tools/lib/lockdep/include/liblockdep/common.h
    > create mode 100644 tools/lib/lockdep/include/liblockdep/mutex.h
    >
    > diff --git a/tools/lib/lockdep/include/liblockdep/common.h b/tools/lib/lockdep/include/liblockdep/common.h
    > new file mode 100644
    > index 0000000..1113cad
    > --- /dev/null
    > +++ b/tools/lib/lockdep/include/liblockdep/common.h
    > @@ -0,0 +1,42 @@
    > +#ifndef _LIBLOCKDEP_COMMON_H
    > +#define _LIBLOCKDEP_COMMON_H
    > +
    > +#include <pthread.h>
    > +
    > +#ifndef _THIS_IP_

    #ifndef _RET_IP_ ?

    > +#define _RET_IP_ (unsigned long)__builtin_return_address(0)
    > +#endif
    > +
    > +#define NR_LOCKDEP_CACHING_CLASSES 2
    > +#define MAX_LOCKDEP_SUBCLASSES 8UL
    > +
    > +struct lockdep_subclass_key {
    > + char __one_byte;
    > +};
    > +
    > +struct lock_class_key {
    > + struct lockdep_subclass_key subkeys[MAX_LOCKDEP_SUBCLASSES];
    > +};
    > +
    > +struct lockdep_map {
    > + struct lock_class_key *key;
    > + struct lock_class *class_cache[NR_LOCKDEP_CACHING_CLASSES];
    > + const char *name;
    > +#ifdef CONFIG_LOCK_STAT
    > + int cpu;
    > + unsigned long ip;
    > +#endif
    > +};
    > +
    > +void lockdep_init_map(struct lockdep_map *lock, const char *name,
    > + struct lock_class_key *key, int subclass);
    > +void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
    > + int trylock, int read, int check,
    > + struct lockdep_map *nest_lock, unsigned long ip);
    > +void lock_release(struct lockdep_map *lock, int nested,
    > + unsigned long ip);
    > +
    > +#define STATIC_LOCKDEP_MAP_INIT(_name, _key) \
    > + { .name = (_name), .key = (void *)(_key), }
    > +
    > +#endif
    > diff --git a/tools/lib/lockdep/include/liblockdep/mutex.h b/tools/lib/lockdep/include/liblockdep/mutex.h
    > new file mode 100644
    > index 0000000..c342f70
    > --- /dev/null
    > +++ b/tools/lib/lockdep/include/liblockdep/mutex.h
    > @@ -0,0 +1,70 @@
    > +#ifndef _LIBLOCKDEP_MUTEX_H
    > +#define _LIBLOCKDEP_MUTEX_H
    > +
    > +#include <pthread.h>
    > +#include "common.h"
    > +
    > +struct liblockdep_pthread_mutex {
    > + pthread_mutex_t mutex;
    > + struct lockdep_map dep_map;
    > +};
    > +
    > +typedef struct liblockdep_pthread_mutex liblockdep_pthread_mutex_t;
    > +
    > +#define LIBLOCKDEP_PTHREAD_MUTEX_INITIALIZER(mtx) \
    > + (const struct liblockdep_pthread_mutex) { \
    > + .mutex = PTHREAD_MUTEX_INITIALIZER, \
    > + .dep_map = STATIC_LOCKDEP_MAP_INIT(#mtx, &((&(mtx))->dep_map)), \
    > +}
    > +
    > +static inline int __mutex_init(liblockdep_pthread_mutex_t *lock,
    > + const char *name,
    > + struct lock_class_key *key,
    > + const pthread_mutexattr_t *__mutexattr)
    > +{
    > + lockdep_init_map(&lock->dep_map, name, key, 0);
    > + return pthread_mutex_init(&lock->mutex, __mutexattr);
    > +}
    > +
    > +#define liblockdep_pthread_mutex_init(mutex, mutexattr) \
    > +({ \
    > + static struct lock_class_key __key; \
    > + \
    > + __mutex_init((mutex), #mutex, &__key, (mutexattr)); \
    > +})

    OK, so people using liblockdep_pthread_mutex_init() do get the 'normal'
    class rules.

    > +
    > +static inline int liblockdep_pthread_mutex_lock(liblockdep_pthread_mutex_t *lock)
    > +{
    > + lock_acquire(&lock->dep_map, 0, 0, 0, 2, NULL, (unsigned long)_RET_IP_);
    > + return pthread_mutex_lock(&lock->mutex);
    > +}

    They will however then also want all the 'normal' lockdep annotations to
    deal with that like:

    liblockdep_pthread_mutex_lock_nested()
    liblockdep_pthread_mutex_lock_nest_lock()

    *phew* and here I always though pthread_mutex_* was a long prefix...

    Also, the above doesn't have the full lockstat contention hooks -- not
    sure that's on purpose or not.

    > +
    > +static inline int liblockdep_pthread_mutex_unlock(liblockdep_pthread_mutex_t *lock)
    > +{
    > + lock_release(&lock->dep_map, 0, (unsigned long)_RET_IP_);
    > + return pthread_mutex_unlock(&lock->mutex);
    > +}
    > +
    > +static inline int liblockdep_pthread_mutex_trylock(liblockdep_pthread_mutex_t *lock)
    > +{
    > + lock_acquire(&lock->dep_map, 0, 1, 0, 2, NULL, (unsigned long)_RET_IP_);
    > + return pthread_mutex_trylock(&lock->mutex) == 0 ? 1 : 0;
    > +}
    > +
    > +static inline int liblockdep_pthread_mutex_destroy(liblockdep_pthread_mutex_t *lock)
    > +{
    > + return pthread_mutex_destroy(&lock->mutex);
    > +}
    > +
    > +#ifdef __USE_LIBLOCKDEP
    > +
    > +#define pthread_mutex_t liblockdep_pthread_mutex_t
    > +#define pthread_mutex_init liblockdep_pthread_mutex_init
    > +#define pthread_mutex_lock liblockdep_pthread_mutex_lock
    > +#define pthread_mutex_unlock liblockdep_pthread_mutex_unlock
    > +#define pthread_mutex_trylock liblockdep_pthread_mutex_trylock
    > +#define pthread_mutex_destroy liblockdep_pthread_mutex_destroy

    Given the liblockdep_* things use 'proper' classes do you want this
    mapping? If you do, should we use the same alias nonsense glibc uses or
    are CPP macros good enough for us?


    \
     
     \ /
      Last update: 2013-05-22 12:01    [W:5.259 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site