int check_and_clear_contig_bits(u32 *word, int first, int nbits) { for (int i = first; i < first + nbits; i++) if (check_and_clear_bit(word, i) < 0) return -1; return 0; }
/* Free element at @addr in @cache. Return negative on error. */ int mem_cache_free(struct mem_cache *cache, void *addr) { unsigned int struct_addr = (unsigned int)addr; unsigned int bit; int err = 0; /* Check boundary */ if (struct_addr < cache->start || struct_addr > cache->end) { printf("Error: This address doesn't belong to this cache.\n"); return -1; } bit = ((struct_addr - cache->start) / cache->struct_size); /* Check alignment: * Find out if there was a lost remainder in last division. * There shouldn't have been, because addresses are allocated at * struct_size offsets from cache->start. */ if (((bit * cache->struct_size) + cache->start) != struct_addr) { printf("Error: This address is not aligned on a predefined " "structure address in this cache.\n"); err = -1; return err; } /* NOTE: If needed, must lock here */ /* Check free/occupied state */ if (check_and_clear_bit(cache->bitmap, bit) < 0) { printf("Error: Anomaly in cache occupied state:\n" "Trying to free already free structure.\n"); err = -1; goto out; } cache->free++; if (cache->free > cache->total) { printf("Error: Anomaly in cache occupied state:\n" "More free elements than total.\n"); err = -1; goto out; } out: /* NOTE: If locked, must unlock here */ return err; }