aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xenstore/talloc.c
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-07-24 14:50:50 +0100
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-07-24 14:50:50 +0100
commit407ce07bc8a6a5011629456e357b37ee7372245a (patch)
treed042965661267bf6ac08cf91aabb9882e49b53e0 /tools/xenstore/talloc.c
parente573cbf5203769ae6af586712b305b185dd5fdad (diff)
downloadxen-407ce07bc8a6a5011629456e357b37ee7372245a.tar.gz
xen-407ce07bc8a6a5011629456e357b37ee7372245a.tar.bz2
xen-407ce07bc8a6a5011629456e357b37ee7372245a.zip
xenstored: Fairly round-robin schedule work across all connections.
Avoids total starvation under some workloads. Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'tools/xenstore/talloc.c')
-rw-r--r--tools/xenstore/talloc.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/tools/xenstore/talloc.c b/tools/xenstore/talloc.c
index ba189199d7..8bff92b3bc 100644
--- a/tools/xenstore/talloc.c
+++ b/tools/xenstore/talloc.c
@@ -97,6 +97,7 @@ struct talloc_chunk {
struct talloc_chunk *next, *prev;
struct talloc_chunk *parent, *child;
struct talloc_reference_handle *refs;
+ unsigned int null_refs; /* references from null_context */
talloc_destructor_t destructor;
const char *name;
size_t size;
@@ -189,6 +190,7 @@ void *_talloc(const void *context, size_t size)
tc->child = NULL;
tc->name = NULL;
tc->refs = NULL;
+ tc->null_refs = 0;
if (context) {
struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
@@ -225,7 +227,11 @@ void talloc_set_destructor(const void *ptr, int (*destructor)(void *))
*/
void talloc_increase_ref_count(const void *ptr)
{
- talloc_reference(null_context, ptr);
+ struct talloc_chunk *tc;
+ if (ptr == NULL) return;
+
+ tc = talloc_chunk_from_ptr(ptr);
+ tc->null_refs++;
}
/*
@@ -287,6 +293,11 @@ static int talloc_unreference(const void *context, const void *ptr)
context = null_context;
}
+ if ((context == null_context) && tc->null_refs) {
+ tc->null_refs--;
+ return 0;
+ }
+
for (h=tc->refs;h;h=h->next) {
struct talloc_chunk *p = talloc_parent_chunk(h);
if (p == NULL) {
@@ -539,6 +550,11 @@ int talloc_free(void *ptr)
tc = talloc_chunk_from_ptr(ptr);
+ if (tc->null_refs) {
+ tc->null_refs--;
+ return -1;
+ }
+
if (tc->refs) {
talloc_reference_destructor(tc->refs);
return -1;