summaryrefslogtreecommitdiffstats
path: root/baseline/source/extra.h
blob: ca92812d9c4218b6060d5b442d0d563269d55c33 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <time.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <limits.h>

#define L3_CACHE_SIZE (11264*1024)



#define SET_UP char *thisProgram=argv[1];\
    int maxJobs=atoi(argv[2]);\
    char *thisCore=argv[3];\
    char *otherCore=argv[4];\
    char *otherProgram=argv[5];\
    char *runID=argv[6];\
    int output=atoi(argv[7]);\
    pid_t killMe;\
    struct timespec start, end;\
    int jobsComplete;\
    long progTime[maxJobs*output];\
    char fileName[50];\
    char *bigArray;\
    int wasteCount;\
    strcpy(fileName, runID);\
    strcat(fileName, ".txt");\
    mlockall(MCL_CURRENT || MCL_FUTURE);


//if output==0, endless loop
//avoids int overflow error with large numbers for background loops

#define SAVE_RESULTS if(jobsComplete>-1) progTime[jobsComplete]=(end.tv_nsec-start.tv_nsec)+(1000000000*(end.tv_sec-start.tv_sec));

#define WRITE_TO_FILE if (output){\
    munlockall();\
    FILE *fp=fopen(fileName, "a");\
    if (fp == NULL) {\
        perror("Error opening file. \n");\
        exit(1);\
    }\
    for(jobsComplete=0; jobsComplete<maxJobs; jobsComplete++){\
        fprintf(fp, "%s %s %s %s %d %ld %s %d \n",\
        thisProgram, otherProgram, thisCore, otherCore, maxJobs,\
        progTime[jobsComplete], runID, jobsComplete);\
    }\
    fclose(fp);\
}

// Call the wbinvld instruction (it's in a kernel module due to it being ring-0)
#define FLUSH_CACHES FILE *fp = fopen("/proc/wbinvd", "r");\
    if (fp == NULL) {\
        perror("Cache flush module interface cannot be opened");\
        exit(1);\
    }\
    char dummy;\
    if (fread(&dummy, 1, 1, fp) == 0) {\
        perror("Unable to access cache flush module interface");\
        exit(1);\
    }\
    fclose(fp);

//invoke start timer twice, stop timer to make sure timer and vars are in cache
//#define START_TIMER clock_gettime(CLOCK_MONOTONIC, &start);\
        clock_gettime(CLOCK_MONOTONIC, &end);\
    clock_gettime(CLOCK_MONOTONIC, &start);\

#define START_TIMER clock_gettime(CLOCK_MONOTONIC, &start);

#define STOP_TIMER clock_gettime(CLOCK_MONOTONIC, &end);

//waste a millisecond

#define WASTE_TIME clock_gettime(CLOCK_MONOTONIC, &start);\
do{clock_gettime(CLOCK_MONOTONIC, &end);}\
while( (end.tv_sec*1000000000+end.tv_nsec)-(start.tv_sec*1000000000+start.tv_nsec) < 1000000);


#define SLEEP nanosleep((const struct timespec[]){{0, 1000000}}, NULL);

//#define LOOP_WASTE for(wasteCount=0; wasteCount<1000000; wasteCount++){}

//at beginning of loop clear cache, waste some time
//wasting time allows interfering process to build up some cache presence
//using sleep instead of waste time loop causes problems
//both sleeping and spinning give advantage to threaded task
//#define START_LOOP if (output) {KILL_CACHE  START_TIMER}

//#define START_LOOP if (output){START_TIMER}

//#define STOP_LOOP if (output) {STOP_TIMER SAVE_RESULTS}
//if (!output) {jobsComplete--;}

#define START_LOOP FLUSH_CACHES START_TIMER
#define STOP_LOOP STOP_TIMER SAVE_RESULTS


/*
Intended structure

main
SET_UP
notice that STOP LOOP negates the ++ if outout=0
for (jobsComplete=-1; jobsComplete<maxJobs; jobsComplete++){
        KILL_CACHE
        START_TIMER
        tacleInit();
        tacleMain();
        STOP_TIMER
        SAVE_RESULTS
}
WRITE_TO_FILE
tacleReturn 
*/