Coverage Report

Created: 2024-05-04 12:45

/proc/self/cwd/external/cpuinfo/src/log.c
Line
Count
Source (jump to first uncovered line)
1
#include <assert.h>
2
#include <stdarg.h>
3
#include <string.h>
4
#include <stdlib.h>
5
#include <stdio.h>
6
#ifdef _WIN32
7
  #include <windows.h>
8
#else
9
  #include <unistd.h>
10
#endif
11
#if defined(__ANDROID__)
12
  #include <android/log.h>
13
#endif
14
#if defined(__hexagon__)
15
  #include <qurt_printf.h>
16
#endif
17
18
#ifndef CPUINFO_LOG_TO_STDIO
19
  #if defined(__ANDROID__)
20
    #define CPUINFO_LOG_TO_STDIO 0
21
  #else
22
    #define CPUINFO_LOG_TO_STDIO 1
23
  #endif
24
#endif
25
26
#include <cpuinfo/log.h>
27
28
29
/* Messages up to this size are formatted entirely on-stack, and don't allocate heap memory */
30
0
#define CPUINFO_LOG_STACK_BUFFER_SIZE 1024
31
32
#ifdef _WIN32
33
  #define CPUINFO_LOG_NEWLINE_LENGTH 2
34
35
  #define CPUINFO_LOG_STDERR STD_ERROR_HANDLE
36
  #define CPUINFO_LOG_STDOUT STD_OUTPUT_HANDLE
37
#elif defined(__hexagon__)
38
  #define CPUINFO_LOG_NEWLINE_LENGTH 1
39
40
  #define CPUINFO_LOG_STDERR 0
41
  #define CPUINFO_LOG_STDOUT 0
42
#else
43
0
  #define CPUINFO_LOG_NEWLINE_LENGTH 1
44
45
0
  #define CPUINFO_LOG_STDERR STDERR_FILENO
46
  #define CPUINFO_LOG_STDOUT STDOUT_FILENO
47
#endif
48
49
#if CPUINFO_LOG_TO_STDIO
50
0
static void cpuinfo_vlog(int output_handle, const char* prefix, size_t prefix_length, const char* format, va_list args) {
51
0
  char stack_buffer[CPUINFO_LOG_STACK_BUFFER_SIZE];
52
0
  char* heap_buffer = NULL;
53
0
  char* out_buffer = &stack_buffer[0];
54
55
  /* The first call to vsnprintf will clobber args, thus need a copy in case a second vsnprintf call is needed */
56
0
  va_list args_copy;
57
0
  va_copy(args_copy, args);
58
59
0
  memcpy(stack_buffer, prefix, prefix_length * sizeof(char));
60
0
  assert((prefix_length + CPUINFO_LOG_NEWLINE_LENGTH) * sizeof(char) <= CPUINFO_LOG_STACK_BUFFER_SIZE);
61
62
0
  const int format_chars = vsnprintf(
63
0
    &stack_buffer[prefix_length],
64
0
    CPUINFO_LOG_STACK_BUFFER_SIZE - (prefix_length + CPUINFO_LOG_NEWLINE_LENGTH) * sizeof(char),
65
0
    format,
66
0
    args);
67
0
  if (format_chars < 0) {
68
    /* Format error in the message: silently ignore this particular message. */
69
0
    goto cleanup;
70
0
  }
71
0
  const size_t format_length = (size_t) format_chars;
72
0
  if ((prefix_length + format_length + CPUINFO_LOG_NEWLINE_LENGTH) * sizeof(char) > CPUINFO_LOG_STACK_BUFFER_SIZE) {
73
    /* Allocate a buffer on heap, and vsnprintf to this buffer */
74
0
    const size_t heap_buffer_size = (prefix_length + format_length + CPUINFO_LOG_NEWLINE_LENGTH) * sizeof(char);
75
    #if _WIN32
76
      heap_buffer = HeapAlloc(GetProcessHeap(), 0, heap_buffer_size);
77
    #else
78
0
      heap_buffer = malloc(heap_buffer_size);
79
0
    #endif
80
0
    if (heap_buffer == NULL) {
81
0
      goto cleanup;
82
0
    }
83
84
    /* Copy pre-formatted prefix into the on-heap buffer */
85
0
    memcpy(heap_buffer, prefix, prefix_length * sizeof(char));
86
0
    vsnprintf(&heap_buffer[prefix_length], (format_length + CPUINFO_LOG_NEWLINE_LENGTH) * sizeof(char), format, args_copy);
87
0
    out_buffer = heap_buffer;
88
0
  }
89
  #ifdef _WIN32
90
    out_buffer[prefix_length + format_length] = '\r';
91
    out_buffer[prefix_length + format_length + 1] = '\n';
92
93
    DWORD bytes_written;
94
    WriteFile(
95
      GetStdHandle((DWORD) output_handle),
96
      out_buffer, (prefix_length + format_length + CPUINFO_LOG_NEWLINE_LENGTH) * sizeof(char),
97
      &bytes_written, NULL);
98
  #elif defined(__hexagon__)
99
    qurt_printf("%s", out_buffer);
100
  #else
101
0
    out_buffer[prefix_length + format_length] = '\n';
102
103
0
    ssize_t bytes_written = write(output_handle, out_buffer, (prefix_length + format_length + CPUINFO_LOG_NEWLINE_LENGTH) * sizeof(char));
104
0
    (void) bytes_written;
105
0
  #endif
106
107
0
cleanup:
108
  #ifdef _WIN32
109
    HeapFree(GetProcessHeap(), 0, heap_buffer);
110
  #else
111
0
    free(heap_buffer);
112
0
  #endif
113
0
  va_end(args_copy);
114
0
}
115
#elif defined(__ANDROID__) && CPUINFO_LOG_LEVEL > CPUINFO_LOG_NONE
116
  static const char cpuinfo_module[] = "XNNPACK";
117
#endif
118
119
#if CPUINFO_LOG_LEVEL >= CPUINFO_LOG_DEBUG
120
  void cpuinfo_vlog_debug(const char* format, va_list args) {
121
    #if CPUINFO_LOG_TO_STDIO
122
      static const char debug_prefix[17] = {
123
        'D', 'e', 'b', 'u', 'g', ' ', '(', 'c', 'p', 'u', 'i', 'n', 'f', 'o', ')', ':', ' '
124
      };
125
      cpuinfo_vlog(CPUINFO_LOG_STDOUT, debug_prefix, 17, format, args);
126
    #elif defined(__ANDROID__)
127
      __android_log_vprint(ANDROID_LOG_DEBUG, cpuinfo_module, format, args);
128
    #else
129
      #error "Platform-specific implementation required"
130
    #endif
131
  }
132
#endif
133
134
#if CPUINFO_LOG_LEVEL >= CPUINFO_LOG_INFO
135
  void cpuinfo_vlog_info(const char* format, va_list args) {
136
    #if CPUINFO_LOG_TO_STDIO
137
      static const char info_prefix[16] = {
138
        'N', 'o', 't', 'e', ' ', '(', 'c', 'p', 'u', 'i', 'n', 'f', 'o', ')', ':', ' '
139
      };
140
      cpuinfo_vlog(CPUINFO_LOG_STDOUT, info_prefix, 16, format, args);
141
    #elif defined(__ANDROID__)
142
      __android_log_vprint(ANDROID_LOG_INFO, cpuinfo_module, format, args);
143
    #else
144
      #error "Platform-specific implementation required"
145
    #endif
146
  }
147
#endif
148
149
#if CPUINFO_LOG_LEVEL >= CPUINFO_LOG_WARNING
150
  void cpuinfo_vlog_warning(const char* format, va_list args) {
151
    #if CPUINFO_LOG_TO_STDIO
152
      static const char warning_prefix[20] = {
153
        'W', 'a', 'r', 'n', 'i', 'n', 'g', ' ', 'i', 'n', ' ', 'c', 'p', 'u', 'i', 'n', 'f', 'o', ':', ' '
154
      };
155
      cpuinfo_vlog(CPUINFO_LOG_STDERR, warning_prefix, 20, format, args);
156
    #elif defined(__ANDROID__)
157
      __android_log_vprint(ANDROID_LOG_WARN, cpuinfo_module, format, args);
158
    #else
159
      #error "Platform-specific implementation required"
160
    #endif
161
  }
162
#endif
163
164
#if CPUINFO_LOG_LEVEL >= CPUINFO_LOG_ERROR
165
0
  void cpuinfo_vlog_error(const char* format, va_list args) {
166
0
    #if CPUINFO_LOG_TO_STDIO
167
0
      static const char error_prefix[18] = {
168
0
        'E', 'r', 'r', 'o', 'r', ' ', 'i', 'n', ' ', 'c', 'p', 'u', 'i', 'n', 'f', 'o', ':', ' '
169
0
      };
170
0
      cpuinfo_vlog(CPUINFO_LOG_STDERR, error_prefix, 18, format, args);
171
    #elif defined(__ANDROID__)
172
      __android_log_vprint(ANDROID_LOG_ERROR, cpuinfo_module, format, args);
173
    #else
174
      #error "Platform-specific implementation required"
175
    #endif
176
0
  }
177
#endif
178
179
#if CPUINFO_LOG_LEVEL >= CPUINFO_LOG_FATAL
180
0
  void cpuinfo_vlog_fatal(const char* format, va_list args) {
181
0
    #if CPUINFO_LOG_TO_STDIO
182
0
      static const char fatal_prefix[24] = {
183
0
        'F', 'a', 't', 'a', 'l', ' ', 'e', 'r', 'r', 'o', 'r', ' ', 'i', 'n', ' ', 'c', 'p', 'u', 'i', 'n', 'f', 'o', ':', ' '
184
0
      };
185
0
      cpuinfo_vlog(CPUINFO_LOG_STDERR, fatal_prefix, 24, format, args);
186
    #elif defined(__ANDROID__)
187
      __android_log_vprint(ANDROID_LOG_FATAL, cpuinfo_module, format, args);
188
    #else
189
      #error "Platform-specific implementation required"
190
    #endif
191
0
  }
192
#endif