static inline int traces_obtain_log_line_number(void) { int linenum; while (1) { /* wait for buffer to be emptied */ while (AO_load(&traces->logcnt) > LAST_LOGLINE); while (AO_test_and_set(&traces->lock) == AO_TS_SET); /* new line will be used! */ AO_fetch_and_add1(&traces->usecnt); /* get log line number */ linenum = AO_fetch_and_add1(&traces->logcnt); AO_CLEAR(&traces->lock); /* line number with valid properties has been acquired so leave */ if (linenum <= LAST_LOGLINE) break; /* release non-existing line number */ AO_fetch_and_sub1(&traces->usecnt); } DEBUG("linenum = %d", linenum); /* linenum is storing now a unique number n, such as 0 <= n <= LAST_LOGLINE */ return linenum; }
static void traces_log_write_out(void) { DEBUG("begin"); /* disallow to obtain new lines */ while (AO_test_and_set(&traces->lock) == AO_TS_SET); /* if any line is still used, wait for it to be released */ while (AO_load(&traces->usecnt) > 0); int lines = (traces->logcnt >= LAST_LOGLINE) ? (LAST_LOGLINE - 1) : traces->logcnt; if (lines > 0) { if (write(traces->logfd, &traces->logs, lines * sizeof(traces_log_t)) == -1) perror("traces: writing out failed: "); else DEBUG("written out %d lines", lines); } memset(&traces->logs, 0, (LAST_LOGLINE - 1) * sizeof(traces_log_t)); /* reset line log counter */ AO_store(&traces->logcnt, 0); AO_CLEAR(&traces->lock); DEBUG("finished"); }
void traces_init_hook(void) { while (AO_test_and_set(&initlock) == AO_TS_SET); if (traces == NULL) { DEBUG("inializing"); /* create shared memory block for malloc traces */ traces_data_t *_traces; _traces = mmap(NULL, sizeof(traces_log_t) * 4096, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); if (_traces == NULL) { perror("Cannot create shared memory segment for malloc traces:"); abort(); } DEBUG("traces data placed at $%.8x", (uint32_t)_traces); memset(&_traces->logs, 0, (LAST_LOGLINE - 1) * sizeof(traces_log_t)); /* open log file */ char *logname = getenv("MALLOC_TRACE_LOG"); if (logname == NULL) logname = "trace-log.bin"; fprintf(stderr, "ptmalloc3 traces logname = %s\n", logname); _traces->logfd = open(logname, O_WRONLY|O_APPEND|O_CREAT, 0600); _traces->logcnt = 0; _traces->usecnt = 0; _traces->lock = AO_TS_INITIALIZER; if (_traces->logfd == -1) { perror("Cannot open log file:"); abort(); } /* get clock id of the process */ if (clock_getcpuclockid(getpid(), &_traces->clkid) != 0) { perror("Cannot obtain clock id:"); abort(); } traces = _traces; DEBUG("initialized"); } else { DEBUG("already initialized"); } AO_CLEAR(&initlock); #if WANT_TO_HAVE_ATEXIT_BUG traces_register_at_exit(); #endif }
static inline struct ia64_script_cache * get_script_cache (unw_addr_space_t as, intrmask_t *saved_maskp) { struct ia64_script_cache *cache = &as->global_cache; unw_caching_policy_t caching = as->caching_policy; if (caching == UNW_CACHE_NONE) return NULL; #ifdef HAVE_ATOMIC_H if (!spin_trylock_irqsave (&cache->busy, *saved_maskp)) return NULL; #else # ifdef HAVE___THREAD if (as->caching_policy == UNW_CACHE_PER_THREAD) cache = &ia64_per_thread_cache; # endif # ifdef HAVE_ATOMIC_OPS_H if (AO_test_and_set (&cache->busy) == AO_TS_SET) return NULL; # else sigprocmask (SIG_SETMASK, &unwi_full_mask, saved_maskp); if (likely (caching == UNW_CACHE_GLOBAL)) { Debug (16, "%s: acquiring lock\n", __FUNCTION__); mutex_lock (&cache->lock); } # endif #endif if (atomic_read (&as->cache_generation) != atomic_read (&cache->generation)) { flush_script_cache (cache); cache->generation = as->cache_generation; } return cache; }