Skip to content

Commit 92c4326

Browse files
author
git apple-llvm automerger
committed
Merge commit 'd1b294029004' from llvm.org/main into next
2 parents 393fe77 + d1b2940 commit 92c4326

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

libc/utils/gpu/loader/Main.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,18 @@
1616
#include "llvm/BinaryFormat/Magic.h"
1717
#include "llvm/Support/CommandLine.h"
1818
#include "llvm/Support/Error.h"
19+
#include "llvm/Support/FileSystem.h"
1920
#include "llvm/Support/MemoryBuffer.h"
21+
#include "llvm/Support/Path.h"
2022
#include "llvm/Support/Signals.h"
2123
#include "llvm/Support/WithColor.h"
2224

25+
#include <cerrno>
2326
#include <cstdio>
2427
#include <cstdlib>
28+
#include <cstring>
2529
#include <string>
30+
#include <sys/file.h>
2631

2732
using namespace llvm;
2833

@@ -62,6 +67,12 @@ static cl::opt<bool>
6267
cl::desc("Output resource usage of launched kernels"),
6368
cl::init(false), cl::cat(loader_category));
6469

70+
static cl::opt<bool>
71+
no_parallelism("no-parallelism",
72+
cl::desc("Allows only a single process to use the GPU at a "
73+
"time. Useful to suppress out-of-resource errors"),
74+
cl::init(false), cl::cat(loader_category));
75+
6576
static cl::opt<std::string> file(cl::Positional, cl::Required,
6677
cl::desc("<gpu executable>"),
6778
cl::cat(loader_category));
@@ -75,6 +86,12 @@ static cl::list<std::string> args(cl::ConsumeAfter,
7586
exit(EXIT_FAILURE);
7687
}
7788

89+
std::string get_main_executable(const char *name) {
90+
void *ptr = (void *)(intptr_t)&get_main_executable;
91+
auto cow_path = sys::fs::getMainExecutable(name, ptr);
92+
return sys::path::parent_path(cow_path).str();
93+
}
94+
7895
int main(int argc, const char **argv, const char **envp) {
7996
sys::PrintStackTraceOnErrorSignal(argv[0]);
8097
cl::HideUnrelatedOptions(loader_category);
@@ -98,12 +115,28 @@ int main(int argc, const char **argv, const char **envp) {
98115
llvm::transform(args, std::back_inserter(new_argv),
99116
[](const std::string &arg) { return arg.c_str(); });
100117

118+
// Claim a file lock on the executable so only a single process can enter this
119+
// region if requested. This prevents the loader from spurious failures.
120+
int fd = -1;
121+
if (no_parallelism) {
122+
fd = open(get_main_executable(argv[0]).c_str(), O_RDONLY);
123+
if (flock(fd, LOCK_EX) == -1)
124+
report_error(createStringError("Failed to lock '%s': %s", argv[0],
125+
strerror(errno)));
126+
}
127+
101128
// Drop the loader from the program arguments.
102129
LaunchParameters params{threads_x, threads_y, threads_z,
103130
blocks_x, blocks_y, blocks_z};
104131
int ret = load(new_argv.size(), new_argv.data(), envp,
105132
const_cast<char *>(image.getBufferStart()),
106133
image.getBufferSize(), params, print_resource_usage);
107134

135+
if (no_parallelism) {
136+
if (flock(fd, LOCK_UN) == -1)
137+
report_error(createStringError("Failed to unlock '%s': %s", argv[0],
138+
strerror(errno)));
139+
}
140+
108141
return ret;
109142
}

0 commit comments

Comments
 (0)