/** ** remove a chunk from the free list **/ static void remove_chunk(SM_MALLOC_CHUNK **list, SM_MALLOC_CHUNK *oc) { SM_MALLOC_CHUNK *tmp; assert(oc->signature == SIGNATURE); if (oc == *list) { *list = smObjGlobalToLocal(oc->next); if (*list != NULL) { (*list)->prev = NULL; } return; } tmp = smObjGlobalToLocal(oc->prev); tmp->next = oc->next; if (oc->next != NULL) { tmp = smObjGlobalToLocal(oc->next); tmp->prev = oc->prev; } }
/** ** Insert a bloc in the sorted free list ** if list == NULL create a new list ** **/ static void insert_after(SM_MALLOC_CHUNK **list, SM_MALLOC_CHUNK *nc) { SM_MALLOC_CHUNK *c, *pc, *tmp; if (*list == NULL) { nc->prev = NULL; nc->next = NULL; nc->signature = SIGNATURE; *list = nc; return; } if (nc < *list) { /* insert at the beginning */ nc->next = smObjLocalToGlobal(*list); nc->prev = NULL; nc->signature = SIGNATURE; (*list)->prev = smObjLocalToGlobal(nc); *list = nc; return; } pc = NULL; for (c = *list; c != NULL; c = smObjGlobalToLocal(c->next)) { if (nc < c) { nc->next = smObjLocalToGlobal(c); nc->prev = c->prev; nc->signature = SIGNATURE; tmp = smObjGlobalToLocal(c->prev); tmp->next = smObjLocalToGlobal(nc); c->prev = smObjLocalToGlobal(nc); return; } pc = c; } pc->next = smObjLocalToGlobal(nc); nc->prev = smObjLocalToGlobal(pc); nc->next = NULL; } /* insert_after */
/** ** Liberation d'une zone **/ STATUS smMemFree(void *ptr) { SM_MALLOC_CHUNK *oc, *c; LOGDBG(("comLib:smMemLib: free 0x%x\n", (unsigned)ptr)); if (ptr == NULL) { LOGDBG(("comLib:smMemLib: free(NULL)\n")); return ERROR; } /* get a pointer to the header */ oc = (SM_MALLOC_CHUNK *)ptr - 1; /* test for allocated bloc */ if (oc->next != MALLOC_MAGIC) { /* what to do ? */ LOGDBG(("comLib:smMemLib: free(something not returned by malloc)\n")); return ERROR; } /* insert free chunk in the free list */ insert_after(&smMemFreeList, oc); /* test if can merge with preceding chunk */ c = smObjGlobalToLocal(oc->prev); if (c != NULL && oc == (SM_MALLOC_CHUNK *)((char *)c + REAL_SIZE(c->length))) { /* merge */ c->length += REAL_SIZE(oc->length); remove_chunk(&smMemFreeList, oc); oc = c; } /* test if can merge with following chunk */ c = smObjGlobalToLocal(oc->next); if (c == (SM_MALLOC_CHUNK *)((char *)oc + REAL_SIZE(oc->length))) { /* merge (=> oc->next != NULL) */ oc->length += REAL_SIZE(c->length); remove_chunk(&smMemFreeList, c); } return OK; }
STATUS h2devClean(const char *name) { int i, match = 0; unsigned char *pool; if (h2devAttach() == ERROR) { return ERROR; } /* Look for devices */ for (i = 0; i < H2_DEV_MAX; i++) { if (H2DEV_TYPE(i) != H2_DEV_TYPE_NONE && fnmatch(name, H2DEV_NAME(i), 0) == 0) { logMsg("Freeing %s\n", H2DEV_NAME(i)); match++; switch (H2DEV_TYPE(i)) { case H2_DEV_TYPE_MBOX: mboxDelete(i); break; case H2_DEV_TYPE_POSTER: pool = smObjGlobalToLocal(H2DEV_POSTER_POOL(i)); if (pool != NULL) smMemFree(pool); h2semDelete(H2DEV_POSTER_SEM_ID(i)); h2devFree(i); break; case H2_DEV_TYPE_TASK: h2semDelete(H2DEV_TASK_SEM_ID(i)); h2devFree(i); break; case H2_DEV_TYPE_SEM: case H2_DEV_TYPE_NONE: break; default: /* error */ logMsg("comLib: unknown device type %d\n", H2DEV_TYPE(i)); return ERROR; break; } /* switch */ } } /* for */ if (match == 0) { logMsg("No matching device\n"); return ERROR; } return OK; }
/** ** Affichage de statistiques sur l'allocateur **/ void smMemShow(BOOL option) { unsigned long bytes = 0, blocks = 0, maxb = 0; SM_MALLOC_CHUNK *c; if (smMemFreeList == NULL) { if (smMemAttach() == ERROR) { return; } } if (option) { logMsg("\nFREE LIST:\n"); logMsg(" num addr size\n"); logMsg(" --- ---------- ----------\n"); } /* Parcours de la liste des blocs libres */ for (c = smMemFreeList; c != NULL; c = smObjGlobalToLocal(c->next)) { assert(c->signature == SIGNATURE); blocks++; bytes += c->length; if (c->length > maxb) { maxb = c->length; } if (option) { logMsg("%4ld 0x%08lx %10lu\n", blocks, (unsigned long)c, (unsigned long)c->length); } } if (option) { logMsg("\nSUMMARY:\n"); } logMsg(" status bytes blocks ave block max block\n"); logMsg(" ------ ---------- -------- ---------- ----------\n"); logMsg("current\n"); logMsg(" free %10lu %9lu %10lu %10lu\n", bytes, blocks, bytes/blocks, maxb); #ifdef notyet logMsg(" alloc %10d %9d %10d %10s\n", allocBytes, allocBlocks, allocBytes/allocBlocks, "-"); #endif }