Subversion Repositories HelenOS

Rev

Rev 3730 | Rev 4226 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3730 Rev 3731
Line 32... Line 32...
32
 */
32
 */
33
/** @file
33
/** @file
34
 */
34
 */
35
 
35
 
36
#include <string.h>
36
#include <string.h>
37
#include <unistd.h>
-
 
38
#include <ctype.h>
37
#include <stdlib.h>
39
#include <limits.h>
38
#include <limits.h>
40
#include <align.h>
-
 
41
#include <sys/types.h>
39
#include <ctype.h>
42
#include <malloc.h>
40
#include <malloc.h>
43
 
41
 
44
/** Fill memory block with a constant value. */
-
 
45
void *memset(void *dest, int b, size_t n)
-
 
46
{
-
 
47
    char *pb;
-
 
48
    unsigned long *pw;
-
 
49
    size_t word_size;
-
 
50
    size_t n_words;
-
 
51
 
-
 
52
    unsigned long pattern;
-
 
53
    size_t i;
-
 
54
    size_t fill;
-
 
55
 
-
 
56
    /* Fill initial segment. */
-
 
57
    word_size = sizeof(unsigned long);
-
 
58
    fill = word_size - ((uintptr_t) dest & (word_size - 1));
-
 
59
    if (fill > n) fill = n;
-
 
60
 
-
 
61
    pb = dest;
-
 
62
 
-
 
63
    i = fill;
-
 
64
    while (i-- != 0)
-
 
65
        *pb++ = b;
-
 
66
 
-
 
67
    /* Compute remaining size. */
-
 
68
    n -= fill;
-
 
69
    if (n == 0) return dest;
-
 
70
 
-
 
71
    n_words = n / word_size;
-
 
72
    n = n % word_size;
-
 
73
    pw = (unsigned long *) pb;
-
 
74
 
-
 
75
    /* Create word-sized pattern for aligned segment. */
-
 
76
    pattern = 0;
-
 
77
    i = word_size;
-
 
78
    while (i-- != 0)
-
 
79
        pattern = (pattern << 8) | (uint8_t) b;
-
 
80
 
-
 
81
    /* Fill aligned segment. */
-
 
82
    i = n_words;
-
 
83
    while (i-- != 0)
-
 
84
        *pw++ = pattern;
-
 
85
 
-
 
86
    pb = (char *) pw;
-
 
87
 
-
 
88
    /* Fill final segment. */
-
 
89
    i = n;
-
 
90
    while (i-- != 0)
-
 
91
        *pb++ = b;
-
 
92
 
-
 
93
    return dest;
-
 
94
}
-
 
95
 
-
 
96
struct along {
-
 
97
    unsigned long n;
-
 
98
} __attribute__ ((packed));
-
 
99
 
-
 
100
static void *unaligned_memcpy(void *dst, const void *src, size_t n)
-
 
101
{
-
 
102
    int i, j;
-
 
103
    struct along *adst = dst;
-
 
104
    const struct along *asrc = src;
-
 
105
 
-
 
106
    for (i = 0; i < n / sizeof(unsigned long); i++)
-
 
107
        adst[i].n = asrc[i].n;
-
 
108
       
-
 
109
    for (j = 0; j < n % sizeof(unsigned long); j++)
-
 
110
        ((unsigned char *) (((unsigned long *) dst) + i))[j] =
-
 
111
            ((unsigned char *) (((unsigned long *) src) + i))[j];
-
 
112
       
-
 
113
    return (char *) dst;
-
 
114
}
-
 
115
 
-
 
116
/** Copy memory block. */
-
 
117
void *memcpy(void *dst, const void *src, size_t n)
-
 
118
{
-
 
119
    size_t i;
-
 
120
    size_t mod, fill;
-
 
121
    size_t word_size;
-
 
122
    size_t n_words;
-
 
123
 
-
 
124
    const unsigned long *srcw;
-
 
125
    unsigned long *dstw;
-
 
126
    const uint8_t *srcb;
-
 
127
    uint8_t *dstb;
-
 
128
 
-
 
129
    word_size = sizeof(unsigned long);
-
 
130
 
-
 
131
    /*
-
 
132
     * Are source and destination addresses congruent modulo word_size?
-
 
133
     * If not, use unaligned_memcpy().
-
 
134
     */
-
 
135
 
-
 
136
    if (((uintptr_t) dst & (word_size - 1)) !=
-
 
137
        ((uintptr_t) src & (word_size - 1)))
-
 
138
        return unaligned_memcpy(dst, src, n);
-
 
139
 
-
 
140
    /*
-
 
141
     * mod is the address modulo word size. fill is the length of the
-
 
142
     * initial buffer segment before the first word boundary.
-
 
143
     * If the buffer is very short, use unaligned_memcpy(), too.
-
 
144
     */
-
 
145
 
-
 
146
    mod = (uintptr_t) dst & (word_size - 1);
-
 
147
    fill = word_size - mod;
-
 
148
    if (fill > n) fill = n;
-
 
149
 
-
 
150
    /* Copy the initial segment. */
-
 
151
 
-
 
152
    srcb = src;
-
 
153
    dstb = dst;
-
 
154
 
-
 
155
    i = fill;
-
 
156
    while (i-- != 0)
-
 
157
        *dstb++ = *srcb++;
-
 
158
 
-
 
159
    /* Compute remaining length. */
-
 
160
 
-
 
161
    n -= fill;
-
 
162
    if (n == 0) return dst;
-
 
163
 
-
 
164
    /* Pointers to aligned segment. */
-
 
165
 
-
 
166
    dstw = (unsigned long *) dstb;
-
 
167
    srcw = (const unsigned long *) srcb;
-
 
168
 
-
 
169
    n_words = n / word_size;    /* Number of whole words to copy. */
-
 
170
    n -= n_words * word_size;   /* Remaining bytes at the end. */
-
 
171
 
-
 
172
    /* "Fast" copy. */
-
 
173
    i = n_words;
-
 
174
    while (i-- != 0)
-
 
175
        *dstw++ = *srcw++;
-
 
176
 
-
 
177
    /*
-
 
178
     * Copy the rest.
-
 
179
     */
-
 
180
 
-
 
181
    srcb = (const uint8_t *) srcw;
-
 
182
    dstb = (uint8_t *) dstw;
-
 
183
 
-
 
184
    i = n;
-
 
185
    while (i-- != 0)
-
 
186
        *dstb++ = *srcb++;
-
 
187
 
-
 
188
    return dst;
-
 
189
}
-
 
190
 
-
 
191
/** Move memory block with possible overlapping. */
-
 
192
void *memmove(void *dst, const void *src, size_t n)
-
 
193
{
-
 
194
    uint8_t *dp, *sp;
-
 
195
 
-
 
196
    /* Nothing to do? */
-
 
197
    if (src == dst)
-
 
198
        return dst;
-
 
199
 
-
 
200
    /* Non-overlapping? */
-
 
201
    if (dst >= src + n || src >= dst + n) {
-
 
202
        return memcpy(dst, src, n);
-
 
203
    }
-
 
204
 
-
 
205
    /* Which direction? */
-
 
206
    if (src > dst) {
-
 
207
        /* Forwards. */
-
 
208
        sp = src;
-
 
209
        dp = dst;
-
 
210
 
-
 
211
        while (n-- != 0)
-
 
212
            *dp++ = *sp++;
-
 
213
    } else {
-
 
214
        /* Backwards. */
-
 
215
        sp = src + (n - 1);
-
 
216
        dp = dst + (n - 1);
-
 
217
 
-
 
218
        while (n-- != 0)
-
 
219
            *dp-- = *sp--;
-
 
220
    }
-
 
221
 
-
 
222
    return dst;
-
 
223
}
-
 
224
 
-
 
225
/** Compare two memory areas.
-
 
226
 *
-
 
227
 * @param s1        Pointer to the first area to compare.
-
 
228
 * @param s2        Pointer to the second area to compare.
-
 
229
 * @param len       Size of the first area in bytes. Both areas must have
-
 
230
 *          the same length.
-
 
231
 * @return      If len is 0, return zero. If the areas match, return
-
 
232
 *          zero. Otherwise return non-zero.
-
 
233
 */
-
 
234
int bcmp(const char *s1, const char *s2, size_t len)
-
 
235
{
-
 
236
    for (; len && *s1++ == *s2++; len--)
-
 
237
        ;
-
 
238
    return len;
-
 
239
}
-
 
240
 
-
 
241
/** Count the number of characters in the string, not including terminating 0.
42
/** Count the number of characters in the string, not including terminating 0.
242
 *
43
 *
243
 * @param str       String.
44
 * @param str       String.
244
 * @return      Number of characters in string.
45
 * @return      Number of characters in string.
245
 */
46
 */