tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kmem API to allocate arrays



> Date: Sun, 30 Jul 2017 10:22:11 +0200
> From: Kamil Rytarowski <n54%gmx.com@localhost>
> 
> 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;
}


Home | Main Index | Thread Index | Old Index