mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-23 18:20:04 +00:00
!9826 pthread_mutex_t对接ffrt
Merge pull request !9826 from chentianyu/ffrt
This commit is contained in:
commit
603c6825a2
2
BUILD.gn
2
BUILD.gn
@ -998,7 +998,7 @@ ecma_platform_source += [
|
||||
"ecmascript/platform/common/map.cpp",
|
||||
"ecmascript/platform/common/mutex.cpp",
|
||||
"ecmascript/platform/common/filesystem.cpp",
|
||||
"ecmascript/platform/common/ffrt.cpp",
|
||||
"ecmascript/platform/common/ffrt_adapter.cpp",
|
||||
]
|
||||
|
||||
config("include_llvm") {
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#include "ecmascript/compiler/aot_file/aot_file_manager.h"
|
||||
#include "ecmascript/jspandafile/js_pandafile_manager.h"
|
||||
#include "ecmascript/platform/ffrt.h"
|
||||
#include "ecmascript/platform/ffrt_adapter.h"
|
||||
|
||||
#if defined(ENABLE_FFRT_INTERFACES)
|
||||
#include "c/executor_task.h"
|
||||
|
@ -753,7 +753,11 @@ void JSThread::CheckAndPassActiveBarrier()
|
||||
bool JSThread::PassSuspendBarrier()
|
||||
{
|
||||
// Use suspendLock_ to avoid data-race between suspend-all-thread and suspended-threads.
|
||||
#if defined(ENABLE_FFRT_INTERFACES)
|
||||
FFRTLockHolder hock(suspendLock_);
|
||||
#else
|
||||
LockHolder lock(suspendLock_);
|
||||
#endif
|
||||
if (suspendBarrier_ != nullptr) {
|
||||
suspendBarrier_->PassStrongly();
|
||||
suspendBarrier_ = nullptr;
|
||||
@ -1152,7 +1156,11 @@ void JSThread::UpdateState(ThreadState newState)
|
||||
|
||||
void JSThread::SuspendThread(bool internalSuspend, SuspendBarrier* barrier)
|
||||
{
|
||||
#if defined(ENABLE_FFRT_INTERFACES)
|
||||
FFRTLockHolder hock(suspendLock_);
|
||||
#else
|
||||
LockHolder lock(suspendLock_);
|
||||
#endif
|
||||
if (!internalSuspend) {
|
||||
// do smth here if we want to combine internal and external suspension
|
||||
}
|
||||
@ -1173,7 +1181,11 @@ void JSThread::SuspendThread(bool internalSuspend, SuspendBarrier* barrier)
|
||||
|
||||
void JSThread::ResumeThread(bool internalSuspend)
|
||||
{
|
||||
#if defined(ENABLE_FFRT_INTERFACES)
|
||||
FFRTLockHolder hock(suspendLock_);
|
||||
#else
|
||||
LockHolder lock(suspendLock_);
|
||||
#endif
|
||||
if (!internalSuspend) {
|
||||
// do smth here if we want to combine internal and external suspension
|
||||
}
|
||||
@ -1194,7 +1206,11 @@ void JSThread::WaitSuspension()
|
||||
UpdateState(ThreadState::IS_SUSPENDED);
|
||||
{
|
||||
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "SuspendTime::WaitSuspension");
|
||||
#if defined(ENABLE_FFRT_INTERFACES)
|
||||
FFRTLockHolder lock(suspendLock_);
|
||||
#else
|
||||
LockHolder lock(suspendLock_);
|
||||
#endif
|
||||
while (suspendCount_ > 0) {
|
||||
suspendCondVar_.TimedWait(&suspendLock_, TIMEOUT);
|
||||
// we need to do smth if Runtime is terminating at this point
|
||||
@ -1286,7 +1302,11 @@ void JSThread::StoreRunningState(ThreadState newState)
|
||||
} else if ((oldStateAndFlags.asNonvolatileStruct.flags & ThreadFlag::SUSPEND_REQUEST) != 0) {
|
||||
constexpr int TIMEOUT = 100;
|
||||
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "SuspendTime::StoreRunningState");
|
||||
#if defined(ENABLE_FFRT_INTERFACES)
|
||||
FFRTLockHolder lock(suspendLock_);
|
||||
#else
|
||||
LockHolder lock(suspendLock_);
|
||||
#endif
|
||||
while (suspendCount_ > 0) {
|
||||
suspendCondVar_.TimedWait(&suspendLock_, TIMEOUT);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
#include "ecmascript/platform/ffrt.h"
|
||||
#include "ecmascript/platform/ffrt_adapter.h"
|
||||
#include "ecmascript/base/aligned_struct.h"
|
||||
#include "ecmascript/builtin_entries.h"
|
||||
#include "ecmascript/daemon/daemon_task.h"
|
||||
@ -37,6 +37,7 @@
|
||||
#if defined(ENABLE_FFRT_INTERFACES)
|
||||
#include "ffrt.h"
|
||||
#include "c/executor_task.h"
|
||||
#include "ecmascript/platform/ffrt_mutex.h"
|
||||
#endif
|
||||
|
||||
namespace panda::ecmascript {
|
||||
@ -1609,9 +1610,14 @@ private:
|
||||
CVector<EcmaContext *> contexts_;
|
||||
EcmaContext *currentContext_ {nullptr};
|
||||
|
||||
#if defined(ENABLE_FFRT_INTERFACES)
|
||||
FFRTMutex suspendLock_;
|
||||
FFRTConditionVariable suspendCondVar_;
|
||||
#else
|
||||
Mutex suspendLock_;
|
||||
int32_t suspendCount_ {0};
|
||||
ConditionVariable suspendCondVar_;
|
||||
#endif
|
||||
int32_t suspendCount_ {0};
|
||||
SuspendBarrier *suspendBarrier_ {nullptr};
|
||||
|
||||
uint64_t jobId_ {0};
|
||||
|
@ -13,7 +13,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ecmascript/platform/ffrt.h"
|
||||
#include "ecmascript/platform/ffrt_adapter.h"
|
||||
#include "libpandabase/os/thread.h"
|
||||
|
||||
#if defined(ENABLE_FFRT_INTERFACES)
|
176
ecmascript/platform/ffrt_mutex.h
Normal file
176
ecmascript/platform/ffrt_mutex.h
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ECMASCRIPT_PLATFORM_FFRT_MUTEX_H
|
||||
#define ECMASCRIPT_PLATFORM_FFRT_MUTEX_H
|
||||
|
||||
#include "ffrt.h"
|
||||
|
||||
#include "ecmascript/common.h"
|
||||
#ifdef DEBUG
|
||||
#define FATAL_IF_ERROR(f, rc) \
|
||||
do { \
|
||||
if (rc != 0) { \
|
||||
LOG_ECMA(FATAL)<< f << " failed: " << rc; \
|
||||
} \
|
||||
} while (false)
|
||||
#else
|
||||
#define FATAL_IF_ERROR(f, rc) static_cast<void>(0)
|
||||
#endif
|
||||
|
||||
namespace panda::ecmascript {
|
||||
|
||||
class PUBLIC_API FFRTMutex {
|
||||
public:
|
||||
explicit FFRTMutex(bool is_init = true)
|
||||
{
|
||||
if (is_init) {
|
||||
Init(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
~FFRTMutex()
|
||||
{
|
||||
[[maybe_unused]]int rc = ffrt_mutex_destroy(&mutex_);
|
||||
FATAL_IF_ERROR("ffrt_mutex_destroy", rc);
|
||||
}
|
||||
|
||||
void Lock()
|
||||
{
|
||||
[[maybe_unused]]int rc = ffrt_mutex_lock(&mutex_);
|
||||
FATAL_IF_ERROR("ffrt_mutex_lock", rc);
|
||||
}
|
||||
|
||||
bool TryLock()
|
||||
{
|
||||
int rc = ffrt_mutex_trylock(&mutex_);
|
||||
if (rc == EBUSY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FATAL_IF_ERROR("ffrt_mutex_trylock", rc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
[[maybe_unused]]int rc = ffrt_mutex_unlock(&mutex_);
|
||||
FATAL_IF_ERROR("ffrt_mutex_unlock", rc);
|
||||
}
|
||||
|
||||
protected:
|
||||
void Init(ffrt_mutexattr_t *attrs)
|
||||
{
|
||||
[[maybe_unused]]int rc = ffrt_mutex_init(&mutex_, attrs);
|
||||
FATAL_IF_ERROR("ffrt_mutex_init", rc);
|
||||
}
|
||||
|
||||
private:
|
||||
ffrt_mutex_t mutex_;
|
||||
friend class FFRTConditionVariable;
|
||||
};
|
||||
|
||||
class PUBLIC_API FFRTConditionVariable {
|
||||
public:
|
||||
FFRTConditionVariable()
|
||||
{
|
||||
[[maybe_unused]]int rc = ffrt_cond_init(&cond_, nullptr);
|
||||
FATAL_IF_ERROR("ffrt_cond_init", rc);
|
||||
}
|
||||
|
||||
~FFRTConditionVariable()
|
||||
{
|
||||
[[maybe_unused]]int rc = ffrt_cond_destroy(&cond_);
|
||||
FATAL_IF_ERROR("ffrt_cond_destroy", rc);
|
||||
}
|
||||
|
||||
void Signal()
|
||||
{
|
||||
[[maybe_unused]]int rc = ffrt_cond_signal(&cond_);
|
||||
FATAL_IF_ERROR("ffrt_cond_signal", rc);
|
||||
}
|
||||
|
||||
void SignalAll()
|
||||
{
|
||||
[[maybe_unused]]int rc = ffrt_cond_broadcast(&cond_);
|
||||
FATAL_IF_ERROR("ffrt_cond_broadcast", rc);
|
||||
}
|
||||
|
||||
void Wait(FFRTMutex *mutex)
|
||||
{
|
||||
[[maybe_unused]]int rc = ffrt_cond_wait(&cond_, &mutex->mutex_);
|
||||
FATAL_IF_ERROR("ffrt_cond_wait", rc);
|
||||
}
|
||||
|
||||
bool TimedWait(FFRTMutex *mutex, uint64_t ms, uint64_t ns = 0, bool is_absolute = false)
|
||||
{
|
||||
struct timespec abs_time = ConvertTime(ms, ns, is_absolute);
|
||||
int rc = ffrt_cond_timedwait(&cond_, &mutex->mutex_, &abs_time);
|
||||
if (rc != 0) {
|
||||
if (rc == ETIMEDOUT) {
|
||||
// interrupted
|
||||
return true;
|
||||
}
|
||||
}
|
||||
FATAL_IF_ERROR("ffrt_cond_timedwait", rc);
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
struct timespec ConvertTime(uint64_t ms, uint64_t ns, bool is_absolute)
|
||||
{
|
||||
struct timespec abs_time = {0, 0};
|
||||
if (!is_absolute) {
|
||||
clock_gettime(CLOCK_REALTIME, &abs_time);
|
||||
}
|
||||
const int64_t MILLISECONDS_PER_SEC = 1000;
|
||||
const int64_t NANOSECONDS_PER_MILLISEC = 1000000;
|
||||
const int64_t NANOSECONDS_PER_SEC = 1000000000;
|
||||
time_t seconds = ms / MILLISECONDS_PER_SEC;
|
||||
time_t nanoseconds = (ms % MILLISECONDS_PER_SEC) * NANOSECONDS_PER_MILLISEC + ns;
|
||||
abs_time.tv_sec += seconds;
|
||||
abs_time.tv_nsec += nanoseconds;
|
||||
if (abs_time.tv_nsec >= NANOSECONDS_PER_SEC) {
|
||||
abs_time.tv_nsec -= NANOSECONDS_PER_SEC;
|
||||
abs_time.tv_sec++;
|
||||
}
|
||||
return abs_time;
|
||||
}
|
||||
|
||||
private:
|
||||
ffrt_cond_t cond_;
|
||||
};
|
||||
|
||||
class FFRTLockHolder {
|
||||
public:
|
||||
explicit FFRTLockHolder(FFRTMutex &mtx) : lock_(mtx)
|
||||
{
|
||||
lock_.Lock();
|
||||
}
|
||||
|
||||
~FFRTLockHolder()
|
||||
{
|
||||
lock_.Unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
FFRTMutex &lock_;
|
||||
|
||||
NO_COPY_SEMANTIC(FFRTLockHolder);
|
||||
NO_MOVE_SEMANTIC(FFRTLockHolder);
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_PLATFORM_FFRT_MUTEX_H
|
@ -134,7 +134,11 @@ void Runtime::DestroyIfLastVm()
|
||||
|
||||
void Runtime::RegisterThread(JSThread* newThread)
|
||||
{
|
||||
#if defined(ENABLE_FFRT_INTERFACES)
|
||||
FFRTLockHolder lock(threadsLock_);
|
||||
#else
|
||||
LockHolder lock(threadsLock_);
|
||||
#endif
|
||||
ASSERT(std::find(threads_.begin(), threads_.end(), newThread) == threads_.end());
|
||||
threads_.emplace_back(newThread);
|
||||
// send all current suspended requests to the new thread
|
||||
@ -146,7 +150,11 @@ void Runtime::RegisterThread(JSThread* newThread)
|
||||
// Note: currently only called when thread is to be destroyed.
|
||||
void Runtime::UnregisterThread(JSThread* thread)
|
||||
{
|
||||
#if defined(ENABLE_FFRT_INTERFACES)
|
||||
FFRTLockHolder lock(threadsLock_);
|
||||
#else
|
||||
LockHolder lock(threadsLock_);
|
||||
#endif
|
||||
ASSERT(std::find(threads_.begin(), threads_.end(), thread) != threads_.end());
|
||||
ASSERT(!thread->IsInRunningState());
|
||||
threads_.remove(thread);
|
||||
@ -179,7 +187,11 @@ void Runtime::SuspendAllThreadsImpl(JSThread *current)
|
||||
SuspendBarrier barrier;
|
||||
for (uint32_t iterCount = 1U;; ++iterCount) {
|
||||
{
|
||||
#if defined(ENABLE_FFRT_INTERFACES)
|
||||
FFRTLockHolder lock(threadsLock_);
|
||||
#else
|
||||
LockHolder lock(threadsLock_);
|
||||
#endif
|
||||
if (suspendNewCount_ == 0) {
|
||||
suspendNewCount_++;
|
||||
if (threads_.size() == 1) {
|
||||
@ -218,7 +230,11 @@ void Runtime::SuspendAllThreadsImpl(JSThread *current)
|
||||
}
|
||||
}
|
||||
if (iterCount < MAX_SUSPEND_RETRIES) {
|
||||
#if defined(ENABLE_FFRT_INTERFACES)
|
||||
FFRTLockHolder lock(threadsLock_);
|
||||
#else
|
||||
LockHolder lock(threadsLock_);
|
||||
#endif
|
||||
if (suspendNewCount_ != 0) {
|
||||
// Someone has already suspended all threads.
|
||||
// Wait until it finishes.
|
||||
@ -234,7 +250,11 @@ void Runtime::SuspendAllThreadsImpl(JSThread *current)
|
||||
|
||||
void Runtime::ResumeAllThreadsImpl(JSThread *current)
|
||||
{
|
||||
#if defined(ENABLE_FFRT_INTERFACES)
|
||||
FFRTLockHolder lock(threadsLock_);
|
||||
#else
|
||||
LockHolder lock(threadsLock_);
|
||||
#endif
|
||||
if (suspendNewCount_ > 0) {
|
||||
suspendNewCount_--;
|
||||
}
|
||||
|
@ -31,6 +31,10 @@
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
#if defined(ENABLE_FFRT_INTERFACES)
|
||||
#include "ecmascript/platform/ffrt_mutex.h"
|
||||
#endif
|
||||
|
||||
namespace panda::ecmascript {
|
||||
class Runtime {
|
||||
public:
|
||||
@ -65,7 +69,11 @@ public:
|
||||
template<class Callback>
|
||||
void GCIterateThreadList(const Callback &cb)
|
||||
{
|
||||
#if defined(ENABLE_FFRT_INTERFACES)
|
||||
FFRTLockHolder lock(threadsLock_);
|
||||
#else
|
||||
LockHolder lock(threadsLock_);
|
||||
#endif
|
||||
GCIterateThreadListWithoutLock(cb);
|
||||
}
|
||||
|
||||
@ -263,8 +271,13 @@ private:
|
||||
return sharedNativePointerCallbacks_;
|
||||
}
|
||||
|
||||
#if defined(ENABLE_FFRT_INTERFACES)
|
||||
FFRTMutex threadsLock_;
|
||||
FFRTConditionVariable threadSuspendCondVar_;
|
||||
#else
|
||||
Mutex threadsLock_;
|
||||
ConditionVariable threadSuspendCondVar_;
|
||||
#endif
|
||||
Mutex serializeLock_;
|
||||
std::list<JSThread*> threads_;
|
||||
uint32_t suspendNewCount_ {0};
|
||||
|
Loading…
Reference in New Issue
Block a user