User code can open a file on its own and pass it to the runtime, rather than
specifying a name and having the runtime open the file. This supports the use
case where a process cannot open a file on its own but can receive a file
descriptor from another process.
Details
- Reviewers
Dor1s vsk liaoyuke davidxl - Commits
- rG758c08921da7: [Profile]: Add runtime interface to specify file handle for profile data (Part…
rCRT362716: [Profile]: Add runtime interface to specify file handle for profile data (Part…
rL362716: [Profile]: Add runtime interface to specify file handle for profile data (Part…
rGc1867557d93d: [Profile]: Add runtime interface to specify file handle for profile data.
rCRT362676: [Profile]: Add runtime interface to specify file handle for profile data.
rL362676: [Profile]: Add runtime interface to specify file handle for profile data.
Diff Detail
- Repository
- rL LLVM
Event Timeline
It looks like this patch is exposing some new symbols which don't have an "__" prefix... do we have some formal policy about that for libclang_rt.profile? It's sort of orthogonal to this patch, though... lprofGetProfileFile and lprofSetProfileFile should probably be marked "static".
It looks like passing in a FILE* implicitly disables profile merging; is that intentional? If so, it should probably be documented somehow.
There should be a test case.
compiler-rt/lib/profile/InstrProfiling.h | ||
---|---|---|
161 ↗ | (On Diff #201733) | Document this interface. Also mention that when file descriptor is provided by the client, profiling runtime won't perform profile merging. With this, the profile file name specified by either environment variable or command line will be ignored, so it should be documented. |
I think it'll be bad if we lose merging with this approach. Should the change be done in a way that openFileForMerging can also use the runtime provided file pointer?
Added support for merging, docs, and test case.
Also set the two internal functions to static and removed the visibility macro from them.
To support merging, the new interface needs to take more
compiler-rt/lib/profile/InstrProfilingFile.c | ||
---|---|---|
268 ↗ | (On Diff #202061) | This is not safe to do always -- you need to make sure the file is exclusively accessed. Suggest changing the public interface with one additional parameter __llvm_profile_set_file_object(FILE *F, bool is_exclusive /*with lock*/ ); If it is not, merging can not be performed. |
269 ↗ | (On Diff #202061) | The change makes the code less readable (especially the primary code path). Suggest: if (!doMerging()) { OutputFile = getFileObject(OutputName) ; // this returns user provided FileObject if exists } else { OutputFile = openFileForMerging(OutputName, &MergeDone); // this uses user provided FIleObject if exists } |
@davidxl We could also have the openFileForMerging function invoke lprofLockFd on the user-provided file, rather than putting the onus for locking on the user. How would you feel about that?
I think it is cleaner for user to make the intention clear by passing the flag if the file handle is passed to the runtime. Otherwise the runtime will have to guess/assume user's intention (e.g, also reopen the file with "r+b" mode for merging).
On further thought, I don't think having a boolean that tells the runtime "user code is controlling locking so it is safe to merge" is a good idea, because typically __llvm_profile_write_file is invoked at exit. User code would have to ensure that it locks the file at the very end of its execution, when it has collected the desired profiling data, but before __lvm_profile_write_file is invoked. Also, in the current implementation, whether or not merging happens is controlled by the pattern of the profiling file name (whether or not it has a %m in it).
Instead I think we should have a separate function, __llvm_profile_enable_merging. When this new function is invoked with true, it overrides the merging state set by the file name pattern. Then openFileForMerging can call lprofLockFd on the user-provided file. This allows the user to explicitly turn merging on if desired.
Sounds reasonable -- the intention is clear with this -- the interface tells runtime to do whatever needed to ensure merging. Please send a patch with merging test case.
Fixed lock/unlock code.
Removed the locking for WIN32 builds because the lock has to be enabled
in CreateFileA, so it will be user code's responsibility in this case.
Added unlocking after write in case __llvm_profile_write_file is
manually invoked by user code before the end of the process.
compiler-rt/lib/profile/InstrProfiling.h | ||
---|---|---|
182 ↗ | (On Diff #202992) | this interface should not be used seperately, so it is better to merge this with llvm_profile_set_file_object(FILE*, in enableMering) |
compiler-rt/lib/profile/InstrProfilingFile.c | ||
253 ↗ | (On Diff #202992) | Add lprofLockFileHandle utility in InstrProfilingUtil.c |
306 ↗ | (On Diff #202992) | What is this for? Why locking the file again? |
compiler-rt/lib/profile/InstrProfilingFile.c | ||
---|---|---|
306 ↗ | (On Diff #202992) | Good catch, that was supposed to be an unlock. |
I suggest you apply for commit right first. There are likely fallouts that need to be dealt with.
Could you be more specific about your concerns? I'm happy to fix any problems in this change.
It is just more convenient for you to contribute to LLVM in the future. I can help you commit this time.
Thank you! I did apply for committer status today but I don't know how long it takes to get it.
LGTM (was OOO), thanks a lot David for Sajjad for multiple iterations here. One question: was the test landed? I see it in the latest patchset (https://reviews.llvm.org/D62541?id=203034), but not in the code that was committed.
compiler-rt/trunk/lib/profile/InstrProfilingFile.c | ||
---|---|---|
270 | nit: looks like this should start with a lowercase, GetFileObject -> getFileObject |
Looks like the tests got added in a separate commit. 758c08921da7282a74a3779d7d89940263f5a6af
nit: looks like this should start with a lowercase, GetFileObject -> getFileObject