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