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 * test_and_set_thr(void * id) { unsigned long i; for (i = 0; i < NITERS/10; ++i) { while (AO_test_and_set_acquire(&lock) != AO_TS_CLEAR); ++locked_counter; if (locked_counter != 1) { fprintf(stderr, "Test and set failure 1, counter = %ld, id = %d\n", (long)locked_counter, (int)(AO_PTRDIFF_T)id); abort(); } locked_counter *= 2; locked_counter -= 1; locked_counter *= 5; locked_counter -= 4; if (locked_counter != 1) { fprintf(stderr, "Test and set failure 2, counter = %ld, id = %d\n", (long)locked_counter, (int)(AO_PTRDIFF_T)id); abort(); } --locked_counter; AO_CLEAR(&lock); /* Spend a bit of time outside the lock. */ junk *= 17; junk *= 17; } return 0; }
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; }
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 void put_script_cache (unw_addr_space_t as, struct ia64_script_cache *cache, intrmask_t *saved_maskp) { assert (as->caching_policy != UNW_CACHE_NONE); Debug (16, "unmasking signals/interrupts and releasing lock\n"); #ifdef HAVE_ATOMIC_H spin_unlock_irqrestore (&cache->busy, *saved_maskp); #else # ifdef HAVE_ATOMIC_OPS_H AO_CLEAR (&cache->busy); # else if (likely (as->caching_policy == UNW_CACHE_GLOBAL)) lock_release (&cache->lock, *saved_maskp); # endif #endif }
AO_INLINE void unlock(volatile AO_TS_T *l) { AO_CLEAR(l); }
void spinlock_unlock(AO_TS_t * lock) { // your implementation here AO_CLEAR(lock); }