- Add option to allow sleeping malloc(9).

- Cleanup locking assertions that aren't needed anymore.
This commit is contained in:
Ariff Abdullah 2007-06-14 11:10:21 +00:00
parent be89d8067c
commit 553dc5c78c
2 changed files with 21 additions and 59 deletions

View File

@ -30,9 +30,7 @@
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#if defined(SND_DIAGNOSTIC) || defined(SND_DEBUG)
@ -77,9 +75,6 @@ struct snd_clone_entry {
/* clone manager */
struct snd_clone {
TAILQ_HEAD(link_head, snd_clone_entry) head;
#ifdef SND_DIAGNOSTIC
struct mtx *lock;
#endif
struct timespec tsp;
int refcount;
int size;
@ -90,18 +85,11 @@ struct snd_clone {
};
#ifdef SND_DIAGNOSTIC
#define SND_CLONE_LOCKASSERT(x) do { \
if ((x)->lock == NULL) \
panic("%s(): NULL mutex!", __func__); \
if (mtx_owned((x)->lock) == 0) \
panic("%s(): mutex not owned!", __func__); \
} while(0)
#define SND_CLONE_ASSERT(x, y) do { \
if (!(x)) \
panic y; \
} while(0)
#else
#define SND_CLONE_LOCKASSERT(...)
#define SND_CLONE_ASSERT(x...) KASSERT(x)
#endif
@ -170,16 +158,10 @@ SYSCTL_PROC(_hw_snd, OID_AUTO, timestamp_precision, CTLTYPE_INT | CTLFLAG_RW,
#endif
/*
* snd_clone_create() : Return opaque allocated clone manager. Mutex is
* not a mandatory requirement if the caller can guarantee safety across
* concurrent access.
* snd_clone_create() : Return opaque allocated clone manager.
*/
struct snd_clone *
snd_clone_create(
#ifdef SND_DIAGNOSTIC
struct mtx *lock,
#endif
int typemask, int maxunit, int deadline, uint32_t flags)
snd_clone_create(int typemask, int maxunit, int deadline, uint32_t flags)
{
struct snd_clone *c;
@ -193,9 +175,6 @@ snd_clone_create(
("invalid clone flags=0x%08x", flags));
c = malloc(sizeof(*c), M_DEVBUF, M_WAITOK | M_ZERO);
#ifdef SND_DIAGNOSTIC
c->lock = lock;
#endif
c->refcount = 0;
c->size = 0;
c->typemask = typemask;
@ -215,7 +194,6 @@ snd_clone_busy(struct snd_clone *c)
struct snd_clone_entry *ce;
SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
SND_CLONE_LOCKASSERT(c);
if (c->size == 0)
return (0);
@ -237,7 +215,6 @@ int
snd_clone_enable(struct snd_clone *c)
{
SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
SND_CLONE_LOCKASSERT(c);
if (c->flags & SND_CLONE_ENABLE)
return (EINVAL);
@ -251,7 +228,6 @@ int
snd_clone_disable(struct snd_clone *c)
{
SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
SND_CLONE_LOCKASSERT(c);
if (!(c->flags & SND_CLONE_ENABLE))
return (EINVAL);
@ -268,7 +244,6 @@ int
snd_clone_getsize(struct snd_clone *c)
{
SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
SND_CLONE_LOCKASSERT(c);
return (c->size);
}
@ -277,7 +252,6 @@ int
snd_clone_getmaxunit(struct snd_clone *c)
{
SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
SND_CLONE_LOCKASSERT(c);
return (c->maxunit);
}
@ -286,7 +260,6 @@ int
snd_clone_setmaxunit(struct snd_clone *c, int maxunit)
{
SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
SND_CLONE_LOCKASSERT(c);
SND_CLONE_ASSERT(maxunit == -1 ||
!(maxunit & ~(~c->typemask & SND_CLONE_MAXUNIT)),
("maxunit overflow: typemask=0x%08x maxunit=%d",
@ -302,7 +275,6 @@ int
snd_clone_getdeadline(struct snd_clone *c)
{
SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
SND_CLONE_LOCKASSERT(c);
return (c->deadline);
}
@ -311,7 +283,6 @@ int
snd_clone_setdeadline(struct snd_clone *c, int deadline)
{
SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
SND_CLONE_LOCKASSERT(c);
c->deadline = deadline;
@ -323,7 +294,6 @@ snd_clone_gettime(struct snd_clone *c, struct timespec *tsp)
{
SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
SND_CLONE_ASSERT(tsp != NULL, ("NULL timespec"));
SND_CLONE_LOCKASSERT(c);
*tsp = c->tsp;
@ -334,7 +304,6 @@ uint32_t
snd_clone_getflags(struct snd_clone *c)
{
SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
SND_CLONE_LOCKASSERT(c);
return (c->flags);
}
@ -343,7 +312,6 @@ uint32_t
snd_clone_setflags(struct snd_clone *c, uint32_t flags)
{
SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
SND_CLONE_LOCKASSERT(c);
SND_CLONE_ASSERT(!(flags & ~SND_CLONE_MASK),
("invalid clone flags=0x%08x", flags));
@ -365,7 +333,6 @@ snd_clone_getdevtime(struct cdev *dev, struct timespec *tsp)
return (ENODEV);
SND_CLONE_ASSERT(ce->parent != NULL, ("NULL parent"));
SND_CLONE_LOCKASSERT(ce->parent);
*tsp = ce->tsp;
@ -384,7 +351,6 @@ snd_clone_getdevflags(struct cdev *dev)
return (0xffffffff);
SND_CLONE_ASSERT(ce->parent != NULL, ("NULL parent"));
SND_CLONE_LOCKASSERT(ce->parent);
return (ce->flags);
}
@ -403,7 +369,6 @@ snd_clone_setdevflags(struct cdev *dev, uint32_t flags)
return (0xffffffff);
SND_CLONE_ASSERT(ce->parent != NULL, ("NULL parent"));
SND_CLONE_LOCKASSERT(ce->parent);
ce->flags = flags;
@ -435,7 +400,6 @@ snd_clone_gc(struct snd_clone *c)
int pruned;
SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
SND_CLONE_LOCKASSERT(c);
if (!(c->flags & SND_CLONE_GC_ENABLE) || c->size == 0)
return (0);
@ -483,18 +447,17 @@ snd_clone_gc(struct snd_clone *c)
void
snd_clone_destroy(struct snd_clone *c)
{
struct snd_clone_entry *ce;
struct snd_clone_entry *ce, *tmp;
SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
SND_CLONE_ASSERT(c->refcount == 0, ("refcount > 0"));
SND_CLONE_LOCKASSERT(c);
while (!TAILQ_EMPTY(&c->head)) {
ce = TAILQ_FIRST(&c->head);
TAILQ_REMOVE(&c->head, ce, link);
ce = TAILQ_FIRST(&c->head);
while (ce != NULL) {
tmp = TAILQ_NEXT(ce, link);
if (ce->devt != NULL)
destroy_dev(ce->devt);
free(ce, M_DEVBUF);
ce = tmp;
}
free(c, M_DEVBUF);
@ -518,7 +481,6 @@ snd_clone_acquire(struct cdev *dev)
return (ENODEV);
SND_CLONE_ASSERT(ce->parent != NULL, ("NULL parent"));
SND_CLONE_LOCKASSERT(ce->parent);
ce->flags &= ~SND_CLONE_INVOKE;
@ -546,7 +508,6 @@ snd_clone_release(struct cdev *dev)
return (ENODEV);
SND_CLONE_ASSERT(ce->parent != NULL, ("NULL parent"));
SND_CLONE_LOCKASSERT(ce->parent);
ce->flags &= ~SND_CLONE_INVOKE;
@ -588,7 +549,6 @@ snd_clone_ref(struct cdev *dev)
c = ce->parent;
SND_CLONE_ASSERT(c != NULL, ("NULL parent"));
SND_CLONE_ASSERT(c->refcount >= 0, ("refcount < 0"));
SND_CLONE_LOCKASSERT(c);
return (++c->refcount);
}
@ -608,7 +568,6 @@ snd_clone_unref(struct cdev *dev)
c = ce->parent;
SND_CLONE_ASSERT(c != NULL, ("NULL parent"));
SND_CLONE_ASSERT(c->refcount > 0, ("refcount <= 0"));
SND_CLONE_LOCKASSERT(c);
c->refcount--;
@ -637,7 +596,6 @@ snd_clone_register(struct snd_clone_entry *ce, struct cdev *dev)
ce->unit, dev2unit(dev)));
SND_CLONE_ASSERT(ce->parent != NULL, ("NULL parent"));
SND_CLONE_LOCKASSERT(ce->parent);
dev->si_drv2 = ce;
ce->devt = dev;
@ -654,7 +612,6 @@ snd_clone_alloc(struct snd_clone *c, struct cdev **dev, int *unit, int tmask)
pid_t curpid;
SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
SND_CLONE_LOCKASSERT(c);
SND_CLONE_ASSERT(dev != NULL, ("NULL dev pointer"));
SND_CLONE_ASSERT((c->typemask & tmask) == tmask,
("invalid tmask: typemask=0x%08x tmask=0x%08x",
@ -771,11 +728,16 @@ snd_clone_alloc_new:
/*
* No free entries found, and we still haven't reached maximum
* allowable units. Allocate, setup a minimal unique entry with busy
* status so nobody will monkey on this new entry since we had to
* give up locking for further setup. Unit magic is set right here
* to avoid collision with other contesting handler.
* status so nobody will monkey on this new entry. Unit magic is set
* right here to avoid collision with other contesting handler.
* The caller must be carefull here to maintain its own
* synchronization, as long as it will not conflict with malloc(9)
* operations.
*
* That said, go figure.
*/
ce = malloc(sizeof(*ce), M_DEVBUF, M_NOWAIT | M_ZERO);
ce = malloc(sizeof(*ce), M_DEVBUF,
((c->flags & SND_CLONE_WAITOK) ? M_WAITOK : M_NOWAIT) | M_ZERO);
if (ce == NULL) {
if (*unit != -1)
return (NULL);

View File

@ -56,6 +56,8 @@ struct snd_clone;
* handler has been expired.
* SND_CLONE_GC_REVOKE - Revoke clone invocation status which has been
* expired instead of removing and freeing it.
* SND_CLONE_WAITOK - malloc() is allowed to sleep while allocating
* clone entry.
*/
#define SND_CLONE_ENABLE 0x00000001
#define SND_CLONE_GC_ENABLE 0x00000002
@ -63,6 +65,7 @@ struct snd_clone;
#define SND_CLONE_GC_LASTREF 0x00000008
#define SND_CLONE_GC_EXPIRED 0x00000010
#define SND_CLONE_GC_REVOKE 0x00000020
#define SND_CLONE_WAITOK 0x80000000
#define SND_CLONE_GC_MASK (SND_CLONE_GC_ENABLE | \
SND_CLONE_GC_UNREF | \
@ -70,7 +73,8 @@ struct snd_clone;
SND_CLONE_GC_EXPIRED | \
SND_CLONE_GC_REVOKE)
#define SND_CLONE_MASK (SND_CLONE_ENABLE | SND_CLONE_GC_MASK)
#define SND_CLONE_MASK (SND_CLONE_ENABLE | SND_CLONE_GC_MASK | \
SND_CLONE_WAITOK)
/*
* Runtime clone device flags
@ -96,11 +100,7 @@ struct snd_clone;
void snd_timestamp(struct timespec *);
#ifdef SND_DIAGNOSTIC
struct snd_clone *snd_clone_create(struct mtx *, int, int, int, uint32_t);
#else
struct snd_clone *snd_clone_create(int, int, int, uint32_t);
#endif
int snd_clone_busy(struct snd_clone *);
int snd_clone_enable(struct snd_clone *);
int snd_clone_disable(struct snd_clone *);