baremetal: second try (with i386-elf-gcc)
This commit is contained in:
@ -1,387 +1,9 @@
|
|||||||
#include "platform_api_vmcore.h"
|
#include "platform_api_vmcore.h"
|
||||||
|
|
||||||
// Many implementations taken from musl: https://git.musl-libc.org
|
|
||||||
|
|
||||||
typedef int (*cmpfun)(const void *, const void *);
|
|
||||||
|
|
||||||
void
|
|
||||||
qsort(void *base, size_t nel, size_t width, cmpfun cmp)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static const int32_t upper_table[] = {
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6,
|
|
||||||
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
|
||||||
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
|
|
||||||
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
|
|
||||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 'A', 'B',
|
|
||||||
'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
|
|
||||||
'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 91, 92, 93, 94, 95, 96,
|
|
||||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
|
||||||
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 123, 124, 125, 126,
|
|
||||||
127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int32_t *const upper_ptable = upper_table + 128;
|
|
||||||
|
|
||||||
const int32_t **
|
|
||||||
__ctype_toupper_loc(void)
|
|
||||||
{
|
|
||||||
return (void *)&upper_ptable;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const int32_t lower_table[] = {
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6,
|
|
||||||
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
|
||||||
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
|
|
||||||
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
|
|
||||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 'a', 'b',
|
|
||||||
'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
|
|
||||||
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 91, 92, 93, 94, 95, 96,
|
|
||||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
|
||||||
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 123, 124, 125, 126,
|
|
||||||
127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int32_t *const lower_ptable = lower_table + 128;
|
|
||||||
|
|
||||||
const int32_t **
|
|
||||||
__ctype_tolower_loc(void)
|
|
||||||
{
|
|
||||||
return (void *)&lower_ptable;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
|
||||||
#define X(x) x
|
|
||||||
#else
|
|
||||||
#define X(x) (((x) / 256 | (x) * 256) % 65536)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const unsigned short table[] = {
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, X(0x200), X(0x200), X(0x200), X(0x200), X(0x200),
|
|
||||||
X(0x200), X(0x200), X(0x200), X(0x200), X(0x320), X(0x220), X(0x220),
|
|
||||||
X(0x220), X(0x220), X(0x200), X(0x200), X(0x200), X(0x200), X(0x200),
|
|
||||||
X(0x200), X(0x200), X(0x200), X(0x200), X(0x200), X(0x200), X(0x200),
|
|
||||||
X(0x200), X(0x200), X(0x200), X(0x200), X(0x200), X(0x200), X(0x160),
|
|
||||||
X(0x4c0), X(0x4c0), X(0x4c0), X(0x4c0), X(0x4c0), X(0x4c0), X(0x4c0),
|
|
||||||
X(0x4c0), X(0x4c0), X(0x4c0), X(0x4c0), X(0x4c0), X(0x4c0), X(0x4c0),
|
|
||||||
X(0x4c0), X(0x8d8), X(0x8d8), X(0x8d8), X(0x8d8), X(0x8d8), X(0x8d8),
|
|
||||||
X(0x8d8), X(0x8d8), X(0x8d8), X(0x8d8), X(0x4c0), X(0x4c0), X(0x4c0),
|
|
||||||
X(0x4c0), X(0x4c0), X(0x4c0), X(0x4c0), X(0x8d5), X(0x8d5), X(0x8d5),
|
|
||||||
X(0x8d5), X(0x8d5), X(0x8d5), X(0x8c5), X(0x8c5), X(0x8c5), X(0x8c5),
|
|
||||||
X(0x8c5), X(0x8c5), X(0x8c5), X(0x8c5), X(0x8c5), X(0x8c5), X(0x8c5),
|
|
||||||
X(0x8c5), X(0x8c5), X(0x8c5), X(0x8c5), X(0x8c5), X(0x8c5), X(0x8c5),
|
|
||||||
X(0x8c5), X(0x8c5), X(0x4c0), X(0x4c0), X(0x4c0), X(0x4c0), X(0x4c0),
|
|
||||||
X(0x4c0), X(0x8d6), X(0x8d6), X(0x8d6), X(0x8d6), X(0x8d6), X(0x8d6),
|
|
||||||
X(0x8c6), X(0x8c6), X(0x8c6), X(0x8c6), X(0x8c6), X(0x8c6), X(0x8c6),
|
|
||||||
X(0x8c6), X(0x8c6), X(0x8c6), X(0x8c6), X(0x8c6), X(0x8c6), X(0x8c6),
|
|
||||||
X(0x8c6), X(0x8c6), X(0x8c6), X(0x8c6), X(0x8c6), X(0x8c6), X(0x4c0),
|
|
||||||
X(0x4c0), X(0x4c0), X(0x4c0), X(0x200), 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned short *const ptable = table + 128;
|
|
||||||
|
|
||||||
const unsigned short **
|
|
||||||
__ctype_b_loc(void)
|
|
||||||
{
|
|
||||||
return (void *)&ptable;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) int
|
|
||||||
os_dumps_proc_mem_info(char *out, unsigned int size)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) void
|
|
||||||
__stack_chk_fail()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) uint32_t
|
|
||||||
__stack_chk_fail_local()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
os_cond_init(korp_cond *cond)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
os_cond_destroy(korp_cond *cond)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************
|
/****************************************************
|
||||||
* string
|
* string.h
|
||||||
****************************************************/
|
****************************************************/
|
||||||
|
|
||||||
static char *
|
|
||||||
twobyte_strstr(const unsigned char *h, const unsigned char *n)
|
|
||||||
{
|
|
||||||
uint16_t nw = n[0] << 8 | n[1], hw = h[0] << 8 | h[1];
|
|
||||||
for (h++; *h && hw != nw; hw = hw << 8 | *++h)
|
|
||||||
;
|
|
||||||
return *h ? (char *)h - 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
threebyte_strstr(const unsigned char *h, const unsigned char *n)
|
|
||||||
{
|
|
||||||
uint32_t nw = (uint32_t)n[0] << 24 | n[1] << 16 | n[2] << 8;
|
|
||||||
uint32_t hw = (uint32_t)h[0] << 24 | h[1] << 16 | h[2] << 8;
|
|
||||||
for (h += 2; *h && hw != nw; hw = (hw | *++h) << 8)
|
|
||||||
;
|
|
||||||
return *h ? (char *)h - 2 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
fourbyte_strstr(const unsigned char *h, const unsigned char *n)
|
|
||||||
{
|
|
||||||
uint32_t nw = (uint32_t)n[0] << 24 | n[1] << 16 | n[2] << 8 | n[3];
|
|
||||||
uint32_t hw = (uint32_t)h[0] << 24 | h[1] << 16 | h[2] << 8 | h[3];
|
|
||||||
for (h += 3; *h && hw != nw; hw = hw << 8 | *++h)
|
|
||||||
;
|
|
||||||
return *h ? (char *)h - 3 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
|
||||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
|
||||||
|
|
||||||
#define BITOP(a, b, op) \
|
|
||||||
((a)[(size_t)(b) / (8 * sizeof *(a))] op(size_t) 1 \
|
|
||||||
<< ((size_t)(b) % (8 * sizeof *(a))))
|
|
||||||
|
|
||||||
static char *
|
|
||||||
twoway_strstr(const unsigned char *h, const unsigned char *n)
|
|
||||||
{
|
|
||||||
const unsigned char *z;
|
|
||||||
size_t l, ip, jp, k, p, ms, p0, mem, mem0;
|
|
||||||
size_t byteset[32 / sizeof(size_t)] = { 0 };
|
|
||||||
size_t shift[256];
|
|
||||||
|
|
||||||
/* Computing length of needle and fill shift table */
|
|
||||||
for (l = 0; n[l] && h[l]; l++)
|
|
||||||
BITOP(byteset, n[l], |=), shift[n[l]] = l + 1;
|
|
||||||
if (n[l])
|
|
||||||
return 0; /* hit the end of h */
|
|
||||||
|
|
||||||
/* Compute maximal suffix */
|
|
||||||
ip = -1;
|
|
||||||
jp = 0;
|
|
||||||
k = p = 1;
|
|
||||||
while (jp + k < l) {
|
|
||||||
if (n[ip + k] == n[jp + k]) {
|
|
||||||
if (k == p) {
|
|
||||||
jp += p;
|
|
||||||
k = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
k++;
|
|
||||||
}
|
|
||||||
else if (n[ip + k] > n[jp + k]) {
|
|
||||||
jp += k;
|
|
||||||
k = 1;
|
|
||||||
p = jp - ip;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ip = jp++;
|
|
||||||
k = p = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ms = ip;
|
|
||||||
p0 = p;
|
|
||||||
|
|
||||||
/* And with the opposite comparison */
|
|
||||||
ip = -1;
|
|
||||||
jp = 0;
|
|
||||||
k = p = 1;
|
|
||||||
while (jp + k < l) {
|
|
||||||
if (n[ip + k] == n[jp + k]) {
|
|
||||||
if (k == p) {
|
|
||||||
jp += p;
|
|
||||||
k = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
k++;
|
|
||||||
}
|
|
||||||
else if (n[ip + k] < n[jp + k]) {
|
|
||||||
jp += k;
|
|
||||||
k = 1;
|
|
||||||
p = jp - ip;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ip = jp++;
|
|
||||||
k = p = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ip + 1 > ms + 1)
|
|
||||||
ms = ip;
|
|
||||||
else
|
|
||||||
p = p0;
|
|
||||||
|
|
||||||
/* Periodic needle? */
|
|
||||||
if (memcmp(n, n + p, ms + 1)) {
|
|
||||||
mem0 = 0;
|
|
||||||
p = MAX(ms, l - ms - 1) + 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mem0 = l - p;
|
|
||||||
mem = 0;
|
|
||||||
|
|
||||||
/* Initialize incremental end-of-haystack pointer */
|
|
||||||
z = h;
|
|
||||||
|
|
||||||
/* Search loop */
|
|
||||||
for (;;) {
|
|
||||||
/* Update incremental end-of-haystack pointer */
|
|
||||||
if (z - h < l) {
|
|
||||||
/* Fast estimate for MAX(l,63) */
|
|
||||||
size_t grow = l | 63;
|
|
||||||
const unsigned char *z2 = memchr(z, 0, grow);
|
|
||||||
if (z2) {
|
|
||||||
z = z2;
|
|
||||||
if (z - h < l)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
z += grow;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check last byte first; advance by shift on mismatch */
|
|
||||||
if (BITOP(byteset, h[l - 1], &)) {
|
|
||||||
k = l - shift[h[l - 1]];
|
|
||||||
if (k) {
|
|
||||||
if (k < mem)
|
|
||||||
k = mem;
|
|
||||||
h += k;
|
|
||||||
mem = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
h += l;
|
|
||||||
mem = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compare right half */
|
|
||||||
for (k = MAX(ms + 1, mem); n[k] && n[k] == h[k]; k++)
|
|
||||||
;
|
|
||||||
if (n[k]) {
|
|
||||||
h += k - ms;
|
|
||||||
mem = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* Compare left half */
|
|
||||||
for (k = ms + 1; k > mem && n[k - 1] == h[k - 1]; k--)
|
|
||||||
;
|
|
||||||
if (k <= mem)
|
|
||||||
return (char *)h;
|
|
||||||
h += p;
|
|
||||||
mem = mem0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) char *
|
|
||||||
strstr(const char *h, const char *n)
|
|
||||||
{
|
|
||||||
/* Return immediately on empty needle */
|
|
||||||
if (!n[0])
|
|
||||||
return (char *)h;
|
|
||||||
|
|
||||||
/* Use faster algorithms for short needles */
|
|
||||||
h = strchr(h, *n);
|
|
||||||
if (!h || !n[1])
|
|
||||||
return (char *)h;
|
|
||||||
if (!h[1])
|
|
||||||
return 0;
|
|
||||||
if (!n[2])
|
|
||||||
return twobyte_strstr((void *)h, (void *)n);
|
|
||||||
if (!h[2])
|
|
||||||
return 0;
|
|
||||||
if (!n[3])
|
|
||||||
return threebyte_strstr((void *)h, (void *)n);
|
|
||||||
if (!h[3])
|
|
||||||
return 0;
|
|
||||||
if (!n[4])
|
|
||||||
return fourbyte_strstr((void *)h, (void *)n);
|
|
||||||
|
|
||||||
return twoway_strstr((void *)h, (void *)n);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) void *
|
__attribute__((weak)) void *
|
||||||
memcpy(void *restrict dest, const void *restrict src, size_t n)
|
memcpy(void *restrict dest, const void *restrict src, size_t n)
|
||||||
{
|
{
|
||||||
@ -459,192 +81,6 @@ memset(void *dest, int c, size_t n)
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((weak)) int
|
|
||||||
memcmp(const void *vl, const void *vr, size_t n)
|
|
||||||
{
|
|
||||||
const unsigned char *l = vl, *r = vr;
|
|
||||||
for (; n && *l == *r; n--, l++, r++)
|
|
||||||
;
|
|
||||||
return n ? *l - *r : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) void *
|
|
||||||
memchr(const void *src, int c, size_t n)
|
|
||||||
{
|
|
||||||
const unsigned char *s = src;
|
|
||||||
c = (unsigned char)c;
|
|
||||||
for (; n && *s != c; s++, n--)
|
|
||||||
;
|
|
||||||
return n ? (void *)s : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) unsigned long
|
|
||||||
strtoul(const char *restrict s, char **restrict p, int base)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) long
|
|
||||||
strtol(const char *restrict s, char **restrict p, int base)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) int
|
|
||||||
strncmp(const char *_l, const char *_r, size_t n)
|
|
||||||
{
|
|
||||||
const unsigned char *l = (void *)_l, *r = (void *)_r;
|
|
||||||
if (!n--)
|
|
||||||
return 0;
|
|
||||||
for (; *l && *r && n && *l == *r; l++, r++, n--)
|
|
||||||
;
|
|
||||||
return *l - *r;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) int
|
|
||||||
strcmp(const char *l, const char *r)
|
|
||||||
{
|
|
||||||
for (; *l == *r && *l; l++, r++)
|
|
||||||
;
|
|
||||||
return *(unsigned char *)l - *(unsigned char *)r;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) size_t
|
|
||||||
strlen(const char *s)
|
|
||||||
{
|
|
||||||
const char *a = s;
|
|
||||||
for (; *s; s++)
|
|
||||||
;
|
|
||||||
return s - a;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) char *
|
|
||||||
__stpncpy(char *restrict d, const char *restrict s, size_t n)
|
|
||||||
{
|
|
||||||
for (; n && (*d = *s); n--, s++, d++)
|
|
||||||
;
|
|
||||||
memset(d, 0, n);
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) char *
|
|
||||||
strncpy(char *restrict d, const char *restrict s, size_t n)
|
|
||||||
{
|
|
||||||
__stpncpy(d, s, n);
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) char *
|
|
||||||
__strchrnul(const char *s, int c)
|
|
||||||
{
|
|
||||||
c = (unsigned char)c;
|
|
||||||
if (!c)
|
|
||||||
return (char *)s + strlen(s);
|
|
||||||
|
|
||||||
for (; *s && *(unsigned char *)s != c; s++)
|
|
||||||
;
|
|
||||||
return (char *)s;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) char *
|
|
||||||
strchr(const char *s, int c)
|
|
||||||
{
|
|
||||||
char *r = __strchrnul(s, c);
|
|
||||||
return *(unsigned char *)r == (unsigned char)c ? r : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) size_t
|
|
||||||
strspn(const char *s, const char *c)
|
|
||||||
{
|
|
||||||
const char *a = s;
|
|
||||||
size_t byteset[32 / sizeof(size_t)] = { 0 };
|
|
||||||
|
|
||||||
if (!c[0])
|
|
||||||
return 0;
|
|
||||||
if (!c[1]) {
|
|
||||||
for (; *s == *c; s++)
|
|
||||||
;
|
|
||||||
return s - a;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; *c && BITOP(byteset, *(unsigned char *)c, |=); c++)
|
|
||||||
;
|
|
||||||
for (; *s && BITOP(byteset, *(unsigned char *)s, &); s++)
|
|
||||||
;
|
|
||||||
return s - a;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) size_t
|
|
||||||
strcspn(const char *s, const char *c)
|
|
||||||
{
|
|
||||||
const char *a = s;
|
|
||||||
size_t byteset[32 / sizeof(size_t)];
|
|
||||||
|
|
||||||
if (!c[0] || !c[1])
|
|
||||||
return __strchrnul(s, *c) - a;
|
|
||||||
|
|
||||||
memset(byteset, 0, sizeof byteset);
|
|
||||||
for (; *c && BITOP(byteset, *(unsigned char *)c, |=); c++)
|
|
||||||
;
|
|
||||||
for (; *s && !BITOP(byteset, *(unsigned char *)s, &); s++)
|
|
||||||
;
|
|
||||||
return s - a;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) int
|
|
||||||
my_tolower(int c)
|
|
||||||
{
|
|
||||||
if ((unsigned)c - 'A' < 26)
|
|
||||||
// if (isupper(c))
|
|
||||||
return c | 32;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) int
|
|
||||||
strncasecmp(const char *_l, const char *_r, size_t n)
|
|
||||||
{
|
|
||||||
const unsigned char *l = (void *)_l, *r = (void *)_r;
|
|
||||||
if (!n--)
|
|
||||||
return 0;
|
|
||||||
for (; *l && *r && n && (*l == *r || my_tolower(*l) == my_tolower(*r));
|
|
||||||
l++, r++, n--)
|
|
||||||
;
|
|
||||||
return my_tolower(*l) - my_tolower(*r);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************
|
|
||||||
* stdio
|
|
||||||
****************************************************/
|
|
||||||
|
|
||||||
__attribute__((weak)) int
|
|
||||||
snprintf(char *restrict s, size_t n, const char *restrict fmt, ...)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) int
|
|
||||||
__snprintf_chk(char *s, size_t n, int m, size_t o, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) int
|
|
||||||
vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) int
|
|
||||||
__vsnprintf_chk(char *s, size_t n, int m, size_t o, const char *fmt,
|
|
||||||
#if __x86_64__
|
|
||||||
__gnuc_va_list whatever)
|
|
||||||
#else
|
|
||||||
char *whatever)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************
|
/****************************************************
|
||||||
* mman
|
* mman
|
||||||
****************************************************/
|
****************************************************/
|
||||||
@ -672,412 +108,6 @@ os_mprotect(void *addr, size_t size, int prot)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************
|
|
||||||
* lgcc/math
|
|
||||||
****************************************************/
|
|
||||||
|
|
||||||
double
|
|
||||||
sqrt(double x)
|
|
||||||
{
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
float
|
|
||||||
sqrtf(float x)
|
|
||||||
{
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
#define arith64_u64 unsigned long long int
|
|
||||||
#define arith64_s64 signed long long int
|
|
||||||
#define arith64_u32 unsigned int
|
|
||||||
#define arith64_s32 int
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
arith64_u64 u64;
|
|
||||||
arith64_s64 s64;
|
|
||||||
struct {
|
|
||||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
|
||||||
arith64_u32 hi;
|
|
||||||
arith64_u32 lo;
|
|
||||||
#else
|
|
||||||
arith64_u32 lo;
|
|
||||||
arith64_u32 hi;
|
|
||||||
#endif
|
|
||||||
} u32;
|
|
||||||
struct {
|
|
||||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
|
||||||
arith64_s32 hi;
|
|
||||||
arith64_s32 lo;
|
|
||||||
#else
|
|
||||||
arith64_s32 lo;
|
|
||||||
arith64_s32 hi;
|
|
||||||
#endif
|
|
||||||
} s32;
|
|
||||||
} arith64_word;
|
|
||||||
|
|
||||||
// extract hi and lo 32-bit words from 64-bit value
|
|
||||||
#define arith64_hi(n) (arith64_word){ .u64 = n }.u32.hi
|
|
||||||
#define arith64_lo(n) (arith64_word){ .u64 = n }.u32.lo
|
|
||||||
|
|
||||||
// Negate a if b is negative, via invert and increment.
|
|
||||||
#define arith64_neg(a, b) \
|
|
||||||
(((a) ^ ((((arith64_s64)(b)) >= 0) - 1)) + (((arith64_s64)(b)) < 0))
|
|
||||||
#define arith64_abs(a) arith64_neg(a, a)
|
|
||||||
|
|
||||||
// Return the absolute value of a.
|
|
||||||
// Note LLINT_MIN cannot be negated.
|
|
||||||
__attribute__((weak)) arith64_s64
|
|
||||||
__absvdi2(arith64_s64 a)
|
|
||||||
{
|
|
||||||
return arith64_abs(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the result of shifting a left by b bits.
|
|
||||||
__attribute__((weak)) arith64_s64
|
|
||||||
__ashldi3(arith64_s64 a, int b)
|
|
||||||
{
|
|
||||||
arith64_word w = { .s64 = a };
|
|
||||||
|
|
||||||
b &= 63;
|
|
||||||
|
|
||||||
if (b >= 32) {
|
|
||||||
w.u32.hi = w.u32.lo << (b - 32);
|
|
||||||
w.u32.lo = 0;
|
|
||||||
}
|
|
||||||
else if (b) {
|
|
||||||
w.u32.hi = (w.u32.lo >> (32 - b)) | (w.u32.hi << b);
|
|
||||||
w.u32.lo <<= b;
|
|
||||||
}
|
|
||||||
return w.s64;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the result of arithmetically shifting a right by b bits.
|
|
||||||
__attribute__((weak)) arith64_s64
|
|
||||||
__ashrdi3(arith64_s64 a, int b)
|
|
||||||
{
|
|
||||||
arith64_word w = { .s64 = a };
|
|
||||||
|
|
||||||
b &= 63;
|
|
||||||
|
|
||||||
if (b >= 32) {
|
|
||||||
w.s32.lo = w.s32.hi >> (b - 32);
|
|
||||||
w.s32.hi >>= 31; // 0xFFFFFFFF or 0
|
|
||||||
}
|
|
||||||
else if (b) {
|
|
||||||
w.u32.lo = (w.u32.hi << (32 - b)) | (w.u32.lo >> b);
|
|
||||||
w.s32.hi >>= b;
|
|
||||||
}
|
|
||||||
return w.s64;
|
|
||||||
}
|
|
||||||
|
|
||||||
// These functions return the number of leading 0-bits in a, starting at the
|
|
||||||
// most significant bit position. If a is zero, the result is undefined.
|
|
||||||
__attribute__((weak)) int
|
|
||||||
__clzsi2(arith64_u32 a)
|
|
||||||
{
|
|
||||||
int b, n = 0;
|
|
||||||
b = !(a & 0xffff0000) << 4;
|
|
||||||
n += b;
|
|
||||||
a <<= b;
|
|
||||||
b = !(a & 0xff000000) << 3;
|
|
||||||
n += b;
|
|
||||||
a <<= b;
|
|
||||||
b = !(a & 0xf0000000) << 2;
|
|
||||||
n += b;
|
|
||||||
a <<= b;
|
|
||||||
b = !(a & 0xc0000000) << 1;
|
|
||||||
n += b;
|
|
||||||
a <<= b;
|
|
||||||
return n + !(a & 0x80000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) int
|
|
||||||
__clzdi2(arith64_u64 a)
|
|
||||||
{
|
|
||||||
int b, n = 0;
|
|
||||||
b = !(a & 0xffffffff00000000ULL) << 5;
|
|
||||||
n += b;
|
|
||||||
a <<= b;
|
|
||||||
b = !(a & 0xffff000000000000ULL) << 4;
|
|
||||||
n += b;
|
|
||||||
a <<= b;
|
|
||||||
b = !(a & 0xff00000000000000ULL) << 3;
|
|
||||||
n += b;
|
|
||||||
a <<= b;
|
|
||||||
b = !(a & 0xf000000000000000ULL) << 2;
|
|
||||||
n += b;
|
|
||||||
a <<= b;
|
|
||||||
b = !(a & 0xc000000000000000ULL) << 1;
|
|
||||||
n += b;
|
|
||||||
a <<= b;
|
|
||||||
return n + !(a & 0x8000000000000000ULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// These functions return the number of trailing 0-bits in a, starting at the
|
|
||||||
// least significant bit position. If a is zero, the result is undefined.
|
|
||||||
__attribute__((weak)) int
|
|
||||||
__ctzsi2(arith64_u32 a)
|
|
||||||
{
|
|
||||||
int b, n = 0;
|
|
||||||
b = !(a & 0x0000ffff) << 4;
|
|
||||||
n += b;
|
|
||||||
a >>= b;
|
|
||||||
b = !(a & 0x000000ff) << 3;
|
|
||||||
n += b;
|
|
||||||
a >>= b;
|
|
||||||
b = !(a & 0x0000000f) << 2;
|
|
||||||
n += b;
|
|
||||||
a >>= b;
|
|
||||||
b = !(a & 0x00000003) << 1;
|
|
||||||
n += b;
|
|
||||||
a >>= b;
|
|
||||||
return n + !(a & 0x00000001);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) int
|
|
||||||
__ctzdi2(arith64_u64 a)
|
|
||||||
{
|
|
||||||
int b, n = 0;
|
|
||||||
b = !(a & 0x00000000ffffffffULL) << 5;
|
|
||||||
n += b;
|
|
||||||
a >>= b;
|
|
||||||
b = !(a & 0x000000000000ffffULL) << 4;
|
|
||||||
n += b;
|
|
||||||
a >>= b;
|
|
||||||
b = !(a & 0x00000000000000ffULL) << 3;
|
|
||||||
n += b;
|
|
||||||
a >>= b;
|
|
||||||
b = !(a & 0x000000000000000fULL) << 2;
|
|
||||||
n += b;
|
|
||||||
a >>= b;
|
|
||||||
b = !(a & 0x0000000000000003ULL) << 1;
|
|
||||||
n += b;
|
|
||||||
a >>= b;
|
|
||||||
return n + !(a & 0x0000000000000001ULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate both the quotient and remainder of the unsigned division of a by
|
|
||||||
// b. The return value is the quotient, and the remainder is placed in variable
|
|
||||||
// pointed to by c (if it's not NULL).
|
|
||||||
__attribute__((weak)) arith64_u64
|
|
||||||
__divmoddi4(arith64_u64 a, arith64_u64 b, arith64_u64 *c)
|
|
||||||
{
|
|
||||||
if (b > a) // divisor > numerator?
|
|
||||||
{
|
|
||||||
if (c)
|
|
||||||
*c = a; // remainder = numerator
|
|
||||||
return 0; // quotient = 0
|
|
||||||
}
|
|
||||||
if (!arith64_hi(b)) // divisor is 32-bit
|
|
||||||
{
|
|
||||||
if (b == 0) // divide by 0
|
|
||||||
{
|
|
||||||
volatile char x = 0;
|
|
||||||
x = 1 / x; // force an exception
|
|
||||||
}
|
|
||||||
if (b == 1) // divide by 1
|
|
||||||
{
|
|
||||||
if (c)
|
|
||||||
*c = 0; // remainder = 0
|
|
||||||
return a; // quotient = numerator
|
|
||||||
}
|
|
||||||
if (!arith64_hi(a)) // numerator is also 32-bit
|
|
||||||
{
|
|
||||||
if (c) // use generic 32-bit operators
|
|
||||||
*c = arith64_lo(a) % arith64_lo(b);
|
|
||||||
return arith64_lo(a) / arith64_lo(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// let's do long division
|
|
||||||
char bits = __clzdi2(b) - __clzdi2(a)
|
|
||||||
+ 1; // number of bits to iterate (a and b are non-zero)
|
|
||||||
arith64_u64 rem = a >> bits; // init remainder
|
|
||||||
a <<= 64 - bits; // shift numerator to the high bit
|
|
||||||
arith64_u64 wrap = 0; // start with wrap = 0
|
|
||||||
while (bits-- > 0) // for each bit
|
|
||||||
{
|
|
||||||
rem = (rem << 1) | (a >> 63); // shift numerator MSB to remainder LSB
|
|
||||||
a = (a << 1) | (wrap & 1); // shift out the numerator, shift in wrap
|
|
||||||
wrap = ((arith64_s64)(b - rem - 1)
|
|
||||||
>> 63); // wrap = (b > rem) ? 0 : 0xffffffffffffffff (via sign
|
|
||||||
// extension)
|
|
||||||
rem -= b & wrap; // if (wrap) rem -= b
|
|
||||||
}
|
|
||||||
if (c)
|
|
||||||
*c = rem; // maybe set remainder
|
|
||||||
return (a << 1) | (wrap & 1); // return the quotient
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the quotient of the signed division of a by b.
|
|
||||||
__attribute__((weak)) arith64_s64
|
|
||||||
__divdi3(arith64_s64 a, arith64_s64 b)
|
|
||||||
{
|
|
||||||
arith64_u64 q = __divmoddi4(arith64_abs(a), arith64_abs(b), (void *)0);
|
|
||||||
return arith64_neg(q, a ^ b); // negate q if a and b signs are different
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the index of the least significant 1-bit in a, or the value zero if a
|
|
||||||
// is zero. The least significant bit is index one.
|
|
||||||
__attribute__((weak)) int
|
|
||||||
__ffsdi2(arith64_u64 a)
|
|
||||||
{
|
|
||||||
return a ? __ctzdi2(a) + 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the result of logically shifting a right by b bits.
|
|
||||||
__attribute__((weak)) arith64_u64
|
|
||||||
__lshrdi3(arith64_u64 a, int b)
|
|
||||||
{
|
|
||||||
arith64_word w = { .u64 = a };
|
|
||||||
|
|
||||||
b &= 63;
|
|
||||||
|
|
||||||
if (b >= 32) {
|
|
||||||
w.u32.lo = w.u32.hi >> (b - 32);
|
|
||||||
w.u32.hi = 0;
|
|
||||||
}
|
|
||||||
else if (b) {
|
|
||||||
w.u32.lo = (w.u32.hi << (32 - b)) | (w.u32.lo >> b);
|
|
||||||
w.u32.hi >>= b;
|
|
||||||
}
|
|
||||||
return w.u64;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the remainder of the signed division of a by b.
|
|
||||||
__attribute__((weak)) arith64_s64
|
|
||||||
__moddi3(arith64_s64 a, arith64_s64 b)
|
|
||||||
{
|
|
||||||
arith64_u64 r;
|
|
||||||
__divmoddi4(arith64_abs(a), arith64_abs(b), &r);
|
|
||||||
return arith64_neg(r, a); // negate remainder if numerator is negative
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the number of bits set in a.
|
|
||||||
__attribute__((weak)) int
|
|
||||||
__popcountsi2(arith64_u32 a)
|
|
||||||
{
|
|
||||||
// collect sums into two low bytes
|
|
||||||
a = a - ((a >> 1) & 0x55555555);
|
|
||||||
a = ((a >> 2) & 0x33333333) + (a & 0x33333333);
|
|
||||||
a = (a + (a >> 4)) & 0x0F0F0F0F;
|
|
||||||
a = (a + (a >> 16));
|
|
||||||
// add the bytes, return bottom 6 bits
|
|
||||||
return (a + (a >> 8)) & 63;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the number of bits set in a.
|
|
||||||
__attribute__((weak)) int
|
|
||||||
__popcountdi2(arith64_u64 a)
|
|
||||||
{
|
|
||||||
// collect sums into two low bytes
|
|
||||||
a = a - ((a >> 1) & 0x5555555555555555ULL);
|
|
||||||
a = ((a >> 2) & 0x3333333333333333ULL) + (a & 0x3333333333333333ULL);
|
|
||||||
a = (a + (a >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
|
|
||||||
a = (a + (a >> 32));
|
|
||||||
a = (a + (a >> 16));
|
|
||||||
// add the bytes, return bottom 7 bits
|
|
||||||
return (a + (a >> 8)) & 127;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the quotient of the unsigned division of a by b.
|
|
||||||
__attribute__((weak)) arith64_u64
|
|
||||||
__udivdi3(arith64_u64 a, arith64_u64 b)
|
|
||||||
{
|
|
||||||
return __divmoddi4(a, b, (void *)0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the remainder of the unsigned division of a by b.
|
|
||||||
__attribute__((weak)) arith64_u64
|
|
||||||
__umoddi3(arith64_u64 a, arith64_u64 b)
|
|
||||||
{
|
|
||||||
arith64_u64 r;
|
|
||||||
__divmoddi4(a, b, &r);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((weak)) arith64_u64
|
|
||||||
__udivmoddi4(arith64_u64 a, arith64_u64 b, arith64_u64 *c)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
https://gcc.gnu.org/onlinedocs/gccint/Integer-library-routines.html#index-_005f_005fudivmoddi4
|
|
||||||
*c = __umoddi3(a, b);
|
|
||||||
return __udivdi3(a, b);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/****************************************************
|
|
||||||
* rwlock
|
|
||||||
****************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
int
|
|
||||||
os_rwlock_init(korp_rwlock *rwlock)
|
|
||||||
{
|
|
||||||
if (!rwlock)
|
|
||||||
return -1;
|
|
||||||
rwlock->readers = 0;
|
|
||||||
rwlock->writer = false;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
os_rwlock_destroy(korp_rwlock *rwlock)
|
|
||||||
{
|
|
||||||
if (!rwlock)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
os_rwlock_rdlock(korp_rwlock *rwlock)
|
|
||||||
{
|
|
||||||
if (!rwlock)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// Wait until no writer
|
|
||||||
while (__atomic_load_n(&rwlock->writer, __ATOMIC_ACQUIRE))
|
|
||||||
;
|
|
||||||
|
|
||||||
// Increment readers count
|
|
||||||
__atomic_fetch_add(&rwlock->readers, 1, __ATOMIC_ACQUIRE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
os_rwlock_wrlock(korp_rwlock *rwlock)
|
|
||||||
{
|
|
||||||
if (!rwlock)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// Wait until no readers and no writer
|
|
||||||
while (__atomic_load_n(&rwlock->readers, __ATOMIC_ACQUIRE) > 0
|
|
||||||
|| __atomic_test_and_set(&rwlock->writer, __ATOMIC_ACQUIRE))
|
|
||||||
;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
os_rwlock_unlock(korp_rwlock *rwlock)
|
|
||||||
{
|
|
||||||
if (!rwlock)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (__atomic_load_n(&rwlock->writer, __ATOMIC_ACQUIRE)) {
|
|
||||||
// Writer releasing
|
|
||||||
__atomic_clear(&rwlock->writer, __ATOMIC_RELEASE);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Reader releasing
|
|
||||||
__atomic_fetch_sub(&rwlock->readers, 1, __ATOMIC_RELEASE);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/****************************************************
|
/****************************************************
|
||||||
* Section 1 *
|
* Section 1 *
|
||||||
* Interfaces required by the runtime *
|
* Interfaces required by the runtime *
|
||||||
|
|||||||
@ -5,17 +5,17 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
// #include <assert.h>
|
// #include <assert.h>
|
||||||
// #include <time.h>
|
// #include <time.h>
|
||||||
#include <string.h>
|
// #include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
// #include <stdlib.h>
|
||||||
#include <math.h>
|
// #include <math.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <ctype.h>
|
// #include <ctype.h>
|
||||||
#include <pthread.h>
|
// #include <pthread.h>
|
||||||
// #include <signal.h>
|
// #include <signal.h>
|
||||||
#include <semaphore.h>
|
// #include <semaphore.h>
|
||||||
// #include <limits.h>
|
// #include <limits.h>
|
||||||
#include <dirent.h>
|
// #include <dirent.h>
|
||||||
// #include <fcntl.h>
|
// #include <fcntl.h>
|
||||||
// #include <unistd.h>
|
// #include <unistd.h>
|
||||||
// #include <poll.h>
|
// #include <poll.h>
|
||||||
@ -42,11 +42,19 @@ extern "C" {
|
|||||||
#define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024)
|
#define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024)
|
||||||
#define BH_THREAD_DEFAULT_PRIORITY 0
|
#define BH_THREAD_DEFAULT_PRIORITY 0
|
||||||
|
|
||||||
typedef pthread_t korp_tid;
|
typedef int korp_tid;
|
||||||
typedef pthread_mutex_t korp_mutex;
|
typedef struct {
|
||||||
typedef pthread_cond_t korp_cond;
|
int dummy;
|
||||||
typedef pthread_t korp_thread;
|
} korp_mutex;
|
||||||
typedef sem_t korp_sem;
|
typedef struct {
|
||||||
|
int dummy;
|
||||||
|
} korp_cond;
|
||||||
|
typedef struct {
|
||||||
|
int dummy;
|
||||||
|
} korp_thread;
|
||||||
|
typedef struct {
|
||||||
|
int dummy;
|
||||||
|
} korp_sem;
|
||||||
|
|
||||||
// typedef pthread_rwlock_t korp_rwlock;
|
// typedef pthread_rwlock_t korp_rwlock;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -55,7 +63,9 @@ typedef struct {
|
|||||||
} korp_rwlock;
|
} korp_rwlock;
|
||||||
|
|
||||||
typedef int os_file_handle;
|
typedef int os_file_handle;
|
||||||
typedef DIR *os_dir_stream;
|
typedef struct {
|
||||||
|
int dummy;
|
||||||
|
} *os_dir_stream;
|
||||||
typedef int os_raw_file_handle;
|
typedef int os_raw_file_handle;
|
||||||
|
|
||||||
static inline os_file_handle
|
static inline os_file_handle
|
||||||
|
|||||||
@ -3,10 +3,10 @@ set (PLATFORM_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR})
|
|||||||
add_definitions(-DBH_PLATFORM_BAREMETAL)
|
add_definitions(-DBH_PLATFORM_BAREMETAL)
|
||||||
|
|
||||||
include_directories(${PLATFORM_SHARED_DIR})
|
include_directories(${PLATFORM_SHARED_DIR})
|
||||||
|
|
||||||
include_directories(${PLATFORM_SHARED_DIR}/../include)
|
include_directories(${PLATFORM_SHARED_DIR}/../include)
|
||||||
|
# file (GLOB header ${PLATFORM_SHARED_DIR}/../include/baremetal/*.h)
|
||||||
|
# list (APPEND RUNTIME_LIB_HEADER_LIST ${header})
|
||||||
|
|
||||||
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
|
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
|
||||||
set (PLATFORM_SHARED_SOURCE ${source_all})
|
set (PLATFORM_SHARED_SOURCE ${source_all})
|
||||||
|
|
||||||
file (GLOB header ${PLATFORM_SHARED_DIR}/../include/baremetal/*.h)
|
|
||||||
LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header})
|
|
||||||
|
|||||||
Reference in New Issue
Block a user