00001
00002
00003
00004
00005
00006
00007
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include "coremark.h"
00011 #if CALLGRIND_RUN
00012 #include <valgrind/callgrind.h>
00013 #endif
00014
00015 #if (MEM_METHOD==MEM_MALLOC)
00016 #include <malloc.h>
00017
00018
00019
00020 void *portable_malloc(size_t size) {
00021 return malloc(size);
00022 }
00023
00024
00025
00026 void portable_free(void *p) {
00027 free(p);
00028 }
00029 #else
00030 void *portable_malloc(size_t size) {
00031 return NULL;
00032 }
00033 void portable_free(void *p) {
00034 p=NULL;
00035 }
00036 #endif
00037
00038 #if (SEED_METHOD==SEED_VOLATILE)
00039 #if VALIDATION_RUN
00040 volatile ee_s32 seed1_volatile=0x3415;
00041 volatile ee_s32 seed2_volatile=0x3415;
00042 volatile ee_s32 seed3_volatile=0x66;
00043 #endif
00044 #if PERFORMANCE_RUN
00045 volatile ee_s32 seed1_volatile=0x0;
00046 volatile ee_s32 seed2_volatile=0x0;
00047 volatile ee_s32 seed3_volatile=0x66;
00048 #endif
00049 #if PROFILE_RUN
00050 volatile ee_s32 seed1_volatile=0x8;
00051 volatile ee_s32 seed2_volatile=0x8;
00052 volatile ee_s32 seed3_volatile=0x8;
00053 #endif
00054 volatile ee_s32 seed4_volatile=ITERATIONS;
00055 volatile ee_s32 seed5_volatile=0;
00056 #endif
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 #if USE_CLOCK
00069 #define NSECS_PER_SEC CLOCKS_PER_SEC
00070 #define EE_TIMER_TICKER_RATE 1000
00071 #define CORETIMETYPE clock_t
00072 #define GETMYTIME(_t) (*_t=clock())
00073 #define MYTIMEDIFF(fin,ini) ((fin)-(ini))
00074 #define TIMER_RES_DIVIDER 1
00075 #define SAMPLE_TIME_IMPLEMENTATION 1
00076 #elif defined(_MSC_VER)
00077 #define NSECS_PER_SEC 10000000
00078 #define EE_TIMER_TICKER_RATE 1000
00079 #define CORETIMETYPE FILETIME
00080 #define GETMYTIME(_t) GetSystemTimeAsFileTime(_t)
00081 #define MYTIMEDIFF(fin,ini) (((*(__int64*)&fin)-(*(__int64*)&ini))/TIMER_RES_DIVIDER)
00082
00083 #ifndef TIMER_RES_DIVIDER
00084 #define TIMER_RES_DIVIDER 1000
00085 #endif
00086 #define SAMPLE_TIME_IMPLEMENTATION 1
00087 #elif HAS_TIME_H
00088 #define NSECS_PER_SEC 1000000000
00089 #define EE_TIMER_TICKER_RATE 1000
00090 #define CORETIMETYPE struct timespec
00091 #define GETMYTIME(_t) clock_gettime(CLOCK_REALTIME,_t)
00092 #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)
00093
00094 #ifndef TIMER_RES_DIVIDER
00095 #define TIMER_RES_DIVIDER 1000000
00096 #endif
00097 #define SAMPLE_TIME_IMPLEMENTATION 1
00098 #else
00099 #define SAMPLE_TIME_IMPLEMENTATION 0
00100 #endif
00101 #define EE_TICKS_PER_SEC (NSECS_PER_SEC / TIMER_RES_DIVIDER)
00102
00103 #if SAMPLE_TIME_IMPLEMENTATION
00104
00105 static CORETIMETYPE start_time_val, stop_time_val;
00106
00107
00108
00109
00110
00111
00112
00113 void start_time(void) {
00114 GETMYTIME(&start_time_val );
00115 #if CALLGRIND_RUN
00116 CALLGRIND_START_INSTRUMENTATION
00117 #endif
00118 #if MICA
00119 asm volatile("int3");
00120 #endif
00121 }
00122
00123
00124
00125
00126
00127
00128 void stop_time(void) {
00129 #if CALLGRIND_RUN
00130 CALLGRIND_STOP_INSTRUMENTATION
00131 #endif
00132 #if MICA
00133 asm volatile("int3");
00134 #endif
00135 GETMYTIME(&stop_time_val );
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 CORE_TICKS get_time(void) {
00147 CORE_TICKS elapsed=(CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
00148 return elapsed;
00149 }
00150
00151
00152
00153
00154
00155
00156 secs_ret time_in_secs(CORE_TICKS ticks) {
00157 secs_ret retval=((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC;
00158 return retval;
00159 }
00160 #else
00161 #error "Please implement timing functionality in core_portme.c"
00162 #endif
00163
00164 ee_u32 default_num_contexts=MULTITHREAD;
00165
00166
00167
00168
00169
00170 void portable_init(core_portable *p, int *argc, char *argv[])
00171 {
00172 #if PRINT_ARGS
00173 int i;
00174 for (i=0; i<*argc; i++) {
00175 ee_printf("Arg[%d]=%s\n",i,argv[i]);
00176 }
00177 #endif
00178 if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) {
00179 ee_printf("ERROR! Please define ee_ptr_int to a type that holds a pointer!\n");
00180 }
00181 if (sizeof(ee_u32) != 4) {
00182 ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n");
00183 }
00184 #if (MAIN_HAS_NOARGC && (SEED_METHOD==SEED_ARG))
00185 ee_printf("ERROR! Main has no argc, but SEED_METHOD defined to SEED_ARG!\n");
00186 #endif
00187
00188 #if (MULTITHREAD>1) && (SEED_METHOD==SEED_ARG)
00189 int nargs=*argc,i;
00190 if ((nargs>1) && (*argv[1]=='M')) {
00191 default_num_contexts=parseval(argv[1]+1);
00192 if (default_num_contexts>MULTITHREAD)
00193 default_num_contexts=MULTITHREAD;
00194
00195 --nargs;
00196 for (i=1; i<nargs; i++)
00197 argv[i]=argv[i+1];
00198 *argc=nargs;
00199 }
00200 #endif
00201 p->portable_id=1;
00202 }
00203
00204
00205
00206 void portable_fini(core_portable *p)
00207 {
00208 p->portable_id=0;
00209 }
00210
00211 #if (MULTITHREAD>1)
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 #if USE_PTHREAD
00226 ee_u8 core_start_parallel(core_results *res) {
00227 return (ee_u8)pthread_create(&(res->port.thread),NULL,iterate,(void *)res);
00228 }
00229 ee_u8 core_stop_parallel(core_results *res) {
00230 void *retval;
00231 return (ee_u8)pthread_join(res->port.thread,&retval);
00232 }
00233 #elif USE_FORK
00234 static int key_id=0;
00235 ee_u8 core_start_parallel(core_results *res) {
00236 key_t key=4321+key_id;
00237 key_id++;
00238 res->port.pid=fork();
00239 res->port.shmid=shmget(key, 8, IPC_CREAT | 0666);
00240 if (res->port.shmid<0) {
00241 ee_printf("ERROR in shmget!\n");
00242 }
00243 if (res->port.pid==0) {
00244 iterate(res);
00245 res->port.shm=shmat(res->port.shmid, NULL, 0);
00246
00247 if (res->port.shm == (char *) -1) {
00248 ee_printf("ERROR in child shmat!\n");
00249 } else {
00250 memcpy(res->port.shm,&(res->crc),8);
00251 shmdt(res->port.shm);
00252 }
00253 exit(0);
00254 }
00255 return 1;
00256 }
00257 ee_u8 core_stop_parallel(core_results *res) {
00258 int status;
00259 pid_t wpid = waitpid(res->port.pid,&status,WUNTRACED);
00260 if (wpid != res->port.pid) {
00261 ee_printf("ERROR waiting for child.\n");
00262 if (errno == ECHILD) ee_printf("errno=No such child %d\n",res->port.pid);
00263 if (errno == EINTR) ee_printf("errno=Interrupted\n");
00264 return 0;
00265 }
00266
00267 res->port.shm=shmat(res->port.shmid, NULL, 0);
00268 if (res->port.shm == (char *) -1) {
00269 ee_printf("ERROR in parent shmat!\n");
00270 return 0;
00271 }
00272 memcpy(&(res->crc),res->port.shm,8);
00273 shmdt(res->port.shm);
00274 return 1;
00275 }
00276 #elif USE_SOCKET
00277 static int key_id=0;
00278 ee_u8 core_start_parallel(core_results *res) {
00279 int bound, buffer_length=8;
00280 res->port.sa.sin_family = AF_INET;
00281 res->port.sa.sin_addr.s_addr = htonl(0x7F000001);
00282 res->port.sa.sin_port = htons(7654+key_id);
00283 key_id++;
00284 res->port.pid=fork();
00285 if (res->port.pid==0) {
00286 iterate(res);
00287 res->port.sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
00288 if (-1 == res->port.sock) {
00289 ee_printf("Error Creating Socket");
00290 } else {
00291 int bytes_sent = sendto(res->port.sock, &(res->crc), buffer_length, 0,(struct sockaddr*)&(res->port.sa), sizeof (struct sockaddr_in));
00292 if (bytes_sent < 0)
00293 ee_printf("Error sending packet: %s\n", strerror(errno));
00294 close(res->port.sock);
00295 }
00296 exit(0);
00297 }
00298
00299 res->port.sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
00300 bound = bind(res->port.sock,(struct sockaddr*)&(res->port.sa), sizeof(struct sockaddr));
00301 if (bound < 0)
00302 ee_printf("bind(): %s\n",strerror(errno));
00303 return 1;
00304 }
00305 ee_u8 core_stop_parallel(core_results *res) {
00306 int status;
00307 int fromlen=sizeof(struct sockaddr);
00308 int recsize = recvfrom(res->port.sock, &(res->crc), 8, 0, (struct sockaddr*)&(res->port.sa), &fromlen);
00309 if (recsize < 0) {
00310 ee_printf("Error in receive: %s\n", strerror(errno));
00311 return 0;
00312 }
00313 pid_t wpid = waitpid(res->port.pid,&status,WUNTRACED);
00314 if (wpid != res->port.pid) {
00315 ee_printf("ERROR waiting for child.\n");
00316 if (errno == ECHILD) ee_printf("errno=No such child %d\n",res->port.pid);
00317 if (errno == EINTR) ee_printf("errno=Interrupted\n");
00318 return 0;
00319 }
00320 return 1;
00321 }
00322 #else
00323 #error "Please implement multicore functionality in core_portme.c to use multiple contexts."
00324 #endif
00325 #endif