Thrill  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
porting.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  * thrill/common/porting.cpp
3  *
4  * Part of Project Thrill - http://project-thrill.org
5  *
6  * Copyright (C) 2015 Alexander Noe <[email protected]>
7  * Copyright (C) 2015 Timo Bingmann <[email protected]>
8  *
9  * All rights reserved. Published under the BSD-2 license in the LICENSE file.
10  ******************************************************************************/
11 
15 #include <thrill/common/string.hpp>
17 
18 #include <tlx/string/replace.hpp>
19 #include <tlx/unused.hpp>
20 
21 #include <fcntl.h>
22 
23 #include <fstream>
24 #include <sstream>
25 #include <string>
26 #include <vector>
27 
28 #if !defined(_MSC_VER)
29 
30 #include <unistd.h>
31 
32 #else
33 
34 #include <io.h>
35 
36 #endif
37 
38 namespace thrill {
39 namespace common {
40 
41 void PortSetCloseOnExec(int fd) {
42 #if !defined(_MSC_VER)
43  if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) {
44  throw ErrnoException("Error setting FD_CLOEXEC on file descriptor");
45  }
46 #else
47  tlx::unused(fd);
48 #endif
49 }
50 
51 void MakePipe(int out_pipefds[2]) {
52 #if THRILL_HAVE_PIPE2
53  if (pipe2(out_pipefds, O_CLOEXEC) != 0)
54  throw ErrnoException("Error creating pipe");
55 #elif defined(_MSC_VER)
56  if (_pipe(out_pipefds, 256, O_BINARY) != 0)
57  throw ErrnoException("Error creating pipe");
58 #else
59  if (pipe(out_pipefds) != 0)
60  throw ErrnoException("Error creating pipe");
61 
62  PortSetCloseOnExec(out_pipefds[0]);
63  PortSetCloseOnExec(out_pipefds[1]);
64 #endif
65 }
66 
68 #if __linux__
69  // read cmdline from /proc/<pid>/cmdline
70  pid_t mypid = getpid();
71 
72  std::ifstream proc("/proc/" + std::to_string(mypid) + "/cmdline");
73  if (!proc.good()) return;
74 
75  std::vector<std::string> args;
76  std::string arg;
77  while (std::getline(proc, arg, '\0'))
78  args.emplace_back(arg);
79 
80  std::string prog;
81  if (!args.empty()) {
82  prog = args[0];
83  std::string::size_type slashpos = prog.rfind('/');
84  if (slashpos != std::string::npos)
85  prog = prog.substr(slashpos + 1);
86  }
87 
88  std::ostringstream cmdline;
89  for (size_t i = 0; i < args.size(); ++i) {
90  if (i != 0)
91  cmdline << ' ';
92 
93  arg = args[i];
94  // escape " -> \"
95  if (arg.find('"') != std::string::npos)
96  tlx::replace_all(arg, "\"", "\\\"");
97  cmdline << arg;
98  }
99 
100  logger << "class" << "Cmdline"
101  << "event" << "start"
102  << "program" << prog
103  << "argv" << args
104  << "cmdline" << cmdline.str();
105 #else
106  tlx::unused(logger);
107 #endif
108 }
109 
110 void SetCpuAffinity(std::thread& thread, size_t cpu_id) {
111 #if __linux__ && !THRILL_ON_TRAVIS
112  cpu_set_t cpuset;
113  CPU_ZERO(&cpuset);
114  CPU_SET(cpu_id % std::thread::hardware_concurrency(), &cpuset);
115  int rc = pthread_setaffinity_np(
116  thread.native_handle(), sizeof(cpu_set_t), &cpuset);
117  if (rc != 0) {
118  LOG1 << "Error calling pthread_setaffinity_np(): "
119  << rc << ": " << strerror(errno);
120  }
121 #else
122  tlx::unused(thread);
123  tlx::unused(cpu_id);
124 #endif
125 }
126 
127 void SetCpuAffinity(size_t cpu_id) {
128 #if __linux__ && !THRILL_ON_TRAVIS
129  cpu_set_t cpuset;
130  CPU_ZERO(&cpuset);
131  CPU_SET(cpu_id % std::thread::hardware_concurrency(), &cpuset);
132  int rc = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
133  if (rc != 0) {
134  LOG1 << "Error calling pthread_setaffinity_np(): "
135  << rc << ": " << strerror(errno);
136  }
137 #else
138  tlx::unused(cpu_id);
139 #endif
140 }
141 
143 #if __linux__
144  char buffer[64];
145  gethostname(buffer, 64);
146  return buffer;
147 #else
148  return "<unknown host>";
149 #endif
150 }
151 
152 } // namespace common
153 } // namespace thrill
154 
155 /******************************************************************************/
void LogCmdlineParams(JsonLogger &logger)
Definition: porting.cpp:67
#define LOG1
Definition: logger.hpp:28
An Exception which is thrown on system errors and contains errno information.
void PortSetCloseOnExec(int fd)
set FD_CLOEXEC on file descriptor (if possible)
Definition: porting.cpp:41
void MakePipe(int out_pipefds[2])
create a pair of pipe file descriptors
Definition: porting.cpp:51
static by_string to_string(int val)
convert to string
void unused(Types &&...)
Definition: unused.hpp:20
std::string & replace_all(std::string *str, const std::string &needle, const std::string &instead)
Replace all occurrences of needle in str.
Definition: replace.cpp:141
std::string GetHostname()
get hostname
Definition: porting.cpp:142
std::basic_string< char, std::char_traits< char >, Allocator< char > > string
string with Manager tracking
Definition: allocator.hpp:220
JsonLogger is a receiver of JSON output objects for logging.
Definition: json_logger.hpp:69
#define O_BINARY
Definition: sys_file.cpp:33
void SetCpuAffinity(std::thread &thread, size_t cpu_id)
set cpu/core affinity of a thread
Definition: porting.cpp:110