From c1b79eb035fa158fb2ac3bc8e559809611070016 Mon Sep 17 00:00:00 2001 From: Yaniv Kamay Date: Sat, 19 Sep 2009 21:25:46 +0300 Subject: fresh start --- tools/bitmap_to_c.c | 396 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/icon_to_c.c | 369 ++++++++++++++++++++++++++++++++++++++++++++++++ tools/reds_stat.c | 132 ++++++++++++++++++ 3 files changed, 897 insertions(+) create mode 100644 tools/bitmap_to_c.c create mode 100644 tools/icon_to_c.c create mode 100644 tools/reds_stat.c (limited to 'tools') diff --git a/tools/bitmap_to_c.c b/tools/bitmap_to_c.c new file mode 100644 index 00000000..3329d5ed --- /dev/null +++ b/tools/bitmap_to_c.c @@ -0,0 +1,396 @@ +/* + Copyright (C) 2009 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define ALIGN(a, b) (((a) + ((b) - 1)) & ~((b) - 1)) +#define TRUE 1 +#define FALSE 0 + +#define ERROR(str) printf("%s: error: %s\n", prog_name, str); exit(-1); + +static char *prog_name = NULL; + +static size_t read_input(const char *file_name, uint8_t** out_buf) +{ + int fd = open(file_name, O_RDONLY); + if (fd == -1) { + ERROR("open source file failed"); + return 0; + } + struct stat file_stat; + if (fstat(fd, &file_stat) == -1) { + ERROR("fstat on source file failed"); + return 0; + } + + uint8_t *buf = malloc(file_stat.st_size); + + if (!buf) { + close(fd); + ERROR("alloc mem failed"); + return 0; + } + + size_t to_read = file_stat.st_size; + uint8_t *buf_pos = buf; + while (to_read) { + int n = read(fd, buf_pos, to_read); + if (n <= 0) { + ERROR("read from source file failed"); + close(fd); + free(buf); + return 0; + } + to_read -= n; + buf_pos += n; + } + close(fd); + *out_buf = buf; + return file_stat.st_size; +} + +typedef struct __attribute__ ((__packed__)) BitmpaHeader { + uint32_t header_size; + uint32_t width; + uint32_t height; + uint16_t plans; + uint16_t bpp; + uint32_t compression; + uint32_t image_size; + uint32_t horizontal_resolution; + uint32_t vertical_resolution; + uint32_t num_colors; + uint32_t important_colors; +} BitmpaHeader; + +typedef struct __attribute__ ((__packed__)) BMPFileHeader { + uint16_t magic; + uint32_t file_size; + uint32_t reserved; + uint32_t data_offset; + BitmpaHeader header; +} BMPFileHeader; + +#define BI_RGB 0 + +typedef struct Pixmap { + uint32_t width; + uint32_t height; + uint32_t stride; + uint32_t bpp; + uint8_t* data; +} Pixmap; + +static Pixmap *init_bitmap(size_t input_size, uint8_t *buf) +{ + BMPFileHeader *file_header; + uint8_t *pixels; + Pixmap *pixmap; + uint32_t stride; + + + if (input_size < sizeof(BMPFileHeader)) { + ERROR("invalid source file"); + return NULL; + } + + file_header = (BMPFileHeader *)buf; + + if (file_header->magic != 0x4d42) { + ERROR("bad bitmap magic"); + return NULL; + } + + if (file_header->file_size != input_size) { + ERROR("invalid source file"); + return NULL; + } + + if (file_header->header.header_size != 40 || file_header->header.plans != 1 || + file_header->header.compression != BI_RGB || + !file_header->header.width || + !file_header->header.height) { + ERROR("invalid bitmap header"); + return NULL; + } + + if (file_header->header.bpp == 32) { + stride = file_header->header.width * sizeof(uint32_t); + } else if (file_header->header.bpp == 24) { + stride = ALIGN(file_header->header.width * 3, 4); + } else { + ERROR("unsupported bpp"); + return NULL; + } + + if (file_header->header.height * stride > file_header->header.image_size) { + ERROR("image size is to small"); + return NULL; + } + pixels = buf + file_header->data_offset; + if (pixels < (uint8_t *)(file_header + 1) || + pixels + file_header->header.image_size > buf + input_size) { + ERROR("bad data offset"); + return NULL; + } + + if (!(pixmap = (Pixmap *)malloc(sizeof(*pixmap)))) { + ERROR("alloc mem failed"); + return NULL; + } + + pixmap->width = file_header->header.width; + pixmap->height = file_header->header.height; + pixmap->stride = stride; + pixmap->bpp = file_header->header.bpp; + pixmap->data = pixels; + return pixmap; +} + +static inline void put_char(FILE* f, uint8_t val) +{ + fprintf(f, "0x%.2x,", val); +} + +static void do_dump_with_alpha_conversion(const Pixmap *pixmap, FILE *f) +{ + uint8_t *line = (uint8_t *)(pixmap->data + ((pixmap->height - 1) * pixmap->stride)); + int line_size = 0; + int i, j; + + for (i = 0; i < pixmap->height; i++) { + uint8_t *now = line; + for (j = 0; j < pixmap->width; j++, now += 4) { + if ((line_size++ % 6) == 0) { + fprintf(f, "\n\t\t"); + } + double alpha = (double)now[3] / 0xff; + put_char(f, alpha * now[0]); + put_char(f, alpha * now[1]); + put_char(f, alpha * now[2]); + put_char(f, now[3]); + } + line -= pixmap->stride; + } +} + +static void do_dump_32bpp(const Pixmap *pixmap, FILE *f) +{ + uint8_t *line = (uint8_t *)(pixmap->data + ((pixmap->height - 1) * pixmap->stride)); + int line_size = 0; + int i, j; + + for (i = 0; i < pixmap->height; i++) { + uint8_t *now = line; + for (j = 0; j < pixmap->width; j++, now += 4) { + if ((line_size++ % 6) == 0) { + fprintf(f, "\n\t\t"); + } + put_char(f, now[0]); + put_char(f, now[1]); + put_char(f, now[2]); + put_char(f, now[3]); + } + line -= pixmap->stride; + } +} + +static void do_dump_24bpp(const Pixmap *pixmap, FILE *f) +{ + uint8_t *line = (uint8_t *)(pixmap->data + ((pixmap->height - 1) * pixmap->stride)); + int line_size = 0; + int i, j; + + for (i = 0; i < pixmap->height; i++) { + uint8_t *now = line; + for (j = 0; j < pixmap->width; j++, now += 3) { + if ((line_size++ % 6) == 0) { + fprintf(f, "\n\t\t"); + } + put_char(f, now[0]); + put_char(f, now[1]); + put_char(f, now[2]); + put_char(f, 0); + } + line -= pixmap->stride; + } +} + +static int pixmap_to_c_struct(const Pixmap *pixmap, const char *dest_file, const char *image_name, + int alpha_convertion) +{ + int fd; + FILE *f; + + if ((fd = open(dest_file, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) { + ERROR("open dest file failed"); + return -1; + } + + if (!(f = fdopen(fd, "w"))) { + ERROR("fdopen failed"); + close(fd); + return -1; + } + + uint32_t data_size = pixmap->width * sizeof(uint32_t) * pixmap->height; + fprintf(f, "static const struct {\n" + "\tuint32_t width;\n" + "\tuint32_t height;\n" + "\tuint8_t pixel_data[%u];\n" + "} %s = { %u, %u, {", + data_size, image_name, pixmap->width, pixmap->height); + + if (alpha_convertion) { + if (pixmap->bpp != 32) { + ERROR("32 bpp is requred for alpha option") + } + do_dump_with_alpha_conversion(pixmap, f); + } else if (pixmap->bpp == 32) { + do_dump_32bpp(pixmap, f); + } else { + do_dump_24bpp(pixmap, f); + } + + fseek(f, -1, SEEK_CUR); + fprintf(f, "}\n};\n"); + fclose(f); + close(fd); + return 0; +} + +enum { + ALPHA_OPT = 'a', + HELP_OPT = 'h', + NAME_OPT = 'n', +}; + +static void usage() +{ + printf("usage: %s [--alpha] [--name ] SOURCE [DEST]\n", prog_name); + printf(" %s --help\n", prog_name); +} + +const struct option longopts[] = { + {"help", no_argument, NULL, HELP_OPT}, + {"alpha", no_argument, NULL, ALPHA_OPT}, + {"name", required_argument, NULL, NAME_OPT}, + {NULL, 0, NULL, 0}, +}; + +int main(int argc, char **argv) +{ + size_t input_size; + uint8_t* buf; + Pixmap *pixmap; + int opt; + int alpha_convertion = FALSE; + char *struct_name = NULL; + char *src = NULL; + char *dest = NULL; + + + if (!(prog_name = strrchr(argv[0], '/'))) { + prog_name = argv[0]; + } else { + prog_name++; + } + + + while ((opt = getopt_long(argc, argv, "ah", longopts, NULL)) != -1) { + switch (opt) { + case 0: + case '?': + usage(); + exit(-1); + case ALPHA_OPT: + alpha_convertion = TRUE; + break; + case HELP_OPT: + usage(); + exit(0); + case NAME_OPT: + struct_name = optarg; + break; + } + } + + int more = argc - optind; + switch (more) { + case 1: { + char *slash; + char *dot; + + dest = malloc(strlen(argv[optind]) + 3); + strcpy(dest, argv[optind]); + dot = strrchr(dest, '.'); + slash = strrchr(dest, '/'); + if (!dot || (slash && slash > dot)) { + strcat(dest, ".c"); + } else { + strcpy(dot, ".c"); + } + break; + } + case 2: + dest = argv[optind + 1]; + //todo: if dir strcat src name + break; + default: + usage(); + exit(-1); + } + + src = argv[optind]; + + if (!struct_name) { + char *struct_name_src; + char *dot; + + struct_name_src = strrchr(dest, '/'); + if (!struct_name_src) { + struct_name_src = dest; + } else { + ++struct_name_src; + } + struct_name = malloc(strlen(struct_name_src) + 1); + strcpy(struct_name, struct_name_src); + if ((dot = strchr(struct_name, '.'))) { + *dot = 0; + } + } + + if (!(input_size = read_input(src, &buf))) { + return -1; + } + + if (!(pixmap = init_bitmap(input_size, buf))) { + return -1; + } + return pixmap_to_c_struct(pixmap, dest, struct_name, alpha_convertion); +} + diff --git a/tools/icon_to_c.c b/tools/icon_to_c.c new file mode 100644 index 00000000..79ae5fac --- /dev/null +++ b/tools/icon_to_c.c @@ -0,0 +1,369 @@ +/* + Copyright (C) 2009 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ALIGN(a, b) (((a) + ((b) - 1)) & ~((b) - 1)) +#define TRUE 1 +#define FALSE 0 + +#define ERROR(str) printf("%s: error: %s\n", prog_name, str); exit(-1); + +static char *prog_name = NULL; + +static size_t read_input(const char *file_name, uint8_t** out_buf) +{ + int fd = open(file_name, O_RDONLY); + if (fd == -1) { + ERROR("open source file failed"); + return 0; + } + struct stat file_stat; + if (fstat(fd, &file_stat) == -1) { + ERROR("fstat on source file failed"); + return 0; + } + + uint8_t *buf = malloc(file_stat.st_size); + + if (!buf) { + close(fd); + ERROR("alloc mem failed"); + return 0; + } + + size_t to_read = file_stat.st_size; + uint8_t *buf_pos = buf; + while (to_read) { + int n = read(fd, buf_pos, to_read); + if (n <= 0) { + ERROR("read from source file failed"); + close(fd); + free(buf); + return 0; + } + to_read -= n; + buf_pos += n; + } + close(fd); + *out_buf = buf; + return file_stat.st_size; +} + +typedef struct __attribute__ ((__packed__)) BitmpaHeader { + uint32_t header_size; + uint32_t width; + uint32_t height; + uint16_t plans; + uint16_t bpp; + uint32_t compression; + uint32_t image_size; + uint32_t horizontal_resolution; + uint32_t vertical_resolution; + uint32_t num_colors; + uint32_t important_colors; +} BitmpaHeader; + + +typedef struct __attribute__ ((__packed__)) ICOHeader { + uint8_t width; + uint8_t height; + uint8_t colors_count; + uint8_t reserved; + uint16_t plans; + uint16_t bpp; + uint32_t bitmap_size; + uint32_t bitmap_offset; +} ICOHeader; + +typedef struct __attribute__ ((__packed__)) ICOFileHeader { + uint16_t reserved; + uint16_t type; + uint16_t image_count; + ICOHeader directory[0]; +} ICOFileHeader; + + +typedef struct Icon { + int width; + int height; + uint8_t* pixmap; + uint8_t* mask; +} Icon; + + +static Icon *init_icon(uint8_t *buf, size_t buf_size) +{ + ICOFileHeader *file_header; + int i; + + uint8_t *buf_end = buf + buf_size; + + if (buf_size < sizeof(ICOFileHeader)) { + ERROR("invalid source file"); + return NULL; + } + + file_header = (ICOFileHeader *)buf; + + if (file_header->reserved != 0 || file_header->type != 1) { + ERROR("invalid icon"); + return NULL; + } + + if (sizeof(ICOFileHeader) + file_header->image_count * sizeof(ICOHeader) > buf_size) { + ERROR("invalid source file"); + } + + for (i = 0; i < file_header->image_count; i++) { + int j; + + ICOHeader *ico = &file_header->directory[i]; + printf("%ux%ux%u size %u\n", (unsigned)ico->width, (unsigned)ico->height, + (unsigned)ico->bpp, ico->bitmap_size); + + if (ico->bitmap_offset + ico->bitmap_size > buf_size) { + ERROR("invalid source file"); + } + BitmpaHeader *bitmap = (BitmpaHeader *)(buf + ico->bitmap_offset); + if (bitmap->header_size != 40) { + ERROR("invalid bitmap header"); + } + if (bitmap->width != ico->width || bitmap->height != ico->height * 2 || + bitmap->plans != ico->plans || bitmap->bpp != ico->bpp || !bitmap->image_size) { + ERROR("invalid bitmap header"); + } + + if (bitmap->compression || bitmap->horizontal_resolution || bitmap->vertical_resolution || + bitmap->num_colors || bitmap->important_colors) { + ERROR("invalid bitmap header"); + } + + if (ico->width != 32 || ico->height != 32 || ico->bpp != 32) { + continue; + } + + int pixmap_size = bitmap->width * sizeof(uint32_t) * ico->height; + int mask_size = ALIGN(bitmap->width, 8) / 8 * ico->height; + Icon* icon = malloc(sizeof(*icon) + pixmap_size + mask_size); + icon->width = ico->width; + icon->height = ico->height; + icon->pixmap = (uint8_t *)(icon + 1); + icon->mask = icon->pixmap + pixmap_size; + + if ((uint8_t *)(bitmap + 1) + pixmap_size + mask_size > buf_end) { + ERROR("invalid source file"); + } + memcpy(icon->pixmap, bitmap + 1, pixmap_size); + memcpy(icon->mask, (uint8_t *)(bitmap + 1) + pixmap_size, mask_size); + for (j = 0; j < mask_size; j++) { + icon->mask[j] = ~icon->mask[j]; + } + return icon; + } + printf("%s: missing 32x32x32\n", prog_name); + return NULL; +} + +static inline void put_char(FILE* f, uint8_t val) +{ + fprintf(f, "0x%.2x,", val); +} + +static int icon_to_c_struct(const Icon *icon, const char *dest_file, const char *image_name) +{ + int i, j; + int fd; + FILE *f; + + if ((fd = open(dest_file, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) { + ERROR("open dest file failed"); + return -1; + } + + if (!(f = fdopen(fd, "w"))) { + ERROR("fdopen failed"); + close(fd); + return -1; + } + uint32_t pixmap_stride = icon->width * sizeof(uint32_t); + uint32_t pixmap_size = pixmap_stride * icon->height; + uint32_t mask_stride = ALIGN(icon->width, 8) / 8; + uint32_t mask_size = mask_stride * icon->height; + fprintf(f, "static const struct {\n" + "\tuint32_t width;\n" + "\tuint32_t height;\n" + "\tuint8_t pixmap[%u];\n" + "\tuint8_t mask[%u];\n" + "} %s = { %u, %u, {", + pixmap_size, mask_size, image_name, icon->width, icon->height); + + uint8_t *line = (uint8_t *)(icon->pixmap + ((icon->height - 1) * pixmap_stride)); + int line_size = 0; + + for (i = 0; i < icon->height; i++) { + uint8_t *now = line; + for (j = 0; j < icon->width; j++, now += 4) { + if ((line_size++ % 6) == 0) { + fprintf(f, "\n\t\t"); + } + put_char(f, now[0]); + put_char(f, now[1]); + put_char(f, now[2]); + put_char(f, now[3]); + } + line -= pixmap_stride; + } + + + fseek(f, -1, SEEK_CUR); + fprintf(f, "},\n\n\t\t{"); + + line = (uint8_t *)(icon->mask + ((icon->height - 1) * mask_stride)); + line_size = 0; + for (i = 0; i < icon->height; i++) { + for (j = 0; j < mask_stride; j++) { + if (line_size && (line_size % 12) == 0) { + fprintf(f, "\n\t\t "); + } + line_size++; + put_char(f, line[j]); + } + line -= mask_stride; + } + + fseek(f, -1, SEEK_CUR); + fprintf(f, "}\n};\n"); + fclose(f); + close(fd); + return 0; +} + +enum { + HELP_OPT = 'h', + NAME_OPT = 'n', +}; + +static void usage() +{ + printf("usage: %s [--name ] SOURCE [DEST]\n", prog_name); + printf(" %s --help\n", prog_name); +} + +const struct option longopts[] = { + {"help", no_argument, NULL, HELP_OPT}, + {"name", required_argument, NULL, NAME_OPT}, + {NULL, 0, NULL, 0}, +}; + +int main(int argc, char **argv) +{ + size_t input_size; + uint8_t* buf; + Icon *icon; + int opt; + char *struct_name = NULL; + char *src = NULL; + char *dest = NULL; + + + if (!(prog_name = strrchr(argv[0], '/'))) { + prog_name = argv[0]; + } else { + prog_name++; + } + + + while ((opt = getopt_long(argc, argv, "ah", longopts, NULL)) != -1) { + switch (opt) { + case 0: + case '?': + usage(); + exit(-1); + case HELP_OPT: + usage(); + exit(0); + case NAME_OPT: + struct_name = optarg; + break; + } + } + + int more = argc - optind; + switch (more) { + case 1: { + char *slash; + char *dot; + + dest = malloc(strlen(argv[optind]) + 3); + strcpy(dest, argv[optind]); + dot = strrchr(dest, '.'); + slash = strrchr(dest, '/'); + if (!dot || (slash && slash > dot)) { + strcat(dest, ".c"); + } else { + strcpy(dot, ".c"); + } + break; + } + case 2: + dest = argv[optind + 1]; + //todo: if dir strcat src name + break; + default: + usage(); + exit(-1); + } + + src = argv[optind]; + + if (!struct_name) { + char *struct_name_src; + char *dot; + + struct_name_src = strrchr(dest, '/'); + if (!struct_name_src) { + struct_name_src = dest; + } else { + ++struct_name_src; + } + struct_name = malloc(strlen(struct_name_src) + 1); + strcpy(struct_name, struct_name_src); + if ((dot = strchr(struct_name, '.'))) { + *dot = 0; + } + } + + if (!(input_size = read_input(src, &buf))) { + return -1; + } + + if (!(icon = init_icon(buf, input_size))) { + return -1; + } + + return icon_to_c_struct(icon, dest, struct_name); +} + diff --git a/tools/reds_stat.c b/tools/reds_stat.c new file mode 100644 index 00000000..76541579 --- /dev/null +++ b/tools/reds_stat.c @@ -0,0 +1,132 @@ +/* + Copyright (C) 2009 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include "reds_stat.h" + +#define TAB_LEN 4 +#define VALUE_TABS 7 +#define INVALID_STAT_REF (~(uint32_t)0) + +static RedsStat *reds_stat = NULL; +static uint64_t *values = NULL; + +void print_stat_tree(int32_t node_index, int depth) +{ + StatNode *node = &reds_stat->nodes[node_index]; + int i; + + if ((node->flags & STAT_NODE_MASK_SHOW) == STAT_NODE_MASK_SHOW) { + printf("%*s%s", depth * TAB_LEN, "", node->name); + if (node->flags & STAT_NODE_FLAG_VALUE) { + printf(":%*s%llu (%llu)\n", (VALUE_TABS - depth) * TAB_LEN - strlen(node->name) - 1, "", + node->value, node->value - values[node_index]); + values[node_index] = node->value; + } else { + printf("\n"); + if (node->first_child_index != INVALID_STAT_REF) { + print_stat_tree(node->first_child_index, depth + 1); + } + } + } + if (node->next_sibling_index != INVALID_STAT_REF) { + print_stat_tree(node->next_sibling_index, depth); + } +} + +int main(int argc, char **argv) +{ + char *shm_name; + pid_t kvm_pid; + uint64_t *val; + uint32_t num_of_nodes = 0; + size_t shm_size; + size_t shm_old_size; + int shm_name_len; + int ret = -1; + int fd; + + if (argc != 2 || !(kvm_pid = atoi(argv[1]))) { + printf("usage: reds_stat [qemu_pid] (e.g. `pgrep qemu`)\n"); + return -1; + } + shm_name_len = strlen(REDS_STAT_SHM_NAME) + strlen(argv[1]); + if (!(shm_name = (char *)malloc(shm_name_len))) { + perror("malloc"); + return -1; + } + snprintf(shm_name, shm_name_len, REDS_STAT_SHM_NAME, kvm_pid); + if ((fd = shm_open(shm_name, O_RDONLY, 0444)) == -1) { + perror("shm_open"); + free(shm_name); + return -1; + } + shm_size = sizeof(RedsStat); + reds_stat = mmap(NULL, shm_size, PROT_READ, MAP_SHARED, fd, 0); + if (reds_stat == (RedsStat *)MAP_FAILED) { + perror("mmap"); + goto error1; + } + if (reds_stat->magic != REDS_STAT_MAGIC) { + printf("bad magic %u\n", reds_stat->magic); + goto error2; + } + if (reds_stat->version != REDS_STAT_VERSION) { + printf("bad version %u\n", reds_stat->version); + goto error2; + } + while (1) { + system("clear"); + printf("spice statistics\n\n"); + if (num_of_nodes != reds_stat->num_of_nodes) { + num_of_nodes = reds_stat->num_of_nodes; + shm_old_size = shm_size; + shm_size = sizeof(RedsStat) + num_of_nodes * sizeof(StatNode); + reds_stat = mremap(reds_stat, shm_old_size, shm_size, MREMAP_MAYMOVE); + if (reds_stat == (RedsStat *)MAP_FAILED) { + perror("mremap"); + goto error3; + } + values = (uint64_t *)realloc(values, num_of_nodes * sizeof(uint64_t)); + if (values == NULL) { + perror("realloc"); + goto error3; + } + memset(values, 0, num_of_nodes * sizeof(uint64_t)); + } + print_stat_tree(reds_stat->root_index, 0); + sleep(1); + } + ret = 0; + +error3: + free(values); +error2: + munmap(reds_stat, shm_size); +error1: + shm_unlink(shm_name); + free(shm_name); + return ret; +} + -- cgit