xref: /aosp_15_r20/external/XNNPACK/src/log.c (revision 4bdc94577ba0e567308109d787f7fec7b531ce36)
1*4bdc9457SAndroid Build Coastguard Worker // Copyright (c) Facebook, Inc. and its affiliates.
2*4bdc9457SAndroid Build Coastguard Worker // All rights reserved.
3*4bdc9457SAndroid Build Coastguard Worker //
4*4bdc9457SAndroid Build Coastguard Worker // Copyright 2022 Google LLC
5*4bdc9457SAndroid Build Coastguard Worker //
6*4bdc9457SAndroid Build Coastguard Worker // This source code is licensed under the BSD-style license found in the
7*4bdc9457SAndroid Build Coastguard Worker // LICENSE file in the root directory of this source tree.
8*4bdc9457SAndroid Build Coastguard Worker 
9*4bdc9457SAndroid Build Coastguard Worker #include <assert.h>
10*4bdc9457SAndroid Build Coastguard Worker #include <stdarg.h>
11*4bdc9457SAndroid Build Coastguard Worker #include <string.h>
12*4bdc9457SAndroid Build Coastguard Worker #include <stdlib.h>
13*4bdc9457SAndroid Build Coastguard Worker #include <stdio.h>
14*4bdc9457SAndroid Build Coastguard Worker #ifdef _WIN32
15*4bdc9457SAndroid Build Coastguard Worker   #include <windows.h>
16*4bdc9457SAndroid Build Coastguard Worker #else
17*4bdc9457SAndroid Build Coastguard Worker   #include <unistd.h>
18*4bdc9457SAndroid Build Coastguard Worker #endif
19*4bdc9457SAndroid Build Coastguard Worker #if defined(__ANDROID__)
20*4bdc9457SAndroid Build Coastguard Worker   #include <android/log.h>
21*4bdc9457SAndroid Build Coastguard Worker #endif
22*4bdc9457SAndroid Build Coastguard Worker 
23*4bdc9457SAndroid Build Coastguard Worker #ifndef XNN_LOG_TO_STDIO
24*4bdc9457SAndroid Build Coastguard Worker   #if defined(__ANDROID__)
25*4bdc9457SAndroid Build Coastguard Worker     #define XNN_LOG_TO_STDIO 0
26*4bdc9457SAndroid Build Coastguard Worker   #else
27*4bdc9457SAndroid Build Coastguard Worker     #define XNN_LOG_TO_STDIO 1
28*4bdc9457SAndroid Build Coastguard Worker   #endif
29*4bdc9457SAndroid Build Coastguard Worker #endif
30*4bdc9457SAndroid Build Coastguard Worker 
31*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/log.h>
32*4bdc9457SAndroid Build Coastguard Worker 
33*4bdc9457SAndroid Build Coastguard Worker 
34*4bdc9457SAndroid Build Coastguard Worker /* Messages up to this size are formatted entirely on-stack, and don't allocate heap memory */
35*4bdc9457SAndroid Build Coastguard Worker #define XNN_LOG_STACK_BUFFER_SIZE 1024
36*4bdc9457SAndroid Build Coastguard Worker 
37*4bdc9457SAndroid Build Coastguard Worker #ifdef _WIN32
38*4bdc9457SAndroid Build Coastguard Worker   #define XNN_LOG_NEWLINE_LENGTH 2
39*4bdc9457SAndroid Build Coastguard Worker 
40*4bdc9457SAndroid Build Coastguard Worker   #define XNN_LOG_STDERR STD_ERROR_HANDLE
41*4bdc9457SAndroid Build Coastguard Worker   #define XNN_LOG_STDOUT STD_OUTPUT_HANDLE
42*4bdc9457SAndroid Build Coastguard Worker #else
43*4bdc9457SAndroid Build Coastguard Worker   #define XNN_LOG_NEWLINE_LENGTH 1
44*4bdc9457SAndroid Build Coastguard Worker 
45*4bdc9457SAndroid Build Coastguard Worker   #define XNN_LOG_STDERR STDERR_FILENO
46*4bdc9457SAndroid Build Coastguard Worker   #define XNN_LOG_STDOUT STDOUT_FILENO
47*4bdc9457SAndroid Build Coastguard Worker #endif
48*4bdc9457SAndroid Build Coastguard Worker 
49*4bdc9457SAndroid Build Coastguard Worker #if XNN_LOG_TO_STDIO
xnn_vlog(int output_handle,const char * prefix,size_t prefix_length,const char * format,va_list args)50*4bdc9457SAndroid Build Coastguard Worker static void xnn_vlog(int output_handle, const char* prefix, size_t prefix_length, const char* format, va_list args) {
51*4bdc9457SAndroid Build Coastguard Worker   char stack_buffer[XNN_LOG_STACK_BUFFER_SIZE];
52*4bdc9457SAndroid Build Coastguard Worker   char* heap_buffer = NULL;
53*4bdc9457SAndroid Build Coastguard Worker   char* out_buffer = &stack_buffer[0];
54*4bdc9457SAndroid Build Coastguard Worker 
55*4bdc9457SAndroid Build Coastguard Worker   /* The first call to vsnprintf will clobber args, thus need a copy in case a second vsnprintf call is needed */
56*4bdc9457SAndroid Build Coastguard Worker   va_list args_copy;
57*4bdc9457SAndroid Build Coastguard Worker   va_copy(args_copy, args);
58*4bdc9457SAndroid Build Coastguard Worker 
59*4bdc9457SAndroid Build Coastguard Worker   memcpy(stack_buffer, prefix, prefix_length * sizeof(char));
60*4bdc9457SAndroid Build Coastguard Worker   assert((prefix_length + XNN_LOG_NEWLINE_LENGTH) * sizeof(char) <= XNN_LOG_STACK_BUFFER_SIZE);
61*4bdc9457SAndroid Build Coastguard Worker 
62*4bdc9457SAndroid Build Coastguard Worker   const int format_chars = vsnprintf(
63*4bdc9457SAndroid Build Coastguard Worker     &stack_buffer[prefix_length],
64*4bdc9457SAndroid Build Coastguard Worker     XNN_LOG_STACK_BUFFER_SIZE - (prefix_length + XNN_LOG_NEWLINE_LENGTH) * sizeof(char),
65*4bdc9457SAndroid Build Coastguard Worker     format,
66*4bdc9457SAndroid Build Coastguard Worker     args);
67*4bdc9457SAndroid Build Coastguard Worker   if (format_chars < 0) {
68*4bdc9457SAndroid Build Coastguard Worker     /* Format error in the message: silently ignore this particular message. */
69*4bdc9457SAndroid Build Coastguard Worker     goto cleanup;
70*4bdc9457SAndroid Build Coastguard Worker   }
71*4bdc9457SAndroid Build Coastguard Worker   const size_t format_length = (size_t) format_chars;
72*4bdc9457SAndroid Build Coastguard Worker   if ((prefix_length + format_length + XNN_LOG_NEWLINE_LENGTH) * sizeof(char) > XNN_LOG_STACK_BUFFER_SIZE) {
73*4bdc9457SAndroid Build Coastguard Worker     /* Allocate a buffer on heap, and vsnprintf to this buffer */
74*4bdc9457SAndroid Build Coastguard Worker     const size_t heap_buffer_size = (prefix_length + format_length + XNN_LOG_NEWLINE_LENGTH) * sizeof(char);
75*4bdc9457SAndroid Build Coastguard Worker     #if _WIN32
76*4bdc9457SAndroid Build Coastguard Worker       heap_buffer = HeapAlloc(GetProcessHeap(), 0, heap_buffer_size);
77*4bdc9457SAndroid Build Coastguard Worker     #else
78*4bdc9457SAndroid Build Coastguard Worker       heap_buffer = malloc(heap_buffer_size);
79*4bdc9457SAndroid Build Coastguard Worker     #endif
80*4bdc9457SAndroid Build Coastguard Worker     if (heap_buffer == NULL) {
81*4bdc9457SAndroid Build Coastguard Worker       goto cleanup;
82*4bdc9457SAndroid Build Coastguard Worker     }
83*4bdc9457SAndroid Build Coastguard Worker 
84*4bdc9457SAndroid Build Coastguard Worker     /* Copy pre-formatted prefix into the on-heap buffer */
85*4bdc9457SAndroid Build Coastguard Worker     memcpy(heap_buffer, prefix, prefix_length * sizeof(char));
86*4bdc9457SAndroid Build Coastguard Worker     vsnprintf(&heap_buffer[prefix_length], (format_length + XNN_LOG_NEWLINE_LENGTH) * sizeof(char), format, args_copy);
87*4bdc9457SAndroid Build Coastguard Worker     out_buffer = heap_buffer;
88*4bdc9457SAndroid Build Coastguard Worker   }
89*4bdc9457SAndroid Build Coastguard Worker   #ifdef _WIN32
90*4bdc9457SAndroid Build Coastguard Worker     out_buffer[prefix_length + format_length] = '\r';
91*4bdc9457SAndroid Build Coastguard Worker     out_buffer[prefix_length + format_length + 1] = '\n';
92*4bdc9457SAndroid Build Coastguard Worker 
93*4bdc9457SAndroid Build Coastguard Worker     DWORD bytes_written;
94*4bdc9457SAndroid Build Coastguard Worker     WriteFile(
95*4bdc9457SAndroid Build Coastguard Worker       GetStdHandle((DWORD) output_handle),
96*4bdc9457SAndroid Build Coastguard Worker       out_buffer, (prefix_length + format_length + XNN_LOG_NEWLINE_LENGTH) * sizeof(char),
97*4bdc9457SAndroid Build Coastguard Worker       &bytes_written, NULL);
98*4bdc9457SAndroid Build Coastguard Worker   #else
99*4bdc9457SAndroid Build Coastguard Worker     out_buffer[prefix_length + format_length] = '\n';
100*4bdc9457SAndroid Build Coastguard Worker 
101*4bdc9457SAndroid Build Coastguard Worker     ssize_t bytes_written = write(output_handle, out_buffer, (prefix_length + format_length + XNN_LOG_NEWLINE_LENGTH) * sizeof(char));
102*4bdc9457SAndroid Build Coastguard Worker     (void) bytes_written;
103*4bdc9457SAndroid Build Coastguard Worker   #endif
104*4bdc9457SAndroid Build Coastguard Worker 
105*4bdc9457SAndroid Build Coastguard Worker cleanup:
106*4bdc9457SAndroid Build Coastguard Worker   #ifdef _WIN32
107*4bdc9457SAndroid Build Coastguard Worker     HeapFree(GetProcessHeap(), 0, heap_buffer);
108*4bdc9457SAndroid Build Coastguard Worker   #else
109*4bdc9457SAndroid Build Coastguard Worker     free(heap_buffer);
110*4bdc9457SAndroid Build Coastguard Worker   #endif
111*4bdc9457SAndroid Build Coastguard Worker   va_end(args_copy);
112*4bdc9457SAndroid Build Coastguard Worker }
113*4bdc9457SAndroid Build Coastguard Worker #elif defined(__ANDROID__)
114*4bdc9457SAndroid Build Coastguard Worker   static const char xnnpack_module[] = "XNNPACK";
115*4bdc9457SAndroid Build Coastguard Worker #endif
116*4bdc9457SAndroid Build Coastguard Worker 
117*4bdc9457SAndroid Build Coastguard Worker #if XNN_LOG_LEVEL >= XNN_LOG_DEBUG
xnn_vlog_debug(const char * format,va_list args)118*4bdc9457SAndroid Build Coastguard Worker   void xnn_vlog_debug(const char* format, va_list args) {
119*4bdc9457SAndroid Build Coastguard Worker     #if XNN_LOG_TO_STDIO
120*4bdc9457SAndroid Build Coastguard Worker       static const char debug_prefix[17] = {
121*4bdc9457SAndroid Build Coastguard Worker         'D', 'e', 'b', 'u', 'g', ' ', '(', 'X', 'N', 'N', 'P', 'A', 'C', 'K', ')', ':', ' '
122*4bdc9457SAndroid Build Coastguard Worker       };
123*4bdc9457SAndroid Build Coastguard Worker       xnn_vlog(XNN_LOG_STDOUT, debug_prefix, 17, format, args);
124*4bdc9457SAndroid Build Coastguard Worker     #elif defined(__ANDROID__)
125*4bdc9457SAndroid Build Coastguard Worker       __android_log_vprint(ANDROID_LOG_DEBUG, xnnpack_module, format, args);
126*4bdc9457SAndroid Build Coastguard Worker     #else
127*4bdc9457SAndroid Build Coastguard Worker       #error "Platform-specific implementation required"
128*4bdc9457SAndroid Build Coastguard Worker     #endif
129*4bdc9457SAndroid Build Coastguard Worker   }
130*4bdc9457SAndroid Build Coastguard Worker #endif
131*4bdc9457SAndroid Build Coastguard Worker 
132*4bdc9457SAndroid Build Coastguard Worker #if XNN_LOG_LEVEL >= XNN_LOG_INFO
xnn_vlog_info(const char * format,va_list args)133*4bdc9457SAndroid Build Coastguard Worker   void xnn_vlog_info(const char* format, va_list args) {
134*4bdc9457SAndroid Build Coastguard Worker     #if XNN_LOG_TO_STDIO
135*4bdc9457SAndroid Build Coastguard Worker       static const char info_prefix[16] = {
136*4bdc9457SAndroid Build Coastguard Worker         'N', 'o', 't', 'e', ' ', '(', 'X', 'N', 'N', 'P', 'A', 'C', 'K', ')', ':', ' '
137*4bdc9457SAndroid Build Coastguard Worker       };
138*4bdc9457SAndroid Build Coastguard Worker       xnn_vlog(XNN_LOG_STDOUT, info_prefix, 16, format, args);
139*4bdc9457SAndroid Build Coastguard Worker     #elif defined(__ANDROID__)
140*4bdc9457SAndroid Build Coastguard Worker       __android_log_vprint(ANDROID_LOG_INFO, xnnpack_module, format, args);
141*4bdc9457SAndroid Build Coastguard Worker     #else
142*4bdc9457SAndroid Build Coastguard Worker       #error "Platform-specific implementation required"
143*4bdc9457SAndroid Build Coastguard Worker     #endif
144*4bdc9457SAndroid Build Coastguard Worker   }
145*4bdc9457SAndroid Build Coastguard Worker #endif
146*4bdc9457SAndroid Build Coastguard Worker 
147*4bdc9457SAndroid Build Coastguard Worker #if XNN_LOG_LEVEL >= XNN_LOG_WARNING
xnn_vlog_warning(const char * format,va_list args)148*4bdc9457SAndroid Build Coastguard Worker   void xnn_vlog_warning(const char* format, va_list args) {
149*4bdc9457SAndroid Build Coastguard Worker     #if XNN_LOG_TO_STDIO
150*4bdc9457SAndroid Build Coastguard Worker       static const char warning_prefix[20] = {
151*4bdc9457SAndroid Build Coastguard Worker         'W', 'a', 'r', 'n', 'i', 'n', 'g', ' ', 'i', 'n', ' ', 'X', 'N', 'N', 'P', 'A', 'C', 'K', ':', ' '
152*4bdc9457SAndroid Build Coastguard Worker       };
153*4bdc9457SAndroid Build Coastguard Worker       xnn_vlog(XNN_LOG_STDERR, warning_prefix, 20, format, args);
154*4bdc9457SAndroid Build Coastguard Worker     #elif defined(__ANDROID__)
155*4bdc9457SAndroid Build Coastguard Worker       __android_log_vprint(ANDROID_LOG_WARN, xnnpack_module, format, args);
156*4bdc9457SAndroid Build Coastguard Worker     #else
157*4bdc9457SAndroid Build Coastguard Worker       #error "Platform-specific implementation required"
158*4bdc9457SAndroid Build Coastguard Worker     #endif
159*4bdc9457SAndroid Build Coastguard Worker   }
160*4bdc9457SAndroid Build Coastguard Worker #endif
161*4bdc9457SAndroid Build Coastguard Worker 
162*4bdc9457SAndroid Build Coastguard Worker #if XNN_LOG_LEVEL >= XNN_LOG_ERROR
xnn_vlog_error(const char * format,va_list args)163*4bdc9457SAndroid Build Coastguard Worker   void xnn_vlog_error(const char* format, va_list args) {
164*4bdc9457SAndroid Build Coastguard Worker     #if XNN_LOG_TO_STDIO
165*4bdc9457SAndroid Build Coastguard Worker       static const char error_prefix[18] = {
166*4bdc9457SAndroid Build Coastguard Worker         'E', 'r', 'r', 'o', 'r', ' ', 'i', 'n', ' ', 'X', 'N', 'N', 'P', 'A', 'C', 'K', ':', ' '
167*4bdc9457SAndroid Build Coastguard Worker       };
168*4bdc9457SAndroid Build Coastguard Worker       xnn_vlog(XNN_LOG_STDERR, error_prefix, 18, format, args);
169*4bdc9457SAndroid Build Coastguard Worker     #elif defined(__ANDROID__)
170*4bdc9457SAndroid Build Coastguard Worker       __android_log_vprint(ANDROID_LOG_ERROR, xnnpack_module, format, args);
171*4bdc9457SAndroid Build Coastguard Worker     #else
172*4bdc9457SAndroid Build Coastguard Worker       #error "Platform-specific implementation required"
173*4bdc9457SAndroid Build Coastguard Worker     #endif
174*4bdc9457SAndroid Build Coastguard Worker   }
175*4bdc9457SAndroid Build Coastguard Worker #endif
176*4bdc9457SAndroid Build Coastguard Worker 
177*4bdc9457SAndroid Build Coastguard Worker #if XNN_LOG_LEVEL >= XNN_LOG_FATAL
xnn_vlog_fatal(const char * format,va_list args)178*4bdc9457SAndroid Build Coastguard Worker   void xnn_vlog_fatal(const char* format, va_list args) {
179*4bdc9457SAndroid Build Coastguard Worker     #if XNN_LOG_TO_STDIO
180*4bdc9457SAndroid Build Coastguard Worker       static const char fatal_prefix[24] = {
181*4bdc9457SAndroid Build Coastguard Worker         'F', 'a', 't', 'a', 'l', ' ', 'e', 'r', 'r', 'o', 'r', ' ', 'i', 'n', ' ', 'X', 'N', 'N', 'P', 'A', 'C', 'K', ':', ' '
182*4bdc9457SAndroid Build Coastguard Worker       };
183*4bdc9457SAndroid Build Coastguard Worker       xnn_vlog(XNN_LOG_STDERR, fatal_prefix, 24, format, args);
184*4bdc9457SAndroid Build Coastguard Worker     #elif defined(__ANDROID__)
185*4bdc9457SAndroid Build Coastguard Worker       __android_log_vprint(ANDROID_LOG_FATAL, xnnpack_module, format, args);
186*4bdc9457SAndroid Build Coastguard Worker     #else
187*4bdc9457SAndroid Build Coastguard Worker       #error "Platform-specific implementation required"
188*4bdc9457SAndroid Build Coastguard Worker     #endif
189*4bdc9457SAndroid Build Coastguard Worker   }
190*4bdc9457SAndroid Build Coastguard Worker #endif
191