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

📄 wip_mem.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 2 页
字号:
  current_stats.bytes_requested += current_stats.last_req;
  current_stats.currently_allocated += current_stats.last_alloc;
  if (current_stats.currently_allocated > current_stats.max_allocated)
    current_stats.max_allocated = current_stats.currently_allocated;
  current_stats.num_alloc++;
  current_stats.traverse_count += tmp_traverse_count;
  current_stats.maxfreelistlength = MAX (current_stats.maxfreelistlength,
                                         tmp_traverse_count);
  check_allocated_chunk (p);
#endif
  return chunk2mem (p);
}

/*
 * Allocate and return a pointer to a memory area of at least
 * the indicated size. The allocated block of memory will be aligned
 * on a 4-byte boundary.
 * Memory blocks allocated with this routine can be freed in one
 * batch operation by calling wip_gc.
 * Returns 0 if allocation fails.
 */
void *
wip_gcmalloc (UINT32 size)
{
  chunkptr p = 0, ptmp;
  UINT32   nb;
  UINT32   sz = 250000;
  UINT32   remsize;
  INT16    i;
#ifdef DEBUG_WIP_MALLOC
  int      tmp_traverse_count  = 0;
#endif

  /* We add space for our overhead (4 bytes) plus round to nearest
   * larger multiple of 4, plus never allocate a chunk less than 8 bytes. */
  nb = request2size (size);

  /* Check all relevant free lists, until a non-empty one is found. */
  for (i = list_idx (nb); i < NUM_FREE_LISTS; i++) {
    chunkptr freelist = freelists[i];

    /* Search the entire list, select chunk with closest fit */
    for (ptmp = forward (freelist); ptmp != freelist;
         ptmp = forward (ptmp)) {
      UINT32 tmpsz = chunksize (ptmp);

#ifdef DEBUG_WIP_MALLOC
      tmp_traverse_count++;
#endif
      if (tmpsz == nb) { /* Exact fit: no need to search any further. */
        p = ptmp;
        sz = tmpsz;
        goto found;
      }
      else if (tmpsz > nb) { /* Chunk is large enough */
        if (tmpsz < sz) {
          /* This is the best so far. */
          p = ptmp;
          sz = tmpsz;
        }
      }
    }
    if (p != 0) {
      goto found;
    }
  }
  /* Searched all lists, but found no large enough chunk */
  return 0;

 found:
  /* We have found a large enough chunk, namely "p" of size "sz". */
  remove_from_list (p);
  remsize = sz - nb;

  if (remsize >= MINCHUNKSIZE) {
    /* The remainder is large enough to become a separate chunk */
    chunkptr q, next;
    chunkptr l;

    sz = nb;
    /* "q" will be the new chunk */
    q = (chunkptr)((BYTE *)p + sz);
    set_hd2 (q, remsize >> 1);
    set_hd1 (q, nb >> 1);
    next = nextchunk (q);
    set_prevsize (next, remsize);

    l = freelists[list_idx (remsize)];
    add_to_list (l, q);
  }
  set_hd2 (p, (sz >> 1) | 0x01);
  set_gcbit (p);

#ifdef DEBUG_WIP_MALLOC
  current_stats.last_alloc = sz;
  current_stats.bytes_allocated += current_stats.last_alloc;
  current_stats.last_req = size;
  current_stats.bytes_requested += current_stats.last_req;
  current_stats.currently_allocated += current_stats.last_alloc;
  if (current_stats.currently_allocated > current_stats.max_allocated)
    current_stats.max_allocated = current_stats.currently_allocated;
  current_stats.num_alloc++;
  current_stats.traverse_count += tmp_traverse_count;
  current_stats.maxfreelistlength = MAX (current_stats.maxfreelistlength,
                                         tmp_traverse_count);
  check_allocated_chunk (p);
#endif
  return chunk2mem (p);
}

/*
 * Free a memory area previously allocated with wip_malloc or wip_gcmalloc.
 * Calling this routine with 'mem' equal to 0 has no effect.
 */
void
wip_free (void* mem)
{
  chunkptr p;         /* chunk corresponding to mem */
  UINT32   sz;        /* its size */
  chunkptr next;      /* next adjacent chunk */
  chunkptr prev;      /* previous adjacent chunk */
  chunkptr l;

  if (mem == 0) {
    return;
  }

  p = mem2chunk (mem);
#ifdef DEBUG_WIP_MALLOC
  check_allocated_chunk (p);
#endif
  if (chunk_isfree (p)) {
    return;
  }
  sz = chunksize (p);
  prev = prevchunk (p);
  next = nextchunk (p);
#ifdef DEBUG_WIP_MALLOC
  current_stats.last_alloc = -(INT32)sz;
  current_stats.last_req = current_stats.last_alloc;
  current_stats.currently_allocated -= sz;
  current_stats.num_free++;
#endif
  
  if (chunk_isfree (prev)) {            /* Join with previous chunk */
    sz += chunksize (prev);
    p = prev;
    remove_from_list (prev);
  }
  if (chunk_isfree (next)) {            /* Join with next chunk */
    sz += chunksize (next);
    remove_from_list (next);
  }
  set_hd2 (p, sz >> 1);
  clear_gcbit (p);
  next = nextchunk (p);
  set_prevsize (next, sz);

  l = freelists [list_idx (sz)];
  add_to_list (l, p);
}


/*
 * Free all memory areas allocated with wip_gcmalloc.
 * Memory blocks allocated with wip_malloc are left undisturbed.
 */
void
wip_gc (void)
{
  chunkptr p;
  chunkptr l;

  for (p = firstchunk; p != lastchunk; p = nextchunk (p)) {
    if (chunk_inuse (p) && chunk_has_gcbit (p)) {
      UINT32    sz;        /* its size */
      chunkptr  next;      /* next contiguous chunk */
      chunkptr  prev;      /* previous contiguous chunk */

      sz = chunksize (p);
      prev = prevchunk (p);
      next = nextchunk (p);
#ifdef DEBUG_WIP_MALLOC
      check_allocated_chunk (p);
      current_stats.last_alloc = -(INT32)sz;
      current_stats.last_req = current_stats.last_alloc;
      current_stats.currently_allocated -= sz;
      current_stats.num_free++;
#endif
  
      if (chunk_isfree (prev)) {            /* Join with previous chunk */
        sz += chunksize (prev);
        remove_from_list (prev);
        p = prev;
      }
      if (chunk_isfree (next)) {            /* Join with next chunk */
        sz += chunksize (next);
        remove_from_list (next);
      }
      set_hd2 (p, sz >> 1);
      clear_gcbit (p);
      next = nextchunk (p);
      set_prevsize (next, sz);

      l = freelists [list_idx (sz)];
      add_to_list (l, p);
    }
  }
}


/*
 * Return the size of an allocated memory area.
 * The reported size includes the overhead used by the memory allocation
 * system.
 */
UINT32
wip_memsize (void *mem)
{
  chunkptr p;         /* chunk corresponding to mem */

  p = mem2chunk (mem);
  return chunksize (p);
}


/*
 * Routines for debugging and statistics.
 */
#ifdef DEBUG_WIP_MALLOC

/*
 * Print all currently allocated chunks.
 */
void
wip_printalloc (FILE *logfile)
{
  chunkptr p;

  for (p = firstchunk; p != lastchunk; p = nextchunk (p)) {
    if (!chunk_isfree (p)) {
      fprintf (logfile, "id: %d\tsize: %d\n", 0, chunksize (p));
    }
  }
}

/*
 * Prints a list of all the current chunks.
 */
void
wip_printchunks (FILE *logfile)
{
  chunkptr p = firstchunk;

  fprintf (logfile, "\n***************\n");
  for (;;) {
    fprintf (logfile, "-------------------\n");
    fprintf (logfile, "address: 0x%x\n", p);
    fprintf (logfile, "prev size: %d\n", prevsize (p));
    fprintf (logfile, "size: %d\n", chunksize (p));
    fprintf (logfile, "gc: %d, inuse: %d\n", chunk_has_gcbit (p),
             chunk_inuse (p));
    if (chunk_isfree (p) || (p == (chunkptr)baseptr)) {
      fprintf (logfile, "fwd: 0x%x\n", forward (p));
      fprintf (logfile, "bck: 0x%x\n", back (p));
    }
    if (p == lastchunk) {
      break;
    }
    p = nextchunk (p);
  }
  fprintf (logfile, "***************\n\n");
}

/*
 * Prints a sequence of numbers representing the sizes of
 * the chunks on the free list.
 */
void
wip_printfreelist (FILE *logfile)
{
  chunkptr p;
  UINT32   sz;
  INT16    i;

  fprintf (logfile, "\t");
  for (i = 0; i < NUM_FREE_LISTS; i++) {
    for (p = forward (freelists[i]); p != freelists[i]; p = forward (p)) {
      sz = chunksize (p);
      fprintf (logfile, " %d", sz);
    }
  }
}

/*
 * Print brief statistics:
 *   the number of bytes requested in the last allocation/free made
 *   the number of bytes allocated in the last allocation/free made
 *   the total number of bytes currently allocated
 *   the number of chunks checked in the last allocation
 *   the current length of the free list
 *   the current number of chunks that the memory is divided into
 */
void
wip_printbriefstats (FILE *logfile)
{
  INT16    i;
  chunkptr p;
  UINT32   listcount = 0;
  UINT32   chunkcount = 0;

  for (i = 0; i < NUM_FREE_LISTS; i++) {
    for (p = forward (freelists[i]); p != freelists[i]; p = forward (p)) {
      listcount++;
    }
  }
  for (p = firstchunk; p != lastchunk; p = nextchunk (p)) {
    chunkcount++;
  }
  if (current_stats.last_req < 0) {
    current_stats.last_req = 0;
  }

  fprintf (logfile, "%6d%6d%6d%6d%6d%6d", current_stats.last_req,
           current_stats.last_alloc, current_stats.currently_allocated,
           current_stats.traverse_count, listcount, chunkcount);
}

/*
 * Prints accumulated statistics.
 */
wip_malloc_stats
wip_getstats (void)
{
  return current_stats;
}

INT16
wip_getfragmentation (void)
{
  chunkptr p;
  UINT32   largestsize = 0;
  UINT32   totalfreesize = 0;
  UINT32   sz;

  for (p = firstchunk; p != lastchunk; p = nextchunk (p)) {
    if (chunk_isfree (p)) {
      sz = chunksize (p);
      totalfreesize += sz;
      largestsize = MAX (largestsize, sz);
    }
  }

  if (totalfreesize == 0)
    return 100;

  return (INT16)((largestsize * 100) / totalfreesize);
}

void
wip_fragmentationstats (FILE *logfile)
{
  chunkptr p;
  UINT32   largestsize = 0;
  UINT32   totalfreesize = 0;
  UINT32   sz;

  for (p = firstchunk; p != lastchunk; p = nextchunk (p)) {
    if (chunk_isfree (p)) {
      sz = chunksize (p);
      totalfreesize += sz;
      largestsize = MAX (largestsize, sz);
    }
  }

  fprintf (logfile, "Total free size: %d\nLargest chunk: %d (%d%%)\n",
           totalfreesize, largestsize, (largestsize * 100) / totalfreesize);
}

#endif
#endif

⌨️ 快捷键说明

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