LCOV - code coverage report
Current view: top level - src/test - LG_brutal_malloc.c (source / functions) Hit Total Coverage
Test: LAGraph code coverage report. Commit id: 3b461aa. Current time (UTC): 2024-01-25T16:04:32Z Lines: 29 29 100.0 %
Date: 2024-01-25 16:05:28 Functions: 4 4 100.0 %

          Line data    Source code
       1             : //------------------------------------------------------------------------------
       2             : // LG_brutal_malloc: brutal memory debugging
       3             : //------------------------------------------------------------------------------
       4             : 
       5             : // LAGraph, (c) 2019-2022 by The LAGraph Contributors, All Rights Reserved.
       6             : // SPDX-License-Identifier: BSD-2-Clause
       7             : //
       8             : // For additional details (including references to third party source code and
       9             : // other files) see the LICENSE file or contact permission@sei.cmu.edu. See
      10             : // Contributors.txt for a full list of contributors. Created, in part, with
      11             : // funding and support from the U.S. Government (see Acknowledgments.txt file).
      12             : // DM22-0790
      13             : 
      14             : // Contributed by Timothy A. Davis, Texas A&M University
      15             : 
      16             : //------------------------------------------------------------------------------
      17             : 
      18             : // To enable brutal memory debugging, these four functions must be passed to
      19             : // LAGr_Init.
      20             : 
      21             : #include "LG_internal.h"
      22             : #include "LG_test.h"
      23             : 
      24             : //------------------------------------------------------------------------------
      25             : // global variables: LG_brutal and LG_nmalloc
      26             : //------------------------------------------------------------------------------
      27             : 
      28             : // If LG_brutal >= 0, then that value gives the # of malloc/calloc/realloc
      29             : // calls that will succeed.  Each time malloc/calloc/realloc is called, the
      30             : // LG_brutal count is decremented.  Once it reaches zero, no more memory
      31             : // allocations will occur, and LG_brutal_malloc, etc, all pretend to fail
      32             : // and return NULL.
      33             : 
      34             : // If LG_brutal is negative, the LG_brutal_malloc/calloc/realloc functions act
      35             : // like the regular malloc/calloc/realloc functions, with no pretend failures.
      36             : 
      37             : // LG_nmalloc is the count of the # of allocated blocks.  It is incremented by
      38             : // LG_brutal_malloc/calloc and by LG_brutal_realloc if a new block is allocated.
      39             : // It is decremented by LG_brutal_free.  After LAGraph_Finalize is called,
      40             : // this value should be zero.  If nonzero, a memory leak has occured.
      41             : 
      42             : LG_TEST_PUBLIC int64_t LG_brutal = -1 ;
      43             : LG_TEST_PUBLIC int64_t LG_nmalloc = 0 ;
      44             : 
      45             : //------------------------------------------------------------------------------
      46             : // LG_brutal_malloc
      47             : //------------------------------------------------------------------------------
      48             : 
      49             : LG_TEST_PUBLIC
      50      950487 : void *LG_brutal_malloc      // return pointer to allocated block of memory
      51             : (
      52             :     size_t size             // # of bytes to allocate
      53             : )
      54             : {
      55             :     void *p ;
      56      950487 :     if (LG_brutal == 0)
      57             :     {
      58             :         // pretend to fail
      59       38005 :         p = NULL ;
      60             :     }
      61             :     else
      62             :     {
      63             :         // malloc a new block
      64             :         #pragma omp critical (LG_brutal_malloc_critical)
      65             :         {
      66             :             // malloc the block of memory (of size at least 1 byte)
      67      912482 :             p = malloc (LAGRAPH_MAX (1, size)) ;
      68      912482 :             if (LG_brutal > 0)
      69             :             {
      70             :                 // one step closer to pretending to fail
      71      896161 :                 LG_brutal-- ;
      72             :             }
      73      912482 :             if (p != NULL)
      74             :             {
      75             :                 // one more block of memory successfully allocated
      76      912482 :                 LG_nmalloc++ ;
      77             :             }
      78             :         }
      79             :     }
      80      950487 :     return (p) ;
      81             : }
      82             : 
      83             : //------------------------------------------------------------------------------
      84             : // LG_brutal_calloc
      85             : //------------------------------------------------------------------------------
      86             : 
      87             : LG_TEST_PUBLIC
      88         683 : void *LG_brutal_calloc      // return pointer to allocated block of memory
      89             : (
      90             :     size_t nitems,          // # of items to allocate
      91             :     size_t itemsize         // # of bytes per item
      92             : )
      93             : {
      94         683 :     size_t size = LAGRAPH_MAX (1, nitems * itemsize) ;
      95         683 :     void *p = LG_brutal_malloc (size) ;
      96         683 :     if (p != NULL)
      97             :     {
      98         682 :         memset (p, 0, size) ;
      99             :     }
     100         683 :     return (p) ;
     101             : }
     102             : 
     103             : //------------------------------------------------------------------------------
     104             : // LG_brutal_free
     105             : //------------------------------------------------------------------------------
     106             : 
     107             : LG_TEST_PUBLIC
     108      912482 : void LG_brutal_free
     109             : (
     110             :     void *p                 // block to free
     111             : )
     112             : {
     113      912482 :     if (p != NULL)
     114             :     {
     115             :         #pragma omp critical (LG_brutal_malloc_critical)
     116             :         {
     117             :             // free the block
     118      912482 :             free (p) ;
     119             :             // one less block of memory allocated
     120      912482 :             LG_nmalloc-- ;
     121             :         }
     122             :     }
     123      912482 : }
     124             : 
     125             : //------------------------------------------------------------------------------
     126             : // LG_brutal_realloc
     127             : //------------------------------------------------------------------------------
     128             : 
     129             : LG_TEST_PUBLIC
     130       25041 : void *LG_brutal_realloc     // return pointer to reallocated memory
     131             : (
     132             :     void *p,                // block to realloc
     133             :     size_t size             // new size of the block
     134             : )
     135             : {
     136       25041 :     if (p == NULL)
     137             :     {
     138             :         // malloc a new block
     139           4 :         p = LG_brutal_malloc (size) ;
     140             :     }
     141             :     else
     142             :     {
     143             :         // realloc an existing block
     144             :         #pragma omp critical (LG_brutal_malloc_critical)
     145             :         {
     146       25037 :             if (LG_brutal == 0)
     147             :             {
     148             :                 // pretend to fail
     149         658 :                 p = NULL ;
     150             :             }
     151             :             else
     152             :             {
     153             :                 // realloc the block
     154       24379 :                 p = realloc (p, size) ;
     155       24379 :                 if (LG_brutal > 0)
     156             :                 {
     157             :                     // one step closer to pretending to fail
     158       24352 :                     LG_brutal-- ;
     159             :                 }
     160             :             }
     161             :         }
     162             :     }
     163       25041 :     return (p) ;
     164             : }

Generated by: LCOV version 1.14