Skip to content

Commit 20fd1b2

Browse files
committed
Introduce PAL function table (#10675)
Summary: This is the implementation of the PAL changes described in #10432. This PR introduces a struct (`pal_table`) to hold function pointers to the PAL function implementations. There is a singleton instance of this struct, which is initialized with the weak/strong et_pal_ functions - maintaining backwards compatibility with the existing override mechanism. I've then added wrapper functions for the PAL into the executorch::runtime namespace which dispatch through the function table. It is intended that callers use these functions instead of the "raw" et_pal_ methods in order to correctly dispatch through the function table. I also update ET callers to do this. Differential Revision: D74121895
1 parent 6cceab6 commit 20fd1b2

File tree

15 files changed

+650
-87
lines changed

15 files changed

+650
-87
lines changed

backends/xnnpack/runtime/profiling/XNNProfiler.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ Error XNNProfiler::start(EventTracer* event_tracer) {
6262
state_ = XNNProfilerState::Running;
6363

6464
// Log the start of execution timestamp.
65-
start_time_ = et_pal_current_ticks();
65+
start_time_ = runtime::pal_current_ticks();
6666

6767
return Error::Ok;
6868
}
@@ -187,7 +187,7 @@ void XNNProfiler::log_operator_timings() {
187187

188188
void XNNProfiler::submit_trace() {
189189
// Retrieve the system tick rate (ratio between ticks and nanoseconds).
190-
auto tick_ns_conv_multiplier = et_pal_ticks_to_ns_multiplier();
190+
auto tick_ns_conv_multiplier = runtime::pal_ticks_to_ns_multiplier();
191191

192192
ET_CHECK(op_timings_.size() == op_count_);
193193
size_t name_len = 0;

devtools/etdump/etdump_flatcc.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ EventTracerEntry ETDumpGen::start_profiling(
224224
prof_entry.chain_id = chain_id;
225225
prof_entry.debug_handle = debug_handle;
226226
}
227-
prof_entry.start_time = et_pal_current_ticks();
227+
prof_entry.start_time = runtime::pal_current_ticks();
228228
return prof_entry;
229229
}
230230

@@ -246,15 +246,15 @@ EventTracerEntry ETDumpGen::start_profiling_delegate(
246246
prof_entry.event_id = delegate_debug_index == kUnsetDelegateDebugIntId
247247
? create_string_entry(name)
248248
: delegate_debug_index;
249-
prof_entry.start_time = et_pal_current_ticks();
249+
prof_entry.start_time = runtime::pal_current_ticks();
250250
return prof_entry;
251251
}
252252

253253
void ETDumpGen::end_profiling_delegate(
254254
EventTracerEntry event_tracer_entry,
255255
const void* metadata,
256256
size_t metadata_len) {
257-
et_timestamp_t end_time = et_pal_current_ticks();
257+
et_timestamp_t end_time = runtime::pal_current_ticks();
258258
check_ready_to_add_events();
259259

260260
// Start building the ProfileEvent entry.
@@ -463,7 +463,7 @@ Result<bool> ETDumpGen::log_intermediate_output_delegate_helper(
463463
}
464464

465465
void ETDumpGen::end_profiling(EventTracerEntry prof_entry) {
466-
et_timestamp_t end_time = et_pal_current_ticks();
466+
et_timestamp_t end_time = runtime::pal_current_ticks();
467467
ET_CHECK_MSG(
468468
prof_entry.delegate_event_id_type == DelegateDebugIdType::kNone,
469469
"Delegate events must use end_profiling_delegate to mark the end of a delegate profiling event.");

examples/portable/executor_runner/executor_runner.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,11 @@ int main(int argc, char** argv) {
269269
(uint32_t)inputs.error());
270270
ET_LOG(Debug, "Inputs prepared.");
271271

272-
const et_timestamp_t before_execute = et_pal_current_ticks();
272+
const et_timestamp_t before_execute =
273+
executorch::runtime::pal_current_ticks();
273274
Error status = method->execute();
274-
const et_timestamp_t after_execute = et_pal_current_ticks();
275+
const et_timestamp_t after_execute =
276+
executorch::runtime::pal_current_ticks();
275277
time_spent_executing += after_execute - before_execute;
276278
ET_CHECK_MSG(
277279
status == Error::Ok,

runtime/executor/platform_memory_allocator.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class PlatformMemoryAllocator final : public MemoryAllocator {
4848

4949
// Allocate enough memory for the node, the data and the alignment bump.
5050
size_t alloc_size = sizeof(AllocationNode) + size + alignment;
51-
void* node_memory = et_pal_allocate(alloc_size);
51+
void* node_memory = runtime::pal_allocate(alloc_size);
5252

5353
// If allocation failed, log message and return nullptr.
5454
if (node_memory == nullptr) {
@@ -87,7 +87,7 @@ class PlatformMemoryAllocator final : public MemoryAllocator {
8787
AllocationNode* current = head_;
8888
while (current != nullptr) {
8989
AllocationNode* next = current->next;
90-
et_pal_free(current);
90+
runtime::pal_free(current);
9191
current = next;
9292
}
9393
head_ = nullptr;

runtime/platform/abort.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace runtime {
1717
* up, and set an abnormal exit status (platform-defined).
1818
*/
1919
ET_NORETURN void runtime_abort() {
20-
et_pal_abort();
20+
pal_abort();
2121
}
2222

2323
} // namespace runtime

runtime/platform/log.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace internal {
2323
* @retval Monotonically non-decreasing timestamp in system ticks.
2424
*/
2525
et_timestamp_t get_log_timestamp() {
26-
return et_pal_current_ticks();
26+
return pal_current_ticks();
2727
}
2828

2929
// Double-check that the log levels are ordered from lowest to highest severity.
@@ -96,7 +96,7 @@ void vlogf(
9696
? kLevelToPal[size_t(level)]
9797
: et_pal_log_level_t::kUnknown;
9898

99-
et_pal_emit_log_message(
99+
pal_emit_log_message(
100100
timestamp, pal_level, filename, function, line, buf, len);
101101

102102
#endif // ET_LOG_ENABLED

runtime/platform/platform.cpp

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
#include <executorch/runtime/platform/log.h>
10+
#include <executorch/runtime/platform/platform.h>
11+
#include <cstdlib>
12+
13+
namespace executorch {
14+
namespace runtime {
15+
16+
namespace {
17+
/**
18+
* The singleton instance of the PAL function table.
19+
*/
20+
pal_table pal_impl = {
21+
et_pal_init,
22+
et_pal_abort,
23+
et_pal_current_ticks,
24+
et_pal_ticks_to_ns_multiplier,
25+
et_pal_emit_log_message,
26+
et_pal_allocate,
27+
et_pal_free,
28+
__FILE__};
29+
30+
/**
31+
* Tracks whether the PAL has been overridden. This is used to warn when
32+
* multiple callers override the PAL.
33+
*/
34+
bool is_pal_overridden = false;
35+
} // namespace
36+
37+
pal_table pal_table::create(
38+
et_pal_emit_log_message_t emit_log_message,
39+
const char* source_filename) {
40+
return pal_table::create(
41+
nullptr, // init
42+
nullptr, // abort
43+
nullptr, // current_ticks
44+
nullptr, // ticks_to_ns_multiplier
45+
emit_log_message,
46+
nullptr, // allocate
47+
nullptr, // free
48+
source_filename);
49+
}
50+
51+
pal_table pal_table::create(
52+
et_pal_init_t init,
53+
et_pal_abort_t abort,
54+
et_pal_current_ticks_t current_ticks,
55+
et_pal_ticks_to_ns_multiplier_t ticks_to_ns_multiplier,
56+
et_pal_emit_log_message_t emit_log_message,
57+
et_pal_allocate_t allocate,
58+
et_pal_free_t free,
59+
const char* source_filename) {
60+
return pal_table{
61+
init,
62+
abort,
63+
current_ticks,
64+
ticks_to_ns_multiplier,
65+
emit_log_message,
66+
allocate,
67+
free,
68+
source_filename};
69+
}
70+
71+
/**
72+
* Override the PAL functions with user implementations. Any null entries in the
73+
* table are unchanged and will keep the default implementation.
74+
*/
75+
bool register_pal(pal_table impl) {
76+
if (is_pal_overridden) {
77+
ET_LOG(
78+
Error,
79+
"register_pal() called multiple times. Subsequent calls will override the previous implementation. Previous implementation was registered from %s.",
80+
impl.source_filename != nullptr ? impl.source_filename : "unknown");
81+
}
82+
is_pal_overridden = true;
83+
84+
if (impl.abort != nullptr) {
85+
pal_impl.abort = impl.abort;
86+
}
87+
88+
if (impl.current_ticks != nullptr) {
89+
pal_impl.current_ticks = impl.current_ticks;
90+
}
91+
92+
if (impl.ticks_to_ns_multiplier != nullptr) {
93+
pal_impl.ticks_to_ns_multiplier = impl.ticks_to_ns_multiplier;
94+
}
95+
96+
if (impl.emit_log_message != nullptr) {
97+
pal_impl.emit_log_message = impl.emit_log_message;
98+
}
99+
100+
if (impl.allocate != nullptr) {
101+
pal_impl.allocate = impl.allocate;
102+
}
103+
104+
if (impl.free != nullptr) {
105+
pal_impl.free = impl.free;
106+
}
107+
108+
if (impl.init != nullptr) {
109+
pal_impl.init = impl.init;
110+
if (pal_impl.init != nullptr) {
111+
pal_impl.init();
112+
}
113+
}
114+
115+
return true;
116+
}
117+
118+
const pal_table* get_pal_impl() {
119+
return &pal_impl;
120+
}
121+
122+
void pal_init() {
123+
pal_impl.init();
124+
}
125+
126+
ET_NORETURN void pal_abort() {
127+
pal_impl.abort();
128+
// This should be unreachable, but in case the PAL implementation doesn't
129+
// abort, force it here.
130+
std::abort();
131+
}
132+
133+
et_timestamp_t pal_current_ticks() {
134+
return pal_impl.current_ticks();
135+
}
136+
137+
et_tick_ratio_t pal_ticks_to_ns_multiplier() {
138+
return pal_impl.ticks_to_ns_multiplier();
139+
}
140+
141+
void pal_emit_log_message(
142+
et_timestamp_t timestamp,
143+
et_pal_log_level_t level,
144+
const char* filename,
145+
const char* function,
146+
size_t line,
147+
const char* message,
148+
size_t length) {
149+
pal_impl.emit_log_message(
150+
timestamp, level, filename, function, line, message, length);
151+
}
152+
153+
void* pal_allocate(size_t size) {
154+
return pal_impl.allocate(size);
155+
}
156+
157+
void pal_free(void* ptr) {
158+
pal_impl.free(ptr);
159+
}
160+
161+
} // namespace runtime
162+
} // namespace executorch

0 commit comments

Comments
 (0)