LCOV - code coverage report
Current view: top level - deps/debug - memtrack.c (source / functions) Hit Total Coverage
Test: mkernel.info Lines: 166 169 98.2 %
Date: 2024-07-31 19:18:37 Functions: 14 14 100.0 %

          Line data    Source code
       1             : /**         @file  memtrack.c
       2             :  *         @brief  Memory block metadata tracking implementation
       3             :  *          @date  25/09/2006
       4             :  *        @author  François Cerbelle (Fanfan), francois@cerbelle.net
       5             :  *     @copyright  Copyright (c) 1997-2024, François Cerbelle
       6             :  *
       7             :  *  Originally inspired by "L'art du code", Steve Maguire, Microsoft Press
       8             :  *
       9             :  *   @internal
      10             :  *       Compiler  gcc
      11             :  *  Last modified  2024-07-28 18:03
      12             :  *   Organization  Cerbelle.net
      13             :  *        Company  Home
      14             :  *
      15             :  *   This source code is released for free distribution under the terms of the
      16             :  *   GNU General Public License as published by the Free Software Foundation.
      17             :  */
      18             : 
      19             : #include "memtrack.h"
      20             : #include <string.h>             /* strdup */
      21             : #include <stdio.h>              /* fprintf */
      22             : 
      23             : static struct MemBlock *Head;   /**< Memory blocks metadata list start sentinal */
      24             : static struct MemBlock *Tail;   /**< Memory blocks metadata list end sentinal */
      25             : static uint64_t NbBlocks;       /**< Memory blocks metadata counter */
      26             : static uint64_t RAMSize;        /**< Memory blocks metadata RAM sum */
      27             : 
      28             : /* Early definition, documented in the implementation below */
      29             : static unsigned int memtrack_init();
      30             : 
      31             : /* Early definition, documented in the implementation below */
      32             : static unsigned int memtrack_addblock_preinit(const void *p_Ptr,
      33             :         const size_t p_Size,
      34             :         const char *p_File,
      35             :         const int p_Line,
      36             :         const char *p_CompilDate,
      37             :         const char *p_CompilTime,
      38             :         const char *p_Function);
      39             : 
      40             : /* Early definition, documented in the implementation below */
      41             : static unsigned int memtrack_delblock_preinit(const void *p_Ptr,
      42             :         const char *p_File,
      43             :         const int p_Line,
      44             :         const char *p_CompilDate,
      45             :         const char *p_CompilTime,
      46             :         const char *p_Function);
      47             : 
      48             : /* Early definition, documented in the implementation below */
      49             : static uint64_t memtrack_dumpblocks_preinit();
      50             : 
      51             : /* Early definition, documented in the implementation below */
      52             : static uint64_t memtrack_getallocatedblocks_preinit();
      53             : 
      54             : /* Early definition, documented in the implementation below */
      55             : static uint64_t memtrack_getallocatedRAM_preinit();
      56             : 
      57             : /* Early definition, documented in the implementation below */
      58             : static size_t memtrack_getblocksize_preinit(const void *p_Ptr);
      59             : 
      60             : /* Early definition, documented in the implementation below */
      61             : static unsigned int memtrack_addblock_postinit(const void *p_Ptr,
      62             :         const size_t p_Size,
      63             :         const char *p_File,
      64             :         const int p_Line,
      65             :         const char *p_CompilDate,
      66             :         const char *p_CompilTime,
      67             :         const char *p_Function);
      68             : 
      69             : /* Early definition, documented in the implementation below */
      70             : static unsigned int memtrack_delblock_postinit(const void *p_Ptr,
      71             :         const char *p_File,
      72             :         const int p_Line,
      73             :         const char *p_CompilDate,
      74             :         const char *p_CompilTime,
      75             :         const char *p_Function);
      76             : 
      77             : /* Early definition, documented in the implementation below */
      78             : static uint64_t memtrack_dumpblocks_postinit();
      79             : 
      80             : /* Early definition, documented in the implementation below */
      81             : static uint64_t memtrack_getallocatedblocks_postinit();
      82             : 
      83             : /* Early definition, documented in the implementation below */
      84             : static uint64_t memtrack_getallocatedRAM_postinit();
      85             : 
      86             : /* Early definition, documented in the implementation below */
      87             : static size_t memtrack_getblocksize_postinit(const void *p_Ptr);
      88             : 
      89             : /*******************/
      90             : /* Implementations */
      91             : /*******************/
      92             : 
      93             : /** Memory block metadata list reset
      94             :  *
      95             :  * This function is not defined in the header file because it should never be
      96             :  * used. It is exported because it is used by the unit tests. NEVER USE IT, it
      97             :  * will crash your code.
      98             :  */
      99        2364 : void memtrack_reset()
     100             : {
     101             :     /* Ne réinitialise que si nécessaire */
     102        2364 :     if ( memtrack_addblock == memtrack_addblock_preinit)
     103        1182 :         return;
     104             : 
     105             :     /* Déconfiguration des foncteurs */
     106        1182 :     memtrack_addblock = memtrack_addblock_preinit;
     107        1182 :     memtrack_delblock = memtrack_delblock_preinit;
     108        1182 :     memtrack_dumpblocks = memtrack_dumpblocks_preinit;
     109        1182 :     memtrack_getallocatedblocks = memtrack_getallocatedblocks_preinit;
     110        1182 :     memtrack_getallocatedRAM = memtrack_getallocatedRAM_preinit;
     111        1182 :     memtrack_getblocksize = memtrack_getblocksize_preinit;
     112             : 
     113             :     /* Purge de la liste */
     114        2892 :     while (Tail!=Head->Next) {
     115        1710 :         memtrack_delblock_postinit(Head->Next->Ptr,NULL,0,NULL,NULL,NULL);
     116             :     }
     117             : 
     118             :     /* Réinitialization des pointeurs */
     119        1182 :     free(Head);
     120        1182 :     free(Tail);
     121        1182 :     Head=NULL;
     122        1182 :     Tail=NULL;
     123             : }
     124             : 
     125             : /** Memory blocks metadata list initialization
     126             :  *
     127             :  * This function is private, not meant to be called externally, it is
     128             :  * automatically called by other functions at the very first usage. It
     129             :  * initializes the memory block metadata list, with start and end sentinels. It
     130             :  * needs to be executed before the real list manipulation functions.
     131             :  *
     132             :  * Each real manipulation function has two private static implementations,
     133             :  * uninitialized and initialized, and a publicly exported functor which is
     134             :  * referencing the uninitialized form by default. The uninitialized forms first
     135             :  * call this initialization function which makes the functos reference the
     136             :  * initialized forms.
     137             :  *
     138             :  *  \return Initialization status
     139             :  *      \retval 0 in case of success
     140             :  */
     141        7327 : static unsigned int memtrack_init()
     142             : {
     143        7327 :     Head = (TMemBlock *) malloc(sizeof(TMemBlock));
     144        7327 :     Tail = (TMemBlock *) malloc(sizeof(TMemBlock));
     145             : 
     146        7327 :     if ((NULL==Head)||(NULL==Tail)) {
     147         880 :         fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
     148             :                 __FILE__,__LINE__);
     149         880 :         return 1;
     150             :     }
     151        6447 :     Head->Prev = (TMemBlock *) NULL;
     152        6447 :     Head->Next = Tail;
     153        6447 :     Tail->Next = (TMemBlock *) NULL;
     154        6447 :     Tail->Prev = Head;
     155        6447 :     Tail->Ptr = Head->Ptr = (void *)NULL;
     156        6447 :     Tail->Size = Head->Size = 0;
     157        6447 :     Tail->File = Head->File = (char *)NULL;
     158        6447 :     Tail->Line = Head->Line = 0;
     159        6447 :     Tail->CompilDate = Head->CompilDate = (char *)NULL;
     160        6447 :     Tail->CompilTime = Head->CompilTime = (char *)NULL;
     161        6447 :     Tail->Function = Head->Function = (char *)NULL;
     162             : 
     163             :     /* Initialisation des compteurs */
     164        6447 :     NbBlocks=0;
     165        6447 :     RAMSize=0;
     166             : 
     167             :     /* Modification des foncteurs pour utiliser les fonctions définitives */
     168        6447 :     memtrack_addblock = memtrack_addblock_postinit;
     169        6447 :     memtrack_delblock = memtrack_delblock_postinit;
     170        6447 :     memtrack_dumpblocks = memtrack_dumpblocks_postinit;
     171        6447 :     memtrack_getallocatedblocks = memtrack_getallocatedblocks_postinit;
     172        6447 :     memtrack_getallocatedRAM = memtrack_getallocatedRAM_postinit;
     173        6447 :     memtrack_getblocksize = memtrack_getblocksize_postinit;
     174             : 
     175        6447 :     return 0;
     176             : }
     177             : 
     178             : 
     179             : /** Add a memory block metadata entry to the list (preinit)
     180             :  *
     181             :  * Default function for the memtrack_addblock functor until initialized by the
     182             :  * memtrack_init function. It is executed if the functor is called before
     183             :  * initialization. It triggers initialization with functors definitive
     184             :  * assignation to the *_postinit functions and calls the actual postinit
     185             :  * function.
     186             :  *
     187             :  * \sa memtrack_addblock
     188             :  * \sa memtrack_addblock_postinit
     189             :  */
     190        3525 : static unsigned int memtrack_addblock_preinit(const void *p_Ptr,
     191             :         const size_t p_Size,
     192             :         const char *p_File,
     193             :         const int p_Line,
     194             :         const char *p_CompilDate,
     195             :         const char *p_CompilTime,
     196             :         const char *p_Function)
     197             : {
     198             :     /* Initialisation de la liste */
     199        3525 :     if (0!=memtrack_init()) {
     200         780 :         fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
     201             :                 __FILE__,__LINE__);
     202             :         /* OOM */
     203         780 :         return 1;
     204             :     }
     205             : 
     206             :     /* Appel de la fonction réelle */
     207        2745 :     return memtrack_addblock(p_Ptr, p_Size, p_File, p_Line, p_CompilDate,
     208             :                              p_CompilTime, p_Function);
     209             : }
     210             : 
     211             : /** Remove a memory block metadata entry from the list (preinit)
     212             :  *
     213             :  * Default function for the memtrack_delblock functor until initialized by the
     214             :  * memtrack_init function. It is executed if the functor is called before
     215             :  * initialization. It triggers initialization with functors definitive
     216             :  * assignation to the *_postinit functions and calls the actual postinit
     217             :  * function.
     218             :  *
     219             :  * \sa memtrack_delblock
     220             :  * \sa memtrack_delblock_postinit
     221             :  */
     222          24 : static unsigned int memtrack_delblock_preinit(const void *p_Ptr,
     223             :         const char *p_File,
     224             :         const int p_Line,
     225             :         const char *p_CompilDate,
     226             :         const char *p_CompilTime,
     227             :         const char *p_Function)
     228             : {
     229             :     /* Initialisation de la liste */
     230          24 :     if (0!=memtrack_init()) {
     231          20 :         fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
     232             :                 __FILE__,__LINE__);
     233             :         /* OOM */
     234          20 :         return 1;
     235             :     }
     236             : 
     237             :     /* Appel de la fonction réelle */
     238           4 :     return memtrack_delblock(p_Ptr, p_File, p_Line, p_CompilDate,
     239             :                              p_CompilTime, p_Function);
     240             : }
     241             : 
     242             : /** Dump memory block metadata entries from the list (preinit)
     243             :  *
     244             :  * Default function for the memtrack_dumpblocks functor until initialized by the
     245             :  * memtrack_init function. It is executed if the functor is called before
     246             :  * initialization. It triggers initialization with functors definitive
     247             :  * assignation to the *_postinit functions and calls the actual postinit
     248             :  * function.
     249             :  *
     250             :  * \sa memtrack_dumpblocks
     251             :  * \sa memtrack_dumpblocks_postinit
     252             :  */
     253          39 : static uint64_t memtrack_dumpblocks_preinit()
     254             : {
     255             :     /* Initialisation de la liste */
     256          39 :     if (0!=memtrack_init()) {
     257          20 :         fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
     258             :                 __FILE__,__LINE__);
     259             :         /* OOM */
     260          20 :         return 0;
     261             :     }
     262             : 
     263             :     /* Appel de la fonction réelle */
     264          19 :     return memtrack_dumpblocks();
     265             : }
     266             : 
     267             : /** Get the memory block metadata entries count (preinit)
     268             :  *
     269             :  * Default function for the memtrack_getallocatedblocks functor until
     270             :  * initialized by the memtrack_init function. It is executed if the functor is
     271             :  * called before initialization. It triggers initialization with functors
     272             :  * definitive assignation to the *_postinit functions and calls the actual
     273             :  * postinit function.
     274             :  *
     275             :  * \sa memtrack_getallocatedblocks
     276             :  * \sa memtrack_getallocatedblocks_postinit
     277             :  */
     278        3648 : static uint64_t memtrack_getallocatedblocks_preinit()
     279             : {
     280             :     /* Initialisation de la liste */
     281        3648 :     if (0!=memtrack_init()) {
     282          20 :         fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
     283             :                 __FILE__,__LINE__);
     284             :         /* OOM */
     285          20 :         return 0;
     286             :     }
     287             : 
     288             :     /* Appel de la fonction réelle */
     289        3628 :     return memtrack_getallocatedblocks();
     290             : }
     291             : 
     292             : /** Get the memory block metadata entries total RAM (preinit)
     293             :  *
     294             :  * Default function for the memtrack_getallocatedRAM functor until
     295             :  * initialized by the memtrack_init function. It is executed if the functor is
     296             :  * called before initialization. It triggers initialization with functors
     297             :  * definitive assignation to the *_postinit functions and calls the actual
     298             :  * postinit function.
     299             :  *
     300             :  * \sa memtrack_getallocatedRAM
     301             :  * \sa memtrack_getallocatedRAM_postinit
     302             :  */
     303          23 : static uint64_t memtrack_getallocatedRAM_preinit()
     304             : {
     305             :     /* Initialisation de la liste */
     306          23 :     if (0!=memtrack_init()) {
     307          20 :         fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
     308             :                 __FILE__,__LINE__);
     309             :         /* OOM */
     310          20 :         return 0;
     311             :     }
     312             : 
     313             :     /* Appel de la fonction réelle */
     314           3 :     return memtrack_getallocatedRAM();
     315             : }
     316             : 
     317             : /** Get a memory block RAM size (preinit)
     318             :  *
     319             :  * Default function for the memtrack_getblocksize functor until initialized by
     320             :  * the memtrack_init function. It is executed if the functor is called before
     321             :  * initialization. It triggers initialization with functors definitive
     322             :  * assignation to the *_postinit functions and calls the actual postinit
     323             :  * function.
     324             :  *
     325             :  * \sa memtrack_getblocksize
     326             :  * \sa memtrack_getblocksize_postinit
     327             :  */
     328          68 : static size_t memtrack_getblocksize_preinit(const void *p_Ptr)
     329             : {
     330             :     /* Initialisation de la liste */
     331          68 :     if (0!=memtrack_init()) {
     332          20 :         fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
     333             :                 __FILE__,__LINE__);
     334             :         /* OOM */
     335          20 :         return 0;
     336             :     }
     337             : 
     338             :     /* Appel de la fonction réelle */
     339          48 :     return memtrack_getblocksize(p_Ptr);
     340             : }
     341             : 
     342             : /** Add a memory block metadata entry to the list (postinit)
     343             :  *
     344             :  * This function is referenced by the memtrack_addblock functor after
     345             :  * initialization. This is the real implementation of the feature.
     346             :  *
     347             :  * \sa memtrack_addblock
     348             :  * \sa memtrack_addblock_preinit
     349             :  */
     350       13752 : static unsigned int memtrack_addblock_postinit(const void *p_Ptr,
     351             :         const size_t p_Size,
     352             :         const char *p_File,
     353             :         const int p_Line,
     354             :         const char *p_CompilDate,
     355             :         const char *p_CompilTime,
     356             :         const char *p_Function)
     357             : {
     358             :     TMemBlock *l_tmp;
     359             : 
     360             :     /* Test de validité des données à enregistrer */
     361             :     /* Meme si malloc permet Size=0, ce n'est pas portable */
     362       13752 :     if ((NULL==p_Ptr)||
     363       13096 :         (0==p_Size)||
     364       13066 :         (NULL==p_File)||
     365       13066 :         (0==p_File[0])||
     366       12508 :         (0==p_Line)||
     367       12478 :         (NULL==p_CompilDate)||
     368       12478 :         (0==p_CompilDate[0])||
     369       12172 :         (NULL==p_CompilTime)||
     370       12172 :         (0==p_CompilTime[0])||
     371       11866 :         (NULL==p_Function)||
     372       11866 :         (0==p_Function[0])) {
     373        2162 :         fprintf(stderr,"%s:%d Null or empty parameters\n",__FILE__, __LINE__);
     374        2162 :         return 1;
     375             :     }
     376             : 
     377             :     /* On ne peut pas dupliquer un pointeur. Pour le modifier, il faut le
     378             :      * supprimer et le recréer, ce n'est pas le rôle de ces fonctions  de
     379             :      * bas-niveau */
     380             : 
     381             :     /* Recherche du pointeur */
     382       11590 :     l_tmp = Head->Next;
     383       28139 :     while ((l_tmp->Ptr != p_Ptr) && (l_tmp != Tail))
     384       16549 :         l_tmp = l_tmp->Next;
     385             : 
     386             :     /* Le bloc ne doit pas avoir été trouvé */
     387       11590 :     if (l_tmp != Tail) {
     388          66 :         fprintf(stderr,"%s:%d Memory bloc already registered\n",__FILE__, __LINE__);
     389          66 :         return 1;
     390             :     }
     391             : 
     392             :     /* Allocation d'un nouveau descripteur de bloc */
     393       11524 :     l_tmp = (TMemBlock *) malloc(sizeof(TMemBlock));
     394             : 
     395             :     /* Allocation réussie ? */
     396       11524 :     if (NULL == l_tmp) {
     397        1892 :         return 1;
     398             :     }
     399             : 
     400             :     /* Remplissage du descripteur */
     401        9632 :     l_tmp->Ptr = (void *)p_Ptr;
     402        9632 :     l_tmp->Size = p_Size;
     403        9632 :     if (NULL==(l_tmp->File = strdup(p_File?p_File:""))) {
     404          76 :         free(l_tmp);
     405          76 :         return 1;
     406             :     };
     407        9556 :     l_tmp->Line = p_Line;
     408        9556 :     if (NULL==(l_tmp->CompilDate = strdup(p_CompilDate?p_CompilDate:""))) {
     409           0 :         free(l_tmp->File);
     410           0 :         free(l_tmp);
     411           0 :         return 1;
     412             :     };
     413        9556 :     if (NULL==(l_tmp->CompilTime = strdup(p_CompilTime?p_CompilTime:""))) {
     414          15 :         free(l_tmp->CompilDate);
     415          15 :         free(l_tmp->File);
     416          15 :         free(l_tmp);
     417          15 :         return 1;
     418             :     };
     419        9541 :     if (NULL==(l_tmp->Function = strdup(p_Function?p_Function:""))) {
     420          39 :         free(l_tmp->CompilTime);
     421          39 :         free(l_tmp->CompilDate);
     422          39 :         free(l_tmp->File);
     423          39 :         free(l_tmp);
     424          39 :         return 1;
     425             :     };
     426             : 
     427             :     /* Ajout de la description dans la liste (Section critique) */
     428        9502 :     l_tmp->Prev = Tail->Prev;
     429        9502 :     l_tmp->Next = Tail;
     430        9502 :     l_tmp->Prev->Next = l_tmp->Next->Prev = l_tmp;
     431             : 
     432             :     /* Mise à jour des compteurs */
     433        9502 :     NbBlocks++;
     434        9502 :     RAMSize += p_Size;
     435             : 
     436        9502 :     return 0;
     437             : }
     438             : 
     439             : /** Remove a memory block metadata entry from the list (postinit)
     440             :  *
     441             :  * This function is referenced by the memtrack_addblock functor after
     442             :  * initialization. This is the real implementation of the feature.
     443             :  *
     444             :  * \sa memtrack_delblock
     445             :  * \sa memtrack_delblock_preinit
     446             :  */
     447        7527 : static unsigned int memtrack_delblock_postinit(const void *p_Ptr,
     448             :         const char *p_File,
     449             :         const int p_Line,
     450             :         const char *p_CompilDate,
     451             :         const char *p_CompilTime,
     452             :         const char *p_Function)
     453             : {
     454             :     TMemBlock *l_tmp;
     455             :     (void) p_File;
     456             :     (void) p_Line;
     457             :     (void) p_CompilDate;
     458             :     (void) p_CompilTime;
     459             :     (void) p_Function;
     460             : 
     461             :     /* Recherche de la description */
     462        7527 :     l_tmp = Head->Next;
     463       10706 :     while ((l_tmp->Ptr != p_Ptr) && (l_tmp != Tail))
     464        3179 :         l_tmp = l_tmp->Next;
     465             : 
     466             :     /* Le bloc doit avoir été trouvé */
     467        7527 :     if (l_tmp == Tail) {
     468         726 :         fprintf(stderr,"%s:%d Block not found for deletion\n",__FILE__, __LINE__);
     469         726 :         return 1;
     470             :     }
     471             : 
     472             :     /* Libération des ressources acquises */
     473             :     /* On ne libère pas le bloc mémoire lui-même */
     474        6801 :     free(l_tmp->File);
     475        6801 :     free(l_tmp->CompilDate);
     476        6801 :     free(l_tmp->CompilTime);
     477        6801 :     free(l_tmp->Function);
     478             : 
     479             :     /* Retrait de la description de la liste (Section critique) */
     480        6801 :     l_tmp->Next->Prev = l_tmp->Prev;
     481        6801 :     l_tmp->Prev->Next = l_tmp->Next;
     482             : 
     483             :     /* Mise à jour des compteurs */
     484        6801 :     NbBlocks--;
     485        6801 :     RAMSize -= l_tmp->Size;
     486             : 
     487             :     /* Libération de la description */
     488        6801 :     free(l_tmp);
     489             : 
     490        6801 :     return 0;
     491             : }
     492             : 
     493             : /** Dump memory block metadata entries from the list (postinit)
     494             :  *
     495             :  * This function is referenced by the memtrack_addblock functor after
     496             :  * initialization. This is the real implementation of the feature.
     497             :  *
     498             :  * \sa memtrack_dumpblocks
     499             :  * \sa memtrack_dumpblocks_preinit
     500             :  */
     501        7900 : static uint64_t memtrack_dumpblocks_postinit()
     502             : {
     503             :     TMemBlock *l_tmp;
     504        7900 :     uint64_t l_NbBlocks = 0;;
     505             : 
     506        7900 :     if (Head->Next != Tail) {
     507             :         size_t l_BlockSize;
     508        3454 :         fprintf(stderr,
     509             :                 "+----------------------------------------------------------------------------------------------------------+\n");
     510        3454 :         fprintf(stderr, "| %-104s |\n", "Memory Tracker Report");
     511        3454 :         fprintf(stderr,
     512             :                 "+----------------------+----------------------+------+-----------------+----------+------------------------+\n");
     513        3454 :         fprintf(stderr,
     514             :                 "| %-20s | %-20s | %-4s | %-15s | %-8s | %-22s |\n",
     515             :                 "Function", "File", "Line", "Address", "Bytes",
     516             :                 "Compiled");
     517        3454 :         fprintf(stderr,
     518             :                 "+----------------------+----------------------+------+-----------------+----------+------------------------+\n");
     519             : 
     520        3454 :         l_tmp = Head->Next;  /**< Curseur */
     521        3454 :         l_BlockSize = 0;
     522       12188 :         while (l_tmp != Tail) {
     523        8734 :             fprintf(stderr,
     524             :                     "| %-20s | %-20s | %4d | %15p | %8lu | %11s @ %8s |\n",
     525             :                     l_tmp->Function, l_tmp->File, l_tmp->Line,
     526        8734 :                     l_tmp->Ptr, (unsigned long)l_tmp->Size, l_tmp->CompilDate,
     527             :                     l_tmp->CompilTime);
     528        8734 :             l_NbBlocks++;
     529        8734 :             l_BlockSize += l_tmp->Size;
     530        8734 :             l_tmp = l_tmp->Next;
     531             :         }
     532        3454 :         fprintf(stderr,
     533             :                 "+----------------------+----------------------+------+-----------------+----------+------------------------+\n");
     534        3454 :         fprintf(stderr,
     535             :                 "| %9lu bytes in %6lu blocks. %70s |\n", (unsigned long)l_BlockSize,
     536             :                 l_NbBlocks, "");
     537        3454 :         fprintf(stderr,
     538             :                 "+----------------------------------------------------------------------------------------------------------+\n");
     539             :     }
     540             :     /* Add ASSERT or assert (l_NbBlocks==NbBlocks) */
     541        7900 :     return l_NbBlocks;
     542             : }
     543             : 
     544             : /** Get the memory block metadata entries count (postinit)
     545             :  *
     546             :  * This function is referenced by the memtrack_addblock functor after
     547             :  * initialization. This is the real implementation of the feature.
     548             :  *
     549             :  * \sa memtrack_getallocatedblocks
     550             :  * \sa memtrack_getallocatedblocks_preinit
     551             :  */
     552       23505 : static uint64_t memtrack_getallocatedblocks_postinit()
     553             : {
     554       23505 :     return NbBlocks;
     555             : }
     556             : 
     557             : /** Get the memory block metadata entries total RAM (postinit)
     558             :  *
     559             :  * This function is referenced by the memtrack_addblock functor after
     560             :  * initialization. This is the real implementation of the feature.
     561             :  *
     562             :  * \sa memtrack_getallocatedRAM
     563             :  * \sa memtrack_getallocatedRAM_preinit
     564             :  */
     565       15997 : static uint64_t memtrack_getallocatedRAM_postinit()
     566             : {
     567       15997 :     return RAMSize;
     568             : }
     569             : 
     570             : /** Get a memory block RAM size (postinit)
     571             :  *
     572             :  * This function is referenced by the memtrack_addblock functor after
     573             :  * initialization. This is the real implementation of the feature.
     574             :  *
     575             :  * \sa memtrack_getblocksize
     576             :  * \sa memtrack_getblocksize_preinit
     577             :  */
     578        9974 : static size_t memtrack_getblocksize_postinit(const void *p_Ptr)
     579             : {
     580             :     /* Recherche de la description */
     581        9974 :     TMemBlock *l_tmp = Head->Next;
     582       21896 :     while ((l_tmp->Ptr != p_Ptr) && (l_tmp != Tail))
     583       11922 :         l_tmp = l_tmp->Next;
     584             : 
     585             :     /* Le bloc doit avoir été trouvé */
     586        9974 :     if (l_tmp == Tail)
     587        5078 :         return 0;
     588             :     else
     589        4896 :         return l_tmp->Size;
     590             : }
     591             : 
     592             : /* Documented in header file */
     593             : unsigned int (*memtrack_addblock) (const void *p_Ptr,
     594             :                                    const size_t p_Size,
     595             :                                    const char *p_File,
     596             :                                    const int p_Line,
     597             :                                    const char *p_CompilDate,
     598             :                                    const char *p_CompilTime,
     599             :                                    const char *p_Function) =
     600             :                                        memtrack_addblock_preinit;
     601             : 
     602             : /* Documented in header file */
     603             : unsigned int (*memtrack_delblock) (const void *p_Ptr,
     604             :                                    const char *p_File,
     605             :                                    const int p_Line,
     606             :                                    const char *p_CompilDate,
     607             :                                    const char *p_CompilTime,
     608             :                                    const char *p_Function) =
     609             :                                        memtrack_delblock_preinit;
     610             : 
     611             : /* Documented in header file */
     612             : uint64_t (*memtrack_dumpblocks) () = memtrack_dumpblocks_preinit;
     613             : 
     614             : /* Documented in header file */
     615             : uint64_t (*memtrack_getallocatedblocks) () = memtrack_getallocatedblocks_preinit;
     616             : 
     617             : /* Documented in header file */
     618             : uint64_t (*memtrack_getallocatedRAM) () = memtrack_getallocatedRAM_preinit;
     619             : 
     620             : /* Documented in header file */
     621             : size_t(*memtrack_getblocksize) (const void *p_Ptr) = memtrack_getblocksize_preinit;

Generated by: LCOV version 1.16