]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #2474 from donaldsharp/vty_thread_cancel_writes
authorRuss White <russ@riw.us>
Tue, 19 Jun 2018 11:28:18 +0000 (07:28 -0400)
committerGitHub <noreply@github.com>
Tue, 19 Jun 2018 11:28:18 +0000 (07:28 -0400)
Add 'show thread poll'

lib/hash.c
lib/thread.c
vtysh/vtysh.c

index ee5401b2367a4816111439863c3b67f1d8df51d7..37f6cdcc8f86a4c3d65e405131942fa2d1fe1367 100644 (file)
@@ -241,15 +241,21 @@ void hash_iterate(struct hash *hash, void (*func)(struct hash_backet *, void *),
        unsigned int i;
        struct hash_backet *hb;
        struct hash_backet *hbnext;
+       uint32_t count = 0;
 
-       for (i = 0; i < hash->size; i++)
+       for (i = 0; i < hash->size; i++) {
                for (hb = hash->index[i]; hb; hb = hbnext) {
                        /* get pointer to next hash backet here, in case (*func)
                         * decides to delete hb by calling hash_release
                         */
                        hbnext = hb->next;
                        (*func)(hb, arg);
+                       count++;
+
                }
+               if (count == hash->count)
+                       return;
+       }
 }
 
 void hash_walk(struct hash *hash, int (*func)(struct hash_backet *, void *),
@@ -259,6 +265,7 @@ void hash_walk(struct hash *hash, int (*func)(struct hash_backet *, void *),
        struct hash_backet *hb;
        struct hash_backet *hbnext;
        int ret = HASHWALK_CONTINUE;
+       uint32_t count = 0;
 
        for (i = 0; i < hash->size; i++) {
                for (hb = hash->index[i]; hb; hb = hbnext) {
@@ -269,7 +276,10 @@ void hash_walk(struct hash *hash, int (*func)(struct hash_backet *, void *),
                        ret = (*func)(hb, arg);
                        if (ret == HASHWALK_ABORT)
                                return;
+                       count++;
                }
+               if (count == hash->count)
+                       return;
        }
 }
 
index 18e1c922804cf43faad3302a2860582835ab79e2..1c5e8387729774dc9bf355b47055c6a736e97383 100644 (file)
@@ -296,6 +296,47 @@ DEFUN (show_thread_cpu,
        return CMD_SUCCESS;
 }
 
+static void show_thread_poll_helper(struct vty *vty, struct thread_master *m)
+{
+       const char *name = m->name ? m->name : "main";
+       char underline[strlen(name) + 1];
+       uint32_t i;
+
+       memset(underline, '-', sizeof(underline));
+       underline[sizeof(underline) - 1] = '\0';
+
+       vty_out(vty, "\nShowing poll FD's for %s\n", name);
+       vty_out(vty, "----------------------%s\n", underline);
+       vty_out(vty, "Count: %u\n", (uint32_t)m->handler.pfdcount);
+       for (i = 0; i < m->handler.pfdcount; i++)
+               vty_out(vty, "\t%6d fd:%6d events:%2d revents:%2d\n", i,
+                       m->handler.pfds[i].fd,
+                       m->handler.pfds[i].events,
+                       m->handler.pfds[i].revents);
+}
+
+DEFUN (show_thread_poll,
+       show_thread_poll_cmd,
+       "show thread poll",
+       SHOW_STR
+       "Thread information\n"
+       "Show poll FD's and information\n")
+{
+       struct listnode *node;
+       struct thread_master *m;
+
+       pthread_mutex_lock(&masters_mtx);
+       {
+               for (ALL_LIST_ELEMENTS_RO(masters, node, m)) {
+                       show_thread_poll_helper(vty, m);
+               }
+       }
+       pthread_mutex_unlock(&masters_mtx);
+
+       return CMD_SUCCESS;
+}
+
+
 DEFUN (clear_thread_cpu,
        clear_thread_cpu_cmd,
        "clear thread cpu [FILTER]",
@@ -325,6 +366,7 @@ DEFUN (clear_thread_cpu,
 void thread_cmd_init(void)
 {
        install_element(VIEW_NODE, &show_thread_cpu_cmd);
+       install_element(VIEW_NODE, &show_thread_poll_cmd);
        install_element(ENABLE_NODE, &clear_thread_cpu_cmd);
 }
 /* CLI end ------------------------------------------------------------------ */
index 328c68d8265f4e40b46dc0a097374293cd2b8356..309493b13e9fc199d717c445868b967fc8185603 100644 (file)
@@ -2136,6 +2136,28 @@ DEFUNSH(VTYSH_INTERFACE, vtysh_quit_interface, vtysh_quit_interface_cmd, "quit",
        return vtysh_exit_interface(self, vty, argc, argv);
 }
 
+DEFUN (vtysh_show_poll,
+       vtysh_show_poll_cmd,
+       "show thread poll",
+       SHOW_STR
+       "Thread information\n"
+       "Thread Poll Information\n")
+{
+       unsigned int i;
+       int ret = CMD_SUCCESS;
+       char line[100];
+
+       snprintf(line, sizeof(line), "do show thread poll\n");
+       for (i = 0; i < array_size(vtysh_client); i++)
+               if (vtysh_client[i].fd >= 0) {
+                       vty_out(vty, "Thread statistics for %s:\n",
+                               vtysh_client[i].name);
+                       ret = vtysh_client_execute(&vtysh_client[i], line);
+                       vty_out(vty, "\n");
+               }
+       return ret;
+}
+
 DEFUN (vtysh_show_thread,
        vtysh_show_thread_cmd,
        "show thread cpu [FILTER]",
@@ -3724,6 +3746,7 @@ void vtysh_init_vty(void)
        install_element(VIEW_NODE, &vtysh_show_work_queues_cmd);
        install_element(VIEW_NODE, &vtysh_show_work_queues_daemon_cmd);
        install_element(VIEW_NODE, &vtysh_show_thread_cmd);
+       install_element(VIEW_NODE, &vtysh_show_poll_cmd);
 
        /* Logging */
        install_element(VIEW_NODE, &vtysh_show_logging_cmd);