blob: 0eb54e7d6686405a0145dea568533c8ac38d2081 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "private.h"
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/log.h>
#ifdef FDIO_LLDEBUG
#define LOGBUF_MAX (ZX_LOG_RECORD_MAX - sizeof(zx_log_record_t))
static ssize_t fdio_lldebug_log_write(const void* _data, size_t len) {
static thread_local struct {
zx_handle_t log;
uint32_t next;
char data[LOGBUF_MAX];
}* logbuf = NULL;
if (logbuf == NULL) {
if ((logbuf = calloc(1, sizeof(*logbuf))) == NULL) {
return len;
}
if (zx_debuglog_create(0, 0, &logbuf->log) != ZX_OK) {
free(logbuf);
logbuf = NULL;
return len;
}
}
const char* data = _data;
size_t r = len;
while (len-- > 0) {
char c = *data++;
if (c == '\n') {
zx_debuglog_write(logbuf->log, 0, logbuf->data, logbuf->next);
logbuf->next = 0;
continue;
}
if (c < ' ') {
continue;
}
logbuf->data[logbuf->next++] = c;
if (logbuf->next == LOGBUF_MAX) {
zx_debuglog_write(logbuf->log, 0, logbuf->data, logbuf->next);
logbuf->next = 0;
continue;
}
}
return r;
}
static unsigned debug_level = FDIO_LLDEBUG;
void fdio_lldebug_printf(unsigned level, const char* fmt, ...) {
if (debug_level >= level) {
va_list ap;
char buf[128];
va_start(ap, fmt);
size_t sz = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
fdio_lldebug_log_write(buf, sz > sizeof(buf) ? sizeof(buf) : sz);
}
}
#endif
void fdio_set_debug_level(unsigned level) {
#ifdef FDIO_LLDEBUG
debug_level = level;
#endif
}
#ifdef FDIO_ALLOCDEBUG
#define PSZ 128
static char POOL[PSZ * 256];
static char* NEXT = POOL;
static mtx_t pool_lock;
void* fdio_alloc(size_t n, size_t sz) {
if ((n > 1) || (sz > PSZ)) {
return NULL;
}
void* ptr = NULL;
mtx_lock(&pool_lock);
if ((NEXT - POOL) < (int)sizeof(POOL)) {
ptr = NEXT;
NEXT += PSZ;
} else {
LOG(1, "fdio: OUT OF FDIO_T POOL SPACE\n");
}
mtx_unlock(&pool_lock);
LOG(5, "fdio: io: alloc: %p\n", ptr);
return ptr;
}
#endif
void fdio_free(fdio_t* io) {
LOG(5, "fdio: io: free: %p\n", io);
io->magic = 0xDEAD0123;
io->ops = NULL;
#ifndef FDIO_ALLOCDEBUG
free(io);
#endif
}