> Date: Sun, 30 Jul 2017 10:22:11 +0200 > From: Kamil Rytarowski <n...@gmx.com> > > I think we should go for kmem_reallocarr(). It has been designed for > overflows like realocarray(3) with an option to be capable to resize a > table fron 1 to N elements and back from N to 0 including freeing.
Initially I was reluctant to do that because (a) we don't even have a kmem_realloc, perhaps for some particular reason, and (b) it requires an extra parameter for the old size. But I don't know any particular reason in (a), and perhaps (b) not so bad after all. Here's a draft: int kmem_reallocarr(void *ptrp, size_t size, size_t ocnt, size_t ncnt, int flags) { void *optr, *nptr; KASSERT(size != 0); if (__predict_false((size|ncnt) >= SQRT_SIZE_MAX && ncnt > SIZE_MAX/size)) return ENOMEM; memcpy(&optr, ptrp, sizeof(void *)); KASSERT((ocnt == 0) == (optr == NULL)); if (ncnt == 0) { nptr = NULL; } else { nptr = kmem_alloc(size*ncnt, flags); KASSERT(nptr != NULL || flags == KM_NOSLEEP); if (nptr == NULL) return ENOMEM; } KASSERT((ncnt == 0) == (nptr == NULL)); if (ocnt & ncnt) memcpy(nptr, optr, size*MIN(ocnt, ncnt)); if (ocnt != 0) kmem_free(optr, size*ocnt); memcpy(ptrp, &nptr, sizeof(void *)); return 0; }