/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ │vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ │ Copyright 2016 Google Inc. │ │ │ │ Licensed under the Apache License, Version 2.0 (the "License"); │ │ you may not use this file except in compliance with the License. │ │ You may obtain a copy of the License at │ │ │ │ http://www.apache.org/licenses/LICENSE-2.0 │ │ │ │ Unless required by applicable law or agreed to in writing, software │ │ distributed under the License is distributed on an "AS IS" BASIS, │ │ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │ │ See the License for the specific language governing permissions and │ │ limitations under the License. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/mem/mem.h" #include "libc/stdio/stdio.h" #include "libc/thread/thread.h" // clang-format off #ifndef NSYNC_ATM_LOG #define NSYNC_ATM_LOG 0 #endif struct atm_log { uintptr_t i; uintptr_t thd_id; uintptr_t c; void *p; uintptr_t o; uintptr_t n; const char *file; uintptr_t line; }; #define LOG_N 14 static struct atm_log log_entries[1 << LOG_N]; static uint32_t log_i; static pthread_mutex_t log_mu; static pthread_key_t key; static pthread_once_t once = PTHREAD_ONCE_INIT; static void do_once (void) { pthread_mutex_init (&log_mu, NULL); pthread_key_create (&key, NULL); } static int thread_id; void nsync_atm_log_ (int c, void *p, uint32_t o, uint32_t n, const char *file, int line) { if (NSYNC_ATM_LOG) { struct atm_log *e; uint32_t i; int *pthd_id; int thd_id; pthread_once (&once, &do_once); pthd_id = (int *) pthread_getspecific (key); pthread_mutex_lock (&log_mu); i = log_i++; if (pthd_id == NULL) { thd_id = thread_id++; pthd_id = (int *) malloc (sizeof (*pthd_id)); pthread_setspecific (key, pthd_id); *pthd_id = thd_id; } else { thd_id = *pthd_id; } pthread_mutex_unlock (&log_mu); e = &log_entries[i & ((1 << LOG_N) - 1)]; e->i = i; e->thd_id = thd_id; e->c = c; e->p = p; e->o = o; e->n = n; e->file = file; e->line = line; } } void nsync_atm_log_print_ (void) { if (NSYNC_ATM_LOG) { uint32_t i; pthread_once (&once, &do_once); pthread_mutex_lock (&log_mu); for (i = 0; i != (1 << LOG_N); i++) { struct atm_log *e = &log_entries[i]; if (e->file != 0) { fprintf (stderr, "%6lx %3d %c p %16p o %8x n %8x %10s:%d\n", (unsigned long) e->i, (int) e->thd_id, e->c <= ' '? '?' : (char)e->c, e->p, (uint32_t) e->o, (uint32_t) e->n, e->file, (int) e->line); } } pthread_mutex_unlock (&log_mu); } }