source: umon/main/glib/memcpy.c @ a7b6f00

Last change on this file since a7b6f00 was a7b6f00, checked in by Ed Sutter <edsutterjr@…>, on 08/04/15 at 01:35:50

tree cleanup using 'astyle --unpad-paren --align-pointer=name --lineend=linux --add-brackets --convert-tabs --style=knf -A4 FILENAME'

  • Property mode set to 100644
File size: 3.1 KB
Line 
1#include "config.h"
2#include <ctype.h>
3#include "genlib.h"
4#include "stddefs.h"
5
6#ifndef MEMCPY_CHUNK
7#define MEMCPY_CHUNK (256*1024)
8#endif
9
10/* memcpy():
11 *  Copy n bytes from 'from' to 'to'; return 'to'.
12 *  This version of memcpy() tries to take advantage of address alignment.
13 *  The goal is to do as many of the copies on 4-byte aligned addresses,
14 *  falling back to 2-byte alignment, and finally, if there is no other
15 *  way, simple byte-by-byte copy.
16 *  Note that there is some point where the amount of overhead may exceed
17 *  the byte count; hence, this will take longer for small byte counts.
18 *  The assumption here is that small byte count memcpy() calls don't really
19 *  care.
20 */
21char *
22memcpy(char *to,char *from,int count)
23{
24    char    *to_copy, *end;
25#if INCLUDE_QUICKMEMCPY
26    char    *tend;
27#endif
28
29    to_copy = to;
30
31#if INCLUDE_QUICKMEMCPY
32    /* If count is greater than 8, get fancy, else just do byte-copy... */
33    if(count > 8) {
34        /* Attempt to optimize the transfer here... */
35        if(((int)to & 3) && ((int)from & 3)) {
36            /* If from and to pointers are both unaligned to the
37             * same degree then we can do a few char copies to get them
38             * 4-byte aligned and then do a lot of 4-byte aligned copies.
39             */
40            if(((int)to & 3) == ((int)from & 3)) {
41                while((int)to & 3) {
42                    *to++ = *from++;
43                    count--;
44                }
45            }
46            /* If from and to pointers are both odd, but different, then
47             * we can increment them both by 1 and do a bunch of 2-byte
48             * aligned copies...
49             */
50            else if(((int)to & 1) && ((int)from & 1)) {
51                *to++ = *from++;
52                count--;
53            }
54        }
55
56        /* If both pointers are now 4-byte aligned or 2-byte aligned,
57         * take advantage of that here...
58         */
59        if(!((int)to & 3) && !((int)from & 3)) {
60            tend = end = to + (count & ~3);
61            count = count & 3;
62#ifdef WATCHDOG_ENABLED
63            do {
64                tend = (end - to <= MEMCPY_CHUNK) ? end : to + MEMCPY_CHUNK;
65#endif
66                while(to < tend) {
67                    *(ulong *)to = *(ulong *)from;
68                    from += 4;
69                    to += 4;
70                }
71#ifdef WATCHDOG_ENABLED
72                WATCHDOG_MACRO;
73            } while(tend != end);
74#endif
75        } else if(!((int)to & 1) && !((int)from & 1)) {
76            tend = end = to + (count & ~1);
77            count = count & 1;
78#ifdef WATCHDOG_ENABLED
79            do {
80                tend = (end - to <= MEMCPY_CHUNK) ? end : to + MEMCPY_CHUNK;
81#endif
82                while(to < tend) {
83                    *(ushort *)to = *(ushort *)from;
84                    from += 2;
85                    to += 2;
86                }
87#ifdef WATCHDOG_ENABLED
88                WATCHDOG_MACRO;
89            } while(tend != end);
90#endif
91        }
92    }
93#endif
94
95    if(count) {
96        end = to + count;
97        while(to < end) {
98            *to++ = *from++;
99        }
100    }
101    return(to_copy);
102}
103
104void
105bcopy(char *from, char *to, int size)
106{
107    memcpy(to,from,size);
108}
Note: See TracBrowser for help on using the repository browser.