-
Notifications
You must be signed in to change notification settings - Fork 873
Expand file tree
/
Copy pathposix.cpp
More file actions
216 lines (194 loc) · 6.49 KB
/
posix.cpp
File metadata and controls
216 lines (194 loc) · 6.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @file
* Fallback PAL implementations for POSIX-compatible systems.
*
* Note that this assumes that the platform defines the symbols used in this
* file (like fprintf()), because this file will still be built even if the
* functions are later overridden. When building for a platform that does not
* provide the necessary symbols, clients can use Minimal.cpp instead, but they
* will need to override all of the functions.
*/
// This cpp file will provide weak implementations of the symbols declared in
// Platform.h. Client users can strongly define any or all of the functions to
// override them.
#define ET_INTERNAL_PLATFORM_WEAKNESS ET_WEAK
#include <executorch/runtime/platform/platform.h>
#include <chrono>
#include <cinttypes>
#include <cstdio>
#include <cstdlib>
#include <executorch/runtime/platform/compiler.h>
// The FILE* to write logs to.
#define ET_LOG_OUTPUT_FILE stderr
/**
* On debug builds, ensure that `et_pal_init` has been called before
* other PAL functions which depend on initialization.
*/
#ifdef NDEBUG
/**
* Assert that the PAL has been initialized.
*/
#define _ASSERT_PAL_INITIALIZED() ((void)0)
#else // NDEBUG
/**
* Assert that the PAL has been initialized.
*/
#define _ASSERT_PAL_INITIALIZED() \
do { \
if (!initialized) { \
fprintf( \
ET_LOG_OUTPUT_FILE, \
"ExecuTorch PAL must be initialized before call to %s()", \
ET_FUNCTION); \
fflush(ET_LOG_OUTPUT_FILE); \
et_pal_abort(); \
} \
} while (0)
#endif // NDEBUG
/// Start time of the system (used to zero the system timestamp).
static std::chrono::time_point<std::chrono::steady_clock> systemStartTime;
/// Flag set to true if the PAL has been successfully initialized.
static bool initialized = false;
/**
* Initialize the platform abstraction layer.
*
* This function should be called before any other function provided by the PAL
* to initialize any global state. Typically overridden by PAL implementer.
*/
#ifdef _MSC_VER
#pragma weak et_pal_init
#endif // _MSC_VER
void et_pal_init(void) {
if (initialized) {
return;
}
systemStartTime = std::chrono::steady_clock::now();
initialized = true;
}
/**
* Immediately abort execution, setting the device into an error state, if
* available.
*/
#ifdef _MSC_VER
#pragma weak et_pal_abort
#endif // _MSC_VER
ET_NORETURN void et_pal_abort(void) {
std::abort();
}
/**
* Return a monotonically non-decreasing timestamp in system ticks.
*
* @retval Timestamp value in system ticks.
*/
#ifdef _MSC_VER
#pragma weak et_pal_current_ticks
#endif // _MSC_VER
et_timestamp_t et_pal_current_ticks(void) {
_ASSERT_PAL_INITIALIZED();
auto systemCurrentTime = std::chrono::steady_clock::now();
return std::chrono::duration_cast<std::chrono::nanoseconds>(
systemCurrentTime - systemStartTime)
.count();
}
/**
* Return the conversion rate from system ticks to nanoseconds, as a fraction.
* To convert an interval from system ticks to nanoseconds, multiply the tick
* count by the numerator and then divide by the denominator:
* nanoseconds = ticks * numerator / denominator
*
* @retval The ratio of nanoseconds to system ticks.
*/
#ifdef _MSC_VER
#pragma weak et_pal_ticks_to_ns_multiplier
#endif // _MSC_VER
et_tick_ratio_t et_pal_ticks_to_ns_multiplier(void) {
// The system tick interval is 1 nanosecond, so the conversion factor is 1.
return {1, 1};
}
/**
* Emit a log message via platform output (serial port, console, etc).
*
* @param[in] timestamp Timestamp of the log event in system ticks since boot.
* @param[in] level Severity level of the message. Must be a printable 7-bit
* ASCII uppercase letter.
* @param[in] filename Name of the file that created the log event.
* @param[in] function Name of the function that created the log event.
* @param[in] line Line in the source file where the log event was created.
* @param[in] message Message string to log.
* @param[in] length Message string length.
*/
#ifdef _MSC_VER
#pragma weak et_pal_emit_log_message
#endif // _MSC_VER
void et_pal_emit_log_message(
et_timestamp_t timestamp,
et_pal_log_level_t level,
const char* filename,
ET_UNUSED const char* function,
size_t line,
const char* message,
ET_UNUSED size_t length) {
_ASSERT_PAL_INITIALIZED();
// Not all platforms have ticks == nanoseconds, but this one does.
timestamp /= 1000; // To microseconds
unsigned long int us = timestamp % 1000000;
timestamp /= 1000000; // To seconds
unsigned int sec = timestamp % 60;
timestamp /= 60; // To minutes
unsigned int min = timestamp % 60;
timestamp /= 60; // To hours
unsigned int hour = timestamp;
// Use a format similar to glog and folly::logging, except:
// - Print time since et_pal_init since we don't have wall time
// - Don't include the thread ID, to avoid adding a threading dependency
// - Add the string "executorch:" to make the logs more searchable
//
// Clients who want to change the format or add other fields can override this
// weak implementation of et_pal_emit_log_message.
fprintf(
ET_LOG_OUTPUT_FILE,
"%c %02u:%02u:%02u.%06lu executorch:%s:%zu] %s\n",
level,
hour,
min,
sec,
us,
filename,
line,
message);
fflush(ET_LOG_OUTPUT_FILE);
}
/**
* NOTE: Core runtime code must not call this directly. It may only be called by
* a MemoryAllocator wrapper.
*
* Allocates size bytes of memory via malloc.
*
* @param[in] size Number of bytes to allocate.
* @returns the allocated memory, or nullptr on failure. Must be freed using
* et_pal_free().
*/
#ifdef _MSC_VER
#pragma weak et_pal_allocate
#endif // _MSC_VER
void* et_pal_allocate(size_t size) {
return malloc(size);
}
/**
* Frees memory allocated by et_pal_allocate().
*
* @param[in] ptr Pointer to memory to free. May be nullptr.
*/
#ifdef _MSC_VER
#pragma weak et_pal_free
#endif // _MSC_VER
void et_pal_free(void* ptr) {
free(ptr);
}