summaryrefslogtreecommitdiffstats
path: root/runtime/base
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2014-06-05 20:48:42 -0700
committerIan Rogers <irogers@google.com>2014-06-10 23:19:29 -0700
commitc5f17732d8144491c642776b6b48c85dfadf4b52 (patch)
tree811daa488ae5ee5dfd9b3b73bd210bc1506e5ca1 /runtime/base
parent08654d40cdd256f6a6c8619bf06d04d4c819714a (diff)
downloadart-c5f17732d8144491c642776b6b48c85dfadf4b52.zip
art-c5f17732d8144491c642776b6b48c85dfadf4b52.tar.gz
art-c5f17732d8144491c642776b6b48c85dfadf4b52.tar.bz2
Remove deprecated WITH_HOST_DALVIK.
Bug: 13751317 Fix the Mac build: - disable x86 selector removal that causes OS/X 10.9 kernel panics, - madvise don't need does zero memory on the Mac, factor into MemMap routine, - switch to the elf.h in elfutils to avoid Linux kernel dependencies, - we can't rely on exclusive_owner_ being available from other pthread libraries so maintain our own when futexes aren't available (we can't rely on the OS/X 10.8 hack any more), - fix symbol naming in assembly code, - work around C library differences, - disable backtrace in DumpNativeStack to avoid a broken libbacktrace dependency, - disable main thread signal handling logic, - align the stack in stub_test, - use $(HOST_SHLIB_SUFFIX) rather than .so in host make file variables. Not all host tests are passing on the Mac with this change. dex2oat works as does running HelloWorld. Change-Id: I5a232aedfb2028524d49daa6397a8e60f3ee40d3
Diffstat (limited to 'runtime/base')
-rw-r--r--runtime/base/mutex-inl.h87
-rw-r--r--runtime/base/mutex.cc88
-rw-r--r--runtime/base/mutex.h2
-rw-r--r--runtime/base/unix_file/fd_file.cc16
-rw-r--r--runtime/base/unix_file/mapped_file.cc4
-rw-r--r--runtime/base/unix_file/mapped_file.h5
6 files changed, 77 insertions, 125 deletions
diff --git a/runtime/base/mutex-inl.h b/runtime/base/mutex-inl.h
index d20eb17..1890181 100644
--- a/runtime/base/mutex-inl.h
+++ b/runtime/base/mutex-inl.h
@@ -45,54 +45,6 @@ static inline int futex(volatile int *uaddr, int op, int val, const struct times
}
#endif // ART_USE_FUTEXES
-#if defined(__APPLE__)
-
-// This works on Mac OS 10.6 but hasn't been tested on older releases.
-struct __attribute__((__may_alias__)) darwin_pthread_mutex_t {
- long padding0; // NOLINT(runtime/int) exact match to darwin type
- int padding1;
- uint32_t padding2;
- int16_t padding3;
- int16_t padding4;
- uint32_t padding5;
- pthread_t darwin_pthread_mutex_owner;
- // ...other stuff we don't care about.
-};
-
-struct __attribute__((__may_alias__)) darwin_pthread_rwlock_t {
- long padding0; // NOLINT(runtime/int) exact match to darwin type
- pthread_mutex_t padding1;
- int padding2;
- pthread_cond_t padding3;
- pthread_cond_t padding4;
- int padding5;
- int padding6;
- pthread_t darwin_pthread_rwlock_owner;
- // ...other stuff we don't care about.
-};
-
-#endif // __APPLE__
-
-#if defined(__GLIBC__)
-
-struct __attribute__((__may_alias__)) glibc_pthread_mutex_t {
- int32_t padding0[2];
- int owner;
- // ...other stuff we don't care about.
-};
-
-struct __attribute__((__may_alias__)) glibc_pthread_rwlock_t {
-#ifdef __LP64__
- int32_t padding0[6];
-#else
- int32_t padding0[7];
-#endif
- int writer;
- // ...other stuff we don't care about.
-};
-
-#endif // __GLIBC__
-
class ScopedContentionRecorder {
public:
ScopedContentionRecorder(BaseMutex* mutex, uint64_t blocked_tid, uint64_t owner_tid)
@@ -219,12 +171,14 @@ inline void ReaderWriterMutex::SharedLock(Thread* self) {
#else
CHECK_MUTEX_CALL(pthread_rwlock_rdlock, (&rwlock_));
#endif
+ DCHECK(exclusive_owner_ == 0U || exclusive_owner_ == -1U);
RegisterAsLocked(self);
AssertSharedHeld(self);
}
inline void ReaderWriterMutex::SharedUnlock(Thread* self) {
DCHECK(self == NULL || self == Thread::Current());
+ DCHECK(exclusive_owner_ == 0U || exclusive_owner_ == -1U);
AssertSharedHeld(self);
RegisterAsUnlocked(self);
#if ART_USE_FUTEXES
@@ -262,26 +216,7 @@ inline bool Mutex::IsExclusiveHeld(const Thread* self) const {
}
inline uint64_t Mutex::GetExclusiveOwnerTid() const {
-#if ART_USE_FUTEXES
return exclusive_owner_;
-#elif defined(__BIONIC__)
- return static_cast<uint64_t>((mutex_.value >> 16) & 0xffff);
-#elif defined(__GLIBC__)
- return reinterpret_cast<const glibc_pthread_mutex_t*>(&mutex_)->owner;
-#elif defined(__APPLE__)
- const darwin_pthread_mutex_t* dpmutex = reinterpret_cast<const darwin_pthread_mutex_t*>(&mutex_);
- pthread_t owner = dpmutex->darwin_pthread_mutex_owner;
- // 0 for unowned, -1 for PTHREAD_MTX_TID_SWITCHING
- // TODO: should we make darwin_pthread_mutex_owner volatile and recheck until not -1?
- if ((owner == (pthread_t)0) || (owner == (pthread_t)-1)) {
- return 0;
- }
- uint64_t tid;
- CHECK_PTHREAD_CALL(pthread_threadid_np, (owner, &tid), __FUNCTION__); // Requires Mac OS 10.6
- return tid;
-#else
-#error unsupported C library
-#endif
}
inline bool ReaderWriterMutex::IsExclusiveHeld(const Thread* self) const {
@@ -307,23 +242,7 @@ inline uint64_t ReaderWriterMutex::GetExclusiveOwnerTid() const {
return exclusive_owner_;
}
#else
-#if defined(__BIONIC__)
- return rwlock_.writerThreadId;
-#elif defined(__GLIBC__)
- return reinterpret_cast<const glibc_pthread_rwlock_t*>(&rwlock_)->writer;
-#elif defined(__APPLE__)
- const darwin_pthread_rwlock_t*
- dprwlock = reinterpret_cast<const darwin_pthread_rwlock_t*>(&rwlock_);
- pthread_t owner = dprwlock->darwin_pthread_rwlock_owner;
- if (owner == (pthread_t)0) {
- return 0;
- }
- uint64_t tid;
- CHECK_PTHREAD_CALL(pthread_threadid_np, (owner, &tid), __FUNCTION__); // Requires Mac OS 10.6
- return tid;
-#else
-#error unsupported C library
-#endif
+ return exclusive_owner_;
#endif
}
diff --git a/runtime/base/mutex.cc b/runtime/base/mutex.cc
index aeece74..fd1eb12 100644
--- a/runtime/base/mutex.cc
+++ b/runtime/base/mutex.cc
@@ -263,19 +263,11 @@ Mutex::Mutex(const char* name, LockLevel level, bool recursive)
: BaseMutex(name, level), recursive_(recursive), recursion_count_(0) {
#if ART_USE_FUTEXES
state_ = 0;
- exclusive_owner_ = 0;
DCHECK_EQ(0, num_contenders_.LoadRelaxed());
-#elif defined(__BIONIC__) || defined(__APPLE__)
- // Use recursive mutexes for bionic and Apple otherwise the
- // non-recursive mutexes don't have TIDs to check lock ownership of.
- pthread_mutexattr_t attributes;
- CHECK_MUTEX_CALL(pthread_mutexattr_init, (&attributes));
- CHECK_MUTEX_CALL(pthread_mutexattr_settype, (&attributes, PTHREAD_MUTEX_RECURSIVE));
- CHECK_MUTEX_CALL(pthread_mutex_init, (&mutex_, &attributes));
- CHECK_MUTEX_CALL(pthread_mutexattr_destroy, (&attributes));
#else
- CHECK_MUTEX_CALL(pthread_mutex_init, (&mutex_, NULL));
+ CHECK_MUTEX_CALL(pthread_mutex_init, (&mutex_, nullptr));
#endif
+ exclusive_owner_ = 0;
}
Mutex::~Mutex() {
@@ -336,10 +328,11 @@ void Mutex::ExclusiveLock(Thread* self) {
// TODO: Change state_ to be a art::Atomic and use an intention revealing CAS operation
// that exposes the ordering semantics.
DCHECK_EQ(state_, 1);
- exclusive_owner_ = SafeGetTid(self);
#else
CHECK_MUTEX_CALL(pthread_mutex_lock, (&mutex_));
#endif
+ DCHECK_EQ(exclusive_owner_, 0U);
+ exclusive_owner_ = SafeGetTid(self);
RegisterAsLocked(self);
}
recursion_count_++;
@@ -369,7 +362,6 @@ bool Mutex::ExclusiveTryLock(Thread* self) {
} while (!done);
// We again assert no memory fence is needed.
DCHECK_EQ(state_, 1);
- exclusive_owner_ = SafeGetTid(self);
#else
int result = pthread_mutex_trylock(&mutex_);
if (result == EBUSY) {
@@ -380,6 +372,8 @@ bool Mutex::ExclusiveTryLock(Thread* self) {
PLOG(FATAL) << "pthread_mutex_trylock failed for " << name_;
}
#endif
+ DCHECK_EQ(exclusive_owner_, 0U);
+ exclusive_owner_ = SafeGetTid(self);
RegisterAsLocked(self);
}
recursion_count_++;
@@ -394,6 +388,7 @@ bool Mutex::ExclusiveTryLock(Thread* self) {
void Mutex::ExclusiveUnlock(Thread* self) {
DCHECK(self == NULL || self == Thread::Current());
AssertHeld(self);
+ DCHECK_NE(exclusive_owner_, 0U);
recursion_count_--;
if (!recursive_ || recursion_count_ == 0) {
if (kDebugLocking) {
@@ -402,34 +397,35 @@ void Mutex::ExclusiveUnlock(Thread* self) {
}
RegisterAsUnlocked(self);
#if ART_USE_FUTEXES
- bool done = false;
- do {
- int32_t cur_state = state_;
- if (LIKELY(cur_state == 1)) {
- // The __sync_bool_compare_and_swap enforces the necessary memory ordering.
- // We're no longer the owner.
- exclusive_owner_ = 0;
- // Change state to 0.
- done = __sync_bool_compare_and_swap(&state_, cur_state, 0 /* new state */);
- if (LIKELY(done)) { // Spurious fail?
- // Wake a contender
- if (UNLIKELY(num_contenders_.LoadRelaxed() > 0)) {
- futex(&state_, FUTEX_WAKE, 1, NULL, NULL, 0);
+ bool done = false;
+ do {
+ int32_t cur_state = state_;
+ if (LIKELY(cur_state == 1)) {
+ // The __sync_bool_compare_and_swap enforces the necessary memory ordering.
+ // We're no longer the owner.
+ exclusive_owner_ = 0;
+ // Change state to 0.
+ done = __sync_bool_compare_and_swap(&state_, cur_state, 0 /* new state */);
+ if (LIKELY(done)) { // Spurious fail?
+ // Wake a contender
+ if (UNLIKELY(num_contenders_.LoadRelaxed() > 0)) {
+ futex(&state_, FUTEX_WAKE, 1, NULL, NULL, 0);
+ }
}
- }
- } else {
- // Logging acquires the logging lock, avoid infinite recursion in that case.
- if (this != Locks::logging_lock_) {
- LOG(FATAL) << "Unexpected state_ in unlock " << cur_state << " for " << name_;
} else {
- LogMessageData data(__FILE__, __LINE__, INTERNAL_FATAL, -1);
- LogMessage::LogLine(data, StringPrintf("Unexpected state_ %d in unlock for %s",
- cur_state, name_).c_str());
- _exit(1);
+ // Logging acquires the logging lock, avoid infinite recursion in that case.
+ if (this != Locks::logging_lock_) {
+ LOG(FATAL) << "Unexpected state_ in unlock " << cur_state << " for " << name_;
+ } else {
+ LogMessageData data(__FILE__, __LINE__, INTERNAL_FATAL, -1);
+ LogMessage::LogLine(data, StringPrintf("Unexpected state_ %d in unlock for %s",
+ cur_state, name_).c_str());
+ _exit(1);
+ }
}
- }
- } while (!done);
+ } while (!done);
#else
+ exclusive_owner_ = 0;
CHECK_MUTEX_CALL(pthread_mutex_unlock, (&mutex_));
#endif
}
@@ -452,12 +448,13 @@ std::ostream& operator<<(std::ostream& os, const Mutex& mu) {
ReaderWriterMutex::ReaderWriterMutex(const char* name, LockLevel level)
: BaseMutex(name, level)
#if ART_USE_FUTEXES
- , state_(0), exclusive_owner_(0), num_pending_readers_(0), num_pending_writers_(0)
+ , state_(0), num_pending_readers_(0), num_pending_writers_(0)
#endif
{ // NOLINT(whitespace/braces)
#if !ART_USE_FUTEXES
- CHECK_MUTEX_CALL(pthread_rwlock_init, (&rwlock_, NULL));
+ CHECK_MUTEX_CALL(pthread_rwlock_init, (&rwlock_, nullptr));
#endif
+ exclusive_owner_ = 0;
}
ReaderWriterMutex::~ReaderWriterMutex() {
@@ -506,10 +503,11 @@ void ReaderWriterMutex::ExclusiveLock(Thread* self) {
}
} while (!done);
DCHECK_EQ(state_, -1);
- exclusive_owner_ = SafeGetTid(self);
#else
CHECK_MUTEX_CALL(pthread_rwlock_wrlock, (&rwlock_));
#endif
+ DCHECK_EQ(exclusive_owner_, 0U);
+ exclusive_owner_ = SafeGetTid(self);
RegisterAsLocked(self);
AssertExclusiveHeld(self);
}
@@ -518,6 +516,7 @@ void ReaderWriterMutex::ExclusiveUnlock(Thread* self) {
DCHECK(self == NULL || self == Thread::Current());
AssertExclusiveHeld(self);
RegisterAsUnlocked(self);
+ DCHECK_NE(exclusive_owner_, 0U);
#if ART_USE_FUTEXES
bool done = false;
do {
@@ -538,6 +537,7 @@ void ReaderWriterMutex::ExclusiveUnlock(Thread* self) {
}
} while (!done);
#else
+ exclusive_owner_ = 0;
CHECK_MUTEX_CALL(pthread_rwlock_unlock, (&rwlock_));
#endif
}
@@ -578,7 +578,6 @@ bool ReaderWriterMutex::ExclusiveLockWithTimeout(Thread* self, int64_t ms, int32
num_pending_writers_--;
}
} while (!done);
- exclusive_owner_ = SafeGetTid(self);
#else
timespec ts;
InitTimeSpec(true, CLOCK_REALTIME, ms, ns, &ts);
@@ -591,6 +590,7 @@ bool ReaderWriterMutex::ExclusiveLockWithTimeout(Thread* self, int64_t ms, int32
PLOG(FATAL) << "pthread_rwlock_timedwrlock failed for " << name_;
}
#endif
+ exclusive_owner_ = SafeGetTid(self);
RegisterAsLocked(self);
AssertSharedHeld(self);
return true;
@@ -656,7 +656,7 @@ ConditionVariable::ConditionVariable(const char* name, Mutex& guard)
num_waiters_ = 0;
#else
pthread_condattr_t cond_attrs;
- CHECK_MUTEX_CALL(pthread_condattr_init(&cond_attrs));
+ CHECK_MUTEX_CALL(pthread_condattr_init, (&cond_attrs));
#if !defined(__APPLE__)
// Apple doesn't have CLOCK_MONOTONIC or pthread_condattr_setclock.
CHECK_MUTEX_CALL(pthread_condattr_setclock(&cond_attrs, CLOCK_MONOTONIC));
@@ -763,8 +763,11 @@ void ConditionVariable::WaitHoldingLocks(Thread* self) {
CHECK_GE(guard_.num_contenders_.LoadRelaxed(), 0);
guard_.num_contenders_--;
#else
+ uint64_t old_owner = guard_.exclusive_owner_;
+ guard_.exclusive_owner_ = 0;
guard_.recursion_count_ = 0;
CHECK_MUTEX_CALL(pthread_cond_wait, (&cond_, &guard_.mutex_));
+ guard_.exclusive_owner_ = old_owner;
#endif
guard_.recursion_count_ = old_recursion_count;
}
@@ -804,6 +807,8 @@ void ConditionVariable::TimedWait(Thread* self, int64_t ms, int32_t ns) {
#else
int clock = CLOCK_REALTIME;
#endif
+ uint64_t old_owner = guard_.exclusive_owner_;
+ guard_.exclusive_owner_ = 0;
guard_.recursion_count_ = 0;
timespec ts;
InitTimeSpec(true, clock, ms, ns, &ts);
@@ -812,6 +817,7 @@ void ConditionVariable::TimedWait(Thread* self, int64_t ms, int32_t ns) {
errno = rc;
PLOG(FATAL) << "TimedWait failed for " << name_;
}
+ guard_.exclusive_owner_ = old_owner;
#endif
guard_.recursion_count_ = old_recursion_count;
}
diff --git a/runtime/base/mutex.h b/runtime/base/mutex.h
index 68b450a..1ba6180 100644
--- a/runtime/base/mutex.h
+++ b/runtime/base/mutex.h
@@ -245,6 +245,7 @@ class LOCKABLE Mutex : public BaseMutex {
AtomicInteger num_contenders_;
#else
pthread_mutex_t mutex_;
+ volatile uint64_t exclusive_owner_; // Guarded by mutex_.
#endif
const bool recursive_; // Can the lock be recursively held?
unsigned int recursion_count_;
@@ -358,6 +359,7 @@ class LOCKABLE ReaderWriterMutex : public BaseMutex {
AtomicInteger num_pending_writers_;
#else
pthread_rwlock_t rwlock_;
+ volatile uint64_t exclusive_owner_; // Guarded by rwlock_.
#endif
DISALLOW_COPY_AND_ASSIGN(ReaderWriterMutex);
};
diff --git a/runtime/base/unix_file/fd_file.cc b/runtime/base/unix_file/fd_file.cc
index 87d1c06..6d5b59c 100644
--- a/runtime/base/unix_file/fd_file.cc
+++ b/runtime/base/unix_file/fd_file.cc
@@ -69,17 +69,29 @@ int FdFile::Close() {
}
int FdFile::Flush() {
+#ifdef __linux__
int rc = TEMP_FAILURE_RETRY(fdatasync(fd_));
+#else
+ int rc = TEMP_FAILURE_RETRY(fsync(fd_));
+#endif
return (rc == -1) ? -errno : rc;
}
int64_t FdFile::Read(char* buf, int64_t byte_count, int64_t offset) const {
+#ifdef __linux__
int rc = TEMP_FAILURE_RETRY(pread64(fd_, buf, byte_count, offset));
+#else
+ int rc = TEMP_FAILURE_RETRY(pread(fd_, buf, byte_count, offset));
+#endif
return (rc == -1) ? -errno : rc;
}
int FdFile::SetLength(int64_t new_length) {
+#ifdef __linux__
int rc = TEMP_FAILURE_RETRY(ftruncate64(fd_, new_length));
+#else
+ int rc = TEMP_FAILURE_RETRY(ftruncate(fd_, new_length));
+#endif
return (rc == -1) ? -errno : rc;
}
@@ -90,7 +102,11 @@ int64_t FdFile::GetLength() const {
}
int64_t FdFile::Write(const char* buf, int64_t byte_count, int64_t offset) {
+#ifdef __linux__
int rc = TEMP_FAILURE_RETRY(pwrite64(fd_, buf, byte_count, offset));
+#else
+ int rc = TEMP_FAILURE_RETRY(pwrite(fd_, buf, byte_count, offset));
+#endif
return (rc == -1) ? -errno : rc;
}
diff --git a/runtime/base/unix_file/mapped_file.cc b/runtime/base/unix_file/mapped_file.cc
index bc23a74..63927b1 100644
--- a/runtime/base/unix_file/mapped_file.cc
+++ b/runtime/base/unix_file/mapped_file.cc
@@ -61,7 +61,11 @@ bool MappedFile::MapReadOnly() {
bool MappedFile::MapReadWrite(int64_t file_size) {
CHECK(IsOpened());
CHECK(!IsMapped());
+#ifdef __linux__
int result = TEMP_FAILURE_RETRY(ftruncate64(Fd(), file_size));
+#else
+ int result = TEMP_FAILURE_RETRY(ftruncate(Fd(), file_size));
+#endif
if (result == -1) {
PLOG(ERROR) << "Failed to truncate file '" << GetPath()
<< "' to size " << file_size;
diff --git a/runtime/base/unix_file/mapped_file.h b/runtime/base/unix_file/mapped_file.h
index 28cc551..73056e9 100644
--- a/runtime/base/unix_file/mapped_file.h
+++ b/runtime/base/unix_file/mapped_file.h
@@ -32,8 +32,13 @@ class MappedFile : public FdFile {
public:
// File modes used in Open().
enum FileMode {
+#ifdef __linux__
kReadOnlyMode = O_RDONLY | O_LARGEFILE,
kReadWriteMode = O_CREAT | O_RDWR | O_LARGEFILE,
+#else
+ kReadOnlyMode = O_RDONLY,
+ kReadWriteMode = O_CREAT | O_RDWR,
+#endif
};
MappedFile() : FdFile(), file_size_(-1), mapped_file_(NULL) {