| OLD | NEW |
| 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 #include "v8threads.h" | 55 #include "v8threads.h" |
| 56 | 56 |
| 57 #include "platform-posix.h" | 57 #include "platform-posix.h" |
| 58 #include "platform.h" | 58 #include "platform.h" |
| 59 #include "vm-state-inl.h" | 59 #include "vm-state-inl.h" |
| 60 | 60 |
| 61 | 61 |
| 62 namespace v8 { | 62 namespace v8 { |
| 63 namespace internal { | 63 namespace internal { |
| 64 | 64 |
| 65 // 0 is never a valid thread id on FreeBSD since tids and pids share a | |
| 66 // name space and pid 0 is used to kill the group (see man 2 kill). | |
| 67 static const pthread_t kNoThread = (pthread_t) 0; | |
| 68 | |
| 69 | |
| 70 double ceiling(double x) { | |
| 71 // Correct as on OS X | |
| 72 if (-1.0 < x && x < 0.0) { | |
| 73 return -0.0; | |
| 74 } else { | |
| 75 return ceil(x); | |
| 76 } | |
| 77 } | |
| 78 | |
| 79 | 65 |
| 80 static Mutex* limit_mutex = NULL; | 66 static Mutex* limit_mutex = NULL; |
| 81 | 67 |
| 82 | 68 |
| 83 void OS::PostSetUp() { | |
| 84 POSIXPostSetUp(); | |
| 85 } | |
| 86 | |
| 87 | |
| 88 uint64_t OS::CpuFeaturesImpliedByPlatform() { | |
| 89 return 0; // FreeBSD runs on anything. | |
| 90 } | |
| 91 | |
| 92 | |
| 93 int OS::ActivationFrameAlignment() { | |
| 94 // 16 byte alignment on FreeBSD | |
| 95 return 16; | |
| 96 } | |
| 97 | |
| 98 | |
| 99 const char* OS::LocalTimezone(double time) { | 69 const char* OS::LocalTimezone(double time) { |
| 100 if (std::isnan(time)) return ""; | 70 if (std::isnan(time)) return ""; |
| 101 time_t tv = static_cast<time_t>(floor(time/msPerSecond)); | 71 time_t tv = static_cast<time_t>(floor(time/msPerSecond)); |
| 102 struct tm* t = localtime(&tv); | 72 struct tm* t = localtime(&tv); |
| 103 if (NULL == t) return ""; | 73 if (NULL == t) return ""; |
| 104 return t->tm_zone; | 74 return t->tm_zone; |
| 105 } | 75 } |
| 106 | 76 |
| 107 | 77 |
| 108 double OS::LocalTimeOffset() { | 78 double OS::LocalTimeOffset() { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 132 Max(highest_ever_allocated, | 102 Max(highest_ever_allocated, |
| 133 reinterpret_cast<void*>(reinterpret_cast<char*>(address) + size)); | 103 reinterpret_cast<void*>(reinterpret_cast<char*>(address) + size)); |
| 134 } | 104 } |
| 135 | 105 |
| 136 | 106 |
| 137 bool OS::IsOutsideAllocatedSpace(void* address) { | 107 bool OS::IsOutsideAllocatedSpace(void* address) { |
| 138 return address < lowest_ever_allocated || address >= highest_ever_allocated; | 108 return address < lowest_ever_allocated || address >= highest_ever_allocated; |
| 139 } | 109 } |
| 140 | 110 |
| 141 | 111 |
| 142 size_t OS::AllocateAlignment() { | |
| 143 return getpagesize(); | |
| 144 } | |
| 145 | |
| 146 | |
| 147 void* OS::Allocate(const size_t requested, | 112 void* OS::Allocate(const size_t requested, |
| 148 size_t* allocated, | 113 size_t* allocated, |
| 149 bool executable) { | 114 bool executable) { |
| 150 const size_t msize = RoundUp(requested, getpagesize()); | 115 const size_t msize = RoundUp(requested, getpagesize()); |
| 151 int prot = PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0); | 116 int prot = PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0); |
| 152 void* mbase = mmap(NULL, msize, prot, MAP_PRIVATE | MAP_ANON, -1, 0); | 117 void* mbase = mmap(NULL, msize, prot, MAP_PRIVATE | MAP_ANON, -1, 0); |
| 153 | 118 |
| 154 if (mbase == MAP_FAILED) { | 119 if (mbase == MAP_FAILED) { |
| 155 LOG(ISOLATE, StringEvent("OS::Allocate", "mmap failed")); | 120 LOG(ISOLATE, StringEvent("OS::Allocate", "mmap failed")); |
| 156 return NULL; | 121 return NULL; |
| 157 } | 122 } |
| 158 *allocated = msize; | 123 *allocated = msize; |
| 159 UpdateAllocatedSpaceLimits(mbase, msize); | 124 UpdateAllocatedSpaceLimits(mbase, msize); |
| 160 return mbase; | 125 return mbase; |
| 161 } | 126 } |
| 162 | 127 |
| 163 | 128 |
| 164 void OS::Free(void* buf, const size_t length) { | |
| 165 // TODO(1240712): munmap has a return value which is ignored here. | |
| 166 int result = munmap(buf, length); | |
| 167 USE(result); | |
| 168 ASSERT(result == 0); | |
| 169 } | |
| 170 | |
| 171 | |
| 172 void OS::Sleep(int milliseconds) { | |
| 173 unsigned int ms = static_cast<unsigned int>(milliseconds); | |
| 174 usleep(1000 * ms); | |
| 175 } | |
| 176 | |
| 177 | |
| 178 int OS::NumberOfCores() { | |
| 179 return sysconf(_SC_NPROCESSORS_ONLN); | |
| 180 } | |
| 181 | |
| 182 | |
| 183 void OS::Abort() { | |
| 184 // Redirect to std abort to signal abnormal program termination. | |
| 185 abort(); | |
| 186 } | |
| 187 | |
| 188 | |
| 189 void OS::DebugBreak() { | |
| 190 #if (defined(__arm__) || defined(__thumb__)) | |
| 191 asm("bkpt 0"); | |
| 192 #elif defined(__aarch64__) | |
| 193 asm("brk 0"); | |
| 194 #else | |
| 195 asm("int $3"); | |
| 196 #endif | |
| 197 } | |
| 198 | |
| 199 | |
| 200 void OS::DumpBacktrace() { | 129 void OS::DumpBacktrace() { |
| 201 POSIXBacktraceHelper<backtrace, backtrace_symbols>::DumpBacktrace(); | 130 POSIXBacktraceHelper<backtrace, backtrace_symbols>::DumpBacktrace(); |
| 202 } | 131 } |
| 203 | 132 |
| 204 | 133 |
| 205 class PosixMemoryMappedFile : public OS::MemoryMappedFile { | 134 class PosixMemoryMappedFile : public OS::MemoryMappedFile { |
| 206 public: | 135 public: |
| 207 PosixMemoryMappedFile(FILE* file, void* memory, int size) | 136 PosixMemoryMappedFile(FILE* file, void* memory, int size) |
| 208 : file_(file), memory_(memory), size_(size) { } | 137 : file_(file), memory_(memory), size_(size) { } |
| 209 virtual ~PosixMemoryMappedFile(); | 138 virtual ~PosixMemoryMappedFile(); |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 return munmap(base, size) == 0; | 365 return munmap(base, size) == 0; |
| 437 } | 366 } |
| 438 | 367 |
| 439 | 368 |
| 440 bool VirtualMemory::HasLazyCommits() { | 369 bool VirtualMemory::HasLazyCommits() { |
| 441 // TODO(alph): implement for the platform. | 370 // TODO(alph): implement for the platform. |
| 442 return false; | 371 return false; |
| 443 } | 372 } |
| 444 | 373 |
| 445 | 374 |
| 446 class Thread::PlatformData : public Malloced { | |
| 447 public: | |
| 448 pthread_t thread_; // Thread handle for pthread. | |
| 449 }; | |
| 450 | |
| 451 | |
| 452 Thread::Thread(const Options& options) | |
| 453 : data_(new PlatformData), | |
| 454 stack_size_(options.stack_size()), | |
| 455 start_semaphore_(NULL) { | |
| 456 set_name(options.name()); | |
| 457 } | |
| 458 | |
| 459 | |
| 460 Thread::~Thread() { | |
| 461 delete data_; | |
| 462 } | |
| 463 | |
| 464 | |
| 465 static void* ThreadEntry(void* arg) { | |
| 466 Thread* thread = reinterpret_cast<Thread*>(arg); | |
| 467 // This is also initialized by the first argument to pthread_create() but we | |
| 468 // don't know which thread will run first (the original thread or the new | |
| 469 // one) so we initialize it here too. | |
| 470 thread->data()->thread_ = pthread_self(); | |
| 471 ASSERT(thread->data()->thread_ != kNoThread); | |
| 472 thread->NotifyStartedAndRun(); | |
| 473 return NULL; | |
| 474 } | |
| 475 | |
| 476 | |
| 477 void Thread::set_name(const char* name) { | |
| 478 strncpy(name_, name, sizeof(name_)); | |
| 479 name_[sizeof(name_) - 1] = '\0'; | |
| 480 } | |
| 481 | |
| 482 | |
| 483 void Thread::Start() { | |
| 484 pthread_attr_t* attr_ptr = NULL; | |
| 485 pthread_attr_t attr; | |
| 486 if (stack_size_ > 0) { | |
| 487 pthread_attr_init(&attr); | |
| 488 pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_)); | |
| 489 attr_ptr = &attr; | |
| 490 } | |
| 491 pthread_create(&data_->thread_, attr_ptr, ThreadEntry, this); | |
| 492 ASSERT(data_->thread_ != kNoThread); | |
| 493 } | |
| 494 | |
| 495 | |
| 496 void Thread::Join() { | |
| 497 pthread_join(data_->thread_, NULL); | |
| 498 } | |
| 499 | |
| 500 | |
| 501 Thread::LocalStorageKey Thread::CreateThreadLocalKey() { | |
| 502 pthread_key_t key; | |
| 503 int result = pthread_key_create(&key, NULL); | |
| 504 USE(result); | |
| 505 ASSERT(result == 0); | |
| 506 return static_cast<LocalStorageKey>(key); | |
| 507 } | |
| 508 | |
| 509 | |
| 510 void Thread::DeleteThreadLocalKey(LocalStorageKey key) { | |
| 511 pthread_key_t pthread_key = static_cast<pthread_key_t>(key); | |
| 512 int result = pthread_key_delete(pthread_key); | |
| 513 USE(result); | |
| 514 ASSERT(result == 0); | |
| 515 } | |
| 516 | |
| 517 | |
| 518 void* Thread::GetThreadLocal(LocalStorageKey key) { | |
| 519 pthread_key_t pthread_key = static_cast<pthread_key_t>(key); | |
| 520 return pthread_getspecific(pthread_key); | |
| 521 } | |
| 522 | |
| 523 | |
| 524 void Thread::SetThreadLocal(LocalStorageKey key, void* value) { | |
| 525 pthread_key_t pthread_key = static_cast<pthread_key_t>(key); | |
| 526 pthread_setspecific(pthread_key, value); | |
| 527 } | |
| 528 | |
| 529 | |
| 530 class FreeBSDSemaphore : public Semaphore { | 375 class FreeBSDSemaphore : public Semaphore { |
| 531 public: | 376 public: |
| 532 explicit FreeBSDSemaphore(int count) { sem_init(&sem_, 0, count); } | 377 explicit FreeBSDSemaphore(int count) { sem_init(&sem_, 0, count); } |
| 533 virtual ~FreeBSDSemaphore() { sem_destroy(&sem_); } | 378 virtual ~FreeBSDSemaphore() { sem_destroy(&sem_); } |
| 534 | 379 |
| 535 virtual void Wait(); | 380 virtual void Wait(); |
| 536 virtual bool Wait(int timeout); | 381 virtual bool Wait(int timeout); |
| 537 virtual void Signal() { sem_post(&sem_); } | 382 virtual void Signal() { sem_post(&sem_); } |
| 538 private: | 383 private: |
| 539 sem_t sem_; | 384 sem_t sem_; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 limit_mutex = CreateMutex(); | 439 limit_mutex = CreateMutex(); |
| 595 } | 440 } |
| 596 | 441 |
| 597 | 442 |
| 598 void OS::TearDown() { | 443 void OS::TearDown() { |
| 599 delete limit_mutex; | 444 delete limit_mutex; |
| 600 } | 445 } |
| 601 | 446 |
| 602 | 447 |
| 603 } } // namespace v8::internal | 448 } } // namespace v8::internal |
| OLD | NEW |