Skip to content

Commit 84a8e89

Browse files
GregoryComerfacebook-github-bot
authored andcommitted
Introduce PAL function table
Summary: This is part 1 of 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. In the following PR, I update ET callers to do this. Differential Revision: D74121895
1 parent 94f7b10 commit 84a8e89

File tree

3 files changed

+188
-0
lines changed

3 files changed

+188
-0
lines changed

runtime/platform/platform.cpp

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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/platform.h>
10+
#include <cstdlib>
11+
12+
namespace executorch {
13+
namespace runtime {
14+
15+
/**
16+
* The singleton instance of the PAL table.
17+
*/
18+
static pal_table global_pal_table = {
19+
.init = et_pal_init,
20+
.abort = et_pal_abort,
21+
.current_ticks = et_pal_current_ticks,
22+
.ticks_to_ns_multiplier = et_pal_ticks_to_ns_multiplier,
23+
.emit_log_message = et_pal_emit_log_message,
24+
.allocate = et_pal_allocate,
25+
.free = et_pal_free,
26+
};
27+
28+
/**
29+
* Retrieve a pointer to the singleton instance of the PAL function table. This
30+
* can be used to override the default implementations of the PAL functions.
31+
*/
32+
pal_table* get_pal_table() {
33+
return &global_pal_table;
34+
}
35+
36+
void pal_init() {
37+
get_pal_table()->init();
38+
}
39+
40+
ET_NORETURN void pal_abort() {
41+
get_pal_table()->abort();
42+
// This should be unreachable, but in case the PAL implementation doesn't
43+
// abort, force it here.
44+
std::abort();
45+
}
46+
47+
et_timestamp_t pal_current_ticks() {
48+
return get_pal_table()->current_ticks();
49+
}
50+
51+
et_tick_ratio_t pal_ticks_to_ns_multiplier() {
52+
return get_pal_table()->ticks_to_ns_multiplier();
53+
}
54+
55+
void pal_emit_log_message(
56+
et_timestamp_t timestamp,
57+
et_pal_log_level_t level,
58+
const char* filename,
59+
const char* function,
60+
size_t line,
61+
const char* message,
62+
size_t length) {
63+
get_pal_table()->emit_log_message(
64+
timestamp, level, filename, function, line, message, length);
65+
}
66+
67+
void* pal_allocate(size_t size) {
68+
return get_pal_table()->allocate(size);
69+
}
70+
71+
void pal_free(void* ptr) {
72+
get_pal_table()->free(ptr);
73+
}
74+
75+
} // namespace runtime
76+
} // namespace executorch

runtime/platform/platform.h

+111
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
* Platform abstraction layer to allow individual platform libraries to override
1212
* symbols in ExecuTorch. PAL functions are defined as C functions so a platform
1313
* library implementer can use C in lieu of C++.
14+
*
15+
* The et_pal_ methods should not be called directly. Use the corresponding methods
16+
* in the executorch::runtime namespace instead to appropriately dispatch through
17+
* the PAL function table.
1418
*/
1519

1620
#pragma once
@@ -53,19 +57,22 @@ typedef struct {
5357
* to initialize any global state. Typically overridden by PAL implementer.
5458
*/
5559
void et_pal_init(void) ET_INTERNAL_PLATFORM_WEAKNESS;
60+
typedef void (*et_pal_init_t)(void);
5661

5762
/**
5863
* Immediately abort execution, setting the device into an error state, if
5964
* available.
6065
*/
6166
ET_NORETURN void et_pal_abort(void) ET_INTERNAL_PLATFORM_WEAKNESS;
67+
typedef void (*et_pal_abort_t)(void);
6268

6369
/**
6470
* Return a monotonically non-decreasing timestamp in system ticks.
6571
*
6672
* @retval Timestamp value in system ticks.
6773
*/
6874
et_timestamp_t et_pal_current_ticks(void) ET_INTERNAL_PLATFORM_WEAKNESS;
75+
typedef et_timestamp_t (*et_pal_current_ticks_t)(void);
6976

7077
/**
7178
* Return the conversion rate from system ticks to nanoseconds as a fraction.
@@ -79,6 +86,7 @@ et_timestamp_t et_pal_current_ticks(void) ET_INTERNAL_PLATFORM_WEAKNESS;
7986
*
8087
* @retval The ratio of nanoseconds to system ticks.
8188
*/
89+
typedef et_tick_ratio_t (*et_pal_ticks_to_ns_multiplier_t)(void);
8290
et_tick_ratio_t et_pal_ticks_to_ns_multiplier(void)
8391
ET_INTERNAL_PLATFORM_WEAKNESS;
8492

@@ -114,6 +122,14 @@ void et_pal_emit_log_message(
114122
size_t line,
115123
const char* message,
116124
size_t length) ET_INTERNAL_PLATFORM_WEAKNESS;
125+
typedef void (*et_pal_emit_log_message_t)(
126+
et_timestamp_t timestamp,
127+
et_pal_log_level_t level,
128+
const char* filename,
129+
const char* function,
130+
size_t line,
131+
const char* message,
132+
size_t length);
117133

118134
/**
119135
* NOTE: Core runtime code must not call this directly. It may only be called by
@@ -126,12 +142,107 @@ void et_pal_emit_log_message(
126142
* et_pal_free().
127143
*/
128144
void* et_pal_allocate(size_t size) ET_INTERNAL_PLATFORM_WEAKNESS;
145+
typedef void* (*et_pal_allocate_t)(size_t size);
129146

130147
/**
131148
* Frees memory allocated by et_pal_allocate().
132149
*
133150
* @param[in] ptr Pointer to memory to free. May be nullptr.
134151
*/
135152
void et_pal_free(void* ptr) ET_INTERNAL_PLATFORM_WEAKNESS;
153+
typedef void (*et_pal_free_t)(void* ptr);
136154

137155
} // extern "C"
156+
157+
namespace executorch {
158+
namespace runtime {
159+
160+
/**
161+
* Table of pointers to platform abstraction layer functions.
162+
*/
163+
struct pal_table {
164+
et_pal_init_t init;
165+
et_pal_abort_t abort;
166+
et_pal_current_ticks_t current_ticks;
167+
et_pal_ticks_to_ns_multiplier_t ticks_to_ns_multiplier;
168+
et_pal_emit_log_message_t emit_log_message;
169+
et_pal_allocate_t allocate;
170+
et_pal_free_t free;
171+
};
172+
173+
/**
174+
* Retrieve a pointer to the singleton instance of the PAL function table. This
175+
* can be used to override the default implementations of the PAL functions.
176+
*/
177+
pal_table* get_pal_table(void);
178+
179+
/**
180+
* Initialize the platform abstraction layer.
181+
*
182+
* This function should be called before any other function provided by the PAL
183+
* to initialize any global state. Typically overridden by PAL implementer.
184+
*/
185+
void pal_init();
186+
187+
/**
188+
* Immediately abort execution, setting the device into an error state, if
189+
* available.
190+
*/
191+
ET_NORETURN void pal_abort();
192+
193+
/**
194+
* Return a monotonically non-decreasing timestamp in system ticks.
195+
*
196+
* @retval Timestamp value in system ticks.
197+
*/
198+
et_timestamp_t pal_current_ticks();
199+
200+
/**
201+
* Return the conversion rate from system ticks to nanoseconds as a fraction.
202+
* To convert a system ticks to nanoseconds, multiply the tick count by the
203+
* numerator and then divide by the denominator:
204+
* nanoseconds = ticks * numerator / denominator
205+
*
206+
* The utility method executorch::runtime::ticks_to_ns(et_timestamp_t) can also
207+
* be used to perform the conversion for a given tick count. It is defined in
208+
* torch/executor/runtime/platform/clock.h.
209+
*
210+
* @retval The ratio of nanoseconds to system ticks.
211+
*/
212+
et_tick_ratio_t pal_ticks_to_ns_multiplier();
213+
214+
/**
215+
* Severity level of a log message. Values must map to printable 7-bit ASCII
216+
* uppercase letters.
217+
*/
218+
void pal_emit_log_message(
219+
et_timestamp_t timestamp,
220+
et_pal_log_level_t level,
221+
const char* filename,
222+
const char* function,
223+
size_t line,
224+
const char* message,
225+
size_t length);
226+
227+
/**
228+
* NOTE: Core runtime code must not call this directly. It may only be called by
229+
* a MemoryAllocator wrapper.
230+
*
231+
* Allocates size bytes of memory.
232+
*
233+
* @param[in] size Number of bytes to allocate.
234+
* @returns the allocated memory, or nullptr on failure. Must be freed using
235+
* et_pal_free().
236+
*/
237+
void* pal_allocate(size_t size);
238+
239+
/**
240+
* Frees memory allocated by et_pal_allocate().
241+
*
242+
* @param[in] ptr Pointer to memory to free. May be nullptr.
243+
*/
244+
void pal_free(void* ptr);
245+
246+
247+
} // namespace runtime
248+
} // namespace executorch

runtime/platform/targets.bzl

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ def define_common_targets():
7373
srcs = [
7474
"abort.cpp",
7575
"log.cpp",
76+
"platform.cpp",
7677
"profiler.cpp",
7778
"runtime.cpp",
7879
],

0 commit comments

Comments
 (0)