/* * Free a memory block owned by a given cookie. * Run some corruption checks. */ void olsr_cookie_free(struct olsr_cookie_info *ci, void *ptr) { struct olsr_cookie_mem_brand *branding; struct list_node *free_list_node; #ifdef OLSR_COOKIE_DEBUG bool reuse = false; #endif branding = (struct olsr_cookie_mem_brand *)ARM_NOWARN_ALIGN(((unsigned char *)ptr + ci->ci_size)); /* * Verify if there has been a memory overrun, or * the wrong owner is trying to free this. */ assert(!memcmp(&branding->cmb_sig, "cookie", 6) && branding->cmb_id == ci->ci_id); /* Kill the brand */ memset(branding, 0, sizeof(*branding)); /* * Rather than freeing the memory right away, try to reuse at a later * point. Keep at least ten percent of the active used blocks or at least * ten blocks on the free list. */ if ((ci->ci_free_list_usage < COOKIE_FREE_LIST_THRESHOLD) || (ci->ci_free_list_usage < ci->ci_usage / COOKIE_FREE_LIST_THRESHOLD)) { free_list_node = (struct list_node *)ptr; list_node_init(free_list_node); list_add_before(&ci->ci_free_list, free_list_node); ci->ci_free_list_usage++; #ifdef OLSR_COOKIE_DEBUG reuse = true; #endif } else { /* * No interest in reusing memory. */ free(ptr); } /* Stats keeping */ olsr_cookie_usage_decr(ci->ci_id); #ifdef OLSR_COOKIE_DEBUG OLSR_PRINTF(1, "MEMORY: free %s, %p, %u bytes%s\n", ci->ci_name, ptr, ci->ci_size, reuse ? ", reuse" : ""); #endif }
/** * Delete a timer. * * @param the timer_entry that shall be removed * @return nada */ void olsr_stop_timer(struct timer_entry *timer) { /* It's okay to get a NULL here */ if (!timer) { return; } assert(timer->timer_cookie); /* we want timer cookies everywhere */ OLSR_PRINTF(7, "TIMER: stop %s timer %p, ctx %p\n", timer->timer_cookie->ci_name, timer, timer->timer_cb_context); /* * Carve out of the existing wheel_slot and free. */ list_remove(&timer->timer_list); timer->timer_flags &= ~OLSR_TIMER_RUNNING; olsr_cookie_usage_decr(timer->timer_cookie->ci_id); olsr_cookie_free(timer_mem_cookie, timer); }