void * basket_remove_if (basket_t * bsk, basket_check_t f, void *cd) { int found = 0; void *remd = NULL; dk_set_t tmp = NULL; void *elt; #ifdef MTX_DEBUG if (bsk->bsk_req_mtx) ASSERT_IN_MTX (bsk->bsk_req_mtx); #endif while ((elt = basket_get (bsk))) { if (!found && f (elt, cd)) { remd = elt; found = 1; } else dk_set_push (&tmp, elt); } dk_set_nreverse (tmp); DO_SET (void *, x, &tmp) { basket_add (bsk, x); } END_DO_SET (); dk_set_free (tmp); return remd; }
void dbs_extent_free (dbe_storage_t * dbs, dp_addr_t ext_dp, int must_be_in_em) { extent_map_t * em; extent_t * ext; int word, bit; uint32 * arr, page_no; ASSERT_IN_DBS (dbs); dbs_locate_ext_bit (dbs, ext_dp, &arr, &page_no, &word, &bit); if (0 == (arr[word] & 1 << bit)) GPF_T1 ("double free in ext set"); page_set_update_checksum (arr, word, bit); arr[word] &= ~(1 << bit); em = DBS_DP_TO_EM (dbs, ext_dp); if (em) { ASSERT_IN_MTX (em->em_mtx); ext = EM_DP_TO_EXT (em, ext_dp); if (ext) { remhash (DP_ADDR2VOID (ext_dp), em->em_dp_to_ext); switch (EXT_TYPE (ext)) { case EXT_INDEX: em->em_n_pages -= EXTENT_SZ; em->em_n_free_pages -= EXTENT_SZ; break; case EXT_REMAP: em->em_n_remap_pages -= EXTENT_SZ; em->em_n_free_remap_pages -= EXTENT_SZ; break; case EXT_BLOB: em->em_n_blob_pages -= EXTENT_SZ; em->em_n_free_blob_pages -= EXTENT_SZ; break; } ext->ext_flags = EXT_FREE; } if (ext == em->em_last_remap_ext) em->em_last_remap_ext = NULL; if (ext == em->em_last_blob_ext) em->em_last_blob_ext = NULL; remhash (DP_ADDR2VOID (ext_dp), dbs->dbs_dp_to_extent_map); } else if (must_be_in_em) GPF_T1 ("cannot free ext that is not part of any em"); }
void * basket_get (basket_t * bsk) { void *data; #ifdef MTX_DEBUG if (bsk->bsk_req_mtx) ASSERT_IN_MTX (bsk->bsk_req_mtx); #endif if (bsk->bsk_count == 0) return NULL; bsk->bsk_count--; bsk = bsk->bsk_next; LISTDELETE (bsk, bsk_next, bsk_prev); data = bsk->bsk_pointer; dk_free (bsk, sizeof (basket_t)); return data; }