version 1.67, 2002/03/08 20:51:26 |
version 1.68, 2002/03/08 21:41:59 |
Line 456 pool_init(struct pool *pp, size_t size, |
|
Line 456 pool_init(struct pool *pp, size_t size, |
|
pp->pr_hardlimit_ratecap.tv_usec = 0; |
pp->pr_hardlimit_ratecap.tv_usec = 0; |
pp->pr_hardlimit_warning_last.tv_sec = 0; |
pp->pr_hardlimit_warning_last.tv_sec = 0; |
pp->pr_hardlimit_warning_last.tv_usec = 0; |
pp->pr_hardlimit_warning_last.tv_usec = 0; |
|
pp->pr_drain_hook = NULL; |
|
pp->pr_drain_hook_arg = NULL; |
|
|
/* |
/* |
* Decide whether to put the page header off page to avoid |
* Decide whether to put the page header off page to avoid |
Line 596 pool_destroy(struct pool *pp) |
|
Line 598 pool_destroy(struct pool *pp) |
|
#endif |
#endif |
} |
} |
|
|
|
void |
|
pool_set_drain_hook(struct pool *pp, void (*fn)(void *, int), void *arg) |
|
{ |
|
|
|
/* XXX no locking -- must be used just after pool_init() */ |
|
#ifdef DIAGNOSTIC |
|
if (pp->pr_drain_hook != NULL) |
|
panic("pool_set_drain_hook(%s): already set", pp->pr_wchan); |
|
#endif |
|
pp->pr_drain_hook = fn; |
|
pp->pr_drain_hook_arg = arg; |
|
} |
|
|
static __inline struct pool_item_header * |
static __inline struct pool_item_header * |
pool_alloc_item_header(struct pool *pp, caddr_t storage, int flags) |
pool_alloc_item_header(struct pool *pp, caddr_t storage, int flags) |
{ |
{ |
Line 663 pool_get(struct pool *pp, int flags) |
|
Line 678 pool_get(struct pool *pp, int flags) |
|
} |
} |
#endif |
#endif |
if (__predict_false(pp->pr_nout == pp->pr_hardlimit)) { |
if (__predict_false(pp->pr_nout == pp->pr_hardlimit)) { |
|
if (pp->pr_drain_hook != NULL) { |
|
/* |
|
* Since the drain hook is going to free things |
|
* back to the pool, unlock, call the hook, re-lock, |
|
* and check the hardlimit condition again. |
|
*/ |
|
pr_leave(pp); |
|
simple_unlock(&pp->pr_slock); |
|
(*pp->pr_drain_hook)(pp->pr_drain_hook_arg, flags); |
|
simple_lock(&pp->pr_slock); |
|
pr_enter(pp, file, line); |
|
if (pp->pr_nout < pp->pr_hardlimit) |
|
goto startover; |
|
} |
|
|
if ((flags & PR_WAITOK) && !(flags & PR_LIMITFAIL)) { |
if ((flags & PR_WAITOK) && !(flags & PR_LIMITFAIL)) { |
/* |
/* |
* XXX: A warning isn't logged in this case. Should |
* XXX: A warning isn't logged in this case. Should |
Line 1264 pool_reclaim(struct pool *pp) |
|
Line 1294 pool_reclaim(struct pool *pp) |
|
if (pp->pr_roflags & PR_STATIC) |
if (pp->pr_roflags & PR_STATIC) |
return (0); |
return (0); |
|
|
|
if (pp->pr_drain_hook != NULL) { |
|
/* |
|
* The drain hook must be called with the pool unlocked. |
|
*/ |
|
(*pp->pr_drain_hook)(pp->pr_drain_hook_arg, PR_NOWAIT); |
|
} |
|
|
if (simple_lock_try(&pp->pr_slock) == 0) |
if (simple_lock_try(&pp->pr_slock) == 0) |
return (0); |
return (0); |
pr_enter(pp, file, line); |
pr_enter(pp, file, line); |
|
|
TAILQ_INIT(&pq); |
TAILQ_INIT(&pq); |
|
|
/* |
/* |
Line 1899 pool_allocator_alloc(struct pool *org, i |
|
Line 1937 pool_allocator_alloc(struct pool *org, i |
|
do { |
do { |
if ((res = (*pa->pa_alloc)(org, flags)) != NULL) |
if ((res = (*pa->pa_alloc)(org, flags)) != NULL) |
return (res); |
return (res); |
if ((flags & PR_WAITOK) == 0) |
if ((flags & PR_WAITOK) == 0) { |
|
/* |
|
* We only run the drain hookhere if PR_NOWAIT. |
|
* In other cases, the hook will be run in |
|
* pool_reclaim(). |
|
*/ |
|
if (org->pr_drain_hook != NULL) { |
|
(*org->pr_drain_hook)(org->pr_drain_hook_arg, |
|
flags); |
|
if ((res = (*pa->pa_alloc)(org, flags)) != NULL) |
|
return (res); |
|
} |
break; |
break; |
|
} |
|
|
/* |
/* |
* Drain all pools, except "org", that use this |
* Drain all pools, except "org", that use this |
Line 1913 pool_allocator_alloc(struct pool *org, i |
|
Line 1963 pool_allocator_alloc(struct pool *org, i |
|
* other way to have potentially sleeping pool_reclaim, |
* other way to have potentially sleeping pool_reclaim, |
* non-sleeping locks on pool_allocator, and some |
* non-sleeping locks on pool_allocator, and some |
* stirring of drained pools in the allocator. |
* stirring of drained pools in the allocator. |
|
* |
|
* XXX Maybe we should use pool_head_slock for locking |
|
* the allocators? |
*/ |
*/ |
freed = 0; |
freed = 0; |
|
|