<commit_before>/**
 *  mymemcpy
 *  ========
 *
 *  A re-implementation of memcpy without using libraries functions.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h> // for size_t in gcc, I'm sorry

void *
mymemcpy(void *dest, const void *src, size_t n)
{
    char *pd, *ps;
    // Use n directly for size_t might be 64-bit, thus unsafe for an int cast.
    for (pd = (char *)dest, ps = (char *)src; n > 0; --n, ++pd, ++ps) *pd = *ps;
    return pd;
}

typedef struct {
    int val;
} foo_t;

int
main(int argc, const char *argv[])
{
    foo_t *foo, *bar;

    foo = (foo_t *)malloc(sizeof(foo_t));
    bar = (foo_t *)malloc(sizeof(foo_t));

    foo->val = 42;
    mymemcpy(bar, foo, sizeof(bar));
    printf("bar->val=%d\n", bar->val);

    return 0;
}
<commit_msg>updated mymemcpy: optimization<commit_after>/**
 *  mymemcpy
 *  ========
 *
 *  A re-implementation of memcpy without using libraries functions.  Test with
 *  -DTEST_64 or -DTEST_32 for some optimizations.
 *
 *  Note: Compile with -O3 with the naive implementation `mymemcpy` will enable
 *  loop unrolling and SIMD instructions usage in GCC 8, which might be much
 *  quicker and closer to the library one `memcpy`.
 */

#include <stdlib.h>
#include <stddef.h>
#include <assert.h>

#define SIZ (1024 * 1024 * 128)

void
mymemcpy(void* dst, const void* src, size_t n)
{
	size_t i;
	unsigned char* d = (unsigned char*)dst;
	unsigned char* s = (unsigned char*)src;
	for (i = 0; i < n; ++i) {
		*d++ = *s++;
	}
}

void
mymemcpy32(void* dst, const void* src, size_t n)
{
	unsigned char* bd = (unsigned char*)dst;
	unsigned char* bs = (unsigned char*)src;

	while (((size_t)bd & 0x3) != 0) {
		*bd++ = *bs++;
		--n;
	}

	unsigned int* ld = (unsigned int*)dst;
	unsigned int* ls = (unsigned int*)src;

	while (n >= 4) {
		*ld++ = *ls++;
		n -= 4;
	}

	if (n) {
		bd = (unsigned char*)ld;
		bs = (unsigned char*)ls;

		while (n) {
			*bd++ = *bs++;
			--n;
		}
	}
}

void
mymemcpy64(void* dst, const void* src, size_t n)
{
	unsigned char* bd = (unsigned char*)dst;
	unsigned char* bs = (unsigned char*)src;

	while (((size_t)bd & 0x7) != 0) {
		*bd++ = *bs++;
		--n;
	}

	size_t* qd = (size_t *)dst;
	size_t* qs = (size_t *)src;

	while (n >= 8) {
		*qd++ = *qs++;
		n -= 8;
	}

	if (n) {
		bd = (unsigned char*)qd;
		bs = (unsigned char*)qs;

		while (n) {
			*bd++ = *bs++;
			--n;
		}
	}
}

int
main()
{
	void *a, *b;
	char *aa, *bb;

	a = malloc(SIZ);
	b = malloc(SIZ);

	aa = (char*)a;
	aa[SIZ - 1] = 'a';
	bb = (char*)b;

#if defined(TEST_64)
	mymemcpy64(b, a, SIZ);
#elif defined(TEST_32)
	mymemcpy32(b, a, SIZ);
#else
	mymemcpy(b, a, SIZ);
#endif /* TEST_64 */

	assert(bb[SIZ - 1] == 'a');
	return 0;
}
{'fraction_non_alphanumeric': 0.19047619047619047, 'fraction_numerical': 0.018973214285714284, 'mean_word_length': 3.0619335347432024, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '760961', 'n_tokens_mistral': 1219, 'n_tokens_neox': 1125, 'n_words': 331}