#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,cnt; 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>3;i++) { cnt=0; uum=task->code_heap->heap_hash[i]; while (uum) { cnt+=uum->size; uum=uum->next; } if (task->data_heap!=task->code_heap) { uum=task->data_heap->heap_hash[i]; while (uum) { cnt+=uum->size; uum=uum->next; } } if (cnt) "%03X:%08X\n",i<<3,cnt; } '\n'; uum=task->code_heap->malloc_free_lst; while (uum) { "%X, ",uum->size; uum=uum->next; } if (task->data_heap!=task->code_heap) { uum=task->data_heap->malloc_free_lst; 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 addr 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 && apags<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>3;i++) { uum=hc->heap_hash[i]; while (uum) { if (!IsInHeapCtrl(uum,hc,FALSE)) goto hc_false; uum=uum->next; } } uum=hc->malloc_free_lst; while (uum) { if (!IsInHeapCtrl(uum,hc,FALSE)) goto hc_false; uum=uum->next; } #if _CFG_HEAP_DBG 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 addr 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; }