191dc43ddSMatthew Dillon /*
291dc43ddSMatthew Dillon * Copyright (c) 2020 The DragonFly Project. All rights reserved.
391dc43ddSMatthew Dillon *
491dc43ddSMatthew Dillon * This code is derived from software contributed to The DragonFly Project
591dc43ddSMatthew Dillon * by Matthew Dillon <dillon@backplane.com>
691dc43ddSMatthew Dillon *
791dc43ddSMatthew Dillon * Redistribution and use in source and binary forms, with or without
891dc43ddSMatthew Dillon * modification, are permitted provided that the following conditions
991dc43ddSMatthew Dillon * are met:
1091dc43ddSMatthew Dillon *
1191dc43ddSMatthew Dillon * 1. Redistributions of source code must retain the above copyright
1291dc43ddSMatthew Dillon * notice, this list of conditions and the following disclaimer.
1391dc43ddSMatthew Dillon * 2. Redistributions in binary form must reproduce the above copyright
1491dc43ddSMatthew Dillon * notice, this list of conditions and the following disclaimer in
1591dc43ddSMatthew Dillon * the documentation and/or other materials provided with the
1691dc43ddSMatthew Dillon * distribution.
1791dc43ddSMatthew Dillon * 3. Neither the name of The DragonFly Project nor the names of its
1891dc43ddSMatthew Dillon * contributors may be used to endorse or promote products derived
1991dc43ddSMatthew Dillon * from this software without specific, prior written permission.
2091dc43ddSMatthew Dillon *
2191dc43ddSMatthew Dillon * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2291dc43ddSMatthew Dillon * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2391dc43ddSMatthew Dillon * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
2491dc43ddSMatthew Dillon * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
2591dc43ddSMatthew Dillon * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
2691dc43ddSMatthew Dillon * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
2791dc43ddSMatthew Dillon * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2891dc43ddSMatthew Dillon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
2991dc43ddSMatthew Dillon * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
3091dc43ddSMatthew Dillon * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
3191dc43ddSMatthew Dillon * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3291dc43ddSMatthew Dillon * SUCH DAMAGE.
3391dc43ddSMatthew Dillon */
3491dc43ddSMatthew Dillon
3591dc43ddSMatthew Dillon #include "flame.h"
3691dc43ddSMatthew Dillon
3791dc43ddSMatthew Dillon typedef struct elm {
3891dc43ddSMatthew Dillon struct elm *next;
3991dc43ddSMatthew Dillon uint64_t hv;
4091dc43ddSMatthew Dillon long ticks;
4191dc43ddSMatthew Dillon const char *id;
4291dc43ddSMatthew Dillon size_t idlen;
4391dc43ddSMatthew Dillon } elm_t;
4491dc43ddSMatthew Dillon
4591dc43ddSMatthew Dillon #define MAXELM 256
4691dc43ddSMatthew Dillon #define HSIZE (1024*1024)
4791dc43ddSMatthew Dillon #define HMASK (HSIZE - 1)
4891dc43ddSMatthew Dillon
4991dc43ddSMatthew Dillon static elm_t *elm_lookup(const char *s);
5091dc43ddSMatthew Dillon static void flame_process_dump(void);
5191dc43ddSMatthew Dillon
52*d50f9ae3SSascha Wildner static long total_ticks;
5391dc43ddSMatthew Dillon
5491dc43ddSMatthew Dillon void
flame_process_loop(void)5591dc43ddSMatthew Dillon flame_process_loop(void)
5691dc43ddSMatthew Dillon {
5791dc43ddSMatthew Dillon char buf[4096];
5891dc43ddSMatthew Dillon char *s;
5991dc43ddSMatthew Dillon elm_t *elm;
6091dc43ddSMatthew Dillon /*elm_t *elms[MAXELM];*/
6191dc43ddSMatthew Dillon int n;
6291dc43ddSMatthew Dillon
6391dc43ddSMatthew Dillon while (fgets(buf, sizeof(buf), stdin) != NULL) {
6491dc43ddSMatthew Dillon n = 0;
6591dc43ddSMatthew Dillon
6691dc43ddSMatthew Dillon s = strtok(buf, " \t\n\r");
6791dc43ddSMatthew Dillon if (s == NULL || strchr(s, '/') == NULL)
6891dc43ddSMatthew Dillon continue;
6991dc43ddSMatthew Dillon while ((s = strtok(NULL, " \t\n\r")) != NULL) {
7091dc43ddSMatthew Dillon elm = elm_lookup(s);
7191dc43ddSMatthew Dillon /*elms[n] = elm;*/
7291dc43ddSMatthew Dillon ++elm->ticks;
7391dc43ddSMatthew Dillon
7491dc43ddSMatthew Dillon if (n == MAXELM)
7591dc43ddSMatthew Dillon break;
7691dc43ddSMatthew Dillon ++n;
7791dc43ddSMatthew Dillon }
7891dc43ddSMatthew Dillon ++total_ticks;
7991dc43ddSMatthew Dillon /* more processing later */
8091dc43ddSMatthew Dillon }
8191dc43ddSMatthew Dillon flame_process_dump();
8291dc43ddSMatthew Dillon }
8391dc43ddSMatthew Dillon
8491dc43ddSMatthew Dillon static elm_t *elm_hash_array[HSIZE];
8591dc43ddSMatthew Dillon
8691dc43ddSMatthew Dillon static elm_t *
elm_lookup(const char * s)8791dc43ddSMatthew Dillon elm_lookup(const char *s)
8891dc43ddSMatthew Dillon {
8991dc43ddSMatthew Dillon size_t len;
9091dc43ddSMatthew Dillon uint64_t hv;
9191dc43ddSMatthew Dillon elm_t **scanp;
9291dc43ddSMatthew Dillon elm_t *scan;
9391dc43ddSMatthew Dillon
9491dc43ddSMatthew Dillon if (s[0] == '0' && s[1] == 'x') {
9591dc43ddSMatthew Dillon hv = strtoul(s, NULL, 0);
9691dc43ddSMatthew Dillon if (hv < 0x8000000000000000LU)
9791dc43ddSMatthew Dillon s = "__userland__";
9891dc43ddSMatthew Dillon }
9991dc43ddSMatthew Dillon
10091dc43ddSMatthew Dillon hv = 0;
10191dc43ddSMatthew Dillon for (len = 0; s[len] && s[len] != '+' && s[len] != '('; ++len)
10291dc43ddSMatthew Dillon hv = hv * 13 ^ (uint8_t)s[len];
10391dc43ddSMatthew Dillon
10491dc43ddSMatthew Dillon scanp = &elm_hash_array[hv % HSIZE];
10591dc43ddSMatthew Dillon while ((scan = *scanp) != NULL) {
10691dc43ddSMatthew Dillon if (scan->hv == hv && len == scan->idlen &&
10791dc43ddSMatthew Dillon bcmp(s, scan->id, len) == 0) {
10891dc43ddSMatthew Dillon return scan;
10991dc43ddSMatthew Dillon }
11091dc43ddSMatthew Dillon scanp = &scan->next;
11191dc43ddSMatthew Dillon }
11291dc43ddSMatthew Dillon scan = malloc(sizeof(elm_t));
11391dc43ddSMatthew Dillon bzero(scan, sizeof(*scan));
11491dc43ddSMatthew Dillon *scanp = scan;
11591dc43ddSMatthew Dillon scan->hv = hv;
11691dc43ddSMatthew Dillon scan->id = strdup(s);
11791dc43ddSMatthew Dillon scan->idlen = len;
11891dc43ddSMatthew Dillon
11991dc43ddSMatthew Dillon return scan;
12091dc43ddSMatthew Dillon }
12191dc43ddSMatthew Dillon
12291dc43ddSMatthew Dillon static void
flame_process_dump(void)12391dc43ddSMatthew Dillon flame_process_dump(void)
12491dc43ddSMatthew Dillon {
12591dc43ddSMatthew Dillon elm_t *elm;
12691dc43ddSMatthew Dillon int i;
12791dc43ddSMatthew Dillon
12891dc43ddSMatthew Dillon for (i = 0; i < HSIZE; ++i) {
12991dc43ddSMatthew Dillon for (elm = elm_hash_array[i]; elm; elm = elm->next) {
13091dc43ddSMatthew Dillon printf("%-6ld %6.3f%% %*.*s\n",
13191dc43ddSMatthew Dillon elm->ticks,
13291dc43ddSMatthew Dillon (double)elm->ticks * 100.0 /
13391dc43ddSMatthew Dillon (double)total_ticks,
13491dc43ddSMatthew Dillon (int)elm->idlen, (int)elm->idlen, elm->id);
13591dc43ddSMatthew Dillon }
13691dc43ddSMatthew Dillon }
13791dc43ddSMatthew Dillon }
138