summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--runtime/ChangeLog13
-rw-r--r--runtime/map-gen.c13
-rw-r--r--runtime/map.c17
-rw-r--r--runtime/map.h2
-rw-r--r--runtime/pmap-gen.c48
5 files changed, 71 insertions, 22 deletions
diff --git a/runtime/ChangeLog b/runtime/ChangeLog
index 18999439..7155d74c 100644
--- a/runtime/ChangeLog
+++ b/runtime/ChangeLog
@@ -1,3 +1,16 @@
+2005-12-14 Martin Hunt <hunt@redhat.com>
+
+ * pmap-gen.c (_stp_pmap_new_*): Initialize lock.
+ (_stp_pmap_set_*): Lock map while in use.
+ (_stp_pmap_add_*): Lock map while in use.
+ (_stp_pmap_get_cpu): Ditto.
+ (_stp_pmap_get): Lock each per-cpu map.
+
+ * map-gen.c: Define and use NULLRET for a NULL return value.
+ * map.c (_stp_pmap_clear): New function.
+ (_stp_pmap_agg): Lock each per-cpu map as
+ it gets aggregated.
+
2005-12-13 Martin Hunt <hunt@redhat.com>
* map.c (_stp_map_sortn): Set a limit of 30 for n. Automatically
diff --git a/runtime/map-gen.c b/runtime/map-gen.c
index fccdecdc..66654913 100644
--- a/runtime/map-gen.c
+++ b/runtime/map-gen.c
@@ -41,6 +41,7 @@
#define MAP_SET_VAL(a,b,c,d) _new_map_set_str(a,b,c,d)
#define MAP_GET_VAL(n) _stp_get_str(n)
#define VAL_IS_ZERO(val,add) (val == 0 || *val == 0)
+#define NULLRET ""
#elif VALUE_TYPE == INT64
#define VALTYPE int64_t
#define VSTYPE int64_t
@@ -49,6 +50,7 @@
#define MAP_SET_VAL(a,b,c,d) _new_map_set_int64(a,b,c,d)
#define MAP_GET_VAL(n) _stp_get_int64(n)
#define VAL_IS_ZERO(val,add) (val == 0)
+#define NULLRET (int64_t)0
#elif VALUE_TYPE == STAT
#define VALTYPE stat*
#define VSTYPE int64_t
@@ -57,6 +59,7 @@
#define MAP_SET_VAL(a,b,c,d) _new_map_set_stat(a,b,c,d)
#define MAP_GET_VAL(n) _stp_get_stat(n)
#define VAL_IS_ZERO(val,add) (val == 0 && !add)
+#define NULLRET (stat*)0
#else
#error Need to define VALUE_TYPE as STRING, STAT, or INT64
#endif /* VALUE_TYPE */
@@ -466,7 +469,7 @@ VALTYPE KEYSYM(_stp_map_get) (MAP map, ALLKEYSD(key))
struct KEYSYM(map_node) *n;
if (map == NULL)
- return (VALTYPE)0;
+ return NULLRET;
hv = KEYSYM(hash) (ALLKEYS(key));
head = &map->hashes[hv];
@@ -492,11 +495,7 @@ VALTYPE KEYSYM(_stp_map_get) (MAP map, ALLKEYSD(key))
}
}
/* key not found */
-#if VALUE_TYPE == STRING
- return "";
-#else
- return (VALTYPE)0;
-#endif
+ return NULLRET;
}
@@ -550,4 +549,4 @@ VALTYPE KEYSYM(_stp_map_get) (MAP map, ALLKEYSD(key))
#undef MAP_SET_VAL
#undef MAP_GET_VAL
#undef VAL_IS_ZERO
-
+#undef NULLRET
diff --git a/runtime/map.c b/runtime/map.c
index 1fa4a0e5..1d6d084e 100644
--- a/runtime/map.c
+++ b/runtime/map.c
@@ -355,6 +355,21 @@ void _stp_map_clear(MAP map)
}
}
+void _stp_pmap_clear(PMAP pmap)
+{
+ int i;
+
+ if (pmap == NULL)
+ return;
+
+ for_each_cpu(i) {
+ MAP m = per_cpu_ptr (pmap->map, i);
+ spin_lock(&m->lock);
+ _stp_map_clear(m);
+ spin_unlock(&m->lock);
+ }
+ _stp_map_clear(&pmap->agg);
+}
static void __stp_map_del(MAP map)
{
@@ -853,6 +868,7 @@ MAP _stp_pmap_agg (PMAP pmap)
for_each_cpu(i) {
m = per_cpu_ptr (pmap->map, i);
+ spin_lock(&m->lock);
/* walk the hash chains. */
for (hash = 0; hash < HASH_TABLE_SIZE; hash++) {
head = &m->hashes[hash];
@@ -873,6 +889,7 @@ MAP _stp_pmap_agg (PMAP pmap)
_stp_new_agg(agg, ahead, ptr);
}
}
+ spin_unlock(&m->lock);
}
return agg;
}
diff --git a/runtime/map.h b/runtime/map.h
index cc470e19..4bb8aee2 100644
--- a/runtime/map.h
+++ b/runtime/map.h
@@ -102,6 +102,8 @@ struct map_root {
int data_offset;
+ spinlock_t lock;
+
/* the hash table for this array */
struct hlist_head hashes[HASH_TABLE_SIZE];
diff --git a/runtime/pmap-gen.c b/runtime/pmap-gen.c
index 49d4f0f4..035fccbf 100644
--- a/runtime/pmap-gen.c
+++ b/runtime/pmap-gen.c
@@ -41,6 +41,7 @@
#define MAP_SET_VAL(a,b,c,d) _new_map_set_str(a,b,c,d)
#define MAP_GET_VAL(n) _stp_get_str(n)
#define VAL_IS_ZERO(val,add) (val == 0 || *val == 0)
+#define NULLRET ""
#elif VALUE_TYPE == INT64
#define VALTYPE int64_t
#define VSTYPE int64_t
@@ -49,6 +50,7 @@
#define MAP_SET_VAL(a,b,c,d) _new_map_set_int64(a,b,c,d)
#define MAP_GET_VAL(n) _stp_get_int64(n)
#define VAL_IS_ZERO(val,add) (val == 0)
+#define NULLRET (int64_t)0
#elif VALUE_TYPE == STAT
#define VALTYPE stat*
#define VSTYPE int64_t
@@ -57,6 +59,7 @@
#define MAP_SET_VAL(a,b,c,d) _new_map_set_stat(a,b,c,d)
#define MAP_GET_VAL(n) _stp_get_stat(n)
#define VAL_IS_ZERO(val,add) (val == 0 && !add)
+#define NULLRET (stat*)0
#else
#error Need to define VALUE_TYPE as STRING, STAT, or INT64
#endif /* VALUE_TYPE */
@@ -411,6 +414,7 @@ PMAP KEYSYM(_stp_pmap_new) (unsigned max_entries)
m->get_key = KEYSYM(pmap_get_key);
m->copy = KEYSYM(pmap_copy_keys);
m->cmp = KEYSYM(pmap_key_cmp);
+ m->lock = SPIN_LOCK_UNLOCKED;
}
m = &pmap->agg;
m->get_key = KEYSYM(pmap_get_key);
@@ -468,6 +472,7 @@ PMAP KEYSYM(_stp_pmap_new) (unsigned max_entries, int htype, ...)
m->get_key = KEYSYM(pmap_get_key);
m->copy = KEYSYM(pmap_copy_keys);
m->cmp = KEYSYM(pmap_key_cmp);
+ m->lock = SPIN_LOCK_UNLOCKED;
}
m = &pmap->agg;
m->get_key = KEYSYM(pmap_get_key);
@@ -520,30 +525,41 @@ int KEYSYM(__stp_pmap_set) (MAP map, ALLKEYSD(key), VSTYPE val, int add)
return MAP_SET_VAL(map,(struct map_node *)n, val, add);
}
}
+
/* key not found */
dbug("key not found\n");
+
if VAL_IS_ZERO(val,add)
return 0;
n = (struct KEYSYM(pmap_node)*)_new_map_create (map, head);
if (n == NULL)
return -1;
+
KEYCPY(n);
return MAP_SET_VAL(map,(struct map_node *)n, val, 0);
}
int KEYSYM(_stp_pmap_set) (PMAP pmap, ALLKEYSD(key), VSTYPE val)
{
+ int res;
MAP m = per_cpu_ptr (pmap->map, get_cpu());
- int res = KEYSYM(__stp_pmap_set) (m, ALLKEYS(key), val, 0);
+ if (!spin_trylock(&m->lock))
+ return -3;
+ res = KEYSYM(__stp_pmap_set) (m, ALLKEYS(key), val, 0);
+ spin_unlock(&m->lock);
put_cpu();
return res;
}
int KEYSYM(_stp_pmap_add) (PMAP pmap, ALLKEYSD(key), VSTYPE val)
{
+ int res;
MAP m = per_cpu_ptr (pmap->map, get_cpu());
- int res = KEYSYM(__stp_pmap_set) (m, ALLKEYS(key), val, 1);
+ if (!spin_trylock(&m->lock))
+ return -3;
+ res = KEYSYM(__stp_pmap_set) (m, ALLKEYS(key), val, 1);
+ spin_unlock(&m->lock);
put_cpu();
return res;
}
@@ -559,13 +575,16 @@ VALTYPE KEYSYM(_stp_pmap_get_cpu) (PMAP pmap, ALLKEYSD(key))
MAP map;
if (pmap == NULL)
- return (VALTYPE)0;
+ return NULLRET;
map = per_cpu_ptr (pmap->map, get_cpu());
hv = KEYSYM(phash) (ALLKEYS(key));
head = &map->hashes[hv];
+ if (!spin_trylock(&map->lock))
+ return NULLRET;
+
hlist_for_each(e, head) {
n = (struct KEYSYM(pmap_node) *)((long)e - sizeof(struct list_head));
dbug("map_node =%lx\n", (long)n);
@@ -584,17 +603,15 @@ VALTYPE KEYSYM(_stp_pmap_get_cpu) (PMAP pmap, ALLKEYSD(key))
#endif
) {
res = MAP_GET_VAL((struct map_node *)n);
+ spin_unlock(&map->lock);
put_cpu();
return res;
}
}
/* key not found */
+ spin_unlock(&map->lock);
put_cpu();
-#if VALUE_TYPE == STRING
- return "";
-#else
- return (VALTYPE)0;
-#endif
+ return NULLRET;
}
VALTYPE KEYSYM(_stp_pmap_get) (PMAP pmap, ALLKEYSD(key))
@@ -608,7 +625,7 @@ VALTYPE KEYSYM(_stp_pmap_get) (PMAP pmap, ALLKEYSD(key))
MAP map, agg;
if (pmap == NULL)
- return (VALTYPE)0;
+ return NULLRET;
hv = KEYSYM(phash) (ALLKEYS(key));
@@ -641,6 +658,10 @@ VALTYPE KEYSYM(_stp_pmap_get) (PMAP pmap, ALLKEYSD(key))
for_each_cpu(cpu) {
map = per_cpu_ptr (pmap->map, cpu);
head = &map->hashes[hv];
+
+ if (!spin_trylock(&map->lock))
+ return NULLRET;
+
hlist_for_each(e, head) {
n = (struct KEYSYM(pmap_node) *)((long)e - sizeof(struct list_head));
if (KEY1_EQ_P(n->key1, key1)
@@ -664,16 +685,13 @@ VALTYPE KEYSYM(_stp_pmap_get) (PMAP pmap, ALLKEYSD(key))
_stp_add_agg(anode, (struct map_node *)n);
}
}
+ spin_unlock(&map->lock);
}
if (anode)
return MAP_GET_VAL(anode);
/* key not found */
-#if VALUE_TYPE == STRING
- return "";
-#else
- return (VALTYPE)0;
-#endif
+ return NULLRET;
}
#undef KEY1NAME
@@ -726,4 +744,4 @@ VALTYPE KEYSYM(_stp_pmap_get) (PMAP pmap, ALLKEYSD(key))
#undef MAP_SET_VAL
#undef MAP_GET_VAL
#undef VAL_IS_ZERO
-
+#undef NULLRET