#help_index "Memory/Task" public I64 TaskMemAlloced(CTask *task=NULL, Bool override_validate=FALSE) {//Count of bytes alloced to a task, used+unused. I64 res; if (!task) task = Fs; if (override_validate || TaskValidate(task)) { res = task->code_heap->alloced_u8s; if (task->code_heap != task->data_heap) res += task->data_heap->alloced_u8s; return res; } else return 0; } public I64 TaskMemUsed(CTask *task=NULL, Bool override_validate=FALSE) {//Count of bytes alloced to a task and in use. I64 res; if (!task) task = Fs; if (override_validate || TaskValidate(task)) { res = task->code_heap->used_u8s; if (task->data_heap != task->code_heap) res += task->data_heap->used_u8s; return res; } else return 0; } #help_index "Memory/Task;Debugging/Heap;Memory/Debugging" public Bool HeapRep(CTask *task) {//Report status of task's heap. I64 i, count; CMemUnused *uum; if (!task || task == Fs) { "Task can't HeapRep on self.\n"; return FALSE; } if (!TaskValidate(task)) return FALSE; PUSHFD CLI while (LBts(&task->code_heap->locked_flags, HClf_LOCKED)) PAUSE if (task->data_heap != task->code_heap) while (LBts(&task->data_heap->locked_flags, HClf_LOCKED)) PAUSE for (i = 0; i < MEM_HEAP_HASH_SIZE >> 3; i++) { count = 0; uum = task->code_heap->heap_hash[i]; while (uum) { count += uum->size; uum = uum->next; } if (task->data_heap != task->code_heap) { uum = task->data_heap->heap_hash[i]; while (uum) { count += uum->size; uum = uum->next; } } if (count) "%03X:%08X\n", i << 3, count; } '\n'; uum = task->code_heap->malloc_free_list; while (uum) { "%X, ", uum->size; uum = uum->next; } if (task->data_heap != task->code_heap) { uum = task->data_heap->malloc_free_list; while (uum) { "%X, ", uum->size; uum = uum->next; } } if (task->data_heap != task->code_heap) LBtr(&task->data_heap->locked_flags, HClf_LOCKED); LBtr(&task->code_heap->locked_flags, HClf_LOCKED); POPFD '\n'; } #help_index "Memory/HeapCtrl;Debugging/Heap;Memory/Debugging" public Bool IsInHeapCtrl(U8 *a, CHeapCtrl *hc, Bool lock=TRUE) {//Check address if in HeapCtrl. CMemBlk *m; PUSHFD CLI if (lock) while (LBts(&hc->locked_flags, HClf_LOCKED)) PAUSE m = hc->next_mem_blk; while (m != &hc->next_mem_blk) { if (a >= m && a < m(U8 *) + m->pags << MEM_PAG_BITS) { if (lock) LBtr(&hc->locked_flags, HClf_LOCKED); POPFD return TRUE; } m = m->next; } if (lock) LBtr(&hc->locked_flags, HClf_LOCKED); POPFD return FALSE; } public Bool HeapCtrlWalk(CHeapCtrl *hc) {//Check integrity of HeapCtrl. I64 i; CMemUnused *uum; PUSHFD CLI while (LBts(&hc->locked_flags, HClf_LOCKED)) PAUSE for (i = 0; i < MEM_HEAP_HASH_SIZE >> 3; i++) { uum = hc->heap_hash[i]; while (uum) { if (!IsInHeapCtrl(uum, hc, FALSE)) goto hc_false; uum = uum->next; } } uum = hc->malloc_free_list; while (uum) { if (!IsInHeapCtrl(uum, hc, FALSE)) goto hc_false; uum = uum->next; } #if _CONFIG_HEAP_DEBUG CMemUsed *um, *um1; um1 = (&hc->next_um)(U8 *) - offset(CMemUsed.next); um = um1->next; while (um != um1) { if (!IsInHeapCtrl(um, hc, FALSE)) goto hc_false; um = um->next; } #endif LBtr(&hc->locked_flags, HClf_LOCKED); POPFD return TRUE; hc_false: LBtr(&hc->locked_flags, HClf_LOCKED); POPFD return FALSE; } #help_index "Memory/Task;Debugging/Heap;Memory/Debugging" public Bool IsInHeap(U8 *a, CTask *task=NULL, Bool lock=TRUE) {//Check address if in task's heaps. if (!task) task = Fs; if (TaskValidate(task) && (IsInHeapCtrl(a, task->code_heap, lock) || task->data_heap != task->code_heap && IsInHeapCtrl(a, task->data_heap, lock))) return TRUE; else return FALSE; } public Bool HeapWalk(CTask *task=NULL) {//Check integrity of task's heaps. if (!task) task = Fs; if (!TaskValidate(task) || !HeapCtrlWalk(task->code_heap) || task->data_heap != task->code_heap && !HeapCtrlWalk(task->data_heap)) return FALSE; else return TRUE; }