forked from Github_Repos/cvw
Made a backup folder accessible to everyone for 3 portme directories that would not be preserved in the case of a clean coremark installation.
This commit is contained in:
parent
565c01709d
commit
44c7494a30
7
riscv-coremark/extraPortmes/README.md
Normal file
7
riscv-coremark/extraPortmes/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
This directory is a backup for the portme files associated with cygwin, linux, and linux64
|
||||||
|
|
||||||
|
This backup is needed in the event that a user replaces the coremark directory with a clean version
|
||||||
|
from EEMBC's github page (the clean version does not have the cygwin, linux,
|
||||||
|
and linux64 files that our version does).
|
||||||
|
|
||||||
|
Please do not delete this directory under any circumstance.
|
336
riscv-coremark/extraPortmes/cygwin/core_portme.c
Executable file
336
riscv-coremark/extraPortmes/cygwin/core_portme.c
Executable file
@ -0,0 +1,336 @@
|
|||||||
|
/*
|
||||||
|
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 <malloc.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
|
293
riscv-coremark/extraPortmes/cygwin/core_portme.h
Executable file
293
riscv-coremark/extraPortmes/cygwin/core_portme.h
Executable file
@ -0,0 +1,293 @@
|
|||||||
|
/*
|
||||||
|
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 ee_u32 ee_ptr_int;
|
||||||
|
typedef size_t ee_size_t;
|
||||||
|
/* align_mem:
|
||||||
|
This macro is used to align an offset to point to a 32b value. It is used in the Matrix algorithm to initialize the input memory blocks.
|
||||||
|
*/
|
||||||
|
#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 */
|
17
riscv-coremark/extraPortmes/cygwin/core_portme.mak
Normal file
17
riscv-coremark/extraPortmes/cygwin/core_portme.mak
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# 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 posix/core_portme.mak
|
338
riscv-coremark/extraPortmes/linux/core_portme.c
Executable file
338
riscv-coremark/extraPortmes/linux/core_portme.c
Executable file
@ -0,0 +1,338 @@
|
|||||||
|
/*
|
||||||
|
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 <malloc.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
|
290
riscv-coremark/extraPortmes/linux/core_portme.h
Executable file
290
riscv-coremark/extraPortmes/linux/core_portme.h
Executable file
@ -0,0 +1,290 @@
|
|||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 ee_u32 ee_ptr_int;
|
||||||
|
typedef size_t ee_size_t;
|
||||||
|
/* align_mem:
|
||||||
|
This macro is used to align an offset to point to a 32b value. It is used in the Matrix algorithm to initialize the input memory blocks.
|
||||||
|
*/
|
||||||
|
#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 */
|
17
riscv-coremark/extraPortmes/linux/core_portme.mak
Normal file
17
riscv-coremark/extraPortmes/linux/core_portme.mak
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# 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 posix/core_portme.mak
|
336
riscv-coremark/extraPortmes/linux64/core_portme.c
Executable file
336
riscv-coremark/extraPortmes/linux64/core_portme.c
Executable file
@ -0,0 +1,336 @@
|
|||||||
|
/*
|
||||||
|
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 <malloc.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
|
291
riscv-coremark/extraPortmes/linux64/core_portme.h
Executable file
291
riscv-coremark/extraPortmes/linux64/core_portme.h
Executable file
@ -0,0 +1,291 @@
|
|||||||
|
/*
|
||||||
|
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
riscv-coremark/extraPortmes/linux64/core_portme.mak
Executable file
140
riscv-coremark/extraPortmes/linux64/core_portme.mak
Executable 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
|
Loading…
Reference in New Issue
Block a user