1*b0104773SPascal Brand /* 2*b0104773SPascal Brand * Copyright (c) 1994-2009 Red Hat, Inc. 3*b0104773SPascal Brand * All rights reserved. 4*b0104773SPascal Brand * 5*b0104773SPascal Brand * Redistribution and use in source and binary forms, with or without 6*b0104773SPascal Brand * modification, are permitted provided that the following conditions are met: 7*b0104773SPascal Brand * 8*b0104773SPascal Brand * 1. Redistributions of source code must retain the above copyright notice, 9*b0104773SPascal Brand * this list of conditions and the following disclaimer. 10*b0104773SPascal Brand * 11*b0104773SPascal Brand * 2. Redistributions in binary form must reproduce the above copyright notice, 12*b0104773SPascal Brand * this list of conditions and the following disclaimer in the documentation 13*b0104773SPascal Brand * and/or other materials provided with the distribution. 14*b0104773SPascal Brand * 15*b0104773SPascal Brand * 3. Neither the name of the copyright holder nor the names of its 16*b0104773SPascal Brand * contributors may be used to endorse or promote products derived from this 17*b0104773SPascal Brand * software without specific prior written permission. 18*b0104773SPascal Brand * 19*b0104773SPascal Brand * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20*b0104773SPascal Brand * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21*b0104773SPascal Brand * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22*b0104773SPascal Brand * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23*b0104773SPascal Brand * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24*b0104773SPascal Brand * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25*b0104773SPascal Brand * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26*b0104773SPascal Brand * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27*b0104773SPascal Brand * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28*b0104773SPascal Brand * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29*b0104773SPascal Brand * POSSIBILITY OF SUCH DAMAGE. 30*b0104773SPascal Brand */ 31*b0104773SPascal Brand 32*b0104773SPascal Brand /* 33*b0104773SPascal Brand FUNCTION 34*b0104773SPascal Brand <<memset>>---set an area of memory 35*b0104773SPascal Brand 36*b0104773SPascal Brand INDEX 37*b0104773SPascal Brand memset 38*b0104773SPascal Brand 39*b0104773SPascal Brand ANSI_SYNOPSIS 40*b0104773SPascal Brand #include <string.h> 41*b0104773SPascal Brand void *memset(void *<[dst]>, int <[c]>, size_t <[length]>); 42*b0104773SPascal Brand 43*b0104773SPascal Brand TRAD_SYNOPSIS 44*b0104773SPascal Brand #include <string.h> 45*b0104773SPascal Brand void *memset(<[dst]>, <[c]>, <[length]>) 46*b0104773SPascal Brand void *<[dst]>; 47*b0104773SPascal Brand int <[c]>; 48*b0104773SPascal Brand size_t <[length]>; 49*b0104773SPascal Brand 50*b0104773SPascal Brand DESCRIPTION 51*b0104773SPascal Brand This function converts the argument <[c]> into an unsigned 52*b0104773SPascal Brand char and fills the first <[length]> characters of the array 53*b0104773SPascal Brand pointed to by <[dst]> to the value. 54*b0104773SPascal Brand 55*b0104773SPascal Brand RETURNS 56*b0104773SPascal Brand <<memset>> returns the value of <[dst]>. 57*b0104773SPascal Brand 58*b0104773SPascal Brand PORTABILITY 59*b0104773SPascal Brand <<memset>> is ANSI C. 60*b0104773SPascal Brand 61*b0104773SPascal Brand <<memset>> requires no supporting OS subroutines. 62*b0104773SPascal Brand 63*b0104773SPascal Brand QUICKREF 64*b0104773SPascal Brand memset ansi pure 65*b0104773SPascal Brand */ 66*b0104773SPascal Brand 67*b0104773SPascal Brand #include "_ansi.h" 68*b0104773SPascal Brand #include <string.h> 69*b0104773SPascal Brand 70*b0104773SPascal Brand #define LBLOCKSIZE (sizeof(long)) 71*b0104773SPascal Brand #define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1)) 72*b0104773SPascal Brand #define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE) 73*b0104773SPascal Brand 74*b0104773SPascal Brand _PTR _DEFUN(memset, (m, c, n), _PTR m _AND int c _AND size_t n) 75*b0104773SPascal Brand { 76*b0104773SPascal Brand char *s = (char *)m; 77*b0104773SPascal Brand 78*b0104773SPascal Brand #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) 79*b0104773SPascal Brand int i; 80*b0104773SPascal Brand unsigned long buffer; 81*b0104773SPascal Brand unsigned long *aligned_addr; 82*b0104773SPascal Brand unsigned int d = c & 0xff; /* To avoid sign extension, copy C to an 83*b0104773SPascal Brand unsigned variable. */ 84*b0104773SPascal Brand 85*b0104773SPascal Brand while (UNALIGNED(s)) { 86*b0104773SPascal Brand if (n--) 87*b0104773SPascal Brand *s++ = (char)c; 88*b0104773SPascal Brand else 89*b0104773SPascal Brand return m; 90*b0104773SPascal Brand } 91*b0104773SPascal Brand 92*b0104773SPascal Brand if (!TOO_SMALL(n)) { 93*b0104773SPascal Brand /* 94*b0104773SPascal Brand * If we get this far, we know that n is large and s is 95*b0104773SPascal Brand * word-aligned. 96*b0104773SPascal Brand */ 97*b0104773SPascal Brand aligned_addr = (unsigned long *)s; 98*b0104773SPascal Brand 99*b0104773SPascal Brand /* Store D into each char sized location in BUFFER so that 100*b0104773SPascal Brand we can set large blocks quickly. */ 101*b0104773SPascal Brand buffer = (d << 8) | d; 102*b0104773SPascal Brand buffer |= (buffer << 16); 103*b0104773SPascal Brand for (i = 32; i < LBLOCKSIZE * 8; i <<= 1) 104*b0104773SPascal Brand buffer = (buffer << i) | buffer; 105*b0104773SPascal Brand 106*b0104773SPascal Brand /* Unroll the loop. */ 107*b0104773SPascal Brand while (n >= LBLOCKSIZE * 4) { 108*b0104773SPascal Brand *aligned_addr++ = buffer; 109*b0104773SPascal Brand *aligned_addr++ = buffer; 110*b0104773SPascal Brand *aligned_addr++ = buffer; 111*b0104773SPascal Brand *aligned_addr++ = buffer; 112*b0104773SPascal Brand n -= 4 * LBLOCKSIZE; 113*b0104773SPascal Brand } 114*b0104773SPascal Brand 115*b0104773SPascal Brand while (n >= LBLOCKSIZE) { 116*b0104773SPascal Brand *aligned_addr++ = buffer; 117*b0104773SPascal Brand n -= LBLOCKSIZE; 118*b0104773SPascal Brand } 119*b0104773SPascal Brand /* Pick up the remainder with a bytewise loop. */ 120*b0104773SPascal Brand s = (char *)aligned_addr; 121*b0104773SPascal Brand } 122*b0104773SPascal Brand #endif /* not PREFER_SIZE_OVER_SPEED */ 123*b0104773SPascal Brand 124*b0104773SPascal Brand while (n--) 125*b0104773SPascal Brand *s++ = (char)c; 126*b0104773SPascal Brand 127*b0104773SPascal Brand return m; 128*b0104773SPascal Brand } 129