getpagesizes.c revision 197331
12224Sctornqvi/*-
22224Sctornqvi * Copyright (c) 2009 Alan L. Cox <alc@cs.rice.edu>
32224Sctornqvi * All rights reserved.
42224Sctornqvi *
52224Sctornqvi * Redistribution and use in source and binary forms, with or without
62224Sctornqvi * modification, are permitted provided that the following conditions
72224Sctornqvi * are met:
82224Sctornqvi * 1. Redistributions of source code must retain the above copyright
92224Sctornqvi *    notice, this list of conditions and the following disclaimer.
102224Sctornqvi * 2. Redistributions in binary form must reproduce the above copyright
112224Sctornqvi *    notice, this list of conditions and the following disclaimer in the
122224Sctornqvi *    documentation and/or other materials provided with the distribution.
132224Sctornqvi *
142224Sctornqvi * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
152224Sctornqvi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
162224Sctornqvi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
172224Sctornqvi * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
182224Sctornqvi * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
192224Sctornqvi * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
202224Sctornqvi * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
212224Sctornqvi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
222224Sctornqvi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
232224Sctornqvi * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
242224Sctornqvi * SUCH DAMAGE.
252224Sctornqvi */
262224Sctornqvi
272224Sctornqvi#include <sys/cdefs.h>
282224Sctornqvi__FBSDID("$FreeBSD: head/lib/libc/gen/getpagesizes.c 197331 2009-09-19 18:01:32Z alc $");
292224Sctornqvi
302224Sctornqvi#include <sys/param.h>
312224Sctornqvi#include <sys/mman.h>
322224Sctornqvi#include <sys/sysctl.h>
332224Sctornqvi
342224Sctornqvi#include <errno.h>
352224Sctornqvi
362224Sctornqvi/*
372224Sctornqvi * Retrieves page size information from the system.  Specifically, returns the
382224Sctornqvi * number of distinct page sizes that are supported by the system, if
392224Sctornqvi * "pagesize" is NULL and "nelem" is 0.  Otherwise, assigns up to "nelem" of
402224Sctornqvi * the system-supported page sizes to consecutive elements of the array
412224Sctornqvi * referenced by "pagesize", and returns the number of such page sizes that it
422224Sctornqvi * assigned to the array.  These page sizes are expressed in bytes.
432224Sctornqvi *
442224Sctornqvi * The implementation of this function does not directly or indirectly call
452224Sctornqvi * malloc(3) or any other dynamic memory allocator that may itself call this
462224Sctornqvi * function.
472224Sctornqvi */
482224Sctornqviint
492224Sctornqvigetpagesizes(size_t pagesize[], int nelem)
502224Sctornqvi{
512224Sctornqvi	static u_long ps[MAXPAGESIZES];
522224Sctornqvi	static int nops;
532224Sctornqvi	size_t size;
542224Sctornqvi	int i;
552224Sctornqvi
562224Sctornqvi	if (nelem < 0 || (nelem > 0 && pagesize == NULL)) {
572224Sctornqvi		errno = EINVAL;
582224Sctornqvi		return (-1);
592224Sctornqvi	}
602224Sctornqvi	/* Cache the result of the sysctl(2). */
612224Sctornqvi	if (nops == 0) {
622224Sctornqvi		size = sizeof(ps);
632224Sctornqvi		if (sysctlbyname("hw.pagesizes", ps, &size, NULL, 0) == -1)
642224Sctornqvi			return (-1);
652224Sctornqvi		/* Count the number of page sizes that are supported. */
662224Sctornqvi		nops = size / sizeof(ps[0]);
672224Sctornqvi		while (nops > 0 && ps[nops - 1] == 0)
682224Sctornqvi			nops--;
692224Sctornqvi	}
702224Sctornqvi	if (pagesize == NULL)
712224Sctornqvi		return (nops);
722224Sctornqvi	/* Return up to "nelem" page sizes from the cached result. */
732224Sctornqvi	if (nelem > nops)
742224Sctornqvi		nelem = nops;
752224Sctornqvi	for (i = 0; i < nelem; i++)
762224Sctornqvi		pagesize[i] = ps[i];
772224Sctornqvi	return (nelem);
782224Sctornqvi}
792224Sctornqvi