Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(android): support work reuse with group id #4049

Merged
merged 2 commits into from
Sep 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ inline namespace framework {
inline namespace connector {
inline namespace dom {

jint CreateDomManager(JNIEnv* j_env, __unused jobject j_obj);
jint CreateDomManager(JNIEnv* j_env, __unused jobject j_obj, jint j_group_id, jint j_share_dom_id);

void DestroyDomManager(JNIEnv* j_env,
__unused jobject j_obj,
Expand Down
53 changes: 39 additions & 14 deletions framework/android/connector/dom/src/main/cpp/src/dom_jni.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ inline namespace dom {

REGISTER_JNI("com/openhippy/connector/DomManager", // NOLINT(cert-err58-cpp)
"createDomManager",
"()I",
"(II)I",
CreateDomManager)

REGISTER_JNI("com/openhippy/connector/DomManager", // NOLINT(cert-err58-cpp)
Expand Down Expand Up @@ -79,6 +79,7 @@ using TaskRunner = footstone::TaskRunner;

constexpr char kDomWorkerName[] = "dom_worker";
constexpr char kDomRunnerName[] = "dom_task_runner";
constexpr int32_t kDefaultGroupId = -1;

void CreateRoot(JNIEnv* j_env,
__unused jobject j_obj,
Expand Down Expand Up @@ -151,21 +152,41 @@ static void SetThreadPriority(jobject j_object) {
j_env->DeleteLocalRef(j_class);
}

jint CreateDomManager(JNIEnv* j_env, jobject j_obj) {
jint CreateDomManager(JNIEnv* j_env, jobject j_obj, jint j_group_id, jint j_share_dom_id) {
auto dom_manager = std::make_shared<DomManager>();
auto dom_id = hippy::global_data_holder_key.fetch_add(1);
hippy::global_data_holder.Insert(dom_id, dom_manager);
auto worker = std::make_shared<WorkerImpl>(kDomWorkerName, false);
auto callback = std::make_shared<JavaRef>(j_env, j_obj);
worker->BeforeStart([callback]() {
if (callback->GetObj()) SetThreadPriority(callback->GetObj());
});
worker->Start();
auto runner = std::make_shared<TaskRunner>(kDomRunnerName);
runner->SetWorker(worker);
worker->Bind({runner});
dom_manager->SetTaskRunner(runner);
dom_manager->SetWorker(worker);
auto group_id = footstone::checked_numeric_cast<jint, int32_t>(j_group_id);
auto share_dom_id = footstone::checked_numeric_cast<jint, int32_t>(j_share_dom_id);
std::any share_dom_manager;
bool flag = false;
if (share_dom_id > 0) {
flag = hippy::global_data_holder.Find(static_cast<uint32_t>(share_dom_id), share_dom_manager);
}
FOOTSTONE_DLOG(ERROR) << "CreateDomManager flag " << flag << ", dom_id " << dom_id << ", share_dom_id " << share_dom_id;
if (flag && group_id != kDefaultGroupId) {
FOOTSTONE_DLOG(ERROR) << "CreateDomManager share ";
auto dom_manager_object = std::any_cast<std::shared_ptr<DomManager>>(share_dom_manager);
auto worker = dom_manager_object->GetWorker();
auto runner = dom_manager_object->GetTaskRunner();
dom_manager->SetTaskRunner(runner);
dom_manager->SetWorker(worker);
auto count = worker->FetchAndAddReuseCount();
FOOTSTONE_DLOG(ERROR) << "CreateDomManager worker reuse count " << count << ", dom manager id " << dom_id;
} else {
FOOTSTONE_DLOG(ERROR) << "CreateDomManager create new ";
auto worker = std::make_shared<WorkerImpl>(kDomWorkerName, false);
auto callback = std::make_shared<JavaRef>(j_env, j_obj);
worker->BeforeStart([callback]() {
if (callback->GetObj()) SetThreadPriority(callback->GetObj());
});
worker->Start();
auto runner = std::make_shared<TaskRunner>(kDomRunnerName);
runner->SetWorker(worker);
worker->Bind({runner});
dom_manager->SetTaskRunner(runner);
dom_manager->SetWorker(worker);
}
return footstone::checked_numeric_cast<uint32_t, jint>(dom_id);
}

Expand All @@ -175,7 +196,11 @@ void DestroyDomManager(__unused JNIEnv* j_env, __unused jobject j_obj, jint j_do
auto flag = hippy::global_data_holder.Find(dom_manager_id, dom_manager);
FOOTSTONE_CHECK(flag);
auto dom_manager_object = std::any_cast<std::shared_ptr<DomManager>>(dom_manager);
dom_manager_object->GetWorker()->Terminate();
auto count = dom_manager_object->GetWorker()->FetchAndSubReuseCount();
FOOTSTONE_DLOG(ERROR) << "DestroyDomManager worker reuse count " << count << ", dom manager id " << dom_manager_id;
if (count == 0) {
dom_manager_object->GetWorker()->Terminate();
}
flag = hippy::global_data_holder.Erase(dom_manager_id);
FOOTSTONE_DCHECK(flag);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,69 @@
import android.view.View;
import androidx.annotation.NonNull;
import android.os.Process;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SuppressWarnings("JavaJniMissingFunction")
public class DomManager implements Connector {

private final int mInstanceId;

public DomManager() {
mInstanceId = createDomManager();
private final int mGroupId;
private static final Map<Integer, List<Integer>> sDomManagerGroup = new HashMap<>();

public DomManager(int groupId) {
int shareDomId = DomManager.getDomIdFromGroup(groupId);
mInstanceId = createDomManager(groupId, shareDomId);
mGroupId = groupId;
addDomManagerToGroup();
}

@Override
public void destroy() {
destroyDomManager(mInstanceId);
removeDomManagerFromGroup();
}

@Override
public int getInstanceId() {
return mInstanceId;
}

public static int getDomIdFromGroup(int groupId) {
List<Integer> group = sDomManagerGroup.get(groupId);
if (group == null || group.isEmpty()) {
return -1;
}
return group.get(0);
}

private void removeDomManagerFromGroup() {
List<Integer> group = sDomManagerGroup.get(mGroupId);
if (group != null) {
try {
group.remove(Integer.valueOf(mInstanceId));
} catch (Exception e) {
e.printStackTrace();
}
}
}

private void addDomManagerToGroup() {
if (mGroupId < 0) {
return;
}
List<Integer> group = sDomManagerGroup.get(mGroupId);
if (group == null) {
group = new ArrayList<>();
group.add(mInstanceId);
sDomManagerGroup.put(mGroupId, group);
} else {
group.add(mInstanceId);
}
}

public void attachToRenderer(@NonNull Connector rendererConnector) {
onAttachToRenderer(mInstanceId, rendererConnector.getInstanceId());
}
Expand Down Expand Up @@ -74,7 +117,7 @@ public void setThreadPrority() {
*
* @return the unique id of native (C++) dom manager
*/
private native int createDomManager();
private native int createDomManager(int groupId, int shareDomId);

/**
* Release native (C++) dom manager instance.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ jint CreateJsDriver(JNIEnv* j_env,
auto param = std::make_shared<V8VMInitParam>();
param->enable_v8_serialization = static_cast<bool>(j_enable_v8_serialization);
param->is_debug = static_cast<bool>(j_is_dev_module);
param->group_id = static_cast<int64_t>(j_group_id);
if (j_vm_init_param) {
jclass cls = j_env->GetObjectClass(j_vm_init_param);
jfieldID init_field = j_env->GetFieldID(cls, "initialHeapSize", "J");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@
import com.tencent.mtt.hippy.views.modal.HippyModalHostManager;
import com.tencent.mtt.hippy.views.modal.HippyModalHostView;
import com.tencent.renderer.FrameworkProxy;
import com.tencent.renderer.NativeRenderContext;
import com.tencent.renderer.component.image.ImageDecoderAdapter;
import com.tencent.renderer.component.text.FontAdapter;
import com.tencent.renderer.node.RenderNode;
Expand Down Expand Up @@ -881,7 +880,7 @@ public HippyEngineContextImpl(@Nullable DomManager domManager) throws RuntimeExc
mBridgeManager = new HippyBridgeManagerImpl(this, mCoreBundleLoader,
getBridgeType(), enableV8Serialization, mDebugMode,
mServerHost, mGroupId, mThirdPartyAdapter, v8InitParams, mJsDriver);
mDomManager = (domManager != null) ? domManager : new DomManager();
mDomManager = (domManager != null) ? domManager : new DomManager(mGroupId);
mRenderer = createRenderer(RenderConnector.NATIVE_RENDERER);
mDomManager.attachToRenderer(mRenderer);
mRenderer.attachToDom(mDomManager);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class HippyEngineWrapper//TODO: Coming soon
initParams.debugMode = isDebug
initParams.enableLog = true
initParams.logAdapter = DefaultLogAdapter()
initParams.groupId = 1
when(driverMode) {
PageConfiguration.DriverMode.JS_REACT -> {
initParams.coreJSAssetsPath = "react/vendor.android.js"
Expand Down
7 changes: 7 additions & 0 deletions modules/footstone/include/footstone/worker.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ class Worker {
inline void SetGroupId(uint32_t id) {
group_id_ = id;
}
inline uint32_t FetchAndSubReuseCount() {
return --reuse_count_;
}
inline uint32_t FetchAndAddReuseCount() {
return ++reuse_count_;
}
static bool IsTaskRunning();
bool RunTask();
void BeforeStart(std::function<void()> before_start) { before_start_ = before_start; }
Expand Down Expand Up @@ -131,6 +137,7 @@ class Worker {
* 不同TaskRunner切换的开销越大,则每个task从加入到执行的延迟可能就越大。
*/
bool is_schedulable_;
uint32_t reuse_count_;
uint32_t group_id_;
std::unique_ptr<Driver> driver_;
};
Expand Down
1 change: 1 addition & 0 deletions modules/footstone/src/worker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Worker::Worker(std::string name, bool is_schedulable, std::unique_ptr<Driver> dr
is_stacking_mode_(false),
has_migration_data_(false),
is_schedulable_(is_schedulable),
reuse_count_(1),
group_id_(0),
driver_(std::move(driver)) {
}
Expand Down
Loading