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

📄 local_services.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************/
/* Copyright 1998, Hewlett-Packard Company                                   */
/* All rights reserved                                                       */
/* File: "local_services.c"                                                  */
/* Description: Abstracts platform and/or application dependent services,    */
/*              such as memory heap management, process termination and      */
/*              messaging.                                                   */
/* Author: David Taubman                                                     */
/* Affiliation: Hewlett-Packard and                                          */
/*              The University of New South Wales, Australia                 */
/* Version: VM6.0                                                            */
/* Last Revised: 27 December, 1999                                           */
/*****************************************************************************/

/*****************************************************************************/
/* Modified by David Taubman to force the `local_malloc' function to zero    */
/* the contents of all allocated memory.                                     */
/*****************************************************************************/

#include <local_services.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

typedef
  struct local_mem {
    struct local_mem_stats *owner;
    int num_bytes;
    int id;
    struct local_mem *next;
  } local_mem, *local_mem_ptr;
  /* This header is attached to every chunk of memory allocated by
     `local_malloc'.  Of course, this is a little wasteful, but the
     purpose is to facilitate debugging and reporting and verification
     of memory consumption throughout the system.
         `owner' points to the `local_mem_stats' structure to whose list
     this chunk of memory belongs.
         `num_bytes' holds the number of bytes which were allocated, not
     including the header.
         `id' is a unique integer which is included to facilitate the
     tracking and elimination of memory leaks.  Every call to `local_malloc'
     generates a different `id' (usually by simply incrementing a counter).
         `next' is used to link all memory requests with the same key string
     together. */

typedef
  struct local_mem_stats {
    const char *key;
    local_mem_ptr head;
    int total_bytes;
    int current_bytes;
    int peak_bytes;
    struct local_mem_stats *next;
  } local_mem_stats, *local_mem_stats_ptr;
  /* This structure is used to build a list with one entry for each
     key string with which memory is allocated by `local_malloc'.
         `key' points to the string passed in to `local_malloc'.
         `head' points to the head of a list of all memory chunks which
     are currently allocated.
         `total_bytes' holds the total number of bytes which have been
     allocated with this key string, not taking into account the fact that
     some of this memory may have been freed.
         `current_bytes' holds the number of bytes which are currently
     allocated.
         `peak_bytes' holds the maximum number of bytes which have ever
     been simultaneously allocated with this key string. */

static local_mem_stats_ptr mem_stats = NULL;
static int local_current_bytes = 0;
static int local_peak_bytes = 0;
static int local_next_id = 0;
static int local_stop_id = 0;
static int local_heap_already_started = 0;

/* ========================================================================= */
/* --------------------------- Heap Management ----------------------------- */
/* ========================================================================= */

/*****************************************************************************/
/* EXTERN                 local_memory_collect_stats                         */
/*****************************************************************************/

void
  local_memory_collect_stats(void)
{
  if (local_heap_already_started)
    local_error("Attempting to invoke `local_memory_collect_stats' after "
                "the first call to `local_malloc'!!");
  local_next_id = 1;
}

/*****************************************************************************/
/* EXTERN                  local_memory_set_stop_id                          */
/*****************************************************************************/

void
  local_memory_set_stop_id(int stop_id)
{
  if ((local_next_id == 0) && (stop_id != 0))
    local_error("Attempting to set a memory \"stop id\" without first "
                "starting the statistics collection sub-system with a call "
                "to `local_memory_collect_stats'!");
  local_stop_id = stop_id;
}

/*****************************************************************************/
/* EXTERN                        local_malloc                                */
/*****************************************************************************/

void *
  local_malloc(const char *key, int num_bytes)
{
  local_mem_stats_ptr stats, scan, prev;
  local_mem_ptr result;
  int cmp = 0;

  local_heap_already_started = 1;
  if (local_next_id == 0)
    { /* No special features. */
      void *ptr;

      ptr = malloc((size_t) num_bytes);
      if (ptr == NULL)
        local_error("OUT OF MEMORY!!  Heap exhausted while trying to "
                    "allocate a new memory block of size %d bytes!",num_bytes);
      memset(ptr,0,(size_t) num_bytes);
      return(ptr);
    }

  for (prev=NULL, scan=mem_stats; scan != NULL; prev=scan, scan=scan->next)
    if ((cmp = strcmp(scan->key,key)) <= 0)
      break;
  if ((scan != NULL) && (cmp == 0))
    stats = scan;
  else
    {
      stats = (local_mem_stats_ptr) malloc(sizeof(local_mem_stats));
      if (stats == NULL)
        local_error("OUT OF MEMORY!!  Heap exhausted while trying to "
                    "allocate a new memory block of size %d bytes!",num_bytes);
      memset(stats,0,sizeof(local_mem_stats));
      stats->next = scan;
      if (prev == NULL)
        mem_stats = stats;
      else
        prev->next = stats;
      stats->key = key;
    }
  result = (local_mem_ptr) malloc(sizeof(local_mem)+(size_t) num_bytes);
  if (result == NULL)
    local_error("OUT OF MEMORY!!  Heap exhausted while trying to "
                "allocate a new memory block of size %d bytes!",num_bytes);
  if (local_next_id == local_stop_id)
    { /* Stop here to catch memory leaks. */
      assert(0);
    }
  result->id = local_next_id++;
  result->num_bytes = num_bytes;
  result->owner = stats;
  result->next = stats->head;
  stats->head = result;
  stats->total_bytes += num_bytes;
  stats->current_bytes += num_bytes;
  if (stats->current_bytes > stats->peak_bytes)
    stats->peak_bytes = stats->current_bytes;
  local_current_bytes += num_bytes;
  if (local_current_bytes > local_peak_bytes)
    local_peak_bytes = local_current_bytes;
  memset((void *)(result+1),0,(size_t) num_bytes);
  return((void *)(result+1));
}

/*****************************************************************************/
/* EXTERN                        local_realloc                               */
/*****************************************************************************/

void *
  local_realloc(void *ptr, int num_bytes)
{
  local_mem_ptr head, new_head;
  local_mem_stats_ptr stats;
  int change;

  if (ptr == NULL)
    local_error("NULL pointer supplied to `local_realloc'!!");
  if (local_next_id == 0)
    { /* No special features. */
      ptr = realloc(ptr,(size_t) num_bytes);
      return(ptr);
    }

  head = ((local_mem_ptr) ptr) - 1;
  stats = head->owner;
  assert(stats != NULL);
  new_head = (local_mem_ptr)
    realloc(head,sizeof(local_mem)+(size_t) num_bytes);
  if (new_head != head)
    {
      local_mem_ptr scan, prev;

      for (prev=NULL, scan=stats->head;
           scan != NULL; prev=scan, scan=scan->next)
        if (scan == head)
          break;
      if (scan == NULL)
        local_error("Attempting to realloc a chunk of memory which was not "
                    "allocated using `local_malloc' or which has been "
                    "corrupted!");
      if (prev != NULL)
        prev->next = new_head;
      else
        stats->head = new_head;
      head = new_head;
    }
  change = num_bytes - head->num_bytes;
  head->num_bytes = num_bytes;
  stats->current_bytes += change;
  local_current_bytes += change;
  if (change > 0)
    {
      stats->total_bytes += change;
      if (stats->current_bytes > stats->peak_bytes)
        stats->peak_bytes = stats->current_bytes;
      if (local_current_bytes > local_peak_bytes)
        local_peak_bytes = local_current_bytes;
    }
  return((void *)(head+1));
}

/*****************************************************************************/
/* EXTERN                         local_free                                 */
/*****************************************************************************/

void
  local_free(void *ptr)
{
  local_mem_ptr head, prev, scan;
  local_mem_stats_ptr stats;

  if (ptr == NULL)
    local_error("Attempting to deallocate memory via a NULL pointer!");
  if (local_next_id == 0)
    { /* No special features. */
      free(ptr);
      return;
    }

  head = ((local_mem_ptr) ptr) - 1;
  stats = head->owner;
  assert(stats != NULL);
  for (prev=NULL, scan=stats->head;

⌨️ 快捷键说明

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