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

📄 sflmem.c

📁 短小精悍的C语言标准函数库。提供450个以上的可移植的算法和工具代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
{
    LIST
       *ptr;

#   if (defined (MEM_TRACE))
    trace ("%s (%ld): commit transaction", 
           filename? filename: "-", (long) lineno);
#   endif

    ptr = &trn-> memhdr;
    if (!list_empty (ptr))              /*  Are there any blocks to commit?  */
      {
        list_relink_before (ptr,        /*  Relink list into main list       */
                            &mem_list. memhdr);
        list_unlink (ptr);
      }

    mem_del_trans (trn);
}


/*  --------------------------------------------------------------------------
 *  mem_del_trans - internal
 *
 *  Deletes a transaction block.
 */

static void
mem_del_trans(
    MEMTRN *trn
)
{
    if (trn == NULL)                    /*  Do nothing if address is null    */
        return;

    ASSERT (list_empty (&trn-> memhdr));

    list_unlink (trn);                  /*  Remove transaction from list     */
    free (trn);
}


/*  ---------------------------------------------------------------------[<]-
    Function: mem_rollback_

    Synopsis: Rolls back allocations for a particular transaction.  This
    frees up all blocks allocated by calls to mem_alloc, mem_realloc and
    mem_strdup since the last call to mem_commit.  Note that for blocks
    allocated with mem_realloc, this is not really a rollback but a free.
    The mem_rollback() function must be used with some care... if you
    forget to do a mem_commit(), a later mem_rollback() will do damage
    to your memory space.  The general rule is to start your processing
    with mem_commit(), then do work, and call mem_rollback() when there
    is an error.  Finally, call mem_commit() at the end.
    ---------------------------------------------------------------------[>]-*/

void
mem_rollback_ (
    MEMTRN *trn,
    const char *filename,               /*  Name of source file making call  */
    size_t lineno                       /*  Line number in calling source    */
)
{
#   if (defined (MEM_TRACE))
    trace ("%s (%ld): rollback transaction", 
           filename? filename: "-", (long) lineno);
#   endif

    mem_free_list ((MEMHDR *) &trn-> memhdr);
    mem_del_trans (trn);
}


/* ---------------------------------------------------------------------------
 *  mem_free_list -- internal
 *
 */

static void
mem_free_list (
    MEMHDR *list                        /*  List of memory allocations       */
)
{
    MEMHDR
        *ptr;

    while (!list_empty (list))
      {
        ptr = list-> next;
        ptr-> tag  = MEMUNTAG;
        mem_total -= ptr-> size;
        mem_free_count += 1;
        list_unlink (ptr);              /*  Remove block from list           */
        free (ptr);
      }
}


/*  ---------------------------------------------------------------------[<]-
    Function: mem_size_

    Synopsis: Returns the size in bytes of a memory block.
    ---------------------------------------------------------------------[>]-*/

size_t
mem_size_ (
    const void *client_ptr,             /*  Block of memory to free          */
    const char *filename,               /*  Name of source file making call  */
    size_t lineno                       /*  Line number in calling source    */
)
{
    MEMHDR
       *ptr;

    if (client_ptr == NULL)             /*  Do nothing if address is null    */
        return 0;

    /*  Check for valid block                                                */
    ptr = CLIENT_2_HDR (client_ptr);
    if (ptr-> tag != MEMTAG)
        mem_tag_err (ptr, filename, lineno);

    return (ptr-> size);
}


/*  ---------------------------------------------------------------------[<]-
    Function: mem_used

    Synopsis: Returns the number of bytes currently allocated using the
    memory management system. The value returned is simply the sum of the
    size requests to allocation routines.  It does not reflect any overhead
    required by the memory management system.
    ---------------------------------------------------------------------[>]-*/

long
mem_used (void)
{
    return (mem_total);
}


/*  ---------------------------------------------------------------------[<]-
    Function: mem_allocs

    Synopsis: Returns the number of blocks allocated in total.  Use this
    to get an idea of the activity of the memory management system.  When
    program ends cleanly, mem_allocs () should be equal to mem_frees().
    ---------------------------------------------------------------------[>]-*/

long
mem_allocs (void)
{
    return (mem_alloc_count);
}


/*  ---------------------------------------------------------------------[<]-
    Function: mem_frees

    Synopsis: Returns the number of blocks freed in total.  Use this
    to get an idea of the activity of the memory management system.  When
    program ends cleanly, mem_allocs () should be equal to mem_frees().
    ---------------------------------------------------------------------[>]-*/

long
mem_frees (void)
{
    return (mem_free_count);
}


/*  ---------------------------------------------------------------------[<]-
    Function: mem_display

    Synopsis: Displays the contents of the memory allocation list.
    ---------------------------------------------------------------------[>]-*/

void
mem_display (
    FILE *fp                            /*  File to dump display to          */
)
{
    MEMTRN
        *trn;

    fprintf (fp, "Index   Size  File(Line) - total size %lu\n", mem_total);
    mem_display_list ((MEMHDR *) &mem_list.memhdr, fp);

    trn = tr_list.next;
    while (trn != (MEMTRN *) &tr_list)
      {
        fprintf (fp, "* Transaction %s (%ld)",
                 trn-> file? trn-> file: "<Unknown>", (long) trn-> line);
        fprintf (fp, "\n");
        mem_display_list ((MEMHDR *) &trn-> memhdr, fp);

        trn = trn-> next;
      }
    fflush (fp);
}

/* ---------------------------------------------------------------------------
 *  mem_display_list -- internal
 *
 *  Displays memory allocations attached to a particular list
 */

static void
mem_display_list (
    MEMHDR *lst,                        /*  List of memory allocations       */
    FILE   *fp                          /*  File to dump display to          */
)
{
    MEMHDR
       *ptr;
    int
        index;

    index = 0;
    ptr = lst-> next;
    while (ptr != lst)
      {
        fprintf (fp, "%-5d %6ld", index++, (long) ptr-> size);
        fprintf (fp, "  %s (%ld)",
                 ptr-> file? ptr-> file: "<Unknown>", (long) ptr-> line);
        if (ptr-> tag != MEMTAG)
            fprintf (fp, " INVALID");

        fprintf (fp, " [%p]\n", HDR_2_CLIENT (ptr));
        ptr = ptr-> next;
      }
}


/*  ---------------------------------------------------------------------[<]-
    Function: mem_scavenger

    Synopsis: Registers a memory scavenger function.  A memory scavenger
    function is an application function that is invoked by mem_alloc_() when
    memory is exhausted, so that unused application objects can be released.
    This allows you to allocate large amounts of memory -- for instance for
    caches -- and then release them when memory runs short.  When you
    register a scavenger function you may provide a void * argument; this is
    passed back to the scavenger if it is ever invoked.  The scavenger
    function returns TRUE if it could release some memory, otherwise it
    returns FALSE.  Note that there is no way to unregister such a function.
    Furthermore, a scavenger function should not itself allocate any new
    memory, unless it can definitely free excess memory first.  Scavenger
    functions are called in an unspecified order.  Returns 0 if the scavenger
    function could be registered, -1 if not.  There is no limit to the number
    of scavenger functions you can register, except available memory.  The
    same scavenger function can be registered several times.
 ---------------------------------------------------------------------[>]-*/

int
mem_scavenger (
    scavenger scav_fct,                 /*  File to dump display to          */
    void    * scav_arg
)
{
    SCAVFCT
        *scavfct;                       /*  Allocated registry function      */

    /*  Allocate an SCAVFCT block and attach it to the scavfcts list         */
    list_create (scavfct, sizeof (SCAVFCT));
    if (scavfct == NULL)
        return (-1);
    list_relink_before (scavfct, &scavfcts);

    scavfct-> scav_fct = scav_fct;
    scavfct-> scav_arg = scav_arg;
    return (0);
}


/*  ---------------------------------------------------------------------[<]-
    Function: mem_freeall

    Synopsis: Frees all allocated memory.  This function is rather brutal and
    can do strange things to an application.  It can be useful when you are
    trying to recover control in a crashed application, and need to free all
    allocated memory before restarting it.
    ---------------------------------------------------------------------[>]-*/

void
mem_freeall (void)
{
    MEMTRN
        *trn;

    mem_free_list ((MEMHDR *) &mem_list.memhdr);
    while (!list_empty (&tr_list))
      {
        trn = tr_list.next;
        mem_free_list ((MEMHDR *) &trn-> memhdr);
        mem_del_trans (trn);
      }
}


⌨️ 快捷键说明

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