LCOV - code coverage report
Current view: top level - util - MemoryManager.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 47 294 16.0 %
Date: 2020-06-30 00:58:45 Functions: 8 20 40.0 %
Branches: 16 462 3.5 %

           Branch data     Line data    Source code
       1                 :            : //-       Class: MemoryManager
       2                 :            : //-       Owner: Jim Hipp
       3                 :            : //- Description: MemoryManager provides object information and stack
       4                 :            : //-              storage pointer management used in association with
       5                 :            : //-              MemoryBlock and MemoryAllocation classes.
       6                 :            : //- Checked By: 
       7                 :            : //-    Version:
       8                 :            : //  Modified 5/7/96 R W Ostensen:  Fixed operator_new function as per recommendation
       9                 :            : //  from J Hipp.  Eliminated assignment of headOfFreeList to wild pointer loaction when
      10                 :            : //  memAllocatnSize=1.
      11                 :            : 
      12                 :            : 
      13                 :            : #include "MemoryBlock.hpp"
      14                 :            : #include "MemoryManager.hpp"
      15                 :            : #include "CubitMessage.hpp"
      16                 :            : #include "ArrayBasedContainer.hpp"
      17                 :            : #include "AppUtil.hpp"
      18                 :            : #include <cassert>
      19                 :            : #include <cstring>
      20                 :            : #include <iostream>
      21                 :            : #ifndef _WIN32
      22                 :            : #include <unistd.h>
      23                 :            : #endif
      24                 :            : 
      25                 :            : 
      26                 :            : MemoryManager* MemoryManager::memoryManagerListHead = NULL;
      27                 :            : 
      28                 :            : // constructors
      29                 :          0 : MemoryManager::MemoryManager() : useNew(false), objectName(NULL)
      30                 :            : {
      31                 :            :   // do not allow default constructor (must assign objectSize)
      32                 :          0 :   assert(0);
      33                 :            : }
      34                 :            : 
      35                 :          0 : MemoryManager::MemoryManager(const MemoryManager&) : useNew(false), objectName(NULL)
      36                 :            : {
      37                 :            :   // do not allow copy
      38                 :          0 :   assert(0);
      39                 :            : }
      40                 :            : 
      41                 :      17985 : MemoryManager::MemoryManager(const char* name, size_t size, int mem_size,
      42                 :            :                              int static_flag)
      43                 :      17985 :   : useNew(true)
      44                 :            : {
      45                 :            :     // allocate space for name and copy into buffer
      46         [ +  - ]:      17985 :   if (name) 
      47                 :            :   {
      48                 :      17985 :     objectName = new char[std::strlen(name) + 1];
      49                 :      17985 :     std::strcpy(objectName, name);
      50                 :            :   }
      51                 :            :   else
      52                 :          0 :     objectName = NULL;
      53                 :            :   
      54                 :            :     // initialize manager parameters
      55                 :      17985 :   staticManager   = static_flag;
      56                 :      17985 :   memBlockStack   = NULL;
      57                 :      17985 :   headOfFreeList  = NULL;
      58                 :            :   
      59         [ -  + ]:      17985 :   assert(size >= sizeof(char*));
      60                 :      17985 :   objectSize = size;
      61                 :            :   
      62                 :      17985 :   set_memory_allocation_increment(mem_size);
      63                 :            :   
      64                 :            :     // attach new manager to static stack
      65                 :      17985 :   next = memoryManagerListHead;
      66                 :      17985 :   memoryManagerListHead = this;
      67                 :      17985 : }
      68                 :            : 
      69                 :            : // destructor
      70                 :      17985 : MemoryManager::~MemoryManager()
      71                 :            : {
      72                 :            :   // delete objectName space and destroy block memory
      73         [ +  - ]:      17985 :   delete [] objectName;
      74                 :      17985 :   objectName = NULL;
      75                 :      17985 :   destroy_memory(staticManager);
      76                 :            :   
      77                 :            :   // find 'prev' manager pointer
      78                 :      17985 :   MemoryManager* prev        = NULL;
      79                 :      17985 :   MemoryManager* mem_manager = memoryManagerListHead;
      80                 :      17985 :   bool first = true;
      81 [ +  - ][ -  + ]:      17985 :   while (mem_manager && mem_manager != this)
      82                 :            :   {
      83 [ #  # ][ #  # ]:          0 :     if (!first && mem_manager == memoryManagerListHead)
      84                 :            :     {
      85                 :            :       // XXX: We aren't in the list!?
      86                 :          0 :       std::cerr << "MemoryManager: corrupted list?" << std::endl;
      87                 :          0 :       return;
      88                 :            :     }
      89                 :          0 :     first = false;
      90                 :          0 :     prev        = mem_manager;
      91                 :          0 :     mem_manager = mem_manager->next;
      92                 :            :   }
      93                 :            : 
      94                 :            :   // remove memory manager from static list
      95                 :            : 
      96         [ +  + ]:      17985 :   if (!next)
      97                 :            :   {
      98         [ +  - ]:       1635 :     if (!prev)
      99                 :            :     {
     100                 :            :       // no memory managers left
     101                 :            : 
     102                 :       1635 :       memoryManagerListHead = NULL;
     103                 :            :     }
     104                 :            :     else
     105                 :            :     {
     106                 :            :       // remove tail node
     107                 :            : 
     108                 :       1635 :       prev->next = NULL;
     109                 :            :     }
     110                 :            :   }
     111                 :            :   else
     112                 :            :   {
     113         [ +  - ]:      16350 :     if (!prev)
     114                 :            :     {
     115                 :            :       // remove head node
     116                 :            : 
     117                 :      16350 :       memoryManagerListHead = next;
     118                 :            :     }
     119                 :            :     else
     120                 :            :     {
     121                 :            :       // remove intermediate node
     122                 :            : 
     123                 :          0 :       prev->next = next;
     124                 :            :     }
     125                 :            :   }
     126                 :      17985 : }
     127                 :            : 
     128                 :            : // set memory block allocation increment
     129                 :      17985 : void MemoryManager::set_memory_allocation_increment(int mem_size)
     130                 :            : {
     131                 :            :   // set memory allocation increment
     132                 :            : 
     133         [ -  + ]:      17985 :   if (mem_size <= 0)
     134                 :            :   {
     135                 :          0 :      memAllocatnSize = DEFAULT_MEMORY_ALLOC_SIZE;
     136                 :            :   }
     137                 :            :   else
     138                 :            :   {
     139                 :      17985 :     memAllocatnSize = mem_size;
     140                 :            :   }
     141                 :      17985 : }
     142                 :            : 
     143                 :            : // destroy allocated block memory
     144                 :      17985 : void MemoryManager::destroy_memory(int static_flag)
     145                 :            : {
     146                 :            :   // assert if this is not a static memory manager and some of it's objects
     147                 :            :   // are still in use
     148         [ -  + ]:      17985 :   if (!static_flag) {
     149         [ #  # ]:          0 :     assert (!get_used_objects());
     150                 :            :   }
     151                 :            : 
     152                 :            :   // else delete block memory if any was allocated
     153 [ -  + ][ #  # ]:      17985 :   if (memBlockStack) delete memBlockStack;
     154                 :            : 
     155                 :            :   // reset stack pointers to empty
     156                 :      17985 :   headOfFreeList = NULL;
     157                 :      17985 :   memBlockStack  = NULL;
     158                 :      17985 : }
     159                 :            : 
     160                 :            : // return number of objects allocated
     161                 :          0 : int MemoryManager::get_allocated_objects()
     162                 :            : {
     163                 :            :   // return total number of objects allocated for this memory manager
     164                 :            : 
     165         [ #  # ]:          0 :   if (memBlockStack)
     166                 :            :   {
     167                 :          0 :     return (memBlockStack->get_memory_allocation() / objectSize);
     168                 :            :   }
     169                 :            :   else
     170                 :            :   {
     171                 :          0 :     return 0;
     172                 :            :   }
     173                 :            : }
     174                 :            : 
     175                 :            : // return free objects
     176                 :          0 : int MemoryManager::get_free_objects()
     177                 :            : {
     178                 :            :   // return total number of free objects (allocated but not used) for this
     179                 :            :   // memory manager
     180                 :            : 
     181         [ #  # ]:          0 :   if (headOfFreeList)
     182                 :            :   {
     183                 :          0 :     int i = 0;
     184                 :          0 :     char* list_ptr = headOfFreeList;
     185         [ #  # ]:          0 :     while (list_ptr)
     186                 :            :     {
     187                 :          0 :       i++;
     188                 :          0 :       list_ptr = *((char**) list_ptr);
     189                 :            :     }
     190                 :            : 
     191                 :          0 :     return i;
     192                 :            :   }
     193                 :            :   else
     194                 :            :   {
     195                 :          0 :     return 0;
     196                 :            :   }
     197                 :            : }
     198                 :            : 
     199                 :            : // return used objects
     200                 :          0 : int MemoryManager::get_used_objects()
     201                 :            : {
     202                 :            :   // return total number of used objects for this memory manager
     203                 :            : 
     204                 :          0 :   return (get_allocated_objects() - get_free_objects());
     205                 :            : }
     206                 :            : 
     207                 :            : // print allocation information to the command line
     208                 :          0 : void MemoryManager::show_object_memory(const char* name)
     209                 :            : {
     210                 :          0 :   int instance = 0;
     211                 :            : 
     212                 :            :   // find all instances of memory managers for object: name
     213                 :            : 
     214                 :          0 :   MemoryManager* mem_manager = memoryManagerListHead;
     215         [ #  # ]:          0 :   while (mem_manager)
     216                 :            :   {
     217         [ #  # ]:          0 :     if (!std::strcmp(mem_manager->objectName, name))
     218                 :            :     {
     219                 :            :       // if found then print pertinent memory allocation information
     220                 :            : 
     221                 :          0 :       instance++;
     222         [ #  # ]:          0 :       if (instance > 1)
     223                 :            :       {
     224 [ #  # ][ #  # ]:          0 :         PRINT_INFO("\nObject Name(%d): %s\n\n", instance, name);
     225                 :            :       }
     226                 :            :       else
     227                 :            :       {
     228 [ #  # ][ #  # ]:          0 :         PRINT_INFO("\nObject Name: %s\n\n", name);
     229                 :            :       }
     230                 :            : 
     231                 :          0 :       int a_obj = mem_manager->get_allocated_objects();
     232                 :          0 :       int f_obj = mem_manager->get_free_objects();
     233                 :          0 :       int u_obj = a_obj - f_obj;
     234                 :            : 
     235         [ #  # ]:          0 :       PRINT_INFO("  Object Size: %lu     Allocation Increment: %d\n\n",
     236         [ #  # ]:          0 :       (unsigned long)mem_manager->objectSize, mem_manager->memAllocatnSize);
     237         [ #  # ]:          0 :       PRINT_INFO("  Allocated Objects: %d  (bytes) %d\n", a_obj,
     238         [ #  # ]:          0 :                  a_obj * (int)(mem_manager->objectSize));
     239         [ #  # ]:          0 :       if (a_obj)
     240                 :            :       {
     241         [ #  # ]:          0 :         PRINT_INFO("       Free Objects: %d  (bytes) %d (%d%%)\n", f_obj,
     242                 :            :                    f_obj * (int)(mem_manager->objectSize),
     243         [ #  # ]:          0 :                    (100*f_obj)/a_obj);
     244         [ #  # ]:          0 :         PRINT_INFO("       Used Objects: %d  (bytes) %d (%d%%)\n", u_obj,
     245                 :            :                    u_obj * (int)(mem_manager->objectSize),
     246         [ #  # ]:          0 :                    (100*u_obj)/a_obj);
     247                 :            :       }
     248                 :            :     }
     249                 :            : 
     250                 :            :     // get next memory manager
     251                 :            : 
     252                 :          0 :     mem_manager = mem_manager->next;
     253                 :            :   }
     254                 :            : 
     255                 :            :   // if none were found then announce
     256                 :            : 
     257         [ #  # ]:          0 :   if (!instance)
     258                 :            :   {
     259 [ #  # ][ #  # ]:          0 :     PRINT_INFO("\nObject: %s was not found ...\n",  name);
     260                 :            :   }
     261                 :          0 : }
     262                 :            : 
     263                 :            : 
     264                 :            : // show allocation for all memory manager objects
     265                 :          0 : void MemoryManager::show_all_object_memory()
     266                 :            : {
     267                 :            : 
     268                 :            : #if defined(MACOSX)
     269                 :            :         
     270                 :            :   pid_t PID = getpid();
     271                 :            :   char command1[60];
     272                 :            :   unsigned long rss=0, vm=0;
     273                 :            : 
     274                 :            :   FILE *pipe;
     275                 :            :   char buf[1024];
     276                 :            :   
     277                 :            :   //get size of real memory
     278                 :            :   sprintf(command1,"ps -o rss -p %d | grep -v RSS",PID);
     279                 :            :   pipe = popen(command1, "r");
     280                 :            :   if (pipe) 
     281                 :            :   {
     282                 :            :     fgets(buf, 1024, pipe);
     283                 :            :     rss = strtoul(buf, NULL, 0);
     284                 :            :     pclose(pipe);
     285                 :            :   }
     286                 :            : 
     287                 :            :   //get size of virtual memory
     288                 :            :   sprintf(command1,"ps -o vsz -p %d | grep -v VSZ",PID);
     289                 :            :   pipe = popen(command1, "r");
     290                 :            :   if (pipe) 
     291                 :            :   {
     292                 :            :     fgets(buf, 1024, pipe);
     293                 :            :     vm = strtoul(buf, NULL, 0);
     294                 :            :     pclose(pipe);
     295                 :            :   }
     296                 :            : 
     297                 :            :   PRINT_INFO("Total memory = %lu\n", (unsigned long)vm );
     298                 :            :   PRINT_INFO("Resident memory = %lu\n", (unsigned long)rss );
     299                 :            : 
     300                 :            : 
     301                 :            : /*
     302                 :            :   struct rusage my_rusage;
     303                 :            :   int ret_val = getrusage( RUSAGE_CHILDREN, &my_rusage ); 
     304                 :            : 
     305                 :            :   if( ret_val == 0 )
     306                 :            :   {
     307                 :            :     PRINT_INFO("It was a success\n");
     308                 :            :     PRINT_INFO("Memory size = %d\n", my_rusage.ru_maxrss );
     309                 :            :     PRINT_INFO("Unshared data size = %d\n", my_rusage.ru_idrss);
     310                 :            :     PRINT_INFO("Integeral unshared data size = %d\n", my_rusage.ru_isrss);
     311                 :            :     PRINT_INFO("more values: %d %d %d %d %d %d %d %d %d %d %d \n",
     312                 :            :                 my_rusage.ru_ixrss, my_rusage.ru_minflt, my_rusage.ru_majflt, my_rusage.ru_nswap, 
     313                 :            :                 my_rusage.ru_inblock, my_rusage.ru_oublock, my_rusage.ru_msgsnd, my_rusage.ru_msgrcv, 
     314                 :            :                 my_rusage.ru_nsignals, my_rusage.ru_nvcsw, my_rusage.ru_nivcsw ); 
     315                 :            :   }
     316                 :            :   else
     317                 :            :     PRINT_INFO("It was a failure\n");
     318                 :            :  */  
     319                 :            : 
     320                 :            :  
     321                 :            : /* 
     322                 :            :   int i, mib[4];
     323                 :            :   size_t len;
     324                 :            :   struct kinfo_proc kp;
     325                 :            : 
     326                 :            :   len = 4;
     327                 :            :   sysctlnametomib("kern.proc.pid", mib, &len);
     328                 :            :   len = sizeof(kp);
     329                 :            :   int pid = getpid();
     330                 :            :   mib[3] = pid;
     331                 :            :   if (sysctl(mib, 4, &kp, &len, NULL, 0) == -1)
     332                 :            :   {
     333                 :            :     perror("sysctl");
     334                 :            :     PRINT_INFO("Got problems\n");
     335                 :            :   }
     336                 :            :   else if (len > 0)
     337                 :            :   {
     338                 :            :     PRINT_INFO("The call was successful!!!\n");
     339                 :            :   }
     340                 :            : */
     341                 :            : 
     342                 :            : /*
     343                 :            :   int i, mib[4];
     344                 :            :   size_t len;
     345                 :            :   struct kinfo_proc kp;
     346                 :            :  
     347                 :            :   len = 4; 
     348                 :            :   sysctlnametomib("kern.proc.pid", mib, &len);
     349                 :            : 
     350                 :            :   for (i = 0; i < 100; i++) 
     351                 :            :   {         
     352                 :            :     mib[3] = i;         
     353                 :            :     len = sizeof(kp);         
     354                 :            :     if (sysctl(mib, 4, &kp, &len, NULL, 0) == -1)
     355                 :            :       perror("sysctl");         
     356                 :            :     else if (len > 0)   
     357                 :            :       PRINT_INFO("Call was successful!\n"); 
     358                 :            :   }
     359                 :            : */ 
     360                 :            : 
     361                 :            : #endif
     362                 :            : 
     363                 :            : 
     364                 :            : #if defined(CUBIT_LINUX)
     365                 :            :   unsigned long vm, rss;
     366         [ #  # ]:          0 :   process_mem_usage( vm, rss );
     367                 :            : 
     368                 :            :   unsigned long read, write;
     369         [ #  # ]:          0 :   process_file_io( read, write );
     370                 :            : 
     371 [ #  # ][ #  # ]:          0 :   PRINT_INFO("Total memory = %lu\n", vm );
         [ #  # ][ #  # ]
     372 [ #  # ][ #  # ]:          0 :   PRINT_INFO("Resident memory = %lu\n", rss );
         [ #  # ][ #  # ]
     373 [ #  # ][ #  # ]:          0 :   PRINT_INFO("Bytes read = %lu\n", read );
         [ #  # ][ #  # ]
     374 [ #  # ][ #  # ]:          0 :   PRINT_INFO("Bytes written = %lu\n", write );
         [ #  # ][ #  # ]
     375                 :            : #endif
     376                 :            : 
     377                 :            :   /*
     378                 :            :   long int a_obj_byte_total = 0;
     379                 :            :   long int f_obj_byte_total = 0;
     380                 :            :   long int u_obj_byte_total = 0;
     381                 :            : 
     382                 :            :   // loop over all memory managers
     383                 :            : 
     384                 :            :   PRINT_INFO("\nDynamic Memory Allocation per Object\n\n");
     385                 :            : 
     386                 :            :   MemoryManager* mem_manager = memoryManagerListHead;
     387                 :            :   while (mem_manager) {
     388                 :            :     long int a_obj = mem_manager->get_allocated_objects();
     389                 :            :     long int f_obj = mem_manager->get_free_objects();
     390                 :            :     long int u_obj = a_obj - f_obj;
     391                 :            :     if (a_obj) {
     392                 :            :       // sum total allocated memory parameters (bytes)
     393                 :            :       a_obj_byte_total += a_obj * mem_manager->objectSize;
     394                 :            :       f_obj_byte_total += f_obj * mem_manager->objectSize;
     395                 :            :       u_obj_byte_total += u_obj * mem_manager->objectSize;
     396                 :            :     }
     397                 :            :     mem_manager = mem_manager->next;
     398                 :            :   }
     399                 :            : 
     400                 :            :   mem_manager = memoryManagerListHead;
     401                 :            :   while (mem_manager)
     402                 :            :   {
     403                 :            :     // print pertinent memory allocation information 
     404                 :            : 
     405                 :            :     long int a_obj = mem_manager->get_allocated_objects();
     406                 :            :     long int f_obj = mem_manager->get_free_objects();
     407                 :            :     long int u_obj = a_obj - f_obj;
     408                 :            : 
     409                 :            :     if (a_obj)
     410                 :            :     {
     411                 :            :       PRINT_INFO("\nObject Name: %s\n\n", mem_manager->objectName);
     412                 :            : 
     413                 :            :       PRINT_INFO("  Object Size: %d     Allocation Increment: %d\n\n",
     414                 :            :                  mem_manager->objectSize, mem_manager->memAllocatnSize);
     415                 :            :       if (a_obj_byte_total != 0)
     416                 :            :       {
     417                 :            :          PRINT_INFO("  Allocated Objects: %ld  (bytes) %ld (%d%% of Total)\n",
     418                 :            :                     a_obj, a_obj * mem_manager->objectSize,
     419                 :            :                     int((100.0*a_obj * mem_manager->objectSize)/a_obj_byte_total));
     420                 :            :          PRINT_INFO("       Free Objects: %ld  (bytes) %ld (%d%%)\n", f_obj,
     421                 :            :                     f_obj * mem_manager->objectSize,
     422                 :            :                     int((100.0*f_obj)/a_obj));
     423                 :            :          PRINT_INFO("       Used Objects: %ld  (bytes) %ld (%d%%)\n", u_obj,
     424                 :            :                     u_obj * mem_manager->objectSize,
     425                 :            :                     int((100.0*u_obj)/a_obj));
     426                 :            :       }
     427                 :            :       else
     428                 :            :       {
     429                 :            :          PRINT_INFO("  Allocated Objects: %ld  (bytes) %ld (100%% of Total)\n",
     430                 :            :                     a_obj, a_obj * mem_manager->objectSize);
     431                 :            :          PRINT_INFO("       Free Objects: %ld  (bytes) %ld (100%%)\n", f_obj,
     432                 :            :                     f_obj * mem_manager->objectSize);
     433                 :            :          PRINT_INFO("       Used Objects: %ld  (bytes) %ld (100%%)\n", u_obj,
     434                 :            :                     u_obj * mem_manager->objectSize);
     435                 :            :       }
     436                 :            :     }
     437                 :            : 
     438                 :            :     mem_manager = mem_manager->next;
     439                 :            :   }
     440                 :            : 
     441                 :            :   // print total memory allocation information
     442                 :            : 
     443                 :            :   char sizechar;
     444                 :            : 
     445                 :            :   PRINT_INFO("\nTotal Memory Allocation Information\n\n");
     446                 :            :   int divisor;
     447                 :            :   if (a_obj_byte_total > 10000000) {
     448                 :            :     sizechar = 'M';
     449                 :            :     divisor = 1000000;
     450                 :            :   }
     451                 :            :   else {
     452                 :            :     sizechar = 'K';
     453                 :            :     divisor = 1000;
     454                 :            :   }
     455                 :            :   
     456                 :            :   PRINT_INFO("  Allocated Memory: %ld%c (%ld bytes)\n", a_obj_byte_total/divisor, 
     457                 :            :              sizechar, a_obj_byte_total);
     458                 :            : 
     459                 :            :   if (a_obj_byte_total)
     460                 :            :   {
     461                 :            :     PRINT_INFO("       Free Memory: %ld%c (%d%%)\n", f_obj_byte_total/divisor, sizechar,
     462                 :            :                int((100.0*f_obj_byte_total)/a_obj_byte_total));
     463                 :            :     PRINT_INFO("       Used Memory: %ld%c (%d%%)\n", u_obj_byte_total/divisor, 
     464                 :            :                sizechar,
     465                 :            :                int((100.0*u_obj_byte_total)/a_obj_byte_total));
     466                 :            :   }
     467                 :            : 
     468                 :            : #ifndef JANUS
     469                 :            : #ifndef _WIN32
     470                 :            :   struct rusage r_usage;
     471                 :            :   AppUtil::instance()->apputil_getrusage(r_usage);
     472                 :            :   PRINT_INFO("       (System reports %ld%c used, incl. executable)\n", 
     473                 :            :               r_usage.ru_maxrss*getpagesize()/divisor, sizechar);
     474                 :            : #else
     475                 :            :   PRINT_INFO("\n");
     476                 :            : #endif // _WIN32
     477                 :            : #endif // JANUS
     478                 :            : 
     479                 :            :   // print DLList non-Pool allocation information
     480                 :            :   PRINT_INFO("\nTotal non-pool ArrayBasedContainer memory allocation  = %u%c\n"
     481                 :            :                "Maximum non-pool ArrayBasedContainer memory allocated = %u%c\n",
     482                 :            :              ArrayBasedContainer::current_allocated_memory()/divisor, sizechar, 
     483                 :            :              ArrayBasedContainer::maximum_allocated_memory()/divisor, sizechar);
     484                 :            : */
     485                 :            : 
     486                 :            : 
     487                 :            : 
     488                 :            : #if 0
     489                 :            :   // print HOOPS memory usage
     490                 :            :   long allocated = 0;
     491                 :            :   long in_use = 0;
     492                 :            :     //  DrawingTool::instance()->show_memory(allocated, in_use);
     493                 :            :   if (allocated != 0)
     494                 :            :      PRINT_INFO("\nGraphics subsystem memory: Allocated = %u%c (%d bytes)\n"
     495                 :            :                 "                           In-Use    = %u%c (%d%%)\n",
     496                 :            :                 allocated/divisor, sizechar, allocated, 
     497                 :            :                 in_use/divisor, sizechar, int((100.0*in_use)/allocated));
     498                 :            :   else
     499                 :            :      PRINT_INFO("\nGraphics subsystem memory: Allocated = %u%c (%d bytes)\n"
     500                 :            :                 "                           In-Use    = %u%c (100%%)\n",
     501                 :            :                 allocated/divisor, sizechar, allocated, 
     502                 :            :                 in_use/divisor, sizechar);
     503                 :            : #endif
     504                 :          0 : }
     505                 :            : 
     506                 :            : // compress memory for the requested object
     507                 :          0 : int MemoryManager::compress_object_memory(const char* name)
     508                 :            : {
     509                 :            :   // find all instances of memory managers for object: name
     510                 :            : 
     511                 :          0 :   int found        = 0;
     512                 :          0 :   int saved_memory = 0;
     513                 :          0 :   MemoryManager* mem_manager = memoryManagerListHead;
     514         [ #  # ]:          0 :   while (mem_manager)
     515                 :            :   {
     516         [ #  # ]:          0 :     if (!std::strcmp(mem_manager->objectName, name))
     517                 :            :     {
     518                 :            :       // if found then compress memory
     519                 :            : 
     520                 :          0 :       saved_memory += mem_manager->compress_memory();
     521                 :          0 :       found         = 1;
     522                 :            :     }
     523                 :            : 
     524                 :          0 :     mem_manager = mem_manager->next;
     525                 :            :   }
     526                 :            : 
     527                 :          0 :   return found;
     528                 :            : }
     529                 :            : 
     530                 :            : // compress all object memory
     531                 :          0 : int MemoryManager::compress_all_object_memory()
     532                 :            : {
     533                 :            :   // find all instances of memory managers
     534                 :          0 :   int saved_memory = 0;
     535                 :          0 :   MemoryManager* mem_manager = memoryManagerListHead;
     536                 :          0 :   MemoryManager* block_manager = NULL;
     537         [ #  # ]:          0 :   while (mem_manager)
     538                 :            :   {
     539         [ #  # ]:          0 :     if (!std::strcmp(mem_manager->objectName, "MemoryBlock"))
     540                 :            :     {
     541                 :            :       // save block_manager until end
     542                 :            : 
     543                 :          0 :       block_manager = mem_manager;
     544                 :            :     }
     545                 :            :     else
     546                 :            :     {
     547                 :            :       // compress memory
     548                 :            : 
     549                 :          0 :       saved_memory += mem_manager->compress_memory();
     550                 :            :     }
     551                 :            : 
     552                 :          0 :     mem_manager = mem_manager->next;
     553                 :            :   }
     554                 :            : 
     555         [ #  # ]:          0 :   if (block_manager)
     556                 :            :   {
     557                 :          0 :     saved_memory += block_manager->compress_memory();
     558                 :            :   }
     559                 :            : 
     560                 :          0 :   return saved_memory;
     561                 :            : }
     562                 :            :       
     563                 :            : // generic operator new call
     564                 :       8362 : void* MemoryManager::operator_new(size_t size)
     565                 :            : {
     566                 :            : 
     567         [ +  - ]:       8362 :   if (useNew) return malloc(size);
     568                 :            : 
     569                 :            :   // send requests of "wrong" size to ::new
     570                 :            :   
     571                 :            :   try
     572                 :            :   { 
     573 [ #  # ][ #  # ]:          0 :     if (size != objectSize) return ::new char[size];
     574                 :            :   }
     575                 :          0 :   catch(...) 
     576                 :            :   {
     577                 :          0 :     return (void*) NULL;
     578                 :            :   }
     579                 :            :   // get new element from head of free list
     580                 :            : 
     581                 :          0 :   char* p = headOfFreeList;
     582                 :            : 
     583                 :            :   try
     584                 :            :   {
     585         [ #  # ]:          0 :     if(!p)
     586                 :            :         {
     587                 :            :         // allocate new block
     588                 :            : 
     589                 :          0 :         int block_size  = memAllocatnSize * size;
     590         [ #  # ]:          0 :         char* new_block = ::new char[block_size];
     591         [ #  # ]:          0 :         if (!new_block) return (void*) NULL;
     592                 :            : 
     593                 :            :         // link new elements to form the free list
     594                 :            : 
     595                 :          0 :         int fill_limit = (memAllocatnSize - 1) * size;
     596         [ #  # ]:          0 :         for (int j = 0; j < fill_limit; j += size)
     597                 :            :         {
     598                 :          0 :           *((char**) &new_block[j]) = &new_block[j + size];
     599                 :            :         }
     600                 :          0 :         *((char**) &new_block[fill_limit]) = (char*) NULL;
     601                 :            : 
     602                 :            :         // assign new element
     603                 :            : 
     604                 :          0 :         p = new_block;
     605                 :            : 
     606                 :            :         // save new block to memory block stack
     607                 :            : 
     608 [ #  # ][ #  # ]:          0 :         memBlockStack = new MemoryBlock(memBlockStack, new_block, block_size);
     609                 :            :       }
     610                 :            :   }
     611                 :          0 :   catch(...)
     612                 :            :   {
     613                 :          0 :     return (void*) NULL;
     614                 :            :   }
     615                 :            :   //assign head of free list and return p
     616                 :            : 
     617                 :          0 :   headOfFreeList = *((char**) p);
     618                 :       8362 :   return (void*) p;
     619                 :            : }
     620                 :            : 
     621                 :            : // generic operator delete call
     622                 :       2736 : void MemoryManager::operator_delete(void *deadObject, size_t size)
     623                 :            : {
     624         [ +  - ]:       2736 :   if (useNew) 
     625                 :            :   {
     626                 :       2736 :     free(deadObject);
     627                 :       2736 :     return;
     628                 :            :   }
     629                 :            : 
     630                 :            :   // requests of "wrong" size to ::delete
     631                 :            : 
     632         [ #  # ]:          0 :   if (size != objectSize)
     633                 :            :   {
     634         [ #  # ]:          0 :     ::delete [] ((char*) deadObject);
     635                 :          0 :     return;
     636                 :            :   }
     637                 :            : 
     638                 :            :   // attach dead element to head of free list
     639                 :            : 
     640                 :          0 :   char* delete_object = (char*) deadObject;
     641                 :          0 :   *((char**) delete_object) = headOfFreeList;
     642                 :          0 :   headOfFreeList = delete_object;
     643                 :            : }
     644                 :            : 
     645                 :            : // compress memory blocks
     646                 :          0 : int MemoryManager::compress_memory()
     647                 :            : {
     648                 :            :   // if free objects exist then begin compression algorithm
     649                 :            : 
     650         [ #  # ]:          0 :   if (headOfFreeList)
     651                 :            :   {
     652                 :            :     // find total number of memory blocks attached to stack
     653                 :            :  
     654                 :          0 :     int n_blocks = 0;
     655                 :          0 :     MemoryBlock* mem_block = memBlockStack;
     656         [ #  # ]:          0 :     while (mem_block)
     657                 :            :     {
     658                 :          0 :       n_blocks++;
     659                 :          0 :       mem_block = mem_block->next_block();
     660                 :            :     }
     661                 :            : 
     662         [ #  # ]:          0 :     if (n_blocks == 0)
     663                 :            :     {
     664                 :            :        // no available memory to free ... return 0
     665                 :            :        // this is here for safety ... n_blocks should never be zero if
     666                 :            :        // headOfFreeList is not Null
     667                 :            : 
     668                 :          0 :        return 0;
     669                 :            :     }
     670                 :            :     else
     671                 :            :     {
     672                 :            :       // first determine if all objects are free ... if so then perform
     673                 :            :       // the easy compression routine
     674                 :            : 
     675 [ #  # ][ #  # ]:          0 :       if (!get_used_objects())
     676                 :            :       {
     677                 :            :         // all objects are free ... delete all blocks
     678                 :            : 
     679         [ #  # ]:          0 :         int n_bytes = memBlockStack->get_memory_allocation();
     680         [ #  # ]:          0 :         destroy_memory(staticManager);
     681                 :            : 
     682                 :            :         // return freed memory
     683                 :            : 
     684                 :          0 :         return n_bytes;
     685                 :            :       }
     686                 :            : 
     687                 :            :       // else perform the complex routine to remove those memory blocks that
     688                 :            :       // have all free elements
     689                 :            : 
     690                 :            :       // begin by constructing an integer array for each memory block to
     691                 :            :       // tally the number of free objects that each block contains
     692                 :            : 
     693                 :            :         // if there are a lot of blocks, we can save a huge amount of
     694                 :            :         // time by looking in the last few blocks that contained an
     695                 :            :         // element.
     696                 :          0 :       const int use_cache = n_blocks > 8;
     697                 :            :       int i, j, k;
     698                 :          0 :       i = j = k = 0;
     699                 :          0 :       const int cache_size = 4;
     700                 :            :       MemoryBlock* mem_block_sav[cache_size];
     701                 :            :       int i_sav[cache_size];
     702         [ #  # ]:          0 :       for ( i = cache_size; i--; )
     703                 :            :       {
     704                 :          0 :         mem_block_sav[i] = NULL;
     705                 :          0 :         i_sav[i] = 0;
     706                 :            :       }
     707                 :          0 :       int found = 0;
     708                 :            :       
     709                 :          0 :       mem_block = NULL;
     710                 :          0 :       char* list_ptr = NULL;
     711                 :            :       
     712 [ #  # ][ #  # ]:          0 :       unsigned int* free_tally = new unsigned int [n_blocks];
     713         [ #  # ]:          0 :       for (i = 0; i < n_blocks; i++) free_tally[i] = 0;
     714                 :            : 
     715                 :            :       // loop through free list tallying free elements
     716                 :            : 
     717                 :          0 :       list_ptr = headOfFreeList;
     718         [ #  # ]:          0 :       while (list_ptr)
     719                 :            :       {
     720                 :            :         // find memory block that owns this element
     721                 :            :         
     722                 :            :           // check last few blocks for speed
     723                 :          0 :         found = CUBIT_FALSE;
     724         [ #  # ]:          0 :         if ( use_cache )
     725                 :            :         {
     726         [ #  # ]:          0 :           for ( i = 0; i < cache_size; i++ )
     727                 :            :           {
     728                 :          0 :             mem_block = mem_block_sav[i];
     729 [ #  # ][ #  # ]:          0 :             if ( mem_block &&
     730 [ #  # ][ #  # ]:          0 :                  list_ptr >= mem_block->get_block() &&
                 [ #  # ]
     731         [ #  # ]:          0 :                  list_ptr < (mem_block->get_block() + 
     732         [ #  # ]:          0 :                              mem_block->block_size()) )
     733                 :            :             {
     734                 :          0 :               k = i_sav[i];
     735                 :          0 :               free_tally[k]++;
     736                 :          0 :               found = CUBIT_TRUE;
     737                 :          0 :               break;
     738                 :            :             }
     739                 :            :           }
     740                 :            :         }
     741         [ #  # ]:          0 :         if ( !found )
     742                 :            :         {
     743                 :            :             // search through all blocks
     744                 :          0 :           mem_block = memBlockStack;
     745         [ #  # ]:          0 :           for (i = 0; i < n_blocks; i++)
     746                 :            :           {
     747 [ #  # ][ #  # ]:          0 :             if ((list_ptr >= mem_block->get_block()) &&
         [ #  # ][ #  # ]
     748 [ #  # ][ #  # ]:          0 :                 (list_ptr < (mem_block->get_block() + mem_block->block_size())))
     749                 :            :             {
     750                 :            :                 // increment tally and exit
     751                 :            :               
     752                 :          0 :               free_tally[i]++;
     753                 :            :                 // save
     754 [ #  # ][ #  # ]:          0 :               if ( use_cache && mem_block_sav[j] != mem_block )
     755                 :            :               {
     756                 :          0 :                 mem_block_sav[j] = mem_block;
     757                 :          0 :                 i_sav[j] = i;
     758         [ #  # ]:          0 :                 if ( ++j >= cache_size )
     759                 :          0 :                   j = 0;
     760                 :            :               }
     761                 :          0 :               break;
     762                 :            :             }
     763                 :            :             
     764                 :            :               //  get next memory block
     765         [ #  # ]:          0 :             mem_block = mem_block->next_block();
     766                 :            :           }
     767                 :            :         }
     768                 :            : 
     769                 :            :         // get next element
     770                 :          0 :         list_ptr = *((char**) list_ptr);
     771                 :            :       }
     772                 :            : 
     773                 :            :       // zero tally for memory blocks that cannot be removed ... those that
     774                 :            :       // have some used elements
     775                 :            : 
     776                 :          0 :       int all_blocks = 0;
     777                 :          0 :       mem_block = memBlockStack;
     778         [ #  # ]:          0 :       for (i = 0; i < n_blocks; i++)
     779                 :            :       {
     780 [ #  # ][ #  # ]:          0 :         if (free_tally[i] != (mem_block->block_size() / objectSize))
     781                 :            :         {
     782                 :          0 :           free_tally[i] = 0;
     783                 :          0 :           all_blocks++;
     784                 :            :         }
     785                 :            : 
     786         [ #  # ]:          0 :         mem_block = mem_block->next_block();
     787                 :            :       }
     788                 :            : 
     789         [ #  # ]:          0 :       if (all_blocks == n_blocks)
     790                 :            :       {
     791                 :            :         // no memory can be saved ... all blocks have some used elements
     792                 :            :         // return 0
     793                 :            : 
     794         [ #  # ]:          0 :         delete [] free_tally;
     795                 :          0 :         return 0;
     796                 :            :       }
     797                 :            : 
     798                 :            :       // adjust free list pointers to remove those that belong to
     799                 :            :       // memory blocks that can be deleted
     800                 :          0 :       char* prev_ptr = NULL;
     801                 :          0 :       list_ptr = headOfFreeList;
     802         [ #  # ]:          0 :       while (list_ptr)
     803                 :            :       {
     804                 :            :         // find memory block that owns this element
     805                 :            :           // check last few blocks for speed
     806                 :          0 :         found = CUBIT_FALSE;
     807         [ #  # ]:          0 :         if ( use_cache )
     808                 :            :         {
     809         [ #  # ]:          0 :           for ( i = 0; i < cache_size; i++ )
     810                 :            :           {
     811                 :          0 :             mem_block = mem_block_sav[i];
     812 [ #  # ][ #  # ]:          0 :             if ( mem_block &&
     813 [ #  # ][ #  # ]:          0 :                  list_ptr >= mem_block->get_block() &&
                 [ #  # ]
     814         [ #  # ]:          0 :                  list_ptr < (mem_block->get_block() + 
     815         [ #  # ]:          0 :                              mem_block->block_size()) )
     816                 :            :             {
     817                 :          0 :               k = i_sav[i];
     818                 :          0 :               found = CUBIT_TRUE;
     819                 :          0 :               break;
     820                 :            :             }
     821                 :            :           }
     822                 :            :         }
     823         [ #  # ]:          0 :         if ( !found )
     824                 :            :         {
     825                 :          0 :           mem_block = memBlockStack;
     826         [ #  # ]:          0 :           for (i = 0; i < n_blocks; i++)
     827                 :            :           {
     828 [ #  # ][ #  # ]:          0 :             if ((list_ptr >= mem_block->get_block()) &&
         [ #  # ][ #  # ]
     829 [ #  # ][ #  # ]:          0 :                 (list_ptr < (mem_block->get_block() + mem_block->block_size())))
     830                 :            :             {
     831                 :          0 :               k = i;
     832                 :            :                 // save
     833 [ #  # ][ #  # ]:          0 :               if ( use_cache && mem_block_sav[j] != mem_block )
     834                 :            :               {
     835                 :          0 :                 mem_block_sav[j] = mem_block;
     836                 :          0 :                 i_sav[j] = i;
     837         [ #  # ]:          0 :                 if ( ++j >= cache_size )
     838                 :          0 :                   j = 0;
     839                 :            :               }
     840                 :          0 :               break;
     841                 :            :             }
     842                 :            :               // get next memory block
     843         [ #  # ]:          0 :             mem_block = mem_block->next_block();
     844                 :            :           }
     845                 :            :         }
     846                 :            :         
     847         [ #  # ]:          0 :         if (free_tally[k])
     848                 :            :         {
     849                 :            :             // remove element
     850                 :            :           
     851         [ #  # ]:          0 :           if (prev_ptr)
     852                 :            :           {
     853                 :          0 :             *((char**) prev_ptr) = *((char**) list_ptr);
     854                 :            :           }
     855                 :            :           else
     856                 :            :           {
     857                 :          0 :             headOfFreeList = *((char**) list_ptr);
     858                 :            :           }
     859                 :            :         }
     860                 :            :         else
     861                 :            :         {
     862                 :            :             // advance prev_ptr  
     863                 :          0 :           prev_ptr = list_ptr;
     864                 :            :         }
     865                 :            : 
     866                 :            :         // get next element
     867                 :          0 :         list_ptr = *((char**) list_ptr);
     868                 :            :       }
     869                 :            : 
     870                 :            :       // delete all memory blocks that have free_tally[i] > 0
     871                 :            : 
     872                 :          0 :       i = 0;
     873                 :          0 :       int save_bytes = 0;
     874                 :          0 :       MemoryBlock* prev_block = NULL;
     875                 :          0 :       mem_block               = memBlockStack;
     876         [ #  # ]:          0 :       while (mem_block)
     877                 :            :       {
     878         [ #  # ]:          0 :         if (free_tally[i])
     879                 :            :         {
     880                 :            :           // set previous MemoryBlocks next pointer to skip this block
     881                 :            : 
     882         [ #  # ]:          0 :           if (prev_block)
     883                 :            :           {
     884 [ #  # ][ #  # ]:          0 :             prev_block->next_block(mem_block->next_block());
     885                 :            :           }
     886                 :            :           else
     887                 :            :           {
     888         [ #  # ]:          0 :             memBlockStack = mem_block->next_block();
     889                 :            :           }
     890                 :            : 
     891                 :            :           // set MemoryBlock next pointer to NULL to avoid recusive delete
     892                 :            :           // update saved memory and delete mem_block
     893                 :            : 
     894         [ #  # ]:          0 :           mem_block->next_block((MemoryBlock*) NULL);
     895         [ #  # ]:          0 :           save_bytes += mem_block->block_size();
     896 [ #  # ][ #  # ]:          0 :           delete mem_block;
     897                 :            : 
     898                 :            :           // update mem_block to point to new current MemoryBlock
     899                 :            : 
     900         [ #  # ]:          0 :           if (prev_block)
     901                 :            :           {
     902         [ #  # ]:          0 :             mem_block = prev_block->next_block();
     903                 :            :           }
     904                 :            :           else
     905                 :            :           {
     906                 :          0 :             mem_block = memBlockStack;
     907                 :            :           }
     908                 :            :         }
     909                 :            :         else
     910                 :            :         {
     911                 :            :           // if block wasn't removed then update previous and current blocks
     912                 :            : 
     913                 :          0 :           prev_block = mem_block;
     914         [ #  # ]:          0 :           mem_block = mem_block->next_block();
     915                 :            :         }
     916                 :            : 
     917                 :            :         // increment to next block (used by free_tally array)
     918                 :            : 
     919                 :          0 :         ++i;
     920                 :            :       }
     921                 :            : 
     922                 :            :       // return freed memory (bytes)
     923                 :            : 
     924         [ #  # ]:          0 :       delete [] free_tally;
     925                 :          0 :       return save_bytes;
     926                 :            :     }
     927                 :            :   }
     928                 :            :   else
     929                 :            :   {
     930                 :            :     // no memory allocated ... return 0
     931                 :            : 
     932                 :          0 :     return 0;
     933                 :            :   }
     934                 :            : }
     935                 :            : 
     936                 :            : 
     937                 :          0 : void MemoryManager::process_mem_usage(unsigned long &vm_usage, unsigned long &resident_set)
     938                 :            : {
     939                 :            : 
     940                 :            : #if defined(CUBIT_LINUX)
     941                 :            :   using std::ios_base;
     942                 :            :   using std::ifstream;
     943                 :            :   using std::string;
     944                 :            : 
     945                 :          0 :   vm_usage     = 0;
     946                 :          0 :   resident_set = 0;
     947                 :            : 
     948                 :            :   // 'file' stat seems to give the most reliable results
     949                 :            :   //
     950         [ #  # ]:          0 :   ifstream stat_stream("/proc/self/stat",ios_base::in);
     951                 :            :   
     952                 :            :   // dummy vars for leading entries in stat that we don't care about
     953                 :            :   //
     954 [ #  # ][ #  # ]:          0 :   string pid, comm, state, ppid, pgrp, session, tty_nr;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     955 [ #  # ][ #  # ]:          0 :   string tpgid, flags, minflt, cminflt, majflt, cmajflt;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     956 [ #  # ][ #  # ]:          0 :   string utime, stime, cutime, cstime, priority, nice;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     957 [ #  # ][ #  # ]:          0 :   string O, itrealvalue, starttime;
           [ #  #  #  # ]
         [ #  # ][ #  # ]
     958                 :            :   
     959                 :            :   // the two fields we want...virtual memory size and resident memory size
     960                 :            :   //
     961                 :            :   unsigned long vsize;
     962                 :            :   long rss;
     963                 :            :   
     964 [ #  # ][ #  # ]:          0 :   stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     965 [ #  # ][ #  # ]:          0 :               >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     966 [ #  # ][ #  # ]:          0 :               >> utime >> stime >> cutime >> cstime >> priority >> nice
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     967 [ #  # ][ #  # ]:          0 :               >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest
         [ #  # ][ #  # ]
                 [ #  # ]
     968                 :            :               
     969                 :          0 :   long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages
     970                 :          0 :   vm_usage     = vsize / 1024;
     971         [ #  # ]:          0 :   resident_set = rss * page_size_kb;
     972                 :            : #else
     973                 :            :   vm_usage = 0;
     974                 :            :   resident_set = 0;
     975                 :            : #endif
     976                 :          0 : }
     977                 :            :   
     978                 :            :  
     979                 :          0 : void MemoryManager::process_file_io(unsigned long &read, unsigned long &write )
     980                 :            : {
     981                 :            : #if defined(CUBIT_LINUX)
     982                 :            :   using std::ios_base;
     983                 :            :   using std::ifstream;
     984                 :            :   using std::string;
     985                 :            : 
     986                 :          0 :   read = 0;
     987                 :          0 :   write = 0;
     988                 :            : 
     989                 :            :   // 'file' stat seems to give the most reliable results
     990                 :            :   //
     991         [ #  # ]:          0 :   ifstream stat_stream("/proc/self/io",ios_base::in);
     992                 :            :   
     993                 :            :   // dummy vars for leading entries in stat that we don't care about
     994                 :            :   //
     995 [ #  # ][ #  # ]:          0 :   string char1, char2;
         [ #  # ][ #  # ]
     996                 :            : 
     997                 :            :   //----------------------Getting two numbers out of this file 
     998                 :            :   // I/O counter: chars read
     999                 :            :   //The number of bytes which this task has caused to be read from storage. This
    1000                 :            :   //is simply the sum of bytes which this process passed to read() and pread().
    1001                 :            :   //It includes things like tty IO and it is unaffected by whether or not actual
    1002                 :            :   //physical disk IO was required (the read might have been satisfied from
    1003                 :            :   //pagecache)
    1004                 :            :   
    1005                 :            :   // I/O counter: chars written
    1006                 :            :   //The number of bytes which this task has caused, or shall cause to be written
    1007                 :            :   //to disk. Similar caveats apply here as with rchar.
    1008                 :            :   
    1009                 :            :   unsigned long tmp_read, tmp_write;
    1010                 :            :   
    1011 [ #  # ][ #  # ]:          0 :   stat_stream >> char1 >> tmp_read >> char2 >> tmp_write; //don't care about the rest 
         [ #  # ][ #  # ]
    1012                 :            :   
    1013                 :          0 :   read = tmp_read;
    1014         [ #  # ]:          0 :   write = tmp_write;
    1015                 :            : #else
    1016                 :            :   read = 0;
    1017                 :            :   write = 0;
    1018                 :            : #endif
    1019 [ +  - ][ +  - ]:       6540 : }
    1020                 :            : 
    1021                 :            : 
    1022                 :            : 

Generated by: LCOV version 1.11