xref: /oneTBB/src/tbbmalloc/Statistics.h (revision c21e688a)
151c0b2f7Stbbdev /*
2*c21e688aSSergey Zheltov     Copyright (c) 2005-2022 Intel Corporation
351c0b2f7Stbbdev 
451c0b2f7Stbbdev     Licensed under the Apache License, Version 2.0 (the "License");
551c0b2f7Stbbdev     you may not use this file except in compliance with the License.
651c0b2f7Stbbdev     You may obtain a copy of the License at
751c0b2f7Stbbdev 
851c0b2f7Stbbdev         http://www.apache.org/licenses/LICENSE-2.0
951c0b2f7Stbbdev 
1051c0b2f7Stbbdev     Unless required by applicable law or agreed to in writing, software
1151c0b2f7Stbbdev     distributed under the License is distributed on an "AS IS" BASIS,
1251c0b2f7Stbbdev     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1351c0b2f7Stbbdev     See the License for the specific language governing permissions and
1451c0b2f7Stbbdev     limitations under the License.
1551c0b2f7Stbbdev */
1651c0b2f7Stbbdev 
1751c0b2f7Stbbdev #define MAX_THREADS 1024
1851c0b2f7Stbbdev #define NUM_OF_BINS 30
1951c0b2f7Stbbdev #define ThreadCommonCounters NUM_OF_BINS
2051c0b2f7Stbbdev 
2151c0b2f7Stbbdev enum counter_type {
2251c0b2f7Stbbdev     allocBlockNew = 0,
2351c0b2f7Stbbdev     allocBlockPublic,
2451c0b2f7Stbbdev     allocBumpPtrUsed,
2551c0b2f7Stbbdev     allocFreeListUsed,
2651c0b2f7Stbbdev     allocPrivatized,
2751c0b2f7Stbbdev     examineEmptyEnough,
2851c0b2f7Stbbdev     examineNotEmpty,
2951c0b2f7Stbbdev     freeRestoreBumpPtr,
3051c0b2f7Stbbdev     freeByOtherThread,
3151c0b2f7Stbbdev     freeToActiveBlock,
3251c0b2f7Stbbdev     freeToInactiveBlock,
3351c0b2f7Stbbdev     freeBlockPublic,
3451c0b2f7Stbbdev     freeBlockBack,
3551c0b2f7Stbbdev     MaxCounters
3651c0b2f7Stbbdev };
3751c0b2f7Stbbdev enum common_counter_type {
3851c0b2f7Stbbdev     allocNewLargeObj = 0,
3951c0b2f7Stbbdev     allocCachedLargeObj,
4051c0b2f7Stbbdev     cacheLargeObj,
4151c0b2f7Stbbdev     freeLargeObj,
4251c0b2f7Stbbdev     lockPublicFreeList,
4351c0b2f7Stbbdev     freeToOtherThread
4451c0b2f7Stbbdev };
4551c0b2f7Stbbdev 
4651c0b2f7Stbbdev #if COLLECT_STATISTICS
4751c0b2f7Stbbdev /* Statistics reporting callback registered via a static object dtor
4851c0b2f7Stbbdev    on Posix or DLL_PROCESS_DETACH on Windows.
4951c0b2f7Stbbdev  */
5051c0b2f7Stbbdev 
5151c0b2f7Stbbdev static bool reportAllocationStatistics;
5251c0b2f7Stbbdev 
5351c0b2f7Stbbdev struct bin_counters {
5451c0b2f7Stbbdev     int counter[MaxCounters];
5551c0b2f7Stbbdev };
5651c0b2f7Stbbdev 
5751c0b2f7Stbbdev static bin_counters statistic[MAX_THREADS][NUM_OF_BINS+1]; //zero-initialized;
5851c0b2f7Stbbdev 
STAT_increment(int thread,int bin,int ctr)5951c0b2f7Stbbdev static inline int STAT_increment(int thread, int bin, int ctr)
6051c0b2f7Stbbdev {
6151c0b2f7Stbbdev     return reportAllocationStatistics && thread < MAX_THREADS ? ++(statistic[thread][bin].counter[ctr]) : 0;
6251c0b2f7Stbbdev }
6351c0b2f7Stbbdev 
initStatisticsCollection()6451c0b2f7Stbbdev static inline void initStatisticsCollection() {
6551c0b2f7Stbbdev #if defined(MALLOCENV_COLLECT_STATISTICS)
6657f524caSIlya Isaev     if (nullptr != getenv(MALLOCENV_COLLECT_STATISTICS))
6751c0b2f7Stbbdev         reportAllocationStatistics = true;
6851c0b2f7Stbbdev #endif
6951c0b2f7Stbbdev }
7051c0b2f7Stbbdev 
7151c0b2f7Stbbdev #else
7251c0b2f7Stbbdev #define STAT_increment(a,b,c) ((void)0)
7351c0b2f7Stbbdev #endif /* COLLECT_STATISTICS */
7451c0b2f7Stbbdev 
7551c0b2f7Stbbdev #if COLLECT_STATISTICS
STAT_print(int thread)7651c0b2f7Stbbdev static inline void STAT_print(int thread)
7751c0b2f7Stbbdev {
7851c0b2f7Stbbdev     if (!reportAllocationStatistics)
7951c0b2f7Stbbdev         return;
8051c0b2f7Stbbdev 
8151c0b2f7Stbbdev     char filename[100];
8251c0b2f7Stbbdev #if USE_PTHREAD
8351c0b2f7Stbbdev     sprintf(filename, "stat_ScalableMalloc_proc%04d_thr%04d.log", getpid(), thread);
8451c0b2f7Stbbdev #else
8551c0b2f7Stbbdev     sprintf(filename, "stat_ScalableMalloc_thr%04d.log", thread);
8651c0b2f7Stbbdev #endif
8751c0b2f7Stbbdev     FILE* outfile = fopen(filename, "w");
8851c0b2f7Stbbdev     for(int i=0; i<NUM_OF_BINS; ++i)
8951c0b2f7Stbbdev     {
9051c0b2f7Stbbdev         bin_counters& ctrs = statistic[thread][i];
9151c0b2f7Stbbdev         fprintf(outfile, "Thr%04d Bin%02d", thread, i);
9251c0b2f7Stbbdev         fprintf(outfile, ": allocNewBlocks %5d", ctrs.counter[allocBlockNew]);
9351c0b2f7Stbbdev         fprintf(outfile, ", allocPublicBlocks %5d", ctrs.counter[allocBlockPublic]);
9451c0b2f7Stbbdev         fprintf(outfile, ", restoreBumpPtr %5d", ctrs.counter[freeRestoreBumpPtr]);
9551c0b2f7Stbbdev         fprintf(outfile, ", privatizeCalled %10d", ctrs.counter[allocPrivatized]);
9651c0b2f7Stbbdev         fprintf(outfile, ", emptyEnough %10d", ctrs.counter[examineEmptyEnough]);
9751c0b2f7Stbbdev         fprintf(outfile, ", notEmptyEnough %10d", ctrs.counter[examineNotEmpty]);
9851c0b2f7Stbbdev         fprintf(outfile, ", freeBlocksPublic %5d", ctrs.counter[freeBlockPublic]);
9951c0b2f7Stbbdev         fprintf(outfile, ", freeBlocksBack %5d", ctrs.counter[freeBlockBack]);
10051c0b2f7Stbbdev         fprintf(outfile, "\n");
10151c0b2f7Stbbdev     }
10251c0b2f7Stbbdev     for(int i=0; i<NUM_OF_BINS; ++i)
10351c0b2f7Stbbdev     {
10451c0b2f7Stbbdev         bin_counters& ctrs = statistic[thread][i];
10551c0b2f7Stbbdev         fprintf(outfile, "Thr%04d Bin%02d", thread, i);
10651c0b2f7Stbbdev         fprintf(outfile, ": allocBumpPtr %10d", ctrs.counter[allocBumpPtrUsed]);
10751c0b2f7Stbbdev         fprintf(outfile, ", allocFreeList %10d", ctrs.counter[allocFreeListUsed]);
10851c0b2f7Stbbdev         fprintf(outfile, ", freeToActiveBlk %10d", ctrs.counter[freeToActiveBlock]);
10951c0b2f7Stbbdev         fprintf(outfile, ", freeToInactive  %10d", ctrs.counter[freeToInactiveBlock]);
11051c0b2f7Stbbdev         fprintf(outfile, ", freedByOther %10d", ctrs.counter[freeByOtherThread]);
11151c0b2f7Stbbdev         fprintf(outfile, "\n");
11251c0b2f7Stbbdev     }
11351c0b2f7Stbbdev     bin_counters& ctrs = statistic[thread][ThreadCommonCounters];
11451c0b2f7Stbbdev     fprintf(outfile, "Thr%04d common counters", thread);
11551c0b2f7Stbbdev     fprintf(outfile, ": allocNewLargeObject %5d", ctrs.counter[allocNewLargeObj]);
11651c0b2f7Stbbdev     fprintf(outfile, ": allocCachedLargeObject %5d", ctrs.counter[allocCachedLargeObj]);
11751c0b2f7Stbbdev     fprintf(outfile, ", cacheLargeObject %5d", ctrs.counter[cacheLargeObj]);
11851c0b2f7Stbbdev     fprintf(outfile, ", freeLargeObject %5d", ctrs.counter[freeLargeObj]);
11951c0b2f7Stbbdev     fprintf(outfile, ", lockPublicFreeList %5d", ctrs.counter[lockPublicFreeList]);
12051c0b2f7Stbbdev     fprintf(outfile, ", freeToOtherThread %10d", ctrs.counter[freeToOtherThread]);
12151c0b2f7Stbbdev     fprintf(outfile, "\n");
12251c0b2f7Stbbdev 
12351c0b2f7Stbbdev     fclose(outfile);
12451c0b2f7Stbbdev }
12551c0b2f7Stbbdev #endif
126