demo工程暂存 优化菜单界面UI和功能
This commit is contained in:
420
MCU/components/modules/coremark/macos/core_portme.c
Normal file
420
MCU/components/modules/coremark/macos/core_portme.c
Normal file
@ -0,0 +1,420 @@
|
||||
/*
|
||||
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original Author: Shay Gal-on
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "coremark.h"
|
||||
#if CALLGRIND_RUN
|
||||
#include <valgrind/callgrind.h>
|
||||
#endif
|
||||
|
||||
#if (MEM_METHOD == MEM_MALLOC)
|
||||
#include <string.h>
|
||||
/* Function: portable_malloc
|
||||
Provide malloc() functionality in a platform specific way.
|
||||
*/
|
||||
void *
|
||||
portable_malloc(size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
/* Function: portable_free
|
||||
Provide free() functionality in a platform specific way.
|
||||
*/
|
||||
void
|
||||
portable_free(void *p)
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
#else
|
||||
void *
|
||||
portable_malloc(size_t size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
void
|
||||
portable_free(void *p)
|
||||
{
|
||||
p = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (SEED_METHOD == SEED_VOLATILE)
|
||||
#if VALIDATION_RUN
|
||||
volatile ee_s32 seed1_volatile = 0x3415;
|
||||
volatile ee_s32 seed2_volatile = 0x3415;
|
||||
volatile ee_s32 seed3_volatile = 0x66;
|
||||
#endif
|
||||
#if PERFORMANCE_RUN
|
||||
volatile ee_s32 seed1_volatile = 0x0;
|
||||
volatile ee_s32 seed2_volatile = 0x0;
|
||||
volatile ee_s32 seed3_volatile = 0x66;
|
||||
#endif
|
||||
#if PROFILE_RUN
|
||||
volatile ee_s32 seed1_volatile = 0x8;
|
||||
volatile ee_s32 seed2_volatile = 0x8;
|
||||
volatile ee_s32 seed3_volatile = 0x8;
|
||||
#endif
|
||||
volatile ee_s32 seed4_volatile = ITERATIONS;
|
||||
volatile ee_s32 seed5_volatile = 0;
|
||||
#endif
|
||||
/* Porting: Timing functions
|
||||
How to capture time and convert to seconds must be ported to whatever is
|
||||
supported by the platform. e.g. Read value from on board RTC, read value from
|
||||
cpu clock cycles performance counter etc. Sample implementation for standard
|
||||
time.h and windows.h definitions included.
|
||||
*/
|
||||
/* Define: TIMER_RES_DIVIDER
|
||||
Divider to trade off timer resolution and total time that can be
|
||||
measured.
|
||||
|
||||
Use lower values to increase resolution, but make sure that overflow
|
||||
does not occur. If there are issues with the return value overflowing,
|
||||
increase this value.
|
||||
*/
|
||||
#if USE_CLOCK
|
||||
#define NSECS_PER_SEC CLOCKS_PER_SEC
|
||||
#define EE_TIMER_TICKER_RATE 1000
|
||||
#define CORETIMETYPE clock_t
|
||||
#define GETMYTIME(_t) (*_t = clock())
|
||||
#define MYTIMEDIFF(fin, ini) ((fin) - (ini))
|
||||
#define TIMER_RES_DIVIDER 1
|
||||
#define SAMPLE_TIME_IMPLEMENTATION 1
|
||||
#elif defined(_MSC_VER)
|
||||
#define NSECS_PER_SEC 10000000
|
||||
#define EE_TIMER_TICKER_RATE 1000
|
||||
#define CORETIMETYPE FILETIME
|
||||
#define GETMYTIME(_t) GetSystemTimeAsFileTime(_t)
|
||||
#define MYTIMEDIFF(fin, ini) \
|
||||
(((*(__int64 *)&fin) - (*(__int64 *)&ini)) / TIMER_RES_DIVIDER)
|
||||
/* setting to millisces resolution by default with MSDEV */
|
||||
#ifndef TIMER_RES_DIVIDER
|
||||
#define TIMER_RES_DIVIDER 1000
|
||||
#endif
|
||||
#define SAMPLE_TIME_IMPLEMENTATION 1
|
||||
#elif HAS_TIME_H
|
||||
#define NSECS_PER_SEC 1000000000
|
||||
#define EE_TIMER_TICKER_RATE 1000
|
||||
#define CORETIMETYPE struct timespec
|
||||
#define GETMYTIME(_t) clock_gettime(CLOCK_REALTIME, _t)
|
||||
#define MYTIMEDIFF(fin, ini) \
|
||||
((fin.tv_sec - ini.tv_sec) * (NSECS_PER_SEC / TIMER_RES_DIVIDER) \
|
||||
+ (fin.tv_nsec - ini.tv_nsec) / TIMER_RES_DIVIDER)
|
||||
/* setting to 1/1000 of a second resolution by default with linux */
|
||||
#ifndef TIMER_RES_DIVIDER
|
||||
#define TIMER_RES_DIVIDER 1000000
|
||||
#endif
|
||||
#define SAMPLE_TIME_IMPLEMENTATION 1
|
||||
#else
|
||||
#define SAMPLE_TIME_IMPLEMENTATION 0
|
||||
#endif
|
||||
#define EE_TICKS_PER_SEC (NSECS_PER_SEC / TIMER_RES_DIVIDER)
|
||||
|
||||
#if SAMPLE_TIME_IMPLEMENTATION
|
||||
/** Define Host specific (POSIX), or target specific global time variables. */
|
||||
static CORETIMETYPE start_time_val, stop_time_val;
|
||||
|
||||
/* Function: start_time
|
||||
This function will be called right before starting the timed portion of
|
||||
the benchmark.
|
||||
|
||||
Implementation may be capturing a system timer (as implemented in the
|
||||
example code) or zeroing some system parameters - e.g. setting the cpu clocks
|
||||
cycles to 0.
|
||||
*/
|
||||
void
|
||||
start_time(void)
|
||||
{
|
||||
GETMYTIME(&start_time_val);
|
||||
#if CALLGRIND_RUN
|
||||
CALLGRIND_START_INSTRUMENTATION
|
||||
#endif
|
||||
#if MICA
|
||||
asm volatile("int3"); /*1 */
|
||||
#endif
|
||||
}
|
||||
/* Function: stop_time
|
||||
This function will be called right after ending the timed portion of the
|
||||
benchmark.
|
||||
|
||||
Implementation may be capturing a system timer (as implemented in the
|
||||
example code) or other system parameters - e.g. reading the current value of
|
||||
cpu cycles counter.
|
||||
*/
|
||||
void
|
||||
stop_time(void)
|
||||
{
|
||||
#if CALLGRIND_RUN
|
||||
CALLGRIND_STOP_INSTRUMENTATION
|
||||
#endif
|
||||
#if MICA
|
||||
asm volatile("int3"); /*1 */
|
||||
#endif
|
||||
GETMYTIME(&stop_time_val);
|
||||
}
|
||||
/* Function: get_time
|
||||
Return an abstract "ticks" number that signifies time on the system.
|
||||
|
||||
Actual value returned may be cpu cycles, milliseconds or any other
|
||||
value, as long as it can be converted to seconds by <time_in_secs>. This
|
||||
methodology is taken to accomodate any hardware or simulated platform. The
|
||||
sample implementation returns millisecs by default, and the resolution is
|
||||
controlled by <TIMER_RES_DIVIDER>
|
||||
*/
|
||||
CORE_TICKS
|
||||
get_time(void)
|
||||
{
|
||||
CORE_TICKS elapsed
|
||||
= (CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
|
||||
return elapsed;
|
||||
}
|
||||
/* Function: time_in_secs
|
||||
Convert the value returned by get_time to seconds.
|
||||
|
||||
The <secs_ret> type is used to accomodate systems with no support for
|
||||
floating point. Default implementation implemented by the EE_TICKS_PER_SEC
|
||||
macro above.
|
||||
*/
|
||||
secs_ret
|
||||
time_in_secs(CORE_TICKS ticks)
|
||||
{
|
||||
secs_ret retval = ((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC;
|
||||
return retval;
|
||||
}
|
||||
#else
|
||||
#error "Please implement timing functionality in core_portme.c"
|
||||
#endif /* SAMPLE_TIME_IMPLEMENTATION */
|
||||
|
||||
ee_u32 default_num_contexts = MULTITHREAD;
|
||||
|
||||
/* Function: portable_init
|
||||
Target specific initialization code
|
||||
Test for some common mistakes.
|
||||
*/
|
||||
void
|
||||
portable_init(core_portable *p, int *argc, char *argv[])
|
||||
{
|
||||
#if PRINT_ARGS
|
||||
int i;
|
||||
for (i = 0; i < *argc; i++)
|
||||
{
|
||||
ee_printf("Arg[%d]=%s\n", i, argv[i]);
|
||||
}
|
||||
#endif
|
||||
if (sizeof(ee_ptr_int) != sizeof(ee_u8 *))
|
||||
{
|
||||
ee_printf(
|
||||
"ERROR! Please define ee_ptr_int to a type that holds a "
|
||||
"pointer!\n");
|
||||
}
|
||||
if (sizeof(ee_u32) != 4)
|
||||
{
|
||||
ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n");
|
||||
}
|
||||
#if (MAIN_HAS_NOARGC && (SEED_METHOD == SEED_ARG))
|
||||
ee_printf(
|
||||
"ERROR! Main has no argc, but SEED_METHOD defined to SEED_ARG!\n");
|
||||
#endif
|
||||
|
||||
#if (MULTITHREAD > 1) && (SEED_METHOD == SEED_ARG)
|
||||
int nargs = *argc, i;
|
||||
if ((nargs > 1) && (*argv[1] == 'M'))
|
||||
{
|
||||
default_num_contexts = parseval(argv[1] + 1);
|
||||
if (default_num_contexts > MULTITHREAD)
|
||||
default_num_contexts = MULTITHREAD;
|
||||
/* Shift args since first arg is directed to the portable part and not
|
||||
* to coremark main */
|
||||
--nargs;
|
||||
for (i = 1; i < nargs; i++)
|
||||
argv[i] = argv[i + 1];
|
||||
*argc = nargs;
|
||||
}
|
||||
#endif /* sample of potential platform specific init via command line, reset \
|
||||
the number of contexts being used if first argument is M<n>*/
|
||||
p->portable_id = 1;
|
||||
}
|
||||
/* Function: portable_fini
|
||||
Target specific final code
|
||||
*/
|
||||
void
|
||||
portable_fini(core_portable *p)
|
||||
{
|
||||
p->portable_id = 0;
|
||||
}
|
||||
|
||||
#if (MULTITHREAD > 1)
|
||||
|
||||
/* Function: core_start_parallel
|
||||
Start benchmarking in a parallel context.
|
||||
|
||||
Three implementations are provided, one using pthreads, one using fork
|
||||
and shared mem, and one using fork and sockets. Other implementations using
|
||||
MCAPI or other standards can easily be devised.
|
||||
*/
|
||||
/* Function: core_stop_parallel
|
||||
Stop a parallel context execution of coremark, and gather the results.
|
||||
|
||||
Three implementations are provided, one using pthreads, one using fork
|
||||
and shared mem, and one using fork and sockets. Other implementations using
|
||||
MCAPI or other standards can easily be devised.
|
||||
*/
|
||||
#if USE_PTHREAD
|
||||
ee_u8
|
||||
core_start_parallel(core_results *res)
|
||||
{
|
||||
return (ee_u8)pthread_create(
|
||||
&(res->port.thread), NULL, iterate, (void *)res);
|
||||
}
|
||||
ee_u8
|
||||
core_stop_parallel(core_results *res)
|
||||
{
|
||||
void *retval;
|
||||
return (ee_u8)pthread_join(res->port.thread, &retval);
|
||||
}
|
||||
#elif USE_FORK
|
||||
static int key_id = 0;
|
||||
ee_u8
|
||||
core_start_parallel(core_results *res)
|
||||
{
|
||||
key_t key = 4321 + key_id;
|
||||
key_id++;
|
||||
res->port.pid = fork();
|
||||
res->port.shmid = shmget(key, 8, IPC_CREAT | 0666);
|
||||
if (res->port.shmid < 0)
|
||||
{
|
||||
ee_printf("ERROR in shmget!\n");
|
||||
}
|
||||
if (res->port.pid == 0)
|
||||
{
|
||||
iterate(res);
|
||||
res->port.shm = shmat(res->port.shmid, NULL, 0);
|
||||
/* copy the validation values to the shared memory area and quit*/
|
||||
if (res->port.shm == (char *)-1)
|
||||
{
|
||||
ee_printf("ERROR in child shmat!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(res->port.shm, &(res->crc), 8);
|
||||
shmdt(res->port.shm);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
ee_u8
|
||||
core_stop_parallel(core_results *res)
|
||||
{
|
||||
int status;
|
||||
pid_t wpid = waitpid(res->port.pid, &status, WUNTRACED);
|
||||
if (wpid != res->port.pid)
|
||||
{
|
||||
ee_printf("ERROR waiting for child.\n");
|
||||
if (errno == ECHILD)
|
||||
ee_printf("errno=No such child %d\n", res->port.pid);
|
||||
if (errno == EINTR)
|
||||
ee_printf("errno=Interrupted\n");
|
||||
return 0;
|
||||
}
|
||||
/* after process is done, get the values from the shared memory area */
|
||||
res->port.shm = shmat(res->port.shmid, NULL, 0);
|
||||
if (res->port.shm == (char *)-1)
|
||||
{
|
||||
ee_printf("ERROR in parent shmat!\n");
|
||||
return 0;
|
||||
}
|
||||
memcpy(&(res->crc), res->port.shm, 8);
|
||||
shmdt(res->port.shm);
|
||||
return 1;
|
||||
}
|
||||
#elif USE_SOCKET
|
||||
static int key_id = 0;
|
||||
ee_u8
|
||||
core_start_parallel(core_results *res)
|
||||
{
|
||||
int bound, buffer_length = 8;
|
||||
res->port.sa.sin_family = AF_INET;
|
||||
res->port.sa.sin_addr.s_addr = htonl(0x7F000001);
|
||||
res->port.sa.sin_port = htons(7654 + key_id);
|
||||
key_id++;
|
||||
res->port.pid = fork();
|
||||
if (res->port.pid == 0)
|
||||
{ /* benchmark child */
|
||||
iterate(res);
|
||||
res->port.sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (-1 == res->port.sock) /* if socket failed to initialize, exit */
|
||||
{
|
||||
ee_printf("Error Creating Socket");
|
||||
}
|
||||
else
|
||||
{
|
||||
int bytes_sent = sendto(res->port.sock,
|
||||
&(res->crc),
|
||||
buffer_length,
|
||||
0,
|
||||
(struct sockaddr *)&(res->port.sa),
|
||||
sizeof(struct sockaddr_in));
|
||||
if (bytes_sent < 0)
|
||||
ee_printf("Error sending packet: %s\n", strerror(errno));
|
||||
close(res->port.sock); /* close the socket */
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
/* parent process, open the socket */
|
||||
res->port.sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
bound = bind(res->port.sock,
|
||||
(struct sockaddr *)&(res->port.sa),
|
||||
sizeof(struct sockaddr));
|
||||
if (bound < 0)
|
||||
ee_printf("bind(): %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
ee_u8
|
||||
core_stop_parallel(core_results *res)
|
||||
{
|
||||
int status;
|
||||
int fromlen = sizeof(struct sockaddr);
|
||||
int recsize = recvfrom(res->port.sock,
|
||||
&(res->crc),
|
||||
8,
|
||||
0,
|
||||
(struct sockaddr *)&(res->port.sa),
|
||||
&fromlen);
|
||||
if (recsize < 0)
|
||||
{
|
||||
ee_printf("Error in receive: %s\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
pid_t wpid = waitpid(res->port.pid, &status, WUNTRACED);
|
||||
if (wpid != res->port.pid)
|
||||
{
|
||||
ee_printf("ERROR waiting for child.\n");
|
||||
if (errno == ECHILD)
|
||||
ee_printf("errno=No such child %d\n", res->port.pid);
|
||||
if (errno == EINTR)
|
||||
ee_printf("errno=Interrupted\n");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#else /* no standard multicore implementation */
|
||||
#error \
|
||||
"Please implement multicore functionality in core_portme.c to use multiple contexts."
|
||||
#endif /* multithread implementations */
|
||||
#endif
|
309
MCU/components/modules/coremark/macos/core_portme.h
Normal file
309
MCU/components/modules/coremark/macos/core_portme.h
Normal file
@ -0,0 +1,309 @@
|
||||
/*
|
||||
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original Author: Shay Gal-on
|
||||
*/
|
||||
|
||||
/* Topic: Description
|
||||
This file contains configuration constants required to execute on
|
||||
different platforms
|
||||
*/
|
||||
#ifndef CORE_PORTME_H
|
||||
#define CORE_PORTME_H
|
||||
/************************/
|
||||
/* Data types and settings */
|
||||
/************************/
|
||||
/* Configuration: HAS_FLOAT
|
||||
Define to 1 if the platform supports floating point.
|
||||
*/
|
||||
#ifndef HAS_FLOAT
|
||||
#define HAS_FLOAT 1
|
||||
#endif
|
||||
/* Configuration: HAS_TIME_H
|
||||
Define to 1 if platform has the time.h header file,
|
||||
and implementation of functions thereof.
|
||||
*/
|
||||
#ifndef HAS_TIME_H
|
||||
#define HAS_TIME_H 1
|
||||
#endif
|
||||
/* Configuration: USE_CLOCK
|
||||
Define to 1 if platform has the time.h header file,
|
||||
and implementation of functions thereof.
|
||||
*/
|
||||
#ifndef USE_CLOCK
|
||||
#define USE_CLOCK 0
|
||||
#endif
|
||||
/* Configuration: HAS_STDIO
|
||||
Define to 1 if the platform has stdio.h.
|
||||
*/
|
||||
#ifndef HAS_STDIO
|
||||
#define HAS_STDIO 1
|
||||
#endif
|
||||
/* Configuration: HAS_PRINTF
|
||||
Define to 1 if the platform has stdio.h and implements the printf
|
||||
function.
|
||||
*/
|
||||
#ifndef HAS_PRINTF
|
||||
#define HAS_PRINTF 1
|
||||
#endif
|
||||
|
||||
/* Configuration: CORE_TICKS
|
||||
Define type of return from the timing functions.
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
#include <windows.h>
|
||||
typedef size_t CORE_TICKS;
|
||||
#elif HAS_TIME_H
|
||||
#include <time.h>
|
||||
typedef clock_t CORE_TICKS;
|
||||
#else
|
||||
#error \
|
||||
"Please define type of CORE_TICKS and implement start_time, end_time get_time and time_in_secs functions!"
|
||||
#endif
|
||||
|
||||
/* Definitions: COMPILER_VERSION, COMPILER_FLAGS, MEM_LOCATION
|
||||
Initialize these strings per platform
|
||||
*/
|
||||
#ifndef COMPILER_VERSION
|
||||
#ifdef __GNUC__
|
||||
#define COMPILER_VERSION "GCC"__VERSION__
|
||||
#else
|
||||
#define COMPILER_VERSION "Please put compiler version here (e.g. gcc 4.1)"
|
||||
#endif
|
||||
#endif
|
||||
#ifndef COMPILER_FLAGS
|
||||
#define COMPILER_FLAGS \
|
||||
FLAGS_STR /* "Please put compiler flags here (e.g. -o3)" */
|
||||
#endif
|
||||
#ifndef MEM_LOCATION
|
||||
#define MEM_LOCATION \
|
||||
"Please put data memory location here\n\t\t\t(e.g. code in flash, data " \
|
||||
"on heap etc)"
|
||||
#define MEM_LOCATION_UNSPEC 1
|
||||
#endif
|
||||
|
||||
/* Data Types:
|
||||
To avoid compiler issues, define the data types that need ot be used for
|
||||
8b, 16b and 32b in <core_portme.h>.
|
||||
|
||||
*Imprtant*:
|
||||
ee_ptr_int needs to be the data type used to hold pointers, otherwise
|
||||
coremark may fail!!!
|
||||
*/
|
||||
typedef signed short ee_s16;
|
||||
typedef unsigned short ee_u16;
|
||||
typedef signed int ee_s32;
|
||||
typedef double ee_f32;
|
||||
typedef unsigned char ee_u8;
|
||||
typedef unsigned int ee_u32;
|
||||
typedef unsigned long long ee_ptr_int;
|
||||
typedef size_t ee_size_t;
|
||||
/* align an offset to point to a 32b value */
|
||||
#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x)-1) & ~3))
|
||||
|
||||
/* Configuration: SEED_METHOD
|
||||
Defines method to get seed values that cannot be computed at compile
|
||||
time.
|
||||
|
||||
Valid values:
|
||||
SEED_ARG - from command line.
|
||||
SEED_FUNC - from a system function.
|
||||
SEED_VOLATILE - from volatile variables.
|
||||
*/
|
||||
#ifndef SEED_METHOD
|
||||
#define SEED_METHOD SEED_ARG
|
||||
#endif
|
||||
|
||||
/* Configuration: MEM_METHOD
|
||||
Defines method to get a block of memry.
|
||||
|
||||
Valid values:
|
||||
MEM_MALLOC - for platforms that implement malloc and have malloc.h.
|
||||
MEM_STATIC - to use a static memory array.
|
||||
MEM_STACK - to allocate the data block on the stack (NYI).
|
||||
*/
|
||||
#ifndef MEM_METHOD
|
||||
#define MEM_METHOD MEM_MALLOC
|
||||
#endif
|
||||
|
||||
/* Configuration: MULTITHREAD
|
||||
Define for parallel execution
|
||||
|
||||
Valid values:
|
||||
1 - only one context (default).
|
||||
N>1 - will execute N copies in parallel.
|
||||
|
||||
Note:
|
||||
If this flag is defined to more then 1, an implementation for launching
|
||||
parallel contexts must be defined.
|
||||
|
||||
Two sample implementations are provided. Use <USE_PTHREAD> or <USE_FORK>
|
||||
to enable them.
|
||||
|
||||
It is valid to have a different implementation of <core_start_parallel>
|
||||
and <core_end_parallel> in <core_portme.c>, to fit a particular architecture.
|
||||
*/
|
||||
#ifndef MULTITHREAD
|
||||
#define MULTITHREAD 1
|
||||
#endif
|
||||
|
||||
/* Configuration: USE_PTHREAD
|
||||
Sample implementation for launching parallel contexts
|
||||
This implementation uses pthread_thread_create and pthread_join.
|
||||
|
||||
Valid values:
|
||||
0 - Do not use pthreads API.
|
||||
1 - Use pthreads API
|
||||
|
||||
Note:
|
||||
This flag only matters if MULTITHREAD has been defined to a value
|
||||
greater then 1.
|
||||
*/
|
||||
#ifndef USE_PTHREAD
|
||||
#define USE_PTHREAD 0
|
||||
#endif
|
||||
|
||||
/* Configuration: USE_FORK
|
||||
Sample implementation for launching parallel contexts
|
||||
This implementation uses fork, waitpid, shmget,shmat and shmdt.
|
||||
|
||||
Valid values:
|
||||
0 - Do not use fork API.
|
||||
1 - Use fork API
|
||||
|
||||
Note:
|
||||
This flag only matters if MULTITHREAD has been defined to a value
|
||||
greater then 1.
|
||||
*/
|
||||
#ifndef USE_FORK
|
||||
#define USE_FORK 0
|
||||
#endif
|
||||
|
||||
/* Configuration: USE_SOCKET
|
||||
Sample implementation for launching parallel contexts
|
||||
This implementation uses fork, socket, sendto and recvfrom
|
||||
|
||||
Valid values:
|
||||
0 - Do not use fork and sockets API.
|
||||
1 - Use fork and sockets API
|
||||
|
||||
Note:
|
||||
This flag only matters if MULTITHREAD has been defined to a value
|
||||
greater then 1.
|
||||
*/
|
||||
#ifndef USE_SOCKET
|
||||
#define USE_SOCKET 0
|
||||
#endif
|
||||
|
||||
/* Configuration: MAIN_HAS_NOARGC
|
||||
Needed if platform does not support getting arguments to main.
|
||||
|
||||
Valid values:
|
||||
0 - argc/argv to main is supported
|
||||
1 - argc/argv to main is not supported
|
||||
*/
|
||||
#ifndef MAIN_HAS_NOARGC
|
||||
#define MAIN_HAS_NOARGC 0
|
||||
#endif
|
||||
|
||||
/* Configuration: MAIN_HAS_NORETURN
|
||||
Needed if platform does not support returning a value from main.
|
||||
|
||||
Valid values:
|
||||
0 - main returns an int, and return value will be 0.
|
||||
1 - platform does not support returning a value from main
|
||||
*/
|
||||
#ifndef MAIN_HAS_NORETURN
|
||||
#define MAIN_HAS_NORETURN 0
|
||||
#endif
|
||||
|
||||
/* Variable: default_num_contexts
|
||||
Number of contexts to spawn in multicore context.
|
||||
Override this global value to change number of contexts used.
|
||||
|
||||
Note:
|
||||
This value may not be set higher then the <MULTITHREAD> define.
|
||||
|
||||
To experiment, you can set the <MULTITHREAD> define to the highest value
|
||||
expected, and use argc/argv in the <portable_init> to set this value from the
|
||||
command line.
|
||||
*/
|
||||
extern ee_u32 default_num_contexts;
|
||||
|
||||
#if (MULTITHREAD > 1)
|
||||
#if USE_PTHREAD
|
||||
#include <pthread.h>
|
||||
#define PARALLEL_METHOD "PThreads"
|
||||
#elif USE_FORK
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/shm.h>
|
||||
#include <string.h> /* for memcpy */
|
||||
#define PARALLEL_METHOD "Fork"
|
||||
#elif USE_SOCKET
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#define PARALLEL_METHOD "Sockets"
|
||||
#else
|
||||
#define PARALLEL_METHOD "Proprietary"
|
||||
#error \
|
||||
"Please implement multicore functionality in core_portme.c to use multiple contexts."
|
||||
#endif /* Method for multithreading */
|
||||
#endif /* MULTITHREAD > 1 */
|
||||
|
||||
typedef struct CORE_PORTABLE_S
|
||||
{
|
||||
#if (MULTITHREAD > 1)
|
||||
#if USE_PTHREAD
|
||||
pthread_t thread;
|
||||
#elif USE_FORK
|
||||
pid_t pid;
|
||||
int shmid;
|
||||
void *shm;
|
||||
#elif USE_SOCKET
|
||||
pid_t pid;
|
||||
int sock;
|
||||
struct sockaddr_in sa;
|
||||
#endif /* Method for multithreading */
|
||||
#endif /* MULTITHREAD>1 */
|
||||
ee_u8 portable_id;
|
||||
} core_portable;
|
||||
|
||||
/* target specific init/fini */
|
||||
void portable_init(core_portable *p, int *argc, char *argv[]);
|
||||
void portable_fini(core_portable *p);
|
||||
|
||||
#if (SEED_METHOD == SEED_VOLATILE)
|
||||
#if (VALIDATION_RUN || PERFORMANCE_RUN || PROFILE_RUN)
|
||||
#define RUN_TYPE_FLAG 1
|
||||
#else
|
||||
#if (TOTAL_DATA_SIZE == 1200)
|
||||
#define PROFILE_RUN 1
|
||||
#else
|
||||
#define PERFORMANCE_RUN 1
|
||||
#endif
|
||||
#endif
|
||||
#endif /* SEED_METHOD==SEED_VOLATILE */
|
||||
|
||||
#endif /* CORE_PORTME_H */
|
140
MCU/components/modules/coremark/macos/core_portme.mak
Normal file
140
MCU/components/modules/coremark/macos/core_portme.mak
Normal file
@ -0,0 +1,140 @@
|
||||
# Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# Original Author: Shay Gal-on
|
||||
|
||||
#File: core_portme.mak
|
||||
|
||||
# Flag: OUTFLAG
|
||||
# Use this flag to define how to to get an executable (e.g -o)
|
||||
OUTFLAG= -o
|
||||
# Flag: CC
|
||||
# Use this flag to define compiler to use
|
||||
CC = gcc
|
||||
# Flag: CFLAGS
|
||||
# Use this flag to define compiler options. Note, you can add compiler options from the command line using XCFLAGS="other flags"
|
||||
PORT_CFLAGS = -O2
|
||||
FLAGS_STR = "$(PORT_CFLAGS) $(XCFLAGS) $(XLFLAGS) $(LFLAGS_END)"
|
||||
CFLAGS = $(PORT_CFLAGS) -I$(PORT_DIR) -I. -DFLAGS_STR=\"$(FLAGS_STR)\"
|
||||
#Flag: LFLAGS_END
|
||||
# Define any libraries needed for linking or other flags that should come at the end of the link line (e.g. linker scripts).
|
||||
# Note: On certain platforms, the default clock_gettime implementation is supported but requires linking of librt.
|
||||
#LFLAGS_END += -lrt
|
||||
# Flag: PORT_SRCS
|
||||
# Port specific source files can be added here
|
||||
PORT_SRCS = $(PORT_DIR)/core_portme.c
|
||||
# Flag: LOAD
|
||||
# Define this flag if you need to load to a target, as in a cross compile environment.
|
||||
|
||||
# Flag: RUN
|
||||
# Define this flag if running does not consist of simple invocation of the binary.
|
||||
# In a cross compile environment, you need to define this.
|
||||
|
||||
#For flashing and using a tera term macro, you could use
|
||||
#LOAD = flash ADDR
|
||||
#RUN = ttpmacro coremark.ttl
|
||||
|
||||
#For copying to target and executing via SSH connection, you could use
|
||||
#LOAD = scp $(OUTFILE) user@target:~
|
||||
#RUN = ssh user@target -c
|
||||
|
||||
#For native compilation and execution
|
||||
LOAD = echo Loading done
|
||||
RUN =
|
||||
|
||||
OEXT = .o
|
||||
EXE = .exe
|
||||
|
||||
# Flag: SEPARATE_COMPILE
|
||||
# Define if you need to separate compilation from link stage.
|
||||
# In this case, you also need to define below how to create an object file, and how to link.
|
||||
ifdef SEPARATE_COMPILE
|
||||
|
||||
LD = gcc
|
||||
OBJOUT = -o
|
||||
LFLAGS =
|
||||
OFLAG = -o
|
||||
COUT = -c
|
||||
# Flag: PORT_OBJS
|
||||
# Port specific object files can be added here
|
||||
PORT_OBJS = $(PORT_DIR)/core_portme$(OEXT)
|
||||
PORT_CLEAN = *$(OEXT)
|
||||
|
||||
$(OPATH)%$(OEXT) : %.c
|
||||
$(CC) $(CFLAGS) $(XCFLAGS) $(COUT) $< $(OBJOUT) $@
|
||||
|
||||
endif
|
||||
|
||||
# Target: port_prebuild
|
||||
# Generate any files that are needed before actual build starts.
|
||||
# E.g. generate profile guidance files. Sample PGO generation for gcc enabled with PGO=1
|
||||
# - First, check if PGO was defined on the command line, if so, need to add -fprofile-use to compile line.
|
||||
# - Second, if PGO reference has not yet been generated, add a step to the prebuild that will build a profile-generate version and run it.
|
||||
# Note - Using REBUILD=1
|
||||
#
|
||||
# Use make PGO=1 to invoke this sample processing.
|
||||
|
||||
ifdef PGO
|
||||
ifeq (,$(findstring $(PGO),gen))
|
||||
PGO_STAGE=build_pgo_gcc
|
||||
CFLAGS+=-fprofile-use
|
||||
endif
|
||||
PORT_CLEAN+=*.gcda *.gcno gmon.out
|
||||
endif
|
||||
|
||||
.PHONY: port_prebuild
|
||||
port_prebuild: $(PGO_STAGE)
|
||||
|
||||
.PHONY: build_pgo_gcc
|
||||
build_pgo_gcc:
|
||||
$(MAKE) PGO=gen XCFLAGS="$(XCFLAGS) -fprofile-generate -DTOTAL_DATA_SIZE=1200" ITERATIONS=10 gen_pgo_data REBUILD=1
|
||||
|
||||
# Target: port_postbuild
|
||||
# Generate any files that are needed after actual build end.
|
||||
# E.g. change format to srec, bin, zip in order to be able to load into flash
|
||||
.PHONY: port_postbuild
|
||||
port_postbuild:
|
||||
|
||||
# Target: port_postrun
|
||||
# Do platform specific after run stuff.
|
||||
# E.g. reset the board, backup the logfiles etc.
|
||||
.PHONY: port_postrun
|
||||
port_postrun:
|
||||
|
||||
# Target: port_prerun
|
||||
# Do platform specific after run stuff.
|
||||
# E.g. reset the board, backup the logfiles etc.
|
||||
.PHONY: port_prerun
|
||||
port_prerun:
|
||||
|
||||
# Target: port_postload
|
||||
# Do platform specific after load stuff.
|
||||
# E.g. reset the reset power to the flash eraser
|
||||
.PHONY: port_postload
|
||||
port_postload:
|
||||
|
||||
# Target: port_preload
|
||||
# Do platform specific before load stuff.
|
||||
# E.g. reset the reset power to the flash eraser
|
||||
.PHONY: port_preload
|
||||
port_preload:
|
||||
|
||||
# FLAG: OPATH
|
||||
# Path to the output folder. Default - current folder.
|
||||
OPATH = ./
|
||||
MKDIR = mkdir -p
|
||||
|
||||
# FLAG: PERL
|
||||
# Define perl executable to calculate the geomean if running separate.
|
||||
PERL=/usr/bin/perl
|
Reference in New Issue
Block a user