⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpool_t.c

📁 一个关于memory pool 的实例
💻 C
📖 第 1 页 / 共 2 页
字号:
    (void)printf("> ");
    if (fgets(line, sizeof(line), stdin) == NULL) {
      break;
    }
    line_p = strchr(line, '\n');
    if (line_p != NULL) {
      *line_p = '\0';
    }
    
    len = strlen(line);
    if (len == 0) {
      continue;
    }
    
    if (strncmp(line, "?", len) == 0
	|| strncmp(line, "help", len) == 0) {
      (void)printf("\thelp      - print this message\n\n");
      
      (void)printf("\tmalloc    - allocate memory\n");
      (void)printf("\tcalloc    - allocate/clear memory\n");
      (void)printf("\tresize    - resize memory\n");
      (void)printf("\tfree      - deallocate memory\n\n");
      
      (void)printf("\tclear     - clear the pool\n");
      (void)printf("\toverwrite - overwrite some memory to test errors\n");
      (void)printf("\trandom    - randomly execute a number of [de] allocs\n");
      
      (void)printf("\tquit      - quit this test program\n");
      continue;
    }
    
    if (strncmp(line, "quit", len) == 0) {
      break;
    }
    
    if (strncmp(line, "malloc", len) == 0) {
      int	size;
      
      (void)printf("How much to malloc: ");
      if (fgets(line, sizeof(line), stdin) == NULL) {
	break;
      }
      size = atoi(line);
      pnt = mpool_alloc(pool, size, &ret);
      if (pnt == NULL) {
	(void)printf("malloc(%d) failed: %s\n", size, mpool_strerror(ret));
      }
      else {
	(void)printf("malloc(%d) returned '%#lx'\n", size, (long)pnt);
      }
      continue;
    }
    
    if (strncmp(line, "calloc", len) == 0) {
      int	size;
      
      (void)printf("How much to calloc: ");
      if (fgets(line, sizeof(line), stdin) == NULL) {
	break;
      }
      size = atoi(line);
      pnt = mpool_calloc(pool, size, sizeof(char), &ret);
      if (pnt == NULL) {
	(void)printf("calloc(%d) failed: %s\n", size, mpool_strerror(ret));
      }
      else {
	(void)printf("calloc(%d) returned '%#lx'\n", size, (long)pnt);
      }
      continue;
    }
    
    if (strncmp(line, "resize", len) == 0) {
      int	size, old_size;
      
      pnt = get_address();
      
      (void)printf("Old size of allocation: ");
      if (fgets(line, sizeof(line), stdin) == NULL) {
	break;
      }
      old_size = atoi(line);
      (void)printf("New size of allocation: ");
      if (fgets(line, sizeof(line), stdin) == NULL) {
	break;
      }
      size = atoi(line);
      
      new_pnt = mpool_resize(pool, pnt, old_size, size, &ret);
      if (new_pnt == NULL) {
	(void)printf("resize(%#lx, %d) failed: %s\n",
		     (long)pnt, size, mpool_strerror(ret));
      }
      else {
	(void)printf("resize(%#lx, %d) returned '%#lx'\n",
		     (long)pnt, size, (long)new_pnt);
      }
      continue;
    }
    
    if (strncmp(line, "free", len) == 0) {
      int	old_size;
      
      pnt = get_address();
      
      (void)printf("Old minimum size we are freeing: ");
      if (fgets(line, sizeof(line), stdin) == NULL) {
	break;
      }
      old_size = atoi(line);
      ret = mpool_free(pool, pnt, old_size);
      if (ret != MPOOL_ERROR_NONE) {
	(void)fprintf(stderr, "free failed: %s\n", mpool_strerror(ret));
      }
      continue;
    }
    
    if (strncmp(line, "clear", len) == 0) {
      ret = mpool_clear(pool);
      if (ret == MPOOL_ERROR_NONE) {
	(void)fprintf(stderr, "clear succeeded\n");
      }
      else {
	(void)fprintf(stderr, "clear failed: %s\n", mpool_strerror(ret));
      }
      continue;
    }
    
    if (strncmp(line, "overwrite", len) == 0) {
      char	*overwrite = "OVERWRITTEN";
      
      pnt = get_address();
      memcpy((char *)pnt, overwrite, strlen(overwrite));
      (void)printf("Done.\n");
      continue;
    }
    
    /* do random heap hits */
    if (strncmp(line, "random", len) == 0) {
      int	iter_n;
      
      (void)printf("How many iterations[%d]: ", default_iter_n);
      if (fgets(line, sizeof(line), stdin) == NULL) {
	break;
      }
      if (line[0] == '\0' || line[0] == '\n') {
	iter_n = default_iter_n;
      }
      else {
	iter_n = atoi(line);
      }
      
      do_random(pool, iter_n);
      continue;
    }
    
    (void)printf("Unknown command '%s'.  Type 'help' for assistance.\n", line);
  }
}

/*
 * static void log_func
 *
 * DESCRIPTION:
 *
 * Mpool transaction log function.
 *
 * RETURNS:
 *
 * None.
 *
 * ARGUMENT:
 *
 * mp_p -> Associated mpool address.
 *
 * func_id -> Integer function ID which identifies which mpool
 * function is being called.
 *
 * byte_size -> Optionally specified byte size.
 *
 * ele_n -> Optionally specified element number.  For mpool_calloc
 * only.
 *
 * new_addr -> Optionally specified new address.  For mpool_alloc,
 * mpool_calloc, and mpool_resize only.
 *
 * old_addr -> Optionally specified old address.  For mpool_resize and
 * mpool_free only.
 *
 * old_byte_size -> Optionally specified old byte size.  For
 * mpool_resize only.
 */
static	void	log_func(const void *mp_p, const int func_id,
			 const unsigned long byte_size,
			 const unsigned long ele_n,
			 const void *new_addr, const void *old_addr,
			 const unsigned long old_byte_size)
{
  (void)printf("mp %#lx ", (long)mp_p);
  
  switch (func_id) {
    
  case MPOOL_FUNC_CLOSE:
    (void)printf("close\n");
    break;
    
  case MPOOL_FUNC_CLEAR:
    (void)printf("clear\n");
    break;
    
  case MPOOL_FUNC_ALLOC:
    (void)printf("alloc %lu bytes got %#lx\n",
		 byte_size, (long)new_addr);
    break;
    
  case MPOOL_FUNC_CALLOC:
    (void)printf("calloc %lu ele size, %lu ele number, got %#lx\n",
		 byte_size, ele_n, (long)new_addr);
    break;
    
  case MPOOL_FUNC_FREE:
    (void)printf("free %#lx of %lu bytes\n", (long)old_addr, byte_size);
    break;
    
  case MPOOL_FUNC_RESIZE:
    (void)printf("resize %#lx of %lu bytes to %lu bytes, got %#lx\n",
		 (long)old_addr, old_byte_size, byte_size,
		 (long)new_addr);
    break;
    
  default:
    (void)printf("unknown function %d, %lu bytes\n", func_id, byte_size);
    break;
  }
}

/*
 * static void usage
 *
 * DESCRIPTION:
 *
 * Print a usage message.
 *
 * RETURNS:
 *
 * None.
 *
 * ARGUMENTS:
 *
 * None.
 */
static	void	usage(void)
{
  (void)fprintf(stderr,
		"Usage: mpool_t [-bhHilMnsv] [-m size] [-p number] "
		"[-P size] [-S seed] [-t times]\n");
  (void)fprintf(stderr,
		"  -b              set MPOOL_FLAG_BEST_FIT\n"
		"  -h              set MPOOL_FLAG_NO_FREE\n"
		"  -H              use system heap not mpool\n"
		"  -i              turn on interactive mode\n"
		"  -l              log memory transactions\n"
		"  -M              max number pages in mpool\n"
		"  -n              set MPOOL_FLAG_NO_FREE\n"
		"  -s              use sbrk instead of mmap\n"
		"  -v              enable verbose messages\n"
		"  -m size         maximum allocation to test\n"
		"  -p max-pnts     number of pointers to test\n"
		"  -S seed-rand    seed for random function\n"
		"  -t interations  number of iterations to run\n");
  exit(1);      
}

/*
 * static void process_args
 *
 * DESCRIPTION:
 *
 * Process our arguments.
 *
 * RETURNS:
 *
 * None.
 *
 * ARGUMENTS:
 *
 * None.
 */
static	void	process_args(int argc, char ** argv)
{
  argc--, argv++;
  
  /* process the args */
  for (; *argv != NULL; argv++, argc--) {
    if (**argv != '-') {
      continue;
    }
    
    switch (*(*argv + 1)) {
      
    case 'b':
      best_fit_b = 1;
      break;
    case 'h':
      heavy_pack_b = 1;
      break;
    case 'H':
      use_malloc_b = 1;
      break;
    case 'i':
      interactive_b = 1;
      break;
    case 'l':
      log_trxn_b = 1;
      break;
    case 'm':
      argv++, argc--;
      if (argc <= 0) {
	usage();
      }
      max_alloc = atoi(*argv);
      break;
    case 'M':
      max_pages_n = 1;
      break;
    case 'n':
      no_free_b = 1;
      break;
    case 'p':
      argv++, argc--;
      if (argc <= 0) {
	usage();
      }
      max_pointers = atoi(*argv);
      break;
    case 'P':
      argv++, argc--;
      if (argc <= 0) {
	usage();
      }
      page_size = atoi(*argv);
      break;
    case 'S':
      argv++, argc--;
      if (argc <= 0) {
	usage();
      }
      seed_random = atoi(*argv);
      break;
    case 't':
      argv++, argc--;
      if (argc <= 0) {
	usage();
      }
      default_iter_n = atoi(*argv);
      break;
    case 'v':
      verbose_b = 1;
      break;
    default:
      usage();
      break;
    }
  }
}

/*
 * Main routine
 */
int	main(int argc, char **argv)
{
  int		ret;
  unsigned int	flags = 0, pool_page_size;
  unsigned long	num_alloced, user_alloced, max_alloced, tot_alloced;
  mpool_t	*pool;
  
  process_args(argc, argv);
  
  /* repeat until we get a non 0 seed */
  while (seed_random == 0) {
    seed_random = time(0) ^ getpid();
  }
  (void)srandom(seed_random);
  
  (void)printf("Random seed is %u\n", seed_random);
  
  if (best_fit_b) {
    flags |= MPOOL_FLAG_BEST_FIT;
  }
  if (heavy_pack_b) {
    flags |= MPOOL_FLAG_HEAVY_PACKING;
  }
  if (no_free_b) {
    flags |= MPOOL_FLAG_NO_FREE;
  }
  if (use_sbrk_b) {
    flags |= MPOOL_FLAG_USE_SBRK;
  }
  
  /* open our memory pool */
  pool = mpool_open(flags, page_size, NULL, &ret);
  if (pool == NULL) {
    (void)fprintf(stderr, "Error in mpool_open: %s\n", mpool_strerror(ret));
    exit(1);
  }
  
  /* are we logging transactions */
  if (log_trxn_b) {
    ret = mpool_set_log_func(pool, log_func);
    if (ret != MPOOL_ERROR_NONE) {
      (void)fprintf(stderr, "Error in mpool_set_log_func: %s\n",
		    mpool_strerror(ret));
    }
  }
  
  if (max_pages_n > 0) {
    ret = mpool_set_max_pages(pool, max_pages_n);
    if (ret != MPOOL_ERROR_NONE) {
      (void)fprintf(stderr, "Error in mpool_set_max_pages: %s\n",
		    mpool_strerror(ret));
    }
  }
  
  if (interactive_b) {
    do_interactive(pool);
  }
  else {
    (void)printf("Running %d tests (use -i for interactive)...\n",
		 default_iter_n);
    (void)fflush(stdout);
    
    do_random(pool, default_iter_n);
  }
  
  /* get stats from the pool */
  ret = mpool_stats(pool, &pool_page_size, &num_alloced, &user_alloced,
		    &max_alloced, &tot_alloced);
  if (ret == MPOOL_ERROR_NONE) {
    (void)printf("Pool page size = %d.  Number active allocated = %lu\n",
		 pool_page_size, num_alloced);
    (void)printf("User bytes allocated = %lu.  Max space allocated = %lu\n",
		 user_alloced, max_alloced);
    (void)printf("Total space allocated = %lu\n", tot_alloced);
  }
  else {
    (void)fprintf(stderr, "Error in mpool_stats: %s\n", mpool_strerror(ret));
  }
  
  /* close the pool */
  ret = mpool_close(pool);
  if (ret != MPOOL_ERROR_NONE) {
    (void)fprintf(stderr, "Error in mpool_close: %s\n", mpool_strerror(ret));
    exit(1);
  }
  
  exit(0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -