amath  1.8.5
Simple command line calculator
memset.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2014-2018 Carsten Sonne Larsen <cs@innolan.net>
3  * Copyright (c) 1990, 1993 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * Mike Hibler and Chris Torek.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  * Project homepage:
30  * https://amath.innolan.net
31  *
32  */
33 
34 /**
35  * @file memset.c
36  * @brief Fill block of memory with a constant value.
37  *
38  * Code originate from FreeBSD base, revision 229286.
39  *
40  * The original source code can be obtained from:
41  * https://svnweb.freebsd.org/base/head/lib/libc/string/memset.c?revision=229286
42  *
43  */
44 
45 #include "amathc.h"
46 
47 #if __GNUC__ > 2
48 #pragma GCC diagnostic ignored "-Wcast-align"
49 #endif
50 
51 typedef uintptr_t mem_ptr;
52 
53 /**
54  * @brief Fill block of memory with a constant value.
55  */
56 void MemSet(void* dst0, int c0, unsigned int length)
57 {
58  unsigned char* dst = (unsigned char*) dst0;
59  unsigned int t;
60  unsigned int c;
61 
62  /*
63  * If not enough words, just fill bytes. A length >= 2 words
64  * guarantees that at least one of them is `complete' after
65  * any necessary alignment. For instance:
66  *
67  * |-----------|-----------|-----------|
68  * |00|01|02|03|04|05|06|07|08|09|0A|00|
69  * ^---------------------^
70  * dst dst+length-1
71  *
72  * but we use a minimum of 3 here since the overhead of the code
73  * to do word writes is substantial.
74  */
75  if (length < 3 * wsize)
76  {
77  while (length != 0)
78  {
79  *dst++ = c0;
80  --length;
81  }
82  }
83 
84  if ((c = (unsigned char)c0) != 0)
85  { /* Fill the word. */
86  c = (c << 8) | c; /* u_int is 16 bits. */
87 #if UINT_MAX > 0xffff
88  c = (c << 16) | c; /* u_int is 32 bits. */
89 #endif
90 #if UINT_MAX > 0xffffffff
91  c = (c << 32) | c; /* u_int is 64 bits. */
92 #endif
93  }
94 
95  /* Align destination by filling in bytes. */
96  if ((t = (mem_ptr)dst & wmask) != 0)
97  {
98  t = wsize - t;
99  length -= t;
100  do
101  {
102  *dst++ = c0;
103  }
104  while (--t != 0);
105  }
106 
107  /* Fill words. Length was >= 2*words so we know t >= 1 here. */
108  t = length / wsize;
109  do
110  {
111  *(unsigned int*)dst = c;
112  dst += wsize;
113  }
114  while (--t != 0);
115 
116  /* Mop up trailing bytes, if any. */
117  t = length & wmask;
118  if (t != 0)
119  do
120  {
121  *dst++ = c0;
122  }
123  while (--t != 0);
124 }
uintptr_t mem_ptr
Definition: memset.c:51
#define wmask
Definition: amath.h:233
#define wsize
Definition: amath.h:232
void MemSet(void *dst0, int c0, unsigned int length)
Fill block of memory with a constant value.
Definition: memset.c:56