seL4/src/util.c
Matthew Fernandez d36447b35f Mark strncmp as a pure function.
Simply a performance optimisation. This has no effect on functional behaviour.
2016-06-29 17:04:28 +10:00

143 lines
3 KiB
C

/*
* Copyright 2014, General Dynamics C4 Systems
*
* This software may be distributed and modified according to the terms of
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
* See "LICENSE_GPLv2.txt" for details.
*
* @TAG(GD_GPL)
*/
#include <assert.h>
#include <stdint.h>
#include <util.h>
/*
* memzero needs a custom type that allows us to use a word
* that has the aliasing properties of a char.
*/
typedef unsigned long __attribute__((__may_alias__)) ulong_alias;
/*
* Zero 'n' bytes of memory starting from 's'.
*
* 'n' and 's' must be word aligned.
*/
void
memzero(void *s, unsigned long n)
{
uint8_t *p = s;
/* Ensure alignment constraints are met. */
assert((unsigned long)s % sizeof(unsigned long) == 0);
assert(n % sizeof(unsigned long) == 0);
/* We will never memzero an area larger than the largest current
live object */
/** GHOSTUPD: "(gs_get_assn cap_get_capSizeBits_'proc \<acute>ghost'state = 0
\<or> \<acute>n <= gs_get_assn cap_get_capSizeBits_'proc \<acute>ghost'state, id)" */
/* Write out words. */
while (n != 0) {
*(ulong_alias *)p = 0;
p += sizeof(ulong_alias);
n -= sizeof(ulong_alias);
}
}
void*
memset(void *s, unsigned long c, unsigned long n)
{
uint8_t *p;
/*
* If we are only writing zeros and we are word aligned, we can
* use the optimized 'memzero' function.
*/
if (likely(c == 0 && ((unsigned long)s % sizeof(unsigned long)) == 0 && (n % sizeof(unsigned long)) == 0)) {
memzero(s, n);
} else {
/* Otherwise, we use a slower, simple memset. */
for (p = (uint8_t *)s; n > 0; n--, p++) {
*p = (uint8_t)c;
}
}
return s;
}
void* USED
memcpy(void* ptr_dst, const void* ptr_src, unsigned long n)
{
uint8_t *p;
const uint8_t *q;
for (p = (uint8_t *)ptr_dst, q = (const uint8_t *)ptr_src; n; n--, p++, q++) {
*p = *q;
}
return ptr_dst;
}
int PURE
strncmp(const char* s1, const char* s2, int n)
{
word_t i;
int diff;
for (i = 0; i < n; i++) {
diff = ((unsigned char*)s1)[i] - ((unsigned char*)s2)[i];
if (diff != 0 || s1[i] == '\0') {
return diff;
}
}
return 0;
}
long CONST
char_to_long(char c)
{
if (c >= '0' && c <= '9') {
return c - '0';
} else if (c >= 'A' && c <= 'F') {
return c - 'A' + 10;
} else if (c >= 'a' && c <= 'f') {
return c - 'a' + 10;
}
return -1;
}
long PURE
str_to_long(const char* str)
{
unsigned int base;
long res;
long val = 0;
char c;
/*check for "0x" */
if (*str == '0' && (*(str + 1) == 'x' || *(str + 1) == 'X')) {
base = 16;
str += 2;
} else {
base = 10;
}
if (!*str) {
return -1;
}
c = *str;
while (c != '\0') {
res = char_to_long(c);
if (res == -1 || res >= base) {
return -1;
}
val = val * base + res;
str++;
c = *str;
}
return val;
}