Skip to content

Commit 36a6afd

Browse files
Reland "[llvm-exegesis] Refactor parent code to separate function (#86232)"
This reverts commit c3a41aa. This relands commit bd49375. Apparently I forgot to update a couple values, so this change failed on every builder that builds those sections (should be every Linux platform) rather than something architecture specific like originally thought. I swore I updated the values and ran check-llvm before merging. Wondering If I forgot to push those changes...
1 parent c3a41aa commit 36a6afd

File tree

1 file changed

+67
-57
lines changed

1 file changed

+67
-57
lines changed

llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp

Lines changed: 67 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -278,90 +278,51 @@ class SubProcessFunctionExecutorImpl
278278
return FD;
279279
}
280280

281-
Error createSubProcessAndRunBenchmark(
282-
StringRef CounterName, SmallVectorImpl<int64_t> &CounterValues,
283-
ArrayRef<const char *> ValidationCounters,
284-
SmallVectorImpl<int64_t> &ValidationCounterValues) const {
285-
int PipeFiles[2];
286-
int PipeSuccessOrErr = socketpair(AF_UNIX, SOCK_DGRAM, 0, PipeFiles);
287-
if (PipeSuccessOrErr != 0) {
288-
return make_error<Failure>(
289-
"Failed to create a pipe for interprocess communication between "
290-
"llvm-exegesis and the benchmarking subprocess: " +
291-
Twine(strerror(errno)));
292-
}
293-
294-
SubprocessMemory SPMemory;
295-
Error MemoryInitError = SPMemory.initializeSubprocessMemory(getpid());
296-
if (MemoryInitError)
297-
return MemoryInitError;
298-
299-
Error AddMemDefError =
300-
SPMemory.addMemoryDefinition(Key.MemoryValues, getpid());
301-
if (AddMemDefError)
302-
return AddMemDefError;
303-
304-
pid_t ParentOrChildPID = fork();
305-
306-
if (ParentOrChildPID == -1) {
307-
return make_error<Failure>("Failed to create child process: " +
308-
Twine(strerror(errno)));
309-
}
310-
311-
if (ParentOrChildPID == 0) {
312-
// We are in the child process, close the write end of the pipe.
313-
close(PipeFiles[1]);
314-
// Unregister handlers, signal handling is now handled through ptrace in
315-
// the host process.
316-
sys::unregisterHandlers();
317-
prepareAndRunBenchmark(PipeFiles[0], Key);
318-
// The child process terminates in the above function, so we should never
319-
// get to this point.
320-
llvm_unreachable("Child process didn't exit when expected.");
321-
}
322-
281+
Error
282+
runParentProcess(pid_t ChildPID, int WriteFD, StringRef CounterName,
283+
SmallVectorImpl<int64_t> &CounterValues,
284+
ArrayRef<const char *> ValidationCounters,
285+
SmallVectorImpl<int64_t> &ValidationCounterValues) const {
323286
const ExegesisTarget &ET = State.getExegesisTarget();
324-
auto CounterOrError = ET.createCounter(
325-
CounterName, State, ValidationCounters, ParentOrChildPID);
287+
auto CounterOrError =
288+
ET.createCounter(CounterName, State, ValidationCounters, ChildPID);
326289

327290
if (!CounterOrError)
328291
return CounterOrError.takeError();
329292

330293
pfm::CounterGroup *Counter = CounterOrError.get().get();
331294

332-
close(PipeFiles[0]);
333-
334295
// Make sure to attach to the process (and wait for the sigstop to be
335296
// delivered and for the process to continue) before we write to the counter
336297
// file descriptor. Attaching to the process before writing to the socket
337298
// ensures that the subprocess at most has blocked on the read call. If we
338299
// attach afterwards, the subprocess might exit before we get to the attach
339300
// call due to effects like scheduler contention, introducing transient
340301
// failures.
341-
if (ptrace(PTRACE_ATTACH, ParentOrChildPID, NULL, NULL) != 0)
302+
if (ptrace(PTRACE_ATTACH, ChildPID, NULL, NULL) != 0)
342303
return make_error<Failure>("Failed to attach to the child process: " +
343304
Twine(strerror(errno)));
344305

345-
if (waitpid(ParentOrChildPID, NULL, 0) == -1) {
306+
if (waitpid(ChildPID, NULL, 0) == -1) {
346307
return make_error<Failure>(
347308
"Failed to wait for child process to stop after attaching: " +
348309
Twine(strerror(errno)));
349310
}
350311

351-
if (ptrace(PTRACE_CONT, ParentOrChildPID, NULL, NULL) != 0)
312+
if (ptrace(PTRACE_CONT, ChildPID, NULL, NULL) != 0)
352313
return make_error<Failure>(
353314
"Failed to continue execution of the child process: " +
354315
Twine(strerror(errno)));
355316

356317
int CounterFileDescriptor = Counter->getFileDescriptor();
357318
Error SendError =
358-
sendFileDescriptorThroughSocket(PipeFiles[1], CounterFileDescriptor);
319+
sendFileDescriptorThroughSocket(WriteFD, CounterFileDescriptor);
359320

360321
if (SendError)
361322
return SendError;
362323

363324
int ChildStatus;
364-
if (waitpid(ParentOrChildPID, &ChildStatus, 0) == -1) {
325+
if (waitpid(ChildPID, &ChildStatus, 0) == -1) {
365326
return make_error<Failure>(
366327
"Waiting for the child process to complete failed: " +
367328
Twine(strerror(errno)));
@@ -395,8 +356,7 @@ class SubProcessFunctionExecutorImpl
395356

396357
// An error was encountered running the snippet, process it
397358
siginfo_t ChildSignalInfo;
398-
if (ptrace(PTRACE_GETSIGINFO, ParentOrChildPID, NULL, &ChildSignalInfo) ==
399-
-1) {
359+
if (ptrace(PTRACE_GETSIGINFO, ChildPID, NULL, &ChildSignalInfo) == -1) {
400360
return make_error<Failure>("Getting signal info from the child failed: " +
401361
Twine(strerror(errno)));
402362
}
@@ -405,13 +365,13 @@ class SubProcessFunctionExecutorImpl
405365
// handlers to run, and calling SIGTERM would mean that ptrace will force
406366
// it to block in the signal-delivery-stop for the SIGSEGV/other signals,
407367
// and upon exit.
408-
if (kill(ParentOrChildPID, SIGKILL) == -1)
368+
if (kill(ChildPID, SIGKILL) == -1)
409369
return make_error<Failure>("Failed to kill child benchmarking proces: " +
410370
Twine(strerror(errno)));
411371

412372
// Wait for the process to exit so that there are no zombie processes left
413373
// around.
414-
if (waitpid(ParentOrChildPID, NULL, 0) == -1)
374+
if (waitpid(ChildPID, NULL, 0) == -1)
415375
return make_error<Failure>("Failed to wait for process to die: " +
416376
Twine(strerror(errno)));
417377

@@ -422,15 +382,65 @@ class SubProcessFunctionExecutorImpl
422382
return make_error<SnippetSignal>(ChildSignalInfo.si_signo);
423383
}
424384

385+
Error createSubProcessAndRunBenchmark(
386+
StringRef CounterName, SmallVectorImpl<int64_t> &CounterValues,
387+
ArrayRef<const char *> ValidationCounters,
388+
SmallVectorImpl<int64_t> &ValidationCounterValues) const {
389+
int PipeFiles[2];
390+
int PipeSuccessOrErr = socketpair(AF_UNIX, SOCK_DGRAM, 0, PipeFiles);
391+
if (PipeSuccessOrErr != 0) {
392+
return make_error<Failure>(
393+
"Failed to create a pipe for interprocess communication between "
394+
"llvm-exegesis and the benchmarking subprocess: " +
395+
Twine(strerror(errno)));
396+
}
397+
398+
SubprocessMemory SPMemory;
399+
Error MemoryInitError = SPMemory.initializeSubprocessMemory(getpid());
400+
if (MemoryInitError)
401+
return MemoryInitError;
402+
403+
Error AddMemDefError =
404+
SPMemory.addMemoryDefinition(Key.MemoryValues, getpid());
405+
if (AddMemDefError)
406+
return AddMemDefError;
407+
408+
pid_t ParentOrChildPID = fork();
409+
410+
if (ParentOrChildPID == -1) {
411+
return make_error<Failure>("Failed to create child process: " +
412+
Twine(strerror(errno)));
413+
}
414+
415+
if (ParentOrChildPID == 0) {
416+
// We are in the child process, close the write end of the pipe.
417+
close(PipeFiles[1]);
418+
// Unregister handlers, signal handling is now handled through ptrace in
419+
// the host process.
420+
sys::unregisterHandlers();
421+
runChildSubprocess(PipeFiles[0], Key);
422+
// The child process terminates in the above function, so we should never
423+
// get to this point.
424+
llvm_unreachable("Child process didn't exit when expected.");
425+
}
426+
427+
// Close the read end of the pipe as we only need to write to the subprocess
428+
// from the parent process.
429+
close(PipeFiles[0]);
430+
return runParentProcess(ParentOrChildPID, PipeFiles[1], CounterName,
431+
CounterValues, ValidationCounters,
432+
ValidationCounterValues);
433+
}
434+
425435
void disableCoreDumps() const {
426436
struct rlimit rlim;
427437

428438
rlim.rlim_cur = 0;
429439
setrlimit(RLIMIT_CORE, &rlim);
430440
}
431441

432-
[[noreturn]] void prepareAndRunBenchmark(int Pipe,
433-
const BenchmarkKey &Key) const {
442+
[[noreturn]] void runChildSubprocess(int Pipe,
443+
const BenchmarkKey &Key) const {
434444
// Disable core dumps in the child process as otherwise everytime we
435445
// encounter an execution failure like a segmentation fault, we will create
436446
// a core dump. We report the information directly rather than require the

0 commit comments

Comments
 (0)