Changeset e64c4b2 in mainline


Ignore:
Timestamp:
2008-12-23T19:45:57Z (15 years ago)
Author:
Jiri Svoboda <jirik.svoboda@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
404464a
Parents:
576845ec
Message:

Separate memxxx() functions into mem.c.

Location:
uspace/lib/libc
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libc/Makefile

    r576845ec re64c4b2  
    5252        generic/as.c \
    5353        generic/cap.c \
     54        generic/mem.c \
    5455        generic/string.c \
    5556        generic/fibril.c \
  • uspace/lib/libc/generic/string.c

    r576845ec re64c4b2  
    3535
    3636#include <string.h>
    37 #include <unistd.h>
     37#include <stdlib.h>
     38#include <limits.h>
    3839#include <ctype.h>
    39 #include <limits.h>
    40 #include <align.h>
    41 #include <sys/types.h>
    4240#include <malloc.h>
    43 
    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 }
    24041
    24142/** Count the number of characters in the string, not including terminating 0.
  • uspace/lib/libc/include/string.h

    r576845ec re64c4b2  
    3636#define LIBC_STRING_H_
    3737
     38#include <mem.h>
    3839#include <sys/types.h>
    39 
    40 #define bzero(ptr, len)  memset((ptr), 0, (len))
    41 
    42 extern void * memset(void *, int, size_t);
    43 extern void * memcpy(void *, const void *, size_t);
    44 extern void * memmove(void *, const void *, size_t);
    45 
    46 extern int bcmp(const char *, const char *, size_t);
    4740
    4841extern int strcmp(const char *, const char *);
Note: See TracChangeset for help on using the changeset viewer.