forked from claziss/embench
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbeebsc.c
177 lines (122 loc) · 3.96 KB
/
beebsc.c
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/* BEEBS local library variants
Copyright (C) 2019 Embecosm Limited.
Contributor Jeremy Bennett <[email protected]>
This file is part of Embench and was formerly part of the Bristol/Embecosm
Embedded Benchmark Suite.
SPDX-License-Identifier: GPL-3.0-or-later */
/* These are very simple local versions of library routines, to ensure the
code is compiled with the flags used for the benchmark. Not all library
routines are here, just ones that cause a lot of unecessary load, or where
there is variation between platforms and architectures. */
#include <stddef.h>
#include <string.h>
#include "beebsc.h"
/* Seed for the random number generator */
static long int seed = 0;
/* Heap records and sane initial values */
static void *heap_ptr = NULL;
static void *heap_end = NULL;
static size_t heap_requested = 0;
/* Yield a sequence of random numbers in the range [0, 2^15-1].
long int is guaranteed to be at least 32 bits. The seed only ever uses 31
bits (so is positive).
For BEEBS this gets round different operating systems using different
multipliers and offsets and RAND_MAX variations. */
int
rand_beebs (void)
{
seed = (seed * 1103515245L + 12345) & ((1UL << 31) - 1);
return (int) (seed >> 16);
}
/* Initialize the random number generator */
void
srand_beebs (unsigned int new_seed)
{
seed = (long int) new_seed;
}
/* Initialize the BEEBS heap pointers. Note that the actual memory block is
in the caller code. */
void
init_heap_beebs (void *heap, size_t heap_size)
{
heap_ptr = (void *) heap;
heap_end = (void *) ((char *) heap_ptr + heap_size);
heap_requested = 0;
}
/* Report if malloc ever failed.
Return non-zero (TRUE) if malloc did not reqest more than was available
since the last call to init_heap_beebs, zero (FALSE) otherwise. */
int
check_heap_beebs (void *heap)
{
return ((void *) ((char *) heap + heap_requested) <= heap_end);
}
/* BEEBS version of malloc.
This is primarily to reduce library and OS dependencies. Malloc is
generally not used in embedded code, or if it is, only in well defined
contexts to pre-allocate a fixed amount of memory. So this simplistic
implementation is just fine.
Note in particular the assumption that memory will never be freed! */
void *
malloc_beebs (size_t size)
{
void *new_ptr = heap_ptr;
heap_requested += size;
if (((void *) ((char *) heap_ptr + size) > heap_end) || (0 == size))
return NULL;
else
{
heap_ptr = (void *) ((char *) heap_ptr + size);
return new_ptr;
}
}
/* BEEBS version of calloc.
Implement as wrapper for malloc */
void *
calloc_beebs (size_t nmemb, size_t size)
{
void *new_ptr = malloc_beebs (nmemb * size);
/* Calloc is defined to zero the memory. OK to use a function here, because
it will be handled specially by the compiler anyway. */
if (NULL != new_ptr)
memset (new_ptr, 0, nmemb * size);
return new_ptr;
}
/* BEEBS version of realloc.
This is primarily to reduce library and OS dependencies. We just have to
allocate new memory and copy stuff across. */
void *
realloc_beebs (void *ptr, size_t size)
{
void *new_ptr = heap_ptr;
heap_requested += size;
if (((void *) ((char *) heap_ptr + size) > heap_end) || (0 == size))
return NULL;
else
{
heap_ptr = (void *) ((char *) heap_ptr + size);
/* This is clunky, since we don't know the size of the original
pointer. However it is a read only action and we know it must
be big enough if we right off the end, or we couldn't have
allocated here. If the size is smaller, it doesn't matter. */
if (NULL != ptr)
{
size_t i;
for (i = 0; i < size; i++)
((char *) new_ptr)[i] = ((char *) ptr)[i];
}
return new_ptr;
}
}
/* BEEBS version of free.
For our simplified version of memory handling, free can just do nothing. */
void
free_beebs (void *ptr __attribute__ ((unused)))
{
}
/*
Local Variables:
mode: C
c-file-style: "gnu"
End:
*/