1/*
2 Copyright (c) 2005-2019 Intel Corporation
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17#define MAX_THREADS 1024
18#define NUM_OF_BINS 30
19#define ThreadCommonCounters NUM_OF_BINS
20
21enum counter_type {
22 allocBlockNew = 0,
23 allocBlockPublic,
24 allocBumpPtrUsed,
25 allocFreeListUsed,
26 allocPrivatized,
27 examineEmptyEnough,
28 examineNotEmpty,
29 freeRestoreBumpPtr,
30 freeByOtherThread,
31 freeToActiveBlock,
32 freeToInactiveBlock,
33 freeBlockPublic,
34 freeBlockBack,
35 MaxCounters
36};
37enum common_counter_type {
38 allocNewLargeObj = 0,
39 allocCachedLargeObj,
40 cacheLargeObj,
41 freeLargeObj,
42 lockPublicFreeList,
43 freeToOtherThread
44};
45
46#if COLLECT_STATISTICS
47/* Statistics reporting callback registered via a static object dtor
48 on Posix or DLL_PROCESS_DETACH on Windows.
49 */
50
51static bool reportAllocationStatistics;
52
53struct bin_counters {
54 int counter[MaxCounters];
55};
56
57static bin_counters statistic[MAX_THREADS][NUM_OF_BINS+1]; //zero-initialized;
58
59static inline int STAT_increment(int thread, int bin, int ctr)
60{
61 return reportAllocationStatistics && thread < MAX_THREADS ? ++(statistic[thread][bin].counter[ctr]) : 0;
62}
63
64static inline void initStatisticsCollection() {
65#if defined(MALLOCENV_COLLECT_STATISTICS)
66 if (NULL != getenv(MALLOCENV_COLLECT_STATISTICS))
67 reportAllocationStatistics = true;
68#endif
69}
70
71#else
72#define STAT_increment(a,b,c) ((void)0)
73#endif /* COLLECT_STATISTICS */
74
75#if COLLECT_STATISTICS
76static inline void STAT_print(int thread)
77{
78 if (!reportAllocationStatistics)
79 return;
80
81 char filename[100];
82#if USE_PTHREAD
83 sprintf(filename, "stat_ScalableMalloc_proc%04d_thr%04d.log", getpid(), thread);
84#else
85 sprintf(filename, "stat_ScalableMalloc_thr%04d.log", thread);
86#endif
87 FILE* outfile = fopen(filename, "w");
88 for(int i=0; i<NUM_OF_BINS; ++i)
89 {
90 bin_counters& ctrs = statistic[thread][i];
91 fprintf(outfile, "Thr%04d Bin%02d", thread, i);
92 fprintf(outfile, ": allocNewBlocks %5d", ctrs.counter[allocBlockNew]);
93 fprintf(outfile, ", allocPublicBlocks %5d", ctrs.counter[allocBlockPublic]);
94 fprintf(outfile, ", restoreBumpPtr %5d", ctrs.counter[freeRestoreBumpPtr]);
95 fprintf(outfile, ", privatizeCalled %10d", ctrs.counter[allocPrivatized]);
96 fprintf(outfile, ", emptyEnough %10d", ctrs.counter[examineEmptyEnough]);
97 fprintf(outfile, ", notEmptyEnough %10d", ctrs.counter[examineNotEmpty]);
98 fprintf(outfile, ", freeBlocksPublic %5d", ctrs.counter[freeBlockPublic]);
99 fprintf(outfile, ", freeBlocksBack %5d", ctrs.counter[freeBlockBack]);
100 fprintf(outfile, "\n");
101 }
102 for(int i=0; i<NUM_OF_BINS; ++i)
103 {
104 bin_counters& ctrs = statistic[thread][i];
105 fprintf(outfile, "Thr%04d Bin%02d", thread, i);
106 fprintf(outfile, ": allocBumpPtr %10d", ctrs.counter[allocBumpPtrUsed]);
107 fprintf(outfile, ", allocFreeList %10d", ctrs.counter[allocFreeListUsed]);
108 fprintf(outfile, ", freeToActiveBlk %10d", ctrs.counter[freeToActiveBlock]);
109 fprintf(outfile, ", freeToInactive %10d", ctrs.counter[freeToInactiveBlock]);
110 fprintf(outfile, ", freedByOther %10d", ctrs.counter[freeByOtherThread]);
111 fprintf(outfile, "\n");
112 }
113 bin_counters& ctrs = statistic[thread][ThreadCommonCounters];
114 fprintf(outfile, "Thr%04d common counters", thread);
115 fprintf(outfile, ": allocNewLargeObject %5d", ctrs.counter[allocNewLargeObj]);
116 fprintf(outfile, ": allocCachedLargeObject %5d", ctrs.counter[allocCachedLargeObj]);
117 fprintf(outfile, ", cacheLargeObject %5d", ctrs.counter[cacheLargeObj]);
118 fprintf(outfile, ", freeLargeObject %5d", ctrs.counter[freeLargeObj]);
119 fprintf(outfile, ", lockPublicFreeList %5d", ctrs.counter[lockPublicFreeList]);
120 fprintf(outfile, ", freeToOtherThread %10d", ctrs.counter[freeToOtherThread]);
121 fprintf(outfile, "\n");
122
123 fclose(outfile);
124}
125#endif
126