Subversion Repositories Kolibri OS

Rev

Rev 4874 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/*
2
FUNCTION
3
	<>---set an area of memory
4
 
5
INDEX
6
	memset
7
 
8
ANSI_SYNOPSIS
9
	#include 
10
	void *memset(void *<[dst]>, int <[c]>, size_t <[length]>);
11
 
12
TRAD_SYNOPSIS
13
	#include 
14
	void *memset(<[dst]>, <[c]>, <[length]>)
15
	void *<[dst]>;
16
	int <[c]>;
17
	size_t <[length]>;
18
 
19
DESCRIPTION
20
	This function converts the argument <[c]> into an unsigned
21
	char and fills the first <[length]> characters of the array
22
	pointed to by <[dst]> to the value.
23
 
24
RETURNS
25
	<> returns the value of <[dst]>.
26
 
27
PORTABILITY
28
<> is ANSI C.
29
 
30
    <> requires no supporting OS subroutines.
31
 
32
QUICKREF
33
	memset ansi pure
34
*/
35
 
36
#include 
4921 Serge 37
#include "local.h"
4349 Serge 38
 
39
#define LBLOCKSIZE (sizeof(long))
40
#define UNALIGNED(X)   ((long)X & (LBLOCKSIZE - 1))
41
#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
42
 
43
_PTR
4921 Serge 44
__inhibit_loop_to_libcall
4349 Serge 45
_DEFUN (memset, (m, c, n),
46
	_PTR m _AND
47
	int c _AND
48
	size_t n)
49
{
50
  char *s = (char *) m;
51
 
52
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
53
  int i;
54
  unsigned long buffer;
55
  unsigned long *aligned_addr;
56
  unsigned int d = c & 0xff;	/* To avoid sign extension, copy C to an
57
				   unsigned variable.  */
58
 
59
  while (UNALIGNED (s))
60
    {
61
      if (n--)
62
        *s++ = (char) c;
63
      else
64
        return m;
65
    }
66
 
67
  if (!TOO_SMALL (n))
68
    {
69
      /* If we get this far, we know that n is large and s is word-aligned. */
70
      aligned_addr = (unsigned long *) s;
71
 
72
      /* Store D into each char sized location in BUFFER so that
73
         we can set large blocks quickly.  */
74
      buffer = (d << 8) | d;
75
      buffer |= (buffer << 16);
76
      for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
77
        buffer = (buffer << i) | buffer;
78
 
79
      /* Unroll the loop.  */
80
      while (n >= LBLOCKSIZE*4)
81
        {
82
          *aligned_addr++ = buffer;
83
          *aligned_addr++ = buffer;
84
          *aligned_addr++ = buffer;
85
          *aligned_addr++ = buffer;
86
          n -= 4*LBLOCKSIZE;
87
        }
88
 
89
      while (n >= LBLOCKSIZE)
90
        {
91
          *aligned_addr++ = buffer;
92
          n -= LBLOCKSIZE;
93
        }
94
      /* Pick up the remainder with a bytewise loop.  */
95
      s = (char*)aligned_addr;
96
    }
97
 
98
#endif /* not PREFER_SIZE_OVER_SPEED */
99
 
100
  while (n--)
101
    *s++ = (char) c;
102
 
103
  return m;
104
}