b_frontend_action.cc
authorZaafar Ahmed <zaafar.tahir@gmail.com>
Wed, 30 Mar 2016 12:59:54 +0000 (17:59 +0500)
committerZaafar Ahmed <zaafar.tahir@gmail.com>
Wed, 30 Mar 2016 12:59:54 +0000 (17:59 +0500)
changed pc_hash/array to percpu_hash/array

table.py
optimised/fixup table.py code based on Brenden feedback

test_percpu.py
Now tests are processor aware and doesn't use sleep
added new line at the EOF

src/cc/frontends/clang/b_frontend_action.cc
src/python/bcc/table.py
tests/python/test_percpu.py

index 3e30c60..a9bd2b8 100644 (file)
@@ -570,9 +570,9 @@ bool BTypeVisitor::VisitVarDecl(VarDecl *Decl) {
       map_type = BPF_MAP_TYPE_HASH;
     } else if (A->getName() == "maps/array") {
       map_type = BPF_MAP_TYPE_ARRAY;
-    } else if (A->getName() == "maps/pc_hash") {
+    } else if (A->getName() == "maps/percpu_hash") {
       map_type = BPF_MAP_TYPE_PERCPU_HASH;
-    } else if (A->getName() == "maps/pc_array") {
+    } else if (A->getName() == "maps/percpu_array") {
       map_type = BPF_MAP_TYPE_PERCPU_ARRAY;
     } else if (A->getName() == "maps/histogram") {
       if (table.key_desc == "\"int\"")
index 948ef4a..72d039c 100644 (file)
@@ -406,8 +406,7 @@ class PerfEventArray(ArrayBase):
 
 class PerCpuHash(HashTable):
     def __init__(self, *args, **kwargs):
-        self.reducer = kwargs["reducer"]
-        del kwargs["reducer"]
+        self.reducer = kwargs.pop("reducer", None)
         super(PerCpuHash, self).__init__(*args, **kwargs)
         self.sLeaf = self.Leaf
         self.total_cpu = multiprocessing.cpu_count()
@@ -424,7 +423,7 @@ class PerCpuHash(HashTable):
             else:
                 raise IndexError("Leaf must be aligned to 8 bytes")
 
-    def __getitem__(self, key):
+    def getvalue(self, key):
         result = super(PerCpuHash, self).__getitem__(key)
         if self.alignment is 0:
             ret = result
@@ -432,10 +431,13 @@ class PerCpuHash(HashTable):
             ret = (self.sLeaf * self.total_cpu)()
             for i in range(0, self.total_cpu):
                 ret[i] = result[i]
-        if (self.reducer):
-            return reduce(self.reducer, ret)
+        return ret
+
+    def __getitem__(self, key):
+        if self.reducer:
+            return reduce(self.reducer, self.getvalue(key))
         else:
-            return ret
+            return self.getvalue(key)
 
     def __setitem__(self, key, leaf):
         super(PerCpuHash, self).__setitem__(key, leaf)
@@ -443,20 +445,12 @@ class PerCpuHash(HashTable):
     def sum(self, key):
         if isinstance(self.Leaf(), ct.Structure):
             raise IndexError("Leaf must be an integer type for default sum functions")
-        temp = self.reducer
-        self.reducer = None
-        result = self.__getitem__(key)
-        self.reducer = temp
-        return self.sLeaf(reduce(lambda x,y: x+y, result))
+        return self.sLeaf(reduce(lambda x,y: x+y, self.getvalue(key)))
 
     def max(self, key):
         if isinstance(self.Leaf(), ct.Structure):
             raise IndexError("Leaf must be an integer type for default max functions")
-        temp = self.reducer
-        self.reducer = None
-        result = self.__getitem__(key)
-        self.reducer = temp
-        return self.sLeaf(max(result))
+        return self.sLeaf(max(self.getvalue(key)))
 
     def average(self, key):
         result = self.sum(key)
@@ -465,8 +459,7 @@ class PerCpuHash(HashTable):
 
 class PerCpuArray(ArrayBase):
     def __init__(self, *args, **kwargs):
-        self.reducer = kwargs["reducer"]
-        del kwargs["reducer"]
+        self.reducer = kwargs.pop("reducer", None)
         super(PerCpuArray, self).__init__(*args, **kwargs)
         self.sLeaf = self.Leaf
         self.total_cpu = multiprocessing.cpu_count()
@@ -483,7 +476,7 @@ class PerCpuArray(ArrayBase):
             else:
                 raise IndexError("Leaf must be aligned to 8 bytes")
 
-    def __getitem__(self, key):
+    def getvalue(self, key):
         result = super(PerCpuArray, self).__getitem__(key)
         if self.alignment is 0:
             ret = result
@@ -491,10 +484,13 @@ class PerCpuArray(ArrayBase):
             ret = (self.sLeaf * self.total_cpu)()
             for i in range(0, self.total_cpu):
                 ret[i] = result[i]
+        return ret
+
+    def __getitem__(self, key):
         if (self.reducer):
-            return reduce(self.reducer, ret)
+            return reduce(self.reducer, self.getvalue(key))
         else:
-            return ret
+            return self.getvalue(key)
 
     def __setitem__(self, key, leaf):
         super(PerCpuArray, self).__setitem__(key, leaf)
@@ -502,20 +498,12 @@ class PerCpuArray(ArrayBase):
     def sum(self, key):
         if isinstance(self.Leaf(), ct.Structure):
             raise IndexError("Leaf must be an integer type for default sum functions")
-        temp = self.reducer
-        self.reducer = None
-        result = self.__getitem__(key)
-        self.reducer = temp
-        return self.sLeaf(reduce(lambda x,y: x+y, result))
+        return self.sLeaf(reduce(lambda x,y: x+y, self.getvalue(key)))
 
     def max(self, key):
         if isinstance(self.Leaf(), ct.Structure):
             raise IndexError("Leaf must be an integer type for default max functions")
-        temp = self.reducer
-        self.reducer = None
-        result = self.__getitem__(key)
-        self.reducer = temp
-        return self.sLeaf(max(result))
+        return self.sLeaf(max(self.getvalue(key)))
 
     def average(self, key):
         result = self.sum(key)
index fa5539d..3f89a54 100755 (executable)
@@ -2,15 +2,16 @@
 # Copyright (c) PLUMgrid, Inc.
 # Licensed under the Apache License, Version 2.0 (the "License")
 
+import os
+import unittest
 from bcc import BPF
-from time import sleep
-import unittest as ut
+import multiprocessing
 
-class TestPercpu(ut.TestCase):
+class TestPercpu(unittest.TestCase):
 
     def test_u64(self):
         test_prog1 = """
-        BPF_TABLE("pc_hash", u32, u64, stats, 1);
+        BPF_TABLE("percpu_hash", u32, u64, stats, 1);
         int hello_world(void *ctx) {
             u32 key=0;
             u64 value = 0, *val;
@@ -23,23 +24,23 @@ class TestPercpu(ut.TestCase):
         bpf_code = BPF(text=test_prog1)
         stats_map = bpf_code.get_table("stats")
         bpf_code.attach_kprobe(event="sys_clone", fn_name="hello_world")
-        sleep(1)
+        ini = stats_map.Leaf()
+        for i in range(0, multiprocessing.cpu_count()):
+            ini[i] = 0
+        stats_map[ stats_map.Key(0) ] = ini
+        f = os.popen("hostname")
+        f.close()
         self.assertEqual(len(stats_map),1)
-        for x in range(0, 10):
-            ini = stats_map.Leaf(0,0,0,0,0,0,0,0)
-            stats_map[ stats_map.Key(0) ] = ini
-            sleep(1)
-            k = stats_map[ stats_map.Key(0) ]
-            x = stats_map.sum(stats_map.Key(0))
-            y = stats_map.average(stats_map.Key(0))
-            z = stats_map.max(stats_map.Key(0))
-            print (x.value)
-            self.assertGreater(x.value, 1L)
-            self.assertGreater(z.value, 1L)
+        val = stats_map[ stats_map.Key(0) ]
+        sum = stats_map.sum(stats_map.Key(0))
+        avg = stats_map.average(stats_map.Key(0))
+        max = stats_map.max(stats_map.Key(0))
+        self.assertGreater(sum.value, 0L)
+        self.assertGreater(max.value, 0L)
 
     def test_u32(self):
         test_prog1 = """
-        BPF_TABLE("pc_array", u32, u32, stats, 1);
+        BPF_TABLE("percpu_array", u32, u32, stats, 1);
         int hello_world(void *ctx) {
             u32 key=0;
             u32 value = 0, *val;
@@ -52,18 +53,19 @@ class TestPercpu(ut.TestCase):
         bpf_code = BPF(text=test_prog1)
         stats_map = bpf_code.get_table("stats")
         bpf_code.attach_kprobe(event="sys_clone", fn_name="hello_world")
-        sleep(1)
+        ini = stats_map.Leaf()
+        for i in range(0, multiprocessing.cpu_count()):
+            ini[i] = 0
+        stats_map[ stats_map.Key(0) ] = ini
+        f = os.popen("hostname")
+        f.close()
         self.assertEqual(len(stats_map),1)
-        for x in range(0, 10):
-            ini = stats_map.Leaf(0,0,0,0,0,0,0,0)
-            stats_map[ stats_map.Key(0) ] = ini
-            sleep(1)
-            k = stats_map[ stats_map.Key(0) ]
-            x = stats_map.sum(stats_map.Key(0))
-            y = stats_map.average(stats_map.Key(0))
-            z = stats_map.max(stats_map.Key(0))
-            self.assertGreater(x.value, 1L)
-            self.assertGreater(z.value, 1L)
+        val = stats_map[ stats_map.Key(0) ]
+        sum = stats_map.sum(stats_map.Key(0))
+        avg = stats_map.average(stats_map.Key(0))
+        max = stats_map.max(stats_map.Key(0))
+        self.assertGreater(sum.value, 0L)
+        self.assertGreater(max.value, 0L)
 
     def test_struct_custom_func(self):
         test_prog2 = """
@@ -71,7 +73,7 @@ class TestPercpu(ut.TestCase):
         u32 c1;
         u32 c2;
         } counter;
-        BPF_TABLE("pc_hash", u32, counter, stats, 1);
+        BPF_TABLE("percpu_hash", u32, counter, stats, 1);
         int hello_world(void *ctx) {
             u32 key=0;
             counter value = {0,0}, *val;
@@ -86,20 +88,19 @@ class TestPercpu(ut.TestCase):
         stats_map = bpf_code.get_table("stats",
                 reducer=lambda x,y: stats_map.sLeaf(x.c1+y.c1))
         bpf_code.attach_kprobe(event="sys_clone", fn_name="hello_world")
-        sleep(1)
+        ini = stats_map.Leaf()
+        for i in ini:
+            i = stats_map.sLeaf(0,0)
+        stats_map[ stats_map.Key(0) ] = ini
+        f = os.popen("hostname")
+        f.close()
         self.assertEqual(len(stats_map),1)
-        for x in range(0, 10):
-            ini = stats_map.Leaf()
-            for i in ini:
-                i = stats_map.sLeaf(0,0)
-            stats_map[ stats_map.Key(0) ] = ini
-            sleep(1)
-            k = stats_map[ stats_map.Key(0) ]
-            self.assertGreater(k.c1, 1L)
+        k = stats_map[ stats_map.Key(0) ]
+        self.assertGreater(k.c1, 0L)
 
     def cleanup(self):
         BPF.detach_kprobe("sys_clone")
 
 
 if __name__ == "__main__":
-    ut.main()
\ No newline at end of file
+    unittest.main()