struct XRaySymbolPool* XRaySymbolPoolCreate() { struct XRaySymbolPool* sympool; struct XRaySymbolPoolNode* node; sympool = (struct XRaySymbolPool*)XRayMalloc(sizeof(*sympool)); node = (struct XRaySymbolPoolNode*)XRayMalloc(sizeof(*node)); sympool->head = node; sympool->current = node; sympool->index = 0; return sympool; }
/* Creates and inializes a symbol table. */ struct XRaySymbolTable* XRaySymbolTableCreate(int size) { struct XRaySymbolTable* symtab; symtab = (struct XRaySymbolTable*)XRayMalloc(sizeof(*symtab)); symtab->num_symbols = 0; symtab->string_pool = XRayStringPoolCreate(); symtab->hash_table = XRayHashTableCreate(size); symtab->symbol_pool = XRaySymbolPoolCreate(); return symtab; }
struct XRaySymbol* XRaySymbolPoolAlloc(struct XRaySymbolPool* sympool) { struct XRaySymbol* symbol; if (sympool->index >= XRAY_SYMBOL_POOL_NODE_SIZE) { struct XRaySymbolPoolNode* new_pool; new_pool = (struct XRaySymbolPoolNode*)XRayMalloc(sizeof(*new_pool)); sympool->current->next = new_pool; sympool->current = new_pool; sympool->index = 0; } symbol = &sympool->current->symbols[sympool->index]; ++sympool->index; return symbol; }
if (0 != (size & (size - 1))) { printf("Xray: Hash table size should be a power of 2!\n"); /* round size up to next power of 2 */ /* see http://aggregate.org/MAGIC/ */ size--; size |= size >> 1; size |= size >> 2; size |= size >> 4; size |= size >> 8; size |= size >> 16; size++; } bytes = sizeof(table->array[0]) * size; table->size = size; table->count = 0; table->array = (struct XRayHashTableEntry *)XRayMalloc(bytes); } /* creates & inializes hash table */ struct XRayHashTable* XRayHashTableCreate(int size) { struct XRayHashTable *table; table = (struct XRayHashTable *)XRayMalloc(sizeof(*table)); XRayHashTableInit(table, size); memset(&g_hash_histo[0], 0, sizeof(g_hash_histo[0]) * HASH_HISTO); return table; } /* prints hash table performance to file; for debugging */ void XRayHashTableHisto(FILE *f) {
void XRayBrowserTraceReport(struct XRayTraceCapture* capture) { const void* cat_enabled = ppb_trace_event_interface->GetCategoryEnabled( "xray"); struct XRaySymbolTable* symbols = XRayGetSymbolTable(capture); int32_t thread_id = XRayGetSavedThreadID(capture); int head = XRayFrameGetHead(capture); int frame = XRayFrameGetTail(capture); while(frame != head) { struct XRayTimestampPair start_time = XRayFrameGetStartTimestampPair( capture, frame); struct XRayTimestampPair end_time = XRayFrameGetEndTimestampPair( capture, frame); double pdiff = (end_time.pepper - start_time.pepper); double odiff = (end_time.xray - start_time.xray); double scale_a = pdiff / odiff; double scale_b = ((double)end_time.pepper) - (scale_a * end_time.xray); printf("Xray timestamp calibration frame %d: %f %f\n", frame, scale_a, scale_b); int start = XRayFrameGetTraceStartIndex(capture, frame); int end = XRayFrameGetTraceEndIndex(capture, frame); struct XRayTraceBufferEntry** stack_base = XRayMalloc( sizeof(struct XRayTraceBufferEntry*) * (XRAY_TRACE_STACK_SIZE + 1)); struct XRayTraceBufferEntry** stack_top = stack_base; *stack_top = NULL; uint32_t num_args = 0; const char* arg_names[] = {"annotation"}; uint8_t arg_types[] = {TRACE_VALUE_TYPE_COPY_STRING}; uint64_t arg_values[] = {0}; char annotation[XRAY_TRACE_ANNOTATION_LENGTH]; int i; for(i = start; i != end; i = XRayTraceNextEntry(capture, i)) { if (XRayTraceIsAnnotation(capture, i)) { continue; } uint32_t depth = XRAY_EXTRACT_DEPTH( XRayTraceGetEntry(capture, i)->depth_addr); while(*stack_top && XRAY_EXTRACT_DEPTH((*stack_top)->depth_addr) >= depth) { struct XRayTraceBufferEntry* e = *(stack_top--); ppb_trace_event_interface->AddTraceEventWithThreadIdAndTimestamp( 'E', cat_enabled, XRayGetName(symbols, e), 0, thread_id, (scale_a * e->end_tick) + scale_b, 0, NULL, NULL, NULL, 0 ); } num_args = 0; struct XRayTraceBufferEntry* e = XRayTraceGetEntry(capture, i); uint32_t annotation_index = e->annotation_index; if (annotation_index) { XRayTraceCopyToString(capture, annotation_index, annotation); union TraceValue val; val.as_string = (const char*)annotation; arg_values[0] = val.as_uint; num_args = 1; } ppb_trace_event_interface->AddTraceEventWithThreadIdAndTimestamp( 'B', cat_enabled, XRayGetName(symbols, e), 0, thread_id, (scale_a * e->start_tick) + scale_b, num_args, arg_names, arg_types, arg_values, 0 ); *(++stack_top) = e; } while(*stack_top) { struct XRayTraceBufferEntry* e = *(stack_top--); ppb_trace_event_interface->AddTraceEventWithThreadIdAndTimestamp( 'E', cat_enabled, XRayGetName(symbols, e), 0, thread_id, (scale_a * e->end_tick) + scale_b, 0, NULL, NULL, NULL, 0 ); } frame = XRayFrameGetNext(capture, frame); XRayFree(stack_base); } }