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