Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/platform-linux.cc

Issue 12592002: Revert "Send SIGPROF signals on the profiler event processor thread" (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/platform-freebsd.cc ('k') | src/platform-macos.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1120 #elif V8_HOST_ARCH_MIPS 1120 #elif V8_HOST_ARCH_MIPS
1121 sample->pc = reinterpret_cast<Address>(mcontext.pc); 1121 sample->pc = reinterpret_cast<Address>(mcontext.pc);
1122 sample->sp = reinterpret_cast<Address>(mcontext.gregs[29]); 1122 sample->sp = reinterpret_cast<Address>(mcontext.gregs[29]);
1123 sample->fp = reinterpret_cast<Address>(mcontext.gregs[30]); 1123 sample->fp = reinterpret_cast<Address>(mcontext.gregs[30]);
1124 #endif // V8_HOST_ARCH_* 1124 #endif // V8_HOST_ARCH_*
1125 sampler->SampleStack(sample); 1125 sampler->SampleStack(sample);
1126 sampler->Tick(sample); 1126 sampler->Tick(sample);
1127 } 1127 }
1128 1128
1129 1129
1130 class CpuProfilerSignalHandler {
1131 public:
1132 static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); }
1133 static void TearDown() { delete mutex_; }
1134
1135 static bool RegisterProfilingSampler() {
1136 ScopedLock lock(mutex_);
1137 if (!profiling_samplers_count_) InstallSignalHandler();
1138 ++profiling_samplers_count_;
1139 return signal_handler_installed_;
1140 }
1141
1142 static void UnregisterProfilingSampler() {
1143 ScopedLock lock(mutex_);
1144 ASSERT(profiling_samplers_count_ > 0);
1145 if (!profiling_samplers_count_) return;
1146 if (profiling_samplers_count_ == 1) RestoreSignalHandler();
1147 --profiling_samplers_count_;
1148 }
1149
1150 private:
1151 static void InstallSignalHandler() {
1152 struct sigaction sa;
1153 sa.sa_sigaction = ProfilerSignalHandler;
1154 sigemptyset(&sa.sa_mask);
1155 sa.sa_flags = SA_RESTART | SA_SIGINFO;
1156 signal_handler_installed_ =
1157 (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0);
1158 }
1159
1160 static void RestoreSignalHandler() {
1161 if (signal_handler_installed_) {
1162 sigaction(SIGPROF, &old_signal_handler_, 0);
1163 signal_handler_installed_ = false;
1164 }
1165 }
1166
1167 // Protects the process wide state below.
1168 static Mutex* mutex_;
1169 static int profiling_samplers_count_;
1170 static bool signal_handler_installed_;
1171 static struct sigaction old_signal_handler_;
1172 };
1173
1174
1175 Mutex* CpuProfilerSignalHandler::mutex_ = NULL;
1176 int CpuProfilerSignalHandler::profiling_samplers_count_ = 0;
1177 bool CpuProfilerSignalHandler::signal_handler_installed_ = false;
1178 struct sigaction CpuProfilerSignalHandler::old_signal_handler_;
1179
1180
1181 class Sampler::PlatformData : public Malloced { 1130 class Sampler::PlatformData : public Malloced {
1182 public: 1131 public:
1183 PlatformData() 1132 PlatformData() : vm_tid_(GetThreadID()) {}
1184 : vm_tgid_(getpid()),
1185 vm_tid_(GetThreadID()),
1186 signal_handler_installed_(false) {}
1187 1133
1188 void set_signal_handler_installed(bool value) { 1134 int vm_tid() const { return vm_tid_; }
1189 signal_handler_installed_ = value;
1190 }
1191
1192 void SendProfilingSignal() {
1193 if (!signal_handler_installed_) return;
1194 // Glibc doesn't provide a wrapper for tgkill(2).
1195 #if defined(ANDROID)
1196 syscall(__NR_tgkill, vm_tgid_, vm_tid_, SIGPROF);
1197 #else
1198 int result = syscall(SYS_tgkill, vm_tgid_, vm_tid_, SIGPROF);
1199 USE(result);
1200 ASSERT(result == 0);
1201 #endif
1202 }
1203 1135
1204 private: 1136 private:
1205 const int vm_tgid_;
1206 const int vm_tid_; 1137 const int vm_tid_;
1207 bool signal_handler_installed_;
1208 }; 1138 };
1209 1139
1210 1140
1211 class SignalSender : public Thread { 1141 class SignalSender : public Thread {
1212 public: 1142 public:
1213 static const int kSignalSenderStackSize = 64 * KB; 1143 static const int kSignalSenderStackSize = 64 * KB;
1214 1144
1215 explicit SignalSender(int interval) 1145 explicit SignalSender(int interval)
1216 : Thread(Thread::Options("SignalSender", kSignalSenderStackSize)), 1146 : Thread(Thread::Options("SignalSender", kSignalSenderStackSize)),
1147 vm_tgid_(getpid()),
1217 interval_(interval) {} 1148 interval_(interval) {}
1218 1149
1219 static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); } 1150 static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); }
1220 static void TearDown() { delete mutex_; } 1151 static void TearDown() { delete mutex_; }
1221 1152
1153 static void InstallSignalHandler() {
1154 struct sigaction sa;
1155 sa.sa_sigaction = ProfilerSignalHandler;
1156 sigemptyset(&sa.sa_mask);
1157 sa.sa_flags = SA_RESTART | SA_SIGINFO;
1158 signal_handler_installed_ =
1159 (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0);
1160 }
1161
1162 static void RestoreSignalHandler() {
1163 if (signal_handler_installed_) {
1164 sigaction(SIGPROF, &old_signal_handler_, 0);
1165 signal_handler_installed_ = false;
1166 }
1167 }
1168
1222 static void AddActiveSampler(Sampler* sampler) { 1169 static void AddActiveSampler(Sampler* sampler) {
1223 ScopedLock lock(mutex_); 1170 ScopedLock lock(mutex_);
1224 SamplerRegistry::AddActiveSampler(sampler); 1171 SamplerRegistry::AddActiveSampler(sampler);
1225 if (instance_ == NULL) { 1172 if (instance_ == NULL) {
1226 // Start a thread that will send SIGPROF signal to VM threads, 1173 // Start a thread that will send SIGPROF signal to VM threads,
1227 // when CPU profiling will be enabled. 1174 // when CPU profiling will be enabled.
1228 instance_ = new SignalSender(sampler->interval()); 1175 instance_ = new SignalSender(sampler->interval());
1229 instance_->Start(); 1176 instance_->Start();
1230 } else { 1177 } else {
1231 ASSERT(instance_->interval_ == sampler->interval()); 1178 ASSERT(instance_->interval_ == sampler->interval());
1232 } 1179 }
1233 } 1180 }
1234 1181
1235 static void RemoveActiveSampler(Sampler* sampler) { 1182 static void RemoveActiveSampler(Sampler* sampler) {
1236 ScopedLock lock(mutex_); 1183 ScopedLock lock(mutex_);
1237 SamplerRegistry::RemoveActiveSampler(sampler); 1184 SamplerRegistry::RemoveActiveSampler(sampler);
1238 if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) { 1185 if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
1239 RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_); 1186 RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
1240 delete instance_; 1187 delete instance_;
1241 instance_ = NULL; 1188 instance_ = NULL;
1189 RestoreSignalHandler();
1242 } 1190 }
1243 } 1191 }
1244 1192
1245 // Implement Thread::Run(). 1193 // Implement Thread::Run().
1246 virtual void Run() { 1194 virtual void Run() {
1247 SamplerRegistry::State state; 1195 SamplerRegistry::State state;
1248 while ((state = SamplerRegistry::GetState()) != 1196 while ((state = SamplerRegistry::GetState()) !=
1249 SamplerRegistry::HAS_NO_SAMPLERS) { 1197 SamplerRegistry::HAS_NO_SAMPLERS) {
1250 // When CPU profiling is enabled both JavaScript and C++ code is 1198 // When CPU profiling is enabled both JavaScript and C++ code is
1251 // profiled. We must not suspend. 1199 // profiled. We must not suspend.
1252 if (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS) { 1200 if (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS) {
1201 if (!signal_handler_installed_) InstallSignalHandler();
1253 SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this); 1202 SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this);
1254 } else { 1203 } else {
1204 if (signal_handler_installed_) RestoreSignalHandler();
1255 if (RuntimeProfiler::WaitForSomeIsolateToEnterJS()) continue; 1205 if (RuntimeProfiler::WaitForSomeIsolateToEnterJS()) continue;
1256 } 1206 }
1257 Sleep(); // TODO(svenpanne) Figure out if OS:Sleep(interval_) is enough. 1207 Sleep(); // TODO(svenpanne) Figure out if OS:Sleep(interval_) is enough.
1258 } 1208 }
1259 } 1209 }
1260 1210
1261 static void DoCpuProfile(Sampler* sampler, void* raw_sender) { 1211 static void DoCpuProfile(Sampler* sampler, void* raw_sender) {
1262 if (!sampler->IsProfiling()) return; 1212 if (!sampler->IsProfiling()) return;
1263 sampler->DoSample(); 1213 SignalSender* sender = reinterpret_cast<SignalSender*>(raw_sender);
1214 sender->SendProfilingSignal(sampler->platform_data()->vm_tid());
1215 }
1216
1217 void SendProfilingSignal(int tid) {
1218 if (!signal_handler_installed_) return;
1219 // Glibc doesn't provide a wrapper for tgkill(2).
1220 #if defined(ANDROID)
1221 syscall(__NR_tgkill, vm_tgid_, tid, SIGPROF);
1222 #else
1223 int result = syscall(SYS_tgkill, vm_tgid_, tid, SIGPROF);
1224 USE(result);
1225 ASSERT(result == 0);
1226 #endif
1264 } 1227 }
1265 1228
1266 void Sleep() { 1229 void Sleep() {
1267 // Convert ms to us and subtract 100 us to compensate delays 1230 // Convert ms to us and subtract 100 us to compensate delays
1268 // occuring during signal delivery. 1231 // occuring during signal delivery.
1269 useconds_t interval = interval_ * 1000 - 100; 1232 useconds_t interval = interval_ * 1000 - 100;
1270 #if defined(ANDROID) 1233 #if defined(ANDROID)
1271 usleep(interval); 1234 usleep(interval);
1272 #else 1235 #else
1273 int result = usleep(interval); 1236 int result = usleep(interval);
1274 #ifdef DEBUG 1237 #ifdef DEBUG
1275 if (result != 0 && errno != EINTR) { 1238 if (result != 0 && errno != EINTR) {
1276 fprintf(stderr, 1239 fprintf(stderr,
1277 "SignalSender usleep error; interval = %u, errno = %d\n", 1240 "SignalSender usleep error; interval = %u, errno = %d\n",
1278 interval, 1241 interval,
1279 errno); 1242 errno);
1280 ASSERT(result == 0 || errno == EINTR); 1243 ASSERT(result == 0 || errno == EINTR);
1281 } 1244 }
1282 #endif // DEBUG 1245 #endif // DEBUG
1283 USE(result); 1246 USE(result);
1284 #endif // ANDROID 1247 #endif // ANDROID
1285 } 1248 }
1286 1249
1250 const int vm_tgid_;
1287 const int interval_; 1251 const int interval_;
1288 1252
1289 // Protects the process wide state below. 1253 // Protects the process wide state below.
1290 static Mutex* mutex_; 1254 static Mutex* mutex_;
1291 static SignalSender* instance_; 1255 static SignalSender* instance_;
1256 static bool signal_handler_installed_;
1292 static struct sigaction old_signal_handler_; 1257 static struct sigaction old_signal_handler_;
1293 1258
1294 private: 1259 private:
1295 DISALLOW_COPY_AND_ASSIGN(SignalSender); 1260 DISALLOW_COPY_AND_ASSIGN(SignalSender);
1296 }; 1261 };
1297 1262
1298 1263
1299 Mutex* SignalSender::mutex_ = NULL; 1264 Mutex* SignalSender::mutex_ = NULL;
1300 SignalSender* SignalSender::instance_ = NULL; 1265 SignalSender* SignalSender::instance_ = NULL;
1301 struct sigaction SignalSender::old_signal_handler_; 1266 struct sigaction SignalSender::old_signal_handler_;
1267 bool SignalSender::signal_handler_installed_ = false;
1302 1268
1303 1269
1304 void OS::SetUp() { 1270 void OS::SetUp() {
1305 // Seed the random number generator. We preserve microsecond resolution. 1271 // Seed the random number generator. We preserve microsecond resolution.
1306 uint64_t seed = Ticks() ^ (getpid() << 16); 1272 uint64_t seed = Ticks() ^ (getpid() << 16);
1307 srandom(static_cast<unsigned int>(seed)); 1273 srandom(static_cast<unsigned int>(seed));
1308 limit_mutex = CreateMutex(); 1274 limit_mutex = CreateMutex();
1309 1275
1310 #ifdef __arm__ 1276 #ifdef __arm__
1311 // When running on ARM hardware check that the EABI used by V8 and 1277 // When running on ARM hardware check that the EABI used by V8 and
1312 // by the C code is the same. 1278 // by the C code is the same.
1313 bool hard_float = OS::ArmUsingHardFloat(); 1279 bool hard_float = OS::ArmUsingHardFloat();
1314 if (hard_float) { 1280 if (hard_float) {
1315 #if !USE_EABI_HARDFLOAT 1281 #if !USE_EABI_HARDFLOAT
1316 PrintF("ERROR: Binary compiled with -mfloat-abi=hard but without " 1282 PrintF("ERROR: Binary compiled with -mfloat-abi=hard but without "
1317 "-DUSE_EABI_HARDFLOAT\n"); 1283 "-DUSE_EABI_HARDFLOAT\n");
1318 exit(1); 1284 exit(1);
1319 #endif 1285 #endif
1320 } else { 1286 } else {
1321 #if USE_EABI_HARDFLOAT 1287 #if USE_EABI_HARDFLOAT
1322 PrintF("ERROR: Binary not compiled with -mfloat-abi=hard but with " 1288 PrintF("ERROR: Binary not compiled with -mfloat-abi=hard but with "
1323 "-DUSE_EABI_HARDFLOAT\n"); 1289 "-DUSE_EABI_HARDFLOAT\n");
1324 exit(1); 1290 exit(1);
1325 #endif 1291 #endif
1326 } 1292 }
1327 #endif 1293 #endif
1328 SignalSender::SetUp(); 1294 SignalSender::SetUp();
1329 CpuProfilerSignalHandler::SetUp();
1330 } 1295 }
1331 1296
1332 1297
1333 void OS::TearDown() { 1298 void OS::TearDown() {
1334 CpuProfilerSignalHandler::TearDown();
1335 SignalSender::TearDown(); 1299 SignalSender::TearDown();
1336 delete limit_mutex; 1300 delete limit_mutex;
1337 } 1301 }
1338 1302
1339 1303
1340 Sampler::Sampler(Isolate* isolate, int interval) 1304 Sampler::Sampler(Isolate* isolate, int interval)
1341 : isolate_(isolate), 1305 : isolate_(isolate),
1342 interval_(interval), 1306 interval_(interval),
1343 profiling_(false), 1307 profiling_(false),
1344 has_processing_thread_(false),
1345 active_(false), 1308 active_(false),
1346 samples_taken_(0) { 1309 samples_taken_(0) {
1347 data_ = new PlatformData; 1310 data_ = new PlatformData;
1348 } 1311 }
1349 1312
1350 1313
1351 Sampler::~Sampler() { 1314 Sampler::~Sampler() {
1352 ASSERT(!IsActive()); 1315 ASSERT(!IsActive());
1353 delete data_; 1316 delete data_;
1354 } 1317 }
1355 1318
1356 1319
1357 void Sampler::Start() { 1320 void Sampler::Start() {
1358 ASSERT(!IsActive()); 1321 ASSERT(!IsActive());
1359 SetActive(true); 1322 SetActive(true);
1360 SignalSender::AddActiveSampler(this); 1323 SignalSender::AddActiveSampler(this);
1361 } 1324 }
1362 1325
1363 1326
1364 void Sampler::Stop() { 1327 void Sampler::Stop() {
1365 ASSERT(IsActive()); 1328 ASSERT(IsActive());
1366 SignalSender::RemoveActiveSampler(this); 1329 SignalSender::RemoveActiveSampler(this);
1367 SetActive(false); 1330 SetActive(false);
1368 } 1331 }
1369 1332
1370 1333
1371 bool Sampler::CanSampleOnProfilerEventsProcessorThread() {
1372 return true;
1373 }
1374
1375
1376 void Sampler::DoSample() {
1377 platform_data()->SendProfilingSignal();
1378 }
1379
1380
1381 void Sampler::StartProfiling() {
1382 platform_data()->set_signal_handler_installed(
1383 CpuProfilerSignalHandler::RegisterProfilingSampler());
1384 }
1385
1386
1387 void Sampler::StopProfiling() {
1388 CpuProfilerSignalHandler::UnregisterProfilingSampler();
1389 platform_data()->set_signal_handler_installed(false);
1390 }
1391
1392
1393 } } // namespace v8::internal 1334 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/platform-freebsd.cc ('k') | src/platform-macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698