Skip to content

Commit e7aab32

Browse files
committed
[profile] Factor out logic for mmap'ing merged profile, NFC
Split out the logic to get the size of a merged profile and to do a compatibility check. This can be shared with both the continuous+merging mode implementation, as well as the runtime-allocated counters implementation planned for Fuchsia. Lifted out of D69586. Differential Revision: https://reviews.llvm.org/D70135
1 parent 3d6b539 commit e7aab32

File tree

1 file changed

+51
-22
lines changed

1 file changed

+51
-22
lines changed

compiler-rt/lib/profile/InstrProfilingFile.c

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -171,21 +171,18 @@ static void setupIOBuffer() {
171171
}
172172
}
173173

174-
/* Read profile data in \c ProfileFile and merge with in-memory
175-
profile counters. Returns -1 if there is fatal error, otheriwse
176-
0 is returned. Returning 0 does not mean merge is actually
177-
performed. If merge is actually done, *MergeDone is set to 1.
178-
*/
179-
static int doProfileMerging(FILE *ProfileFile, int *MergeDone) {
180-
uint64_t ProfileFileSize;
181-
char *ProfileBuffer;
182-
174+
/* Get the size of the profile file. If there are any errors, print the
175+
* message under the assumption that the profile is being read for merging
176+
* purposes, and return -1. Otherwise return the file size in the inout param
177+
* \p ProfileFileSize. */
178+
static int getProfileFileSizeForMerging(FILE *ProfileFile,
179+
uint64_t *ProfileFileSize) {
183180
if (fseek(ProfileFile, 0L, SEEK_END) == -1) {
184181
PROF_ERR("Unable to merge profile data, unable to get size: %s\n",
185182
strerror(errno));
186183
return -1;
187184
}
188-
ProfileFileSize = ftell(ProfileFile);
185+
*ProfileFileSize = ftell(ProfileFile);
189186

190187
/* Restore file offset. */
191188
if (fseek(ProfileFile, 0L, SEEK_SET) == -1) {
@@ -194,28 +191,60 @@ static int doProfileMerging(FILE *ProfileFile, int *MergeDone) {
194191
return -1;
195192
}
196193

197-
/* Nothing to merge. */
198-
if (ProfileFileSize < sizeof(__llvm_profile_header)) {
199-
if (ProfileFileSize)
200-
PROF_WARN("Unable to merge profile data: %s\n",
201-
"source profile file is too small.");
202-
return 0;
194+
if (*ProfileFileSize > 0 &&
195+
*ProfileFileSize < sizeof(__llvm_profile_header)) {
196+
PROF_WARN("Unable to merge profile data: %s\n",
197+
"source profile file is too small.");
198+
return -1;
203199
}
200+
return 0;
201+
}
204202

205-
ProfileBuffer = mmap(NULL, ProfileFileSize, PROT_READ, MAP_SHARED | MAP_FILE,
206-
fileno(ProfileFile), 0);
207-
if (ProfileBuffer == MAP_FAILED) {
203+
/* mmap() \p ProfileFile for profile merging purposes, assuming that an
204+
* exclusive lock is held on the file and that \p ProfileFileSize is the
205+
* length of the file. Return the mmap'd buffer in the inout variable
206+
* \p ProfileBuffer. Returns -1 on failure. On success, the caller is
207+
* responsible for unmapping the mmap'd buffer in \p ProfileBuffer. */
208+
static int mmapProfileForMerging(FILE *ProfileFile, uint64_t ProfileFileSize,
209+
char **ProfileBuffer) {
210+
*ProfileBuffer = mmap(NULL, ProfileFileSize, PROT_READ, MAP_SHARED | MAP_FILE,
211+
fileno(ProfileFile), 0);
212+
if (*ProfileBuffer == MAP_FAILED) {
208213
PROF_ERR("Unable to merge profile data, mmap failed: %s\n",
209214
strerror(errno));
210215
return -1;
211216
}
212217

213-
if (__llvm_profile_check_compatibility(ProfileBuffer, ProfileFileSize)) {
214-
(void)munmap(ProfileBuffer, ProfileFileSize);
218+
if (__llvm_profile_check_compatibility(*ProfileBuffer, ProfileFileSize)) {
219+
(void)munmap(*ProfileBuffer, ProfileFileSize);
215220
PROF_WARN("Unable to merge profile data: %s\n",
216221
"source profile file is not compatible.");
217-
return 0;
222+
return -1;
218223
}
224+
return 0;
225+
}
226+
227+
/* Read profile data in \c ProfileFile and merge with in-memory
228+
profile counters. Returns -1 if there is fatal error, otheriwse
229+
0 is returned. Returning 0 does not mean merge is actually
230+
performed. If merge is actually done, *MergeDone is set to 1.
231+
*/
232+
static int doProfileMerging(FILE *ProfileFile, int *MergeDone) {
233+
uint64_t ProfileFileSize;
234+
char *ProfileBuffer;
235+
236+
/* Get the size of the profile on disk. */
237+
if (getProfileFileSizeForMerging(ProfileFile, &ProfileFileSize) == -1)
238+
return -1;
239+
240+
/* Nothing to merge. */
241+
if (!ProfileFileSize)
242+
return 0;
243+
244+
/* mmap() the profile and check that it is compatible with the data in
245+
* the current image. */
246+
if (mmapProfileForMerging(ProfileFile, ProfileFileSize, &ProfileBuffer) == -1)
247+
return -1;
219248

220249
/* Now start merging */
221250
__llvm_profile_merge_from_buffer(ProfileBuffer, ProfileFileSize);

0 commit comments

Comments
 (0)