usb: gadget: pch_udc: Reduce redundant interrupt
[linux-flexiantxendom0.git] / lib / plist.c
index 8c614d0..a0a4da4 100644 (file)
@@ -28,6 +28,8 @@
 
 #ifdef CONFIG_DEBUG_PI_LIST
 
+static struct plist_head test_head;
+
 static void plist_check_prev_next(struct list_head *t, struct list_head *p,
                                  struct list_head *n)
 {
@@ -54,11 +56,6 @@ static void plist_check_list(struct list_head *top)
 
 static void plist_check_head(struct plist_head *head)
 {
-       WARN_ON(!head->rawlock && !head->spinlock);
-       if (head->rawlock)
-               WARN_ON_SMP(!raw_spin_is_locked(head->rawlock));
-       if (head->spinlock)
-               WARN_ON_SMP(!spin_is_locked(head->spinlock));
        if (!plist_head_empty(head))
                plist_check_list(&plist_first(head)->prio_list);
        plist_check_list(&head->node_list);
@@ -135,3 +132,80 @@ void plist_del(struct plist_node *node, struct plist_head *head)
 
        plist_check_head(head);
 }
+
+#ifdef CONFIG_DEBUG_PI_LIST
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+static struct plist_node __initdata test_node[241];
+
+static void __init plist_test_check(int nr_expect)
+{
+       struct plist_node *first, *prio_pos, *node_pos;
+
+       if (plist_head_empty(&test_head)) {
+               BUG_ON(nr_expect != 0);
+               return;
+       }
+
+       prio_pos = first = plist_first(&test_head);
+       plist_for_each(node_pos, &test_head) {
+               if (nr_expect-- < 0)
+                       break;
+               if (node_pos == first)
+                       continue;
+               if (node_pos->prio == prio_pos->prio) {
+                       BUG_ON(!list_empty(&node_pos->prio_list));
+                       continue;
+               }
+
+               BUG_ON(prio_pos->prio > node_pos->prio);
+               BUG_ON(prio_pos->prio_list.next != &node_pos->prio_list);
+               prio_pos = node_pos;
+       }
+
+       BUG_ON(nr_expect != 0);
+       BUG_ON(prio_pos->prio_list.next != &first->prio_list);
+}
+
+static int  __init plist_test(void)
+{
+       int nr_expect = 0, i, loop;
+       unsigned int r = local_clock();
+
+       printk(KERN_INFO "start plist test\n");
+       plist_head_init(&test_head);
+       for (i = 0; i < ARRAY_SIZE(test_node); i++)
+               plist_node_init(test_node + i, 0);
+
+       for (loop = 0; loop < 1000; loop++) {
+               r = r * 193939 % 47629;
+               i = r % ARRAY_SIZE(test_node);
+               if (plist_node_empty(test_node + i)) {
+                       r = r * 193939 % 47629;
+                       test_node[i].prio = r % 99;
+                       plist_add(test_node + i, &test_head);
+                       nr_expect++;
+               } else {
+                       plist_del(test_node + i, &test_head);
+                       nr_expect--;
+               }
+               plist_test_check(nr_expect);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(test_node); i++) {
+               if (plist_node_empty(test_node + i))
+                       continue;
+               plist_del(test_node + i, &test_head);
+               nr_expect--;
+               plist_test_check(nr_expect);
+       }
+
+       printk(KERN_INFO "end plist test\n");
+       return 0;
+}
+
+module_init(plist_test);
+
+#endif