LCOV - code coverage report
Current view: top level - src - memtrack.c (source / functions) Hit Total Coverage
Test: libdebug.info Lines: 140 169 82.8 %
Date: 2025-02-25 19:31:32 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-12-19 19:49
      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             : #define _XOPEN_SOURCE 500                       /* strdup */
      20             : #include "libdebug/memtrack.h"
      21             : #include <string.h>                             /* strdup */
      22             : #include <stdio.h>                              /* fprintf */
      23             : 
      24             : static TMemBlock *Head;         /**< Memory blocks metadata list start sentinal */
      25             : static TMemBlock *Tail;         /**< Memory blocks metadata list end sentinal */
      26             : static uint64_t NbBlocks;       /**< Memory blocks metadata counter */
      27             : static uint64_t RAMSize;        /**< Memory blocks metadata RAM sum */
      28             : 
      29             : static unsigned int memtrack_init();
      30             : static unsigned int memtrack_addblock_preinit(const void *p_Ptr,
      31             :         const size_t p_Size,
      32             :         const char *p_File,
      33             :         const int p_Line,
      34             :         const char *p_CompilDate,
      35             :         const char *p_CompilTime,
      36             :         const char *p_Function);
      37             : static unsigned int memtrack_delblock_preinit(const void *p_Ptr,
      38             :         const char *p_File,
      39             :         const int p_Line,
      40             :         const char *p_CompilDate,
      41             :         const char *p_CompilTime,
      42             :         const char *p_Function);
      43             : static uint64_t memtrack_dumpblocks_preinit();
      44             : static uint64_t memtrack_getallocatedblocks_preinit();
      45             : static uint64_t memtrack_getallocatedRAM_preinit();
      46             : static size_t memtrack_getblocksize_preinit(const void *p_Ptr);
      47             : static unsigned int memtrack_addblock_postinit(const void *p_Ptr,
      48             :         const size_t p_Size,
      49             :         const char *p_File,
      50             :         const int p_Line,
      51             :         const char *p_CompilDate,
      52             :         const char *p_CompilTime,
      53             :         const char *p_Function);
      54             : static unsigned int memtrack_delblock_postinit(const void *p_Ptr,
      55             :         const char *p_File,
      56             :         const int p_Line,
      57             :         const char *p_CompilDate,
      58             :         const char *p_CompilTime,
      59             :         const char *p_Function);
      60             : static uint64_t memtrack_dumpblocks_postinit();
      61             : static uint64_t memtrack_getallocatedblocks_postinit();
      62             : static uint64_t memtrack_getallocatedRAM_postinit();
      63             : static size_t memtrack_getblocksize_postinit(const void *p_Ptr);
      64             : 
      65             : /*******************/
      66             : /* Implementations */
      67             : /*******************/
      68             : 
      69             : /** Memory block metadata list reset
      70             :  *
      71             :  * This function is not defined in the header file because it should never be
      72             :  * used. It is exported because it is used by the unit tests. NEVER USE IT, it
      73             :  * will crash your code.
      74             :  */
      75         204 : void memtrack_reset() {
      76             :     /* Ne réinitialise que si nécessaire */
      77         204 :     if ( memtrack_addblock == memtrack_addblock_preinit)
      78         102 :         return;
      79             : 
      80             :     /* Déconfiguration des foncteurs */
      81         102 :     memtrack_addblock = memtrack_addblock_preinit;
      82         102 :     memtrack_delblock = memtrack_delblock_preinit;
      83         102 :     memtrack_dumpblocks = memtrack_dumpblocks_preinit;
      84         102 :     memtrack_getallocatedblocks = memtrack_getallocatedblocks_preinit;
      85         102 :     memtrack_getallocatedRAM = memtrack_getallocatedRAM_preinit;
      86         102 :     memtrack_getblocksize = memtrack_getblocksize_preinit;
      87             : 
      88             :     /* Purge de la liste */
      89         282 :     while (Tail!=Head->Next) {
      90         180 :         memtrack_delblock_postinit(Head->Next->Ptr,NULL,0,NULL,NULL,NULL);
      91             :     }
      92             : 
      93             :     /* Réinitialization des pointeurs */
      94         102 :     free(Head);
      95         102 :     free(Tail);
      96         102 :     Head=NULL;
      97         102 :     Tail=NULL;
      98             : }
      99             : 
     100             : /** Memory blocks metadata list initialization
     101             :  *
     102             :  * This function is private, not meant to be called externally, it is
     103             :  * automatically called by other functions at the very first usage. It
     104             :  * initializes the memory block metadata list, with start and end sentinels. It
     105             :  * needs to be executed before the real list manipulation functions.
     106             :  *
     107             :  * Each real manipulation function has two private static implementations,
     108             :  * uninitialized and initialized, and a publicly exported functor which is
     109             :  * referencing the uninitialized form by default. The uninitialized forms first
     110             :  * call this initialization function which makes the functos reference the
     111             :  * initialized forms.
     112             :  *
     113             :  *  \return Initialization status
     114             :  *      \retval 0 in case of success
     115             :  */
     116         393 : static unsigned int memtrack_init() {
     117         393 :     Head = (TMemBlock *) malloc(sizeof(TMemBlock));
     118         393 :     Tail = (TMemBlock *) malloc(sizeof(TMemBlock));
     119             : 
     120         393 :     if ((NULL==Head)||(NULL==Tail)) {
     121           0 :         fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
     122             :                 __FILE__,__LINE__);
     123           0 :         return 1;
     124             :     }
     125         393 :     Head->Prev = (TMemBlock *) NULL;
     126         393 :     Head->Next = Tail;
     127         393 :     Tail->Next = (TMemBlock *) NULL;
     128         393 :     Tail->Prev = Head;
     129         393 :     Tail->Ptr = Head->Ptr = (void *)NULL;
     130         393 :     Tail->Size = Head->Size = 0;
     131         393 :     Tail->File = Head->File = (char *)NULL;
     132         393 :     Tail->Line = Head->Line = 0;
     133         393 :     Tail->CompilDate = Head->CompilDate = (char *)NULL;
     134         393 :     Tail->CompilTime = Head->CompilTime = (char *)NULL;
     135         393 :     Tail->Function = Head->Function = (char *)NULL;
     136             : 
     137             :     /* Initialisation des compteurs */
     138         393 :     NbBlocks=0;
     139         393 :     RAMSize=0;
     140             : 
     141             :     /* Modification des foncteurs pour utiliser les fonctions définitives */
     142         393 :     memtrack_addblock = memtrack_addblock_postinit;
     143         393 :     memtrack_delblock = memtrack_delblock_postinit;
     144         393 :     memtrack_dumpblocks = memtrack_dumpblocks_postinit;
     145         393 :     memtrack_getallocatedblocks = memtrack_getallocatedblocks_postinit;
     146         393 :     memtrack_getallocatedRAM = memtrack_getallocatedRAM_postinit;
     147         393 :     memtrack_getblocksize = memtrack_getblocksize_postinit;
     148             : 
     149         393 :     return 0;
     150             : }
     151             : 
     152             : 
     153             : /** Add a memory block metadata entry to the list (preinit)
     154             :  *
     155             :  * Default function for the memtrack_addblock functor until initialized by the
     156             :  * memtrack_init function. It is executed if the functor is called before
     157             :  * initialization. It triggers initialization with functors definitive
     158             :  * assignation to the *_postinit functions and calls the actual postinit
     159             :  * function.
     160             :  *
     161             :  * \sa memtrack_addblock
     162             :  * \sa memtrack_addblock_postinit
     163             :  */
     164          70 : static unsigned int memtrack_addblock_preinit(const void *p_Ptr,
     165             :         const size_t p_Size,
     166             :         const char *p_File,
     167             :         const int p_Line,
     168             :         const char *p_CompilDate,
     169             :         const char *p_CompilTime,
     170             :         const char *p_Function) {
     171             :     /* Initialisation de la liste */
     172          70 :     if (0!=memtrack_init()) {
     173           0 :         fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
     174             :                 __FILE__,__LINE__);
     175             :         /* OOM */
     176           0 :         return 1;
     177             :     }
     178             : 
     179             :     /* Appel de la fonction réelle */
     180          70 :     return memtrack_addblock(p_Ptr, p_Size, p_File, p_Line, p_CompilDate,
     181             :                              p_CompilTime, p_Function);
     182             : }
     183             : 
     184             : /** Remove a memory block metadata entry from the list (preinit)
     185             :  *
     186             :  * Default function for the memtrack_delblock functor until initialized by the
     187             :  * memtrack_init function. It is executed if the functor is called before
     188             :  * initialization. It triggers initialization with functors definitive
     189             :  * assignation to the *_postinit functions and calls the actual postinit
     190             :  * function.
     191             :  *
     192             :  * \sa memtrack_delblock
     193             :  * \sa memtrack_delblock_postinit
     194             :  */
     195           4 : static unsigned int memtrack_delblock_preinit(const void *p_Ptr,
     196             :         const char *p_File,
     197             :         const int p_Line,
     198             :         const char *p_CompilDate,
     199             :         const char *p_CompilTime,
     200             :         const char *p_Function) {
     201             :     /* Initialisation de la liste */
     202           4 :     if (0!=memtrack_init()) {
     203           0 :         fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
     204             :                 __FILE__,__LINE__);
     205             :         /* OOM */
     206           0 :         return 1;
     207             :     }
     208             : 
     209             :     /* Appel de la fonction réelle */
     210           4 :     return memtrack_delblock(p_Ptr, p_File, p_Line, p_CompilDate,
     211             :                              p_CompilTime, p_Function);
     212             : }
     213             : 
     214             : /** Dump memory block metadata entries from the list (preinit)
     215             :  *
     216             :  * Default function for the memtrack_dumpblocks functor until initialized by the
     217             :  * memtrack_init function. It is executed if the functor is called before
     218             :  * initialization. It triggers initialization with functors definitive
     219             :  * assignation to the *_postinit functions and calls the actual postinit
     220             :  * function.
     221             :  *
     222             :  * \sa memtrack_dumpblocks
     223             :  * \sa memtrack_dumpblocks_postinit
     224             :  */
     225           2 : static uint64_t memtrack_dumpblocks_preinit() {
     226             :     /* Initialisation de la liste */
     227           2 :     if (0!=memtrack_init()) {
     228           0 :         fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
     229             :                 __FILE__,__LINE__);
     230             :         /* OOM */
     231           0 :         return 0;
     232             :     }
     233             : 
     234             :     /* Appel de la fonction réelle */
     235           2 :     return memtrack_dumpblocks();
     236             : }
     237             : 
     238             : /** Get the memory block metadata entries count (preinit)
     239             :  *
     240             :  * Default function for the memtrack_getallocatedblocks functor until
     241             :  * initialized by the memtrack_init function. It is executed if the functor is
     242             :  * called before initialization. It triggers initialization with functors
     243             :  * definitive assignation to the *_postinit functions and calls the actual
     244             :  * postinit function.
     245             :  *
     246             :  * \sa memtrack_getallocatedblocks
     247             :  * \sa memtrack_getallocatedblocks_postinit
     248             :  */
     249         306 : static uint64_t memtrack_getallocatedblocks_preinit() {
     250             :     /* Initialisation de la liste */
     251         306 :     if (0!=memtrack_init()) {
     252           0 :         fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
     253             :                 __FILE__,__LINE__);
     254             :         /* OOM */
     255           0 :         return 0;
     256             :     }
     257             : 
     258             :     /* Appel de la fonction réelle */
     259         306 :     return memtrack_getallocatedblocks();
     260             : }
     261             : 
     262             : /** Get the memory block metadata entries total RAM (preinit)
     263             :  *
     264             :  * Default function for the memtrack_getallocatedRAM functor until
     265             :  * initialized by the memtrack_init function. It is executed if the functor is
     266             :  * called before initialization. It triggers initialization with functors
     267             :  * definitive assignation to the *_postinit functions and calls the actual
     268             :  * postinit function.
     269             :  *
     270             :  * \sa memtrack_getallocatedRAM
     271             :  * \sa memtrack_getallocatedRAM_postinit
     272             :  */
     273           3 : static uint64_t memtrack_getallocatedRAM_preinit() {
     274             :     /* Initialisation de la liste */
     275           3 :     if (0!=memtrack_init()) {
     276           0 :         fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
     277             :                 __FILE__,__LINE__);
     278             :         /* OOM */
     279           0 :         return 0;
     280             :     }
     281             : 
     282             :     /* Appel de la fonction réelle */
     283           3 :     return memtrack_getallocatedRAM();
     284             : }
     285             : 
     286             : /** Get a memory block RAM size (preinit)
     287             :  *
     288             :  * Default function for the memtrack_getblocksize functor until initialized by
     289             :  * the memtrack_init function. It is executed if the functor is called before
     290             :  * initialization. It triggers initialization with functors definitive
     291             :  * assignation to the *_postinit functions and calls the actual postinit
     292             :  * function.
     293             :  *
     294             :  * \sa memtrack_getblocksize
     295             :  * \sa memtrack_getblocksize_postinit
     296             :  */
     297           8 : static size_t memtrack_getblocksize_preinit(const void *p_Ptr) {
     298             :     /* Initialisation de la liste */
     299           8 :     if (0!=memtrack_init()) {
     300           0 :         fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
     301             :                 __FILE__,__LINE__);
     302             :         /* OOM */
     303           0 :         return 0;
     304             :     }
     305             : 
     306             :     /* Appel de la fonction réelle */
     307           8 :     return memtrack_getblocksize(p_Ptr);
     308             : }
     309             : 
     310             : /** Add a memory block metadata entry to the list (postinit)
     311             :  *
     312             :  * This function is referenced by the memtrack_addblock functor after
     313             :  * initialization. This is the real implementation of the feature.
     314             :  *
     315             :  * \sa memtrack_addblock
     316             :  * \sa memtrack_addblock_preinit
     317             :  */
     318        1110 : static unsigned int memtrack_addblock_postinit(const void *p_Ptr,
     319             :         const size_t p_Size,
     320             :         const char *p_File,
     321             :         const int p_Line,
     322             :         const char *p_CompilDate,
     323             :         const char *p_CompilTime,
     324             :         const char *p_Function) {
     325             :     TMemBlock *l_tmp;
     326             : 
     327             :     /* Test de validité des données à enregistrer */
     328             :     /* Meme si malloc permet Size=0, ce n'est pas portable */
     329        1110 :     if ((NULL==p_Ptr)||
     330        1044 :             (0==p_Size)||
     331        1032 :             (NULL==p_File)||
     332        1032 :             (0==p_File[0])||
     333         954 :             (0==p_Line)||
     334         942 :             (NULL==p_CompilDate)||
     335         942 :             (0==p_CompilDate[0])||
     336         894 :             (NULL==p_CompilTime)||
     337         894 :             (0==p_CompilTime[0])||
     338         846 :             (NULL==p_Function)||
     339         846 :             (0==p_Function[0])) {
     340         300 :         fprintf(stderr,"%s:%d Null or empty parameters\n",__FILE__, __LINE__);
     341         300 :         return 1;
     342             :     }
     343             : 
     344             :     /* On ne peut pas dupliquer un pointeur. Pour le modifier, il faut le
     345             :      * supprimer et le recréer, ce n'est pas le rôle de ces fonctions  de
     346             :      * bas-niveau */
     347             : 
     348             :     /* Recherche du pointeur */
     349         810 :     l_tmp = Head->Next;
     350        2271 :     while ((l_tmp->Ptr != p_Ptr) && (l_tmp != Tail))
     351        1461 :         l_tmp = l_tmp->Next;
     352             : 
     353             :     /* Le bloc ne doit pas avoir été trouvé */
     354         810 :     if (l_tmp != Tail) {
     355           6 :         fprintf(stderr,"%s:%d Memory bloc already registered\n",__FILE__, __LINE__);
     356           6 :         return 1;
     357             :     }
     358             : 
     359             :     /* Allocation d'un nouveau descripteur de bloc */
     360         804 :     l_tmp = (TMemBlock *) malloc(sizeof(TMemBlock));
     361             : 
     362             :     /* Allocation réussie ? */
     363         804 :     if (NULL == l_tmp) {
     364           0 :         return 1;
     365             :     }
     366             : 
     367             :     /* Remplissage du descripteur */
     368         804 :     l_tmp->Ptr = (void *)p_Ptr;
     369         804 :     l_tmp->Size = p_Size;
     370         804 :     if (NULL==(l_tmp->File = strdup(p_File?p_File:""))) {
     371           0 :         free(l_tmp);
     372           0 :         return 1;
     373             :     };
     374         804 :     l_tmp->Line = p_Line;
     375         804 :     if (NULL==(l_tmp->CompilDate = strdup(p_CompilDate?p_CompilDate:""))) {
     376           0 :         free(l_tmp->File);
     377           0 :         free(l_tmp);
     378           0 :         return 1;
     379             :     };
     380         804 :     if (NULL==(l_tmp->CompilTime = strdup(p_CompilTime?p_CompilTime:""))) {
     381           0 :         free(l_tmp->CompilDate);
     382           0 :         free(l_tmp->File);
     383           0 :         free(l_tmp);
     384           0 :         return 1;
     385             :     };
     386         804 :     if (NULL==(l_tmp->Function = strdup(p_Function?p_Function:""))) {
     387           0 :         free(l_tmp->CompilTime);
     388           0 :         free(l_tmp->CompilDate);
     389           0 :         free(l_tmp->File);
     390           0 :         free(l_tmp);
     391           0 :         return 1;
     392             :     };
     393             : 
     394             :     /* Ajout de la description dans la liste (Section critique) */
     395         804 :     l_tmp->Prev = Tail->Prev;
     396         804 :     l_tmp->Next = Tail;
     397         804 :     l_tmp->Prev->Next = l_tmp->Next->Prev = l_tmp;
     398             : 
     399             :     /* Mise à jour des compteurs */
     400         804 :     NbBlocks++;
     401         804 :     RAMSize += p_Size;
     402             : 
     403         804 :     return 0;
     404             : }
     405             : 
     406             : /** Remove a memory block metadata entry from the list (postinit)
     407             :  *
     408             :  * This function is referenced by the memtrack_addblock functor after
     409             :  * initialization. This is the real implementation of the feature.
     410             :  *
     411             :  * \sa memtrack_delblock
     412             :  * \sa memtrack_delblock_preinit
     413             :  */
     414         770 : static unsigned int memtrack_delblock_postinit(const void *p_Ptr,
     415             :         const char *p_File,
     416             :         const int p_Line,
     417             :         const char *p_CompilDate,
     418             :         const char *p_CompilTime,
     419             :         const char *p_Function) {
     420             :     TMemBlock *l_tmp;
     421             :     (void) p_File;
     422             :     (void) p_Line;
     423             :     (void) p_CompilDate;
     424             :     (void) p_CompilTime;
     425             :     (void) p_Function;
     426             : 
     427             :     /* Recherche de la description */
     428         770 :     l_tmp = Head->Next;
     429        1179 :     while ((l_tmp->Ptr != p_Ptr) && (l_tmp != Tail))
     430         409 :         l_tmp = l_tmp->Next;
     431             : 
     432             :     /* Le bloc doit avoir été trouvé */
     433         770 :     if (l_tmp == Tail) {
     434          26 :         fprintf(stderr,"%s:%d Block not found for deletion\n",__FILE__, __LINE__);
     435          26 :         return 1;
     436             :     }
     437             : 
     438             :     /* Libération des ressources acquises */
     439             :     /* On ne libère pas le bloc mémoire lui-même */
     440         744 :     free(l_tmp->File);
     441         744 :     free(l_tmp->CompilDate);
     442         744 :     free(l_tmp->CompilTime);
     443         744 :     free(l_tmp->Function);
     444             : 
     445             :     /* Retrait de la description de la liste (Section critique) */
     446         744 :     l_tmp->Next->Prev = l_tmp->Prev;
     447         744 :     l_tmp->Prev->Next = l_tmp->Next;
     448             : 
     449             :     /* Mise à jour des compteurs */
     450         744 :     NbBlocks--;
     451         744 :     RAMSize -= l_tmp->Size;
     452             : 
     453             :     /* Libération de la description */
     454         744 :     free(l_tmp);
     455             : 
     456         744 :     return 0;
     457             : }
     458             : 
     459             : /** Dump memory block metadata entries from the list (postinit)
     460             :  *
     461             :  * This function is referenced by the memtrack_addblock functor after
     462             :  * initialization. This is the real implementation of the feature.
     463             :  *
     464             :  * \sa memtrack_dumpblocks
     465             :  * \sa memtrack_dumpblocks_preinit
     466             :  */
     467         690 : static uint64_t memtrack_dumpblocks_postinit() {
     468             :     TMemBlock *l_tmp;
     469         690 :     uint64_t l_NbBlocks = 0;;
     470             : 
     471         690 :     if (Head->Next != Tail) {
     472             :         size_t l_BlockSize;
     473         321 :         fprintf(stderr,
     474             :                 "+----------------------------------------------------------------------------------------------------------+\n");
     475         321 :         fprintf(stderr, "| %-104s |\n", "Memory Tracker Report");
     476         321 :         fprintf(stderr,
     477             :                 "+----------------------+----------------------+------+-----------------+----------+------------------------+\n");
     478         321 :         fprintf(stderr,
     479             :                 "| %-20s | %-20s | %-4s | %-15s | %-8s | %-22s |\n",
     480             :                 "Function", "File", "Line", "Address", "Bytes",
     481             :                 "Compiled");
     482         321 :         fprintf(stderr,
     483             :                 "+----------------------+----------------------+------+-----------------+----------+------------------------+\n");
     484             : 
     485         321 :         l_tmp = Head->Next;  /**< Curseur */
     486         321 :         l_BlockSize = 0;
     487        1170 :         while (l_tmp != Tail) {
     488         849 :             fprintf(stderr,
     489             :                     "| %-20s | %-20s | %4d | %15p | %8lu | %11s @ %8s |\n",
     490             :                     l_tmp->Function, l_tmp->File, l_tmp->Line,
     491         849 :                     l_tmp->Ptr, (unsigned long)l_tmp->Size, l_tmp->CompilDate,
     492             :                     l_tmp->CompilTime);
     493         849 :             l_NbBlocks++;
     494         849 :             l_BlockSize += l_tmp->Size;
     495         849 :             l_tmp = l_tmp->Next;
     496             :         }
     497         321 :         fprintf(stderr,
     498             :                 "+----------------------+----------------------+------+-----------------+----------+------------------------+\n");
     499         321 :         fprintf(stderr,
     500             :                 "| %9lu bytes in %6lu blocks. %70s |\n", (unsigned long)l_BlockSize,
     501             :                 (unsigned long)l_NbBlocks, "");
     502         321 :         fprintf(stderr,
     503             :                 "+----------------------------------------------------------------------------------------------------------+\n");
     504             :     }
     505             :     /* Add ASSERT or assert (l_NbBlocks==NbBlocks) */
     506         690 :     return l_NbBlocks;
     507             : }
     508             : 
     509             : /** Get the memory block metadata entries count (postinit)
     510             :  *
     511             :  * This function is referenced by the memtrack_addblock functor after
     512             :  * initialization. This is the real implementation of the feature.
     513             :  *
     514             :  * \sa memtrack_getallocatedblocks
     515             :  * \sa memtrack_getallocatedblocks_preinit
     516             :  */
     517        1930 : static uint64_t memtrack_getallocatedblocks_postinit() {
     518        1930 :     return NbBlocks;
     519             : }
     520             : 
     521             : /** Get the memory block metadata entries total RAM (postinit)
     522             :  *
     523             :  * This function is referenced by the memtrack_addblock functor after
     524             :  * initialization. This is the real implementation of the feature.
     525             :  *
     526             :  * \sa memtrack_getallocatedRAM
     527             :  * \sa memtrack_getallocatedRAM_preinit
     528             :  */
     529        1235 : static uint64_t memtrack_getallocatedRAM_postinit() {
     530        1235 :     return RAMSize;
     531             : }
     532             : 
     533             : /** Get a memory block RAM size (postinit)
     534             :  *
     535             :  * This function is referenced by the memtrack_addblock functor after
     536             :  * initialization. This is the real implementation of the feature.
     537             :  *
     538             :  * \sa memtrack_getblocksize
     539             :  * \sa memtrack_getblocksize_preinit
     540             :  */
     541         904 : static size_t memtrack_getblocksize_postinit(const void *p_Ptr) {
     542             :     /* Recherche de la description */
     543         904 :     TMemBlock *l_tmp = Head->Next;
     544        2206 :     while ((l_tmp->Ptr != p_Ptr) && (l_tmp != Tail))
     545        1302 :         l_tmp = l_tmp->Next;
     546             : 
     547             :     /* Le bloc doit avoir été trouvé */
     548         904 :     if (l_tmp == Tail)
     549         388 :         return 0;
     550             :     else
     551         516 :         return l_tmp->Size;
     552             : }
     553             : 
     554             : /** Functor to register an allocated memory block metadata
     555             :  *
     556             :  * Create and adds a memory block metadata record in the tracking system to
     557             :  * detect memory leaks. It performs some basic sanity checks. The filename,
     558             :  * compilation date and compilation time can not be null or empty, the line
     559             :  * number can not be 0, the memory pointer to store can not be NULL or already
     560             :  * registered and its size needs to be greater than 0.
     561             :  *
     562             :  * The function is called from memdbg.c functions used in the application code
     563             :  * thru memory.h macros. The macro automatically fills the filename, line
     564             :  * number, compilation date and time, and function name (using GCC's non-ansi
     565             :  * __func_ extension).
     566             :  *
     567             :  * This functor is used to implement a lazy initialization. It initialy
     568             :  * reference a temporary function to trigger memtrack initialization before
     569             :  * calling the actual function. Then, it references the actual function directly
     570             :  * to avoid any useless tests.
     571             :  *
     572             :  *  @param [in] p_Ptr Allocated memory block pointer
     573             :  *  @param [in] p_Size Allocated memory block size
     574             :  *  @param [in] p_File : Source file
     575             :  *  @param [in] p_Line : Source line number
     576             :  *  @param [in] p_CompilDate : File compilation date
     577             :  *  @param [in] p_CompilTime : File compilation time
     578             :  *  @param [in] p_Function : Source function name
     579             :  *
     580             :  *  @return Registration status
     581             :  *      @retval 0 if succeeded,
     582             :  *      @retval 1 if not possible.
     583             :  */
     584             : unsigned int (*memtrack_addblock) (const void *p_Ptr,
     585             :                                    const size_t p_Size,
     586             :                                    const char *p_File,
     587             :                                    const int p_Line,
     588             :                                    const char *p_CompilDate,
     589             :                                    const char *p_CompilTime,
     590             :                                    const char *p_Function) =
     591             :                                        memtrack_addblock_preinit;
     592             : 
     593             : /** Functor to unregister an allocated memory block metadata
     594             :  *
     595             :  * Find and delete a memory block metadata record in the tracking system.
     596             :  * It performs some basic sanity checks. The filename, compilation date and
     597             :  * compilation time can not be null or empty, the line number can not be 0, the
     598             :  * memory pointer to remove can not be NULL, it needs to already be registered.
     599             :  *
     600             :  * The function is called from memdbg.c functions used in the application code
     601             :  * thru memory.h macros. The macro automatically fills the filename, line
     602             :  * number, compilation date and time, and function name (using GCC's non-ansi
     603             :  * __func_ extension).
     604             :  *
     605             :  * This functor is used to implement a lazy initialization. It initialy
     606             :  * reference a temporary function to trigger memtrack initialization before
     607             :  * calling the actual function. Then, it references the actual function directly
     608             :  * to avoid any useless tests.
     609             :  *
     610             :  *  @param [in] p_Ptr Allocated memory block pointer
     611             :  *  @param [in] p_File : Source file
     612             :  *  @param [in] p_Line : Source line number
     613             :  *  @param [in] p_CompilDate : File compilation date
     614             :  *  @param [in] p_CompilTime : File compilation time
     615             :  *  @param [in] p_Function : Source function name
     616             :  *
     617             :  *  @return Registration status
     618             :  *      @retval 0 if succeeded,
     619             :  *      @retval !0 if not possible.
     620             :  */
     621             : unsigned int (*memtrack_delblock) (const void *p_Ptr,
     622             :                                    const char *p_File,
     623             :                                    const int p_Line,
     624             :                                    const char *p_CompilDate,
     625             :                                    const char *p_CompilTime,
     626             :                                    const char *p_Function) =
     627             :                                        memtrack_delblock_preinit;
     628             : 
     629             : /** Functor to list allocated memory blocks metadata
     630             :  *
     631             :  * Dumps all the metadata of the registered memory blocks to stderr.
     632             :  *
     633             :  * This functor is used to implement a lazy initialization. It initialy
     634             :  * reference a temporary function to trigger memtrack initialization before
     635             :  * calling the actual function. Then, it references the actual function directly
     636             :  * to avoid any useless tests.
     637             :  *
     638             :  *  @return Number of registered blocks (counted)
     639             :  *      @retval 0 if succeeded,
     640             :  *      @retval !0 if not possible.
     641             :  */
     642             : uint64_t (*memtrack_dumpblocks) () = memtrack_dumpblocks_preinit;
     643             : 
     644             : /** Functor to get the number of allocated blocks
     645             :  *
     646             :  * This function returns the value of the internal counter of allocated memory
     647             :  * blocks metadata.
     648             :  *
     649             :  * This functor is used to implement a lazy initialization. It initialy
     650             :  * reference a temporary function to trigger memtrack initialization before
     651             :  * calling the actual function. Then, it references the actual function directly
     652             :  * to avoid any useless tests.
     653             :  *
     654             :  *  @return Number of registered blocks
     655             :  */
     656             : uint64_t (*memtrack_getallocatedblocks) () = memtrack_getallocatedblocks_preinit;
     657             : 
     658             : /** Functor to get the total RAM size allocated
     659             :  *
     660             :  * This function returns the internal summ of all the allocated memory blocks
     661             :  * which are registered.
     662             :  *
     663             :  * This functor is used to implement a lazy initialization. It initialy
     664             :  * reference a temporary function to trigger memtrack initialization before
     665             :  * calling the actual function. Then, it references the actual function directly
     666             :  * to avoid any useless tests.
     667             :  *
     668             :  *  @return Total RAM size in bytes
     669             :  */
     670             : uint64_t (*memtrack_getallocatedRAM) () = memtrack_getallocatedRAM_preinit;
     671             : 
     672             : /** Functor to get size of a specific memory block
     673             :  *
     674             :  * The function will search in the list for the specified pointer. If the
     675             :  * pointer is not found, it will return 0, which is discriminent as the
     676             :  * memtracker does not allow to track a zero sized block. The memtracker does
     677             :  * not allow neither to track a NULL pointer, thus NULL will return 0.
     678             :  * Otherwise, the function will return the memory block size.
     679             :  *
     680             :  * This functor is used to implement a lazy initialization. It initialy
     681             :  * reference a temporary function to trigger memtrack initialization before
     682             :  * calling the actual function. Then, it references the actual function directly
     683             :  * to avoid any useless tests.
     684             :  *
     685             :  *  @param [in] p_Ptr Allocated and tracked memory block pointer
     686             :  *
     687             :  *  @return Memory block size in bytes
     688             :  */
     689             : size_t(*memtrack_getblocksize) (const void *p_Ptr) = memtrack_getblocksize_preinit;
     690             : 
     691             : /* vim: set tw=80: */

Generated by: LCOV version 1.16