-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathkonata.js
183 lines (155 loc) · 5.49 KB
/
konata.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// JSDoc のタイプチェックに型を認識させるため
let Op = require("./op").Op; // eslint-disable-line
let CreateStats = require("./stats").CreateStats; // eslint-disable-line
let OnikiriParser = require("./onikiri_parser").OnikiriParser;
let Gem5O3PipeViewParser = require("./gem5_o3_pipe_view_parser").Gem5O3PipeViewParser;
// To avoid conflicts with node.js internal FileReader, use a different name.
let InternalFileReader = require("./file_reader").FileReader; // eslint-disable-line
class Konata{
constructor(){
this.name = "Konata";
/** @type {OnikiriParser|Gem5O3PipeViewParser} */
this.parser_ = null;
/** @type {InternalFileReader} */
this.file_ = null;
this.filePath_ = "";
// Callback handlers
this.updateCallback_ = null;
this.finishCallback_ = null;
this.errorCallback_ = null;
this.closed_ = false;
}
close(){
this.closed_ = true;
if (this.parser_) {
this.parser_.close();
this.parser_ = null;
}
if (this.file_){
this.file_.close();
this.file_ = null;
console.log(`Closed: ${this.filePath_}`);
}
// GC を走らせておく
if (global.gc) {
console.log("Run GC");
global.gc();
}
}
openFile(path, updateCallback, finishCallback, errorCallback){
this.filePath_ = path;
this.updateCallback_ = updateCallback;
this.finishCallback_ = finishCallback;
this.errorCallback_ = errorCallback;
this.reload();
}
reload(){
let parsers = [
new OnikiriParser(),
new Gem5O3PipeViewParser()
];
this.load_(parsers);
}
/**
* 与えられた parser を使ってファイルのロードを試みる
* @param {array} parsers - パーサーのリスト.先頭から順に読み出し試行される
*/
load_(parsers){
this.close();
this.file_ = new InternalFileReader();
this.file_.open(this.filePath_);
this.closed_ = false;
this.parser_ = parsers.shift();
console.log(`Open (${this.parser_.name}): ${this.filePath_}`);
let self = this;
this.parser_.setFile(
this.file_,
this.updateCallback_,
function(){ // Finish handler
if (self.file_) {
self.file_.close(); // The parser must not be closed.
}
self.finishCallback_();
},
function(fileNotSupport, error){ // Error handler
console.log("Filed to load by:", self.parser_.name);
self.close();
if (fileNotSupport) {
// 読み出し試行に失敗したの次のパーサーに
if (parsers.length > 0) {
self.load_(parsers);
}
else if (parsers.length == 0) {
self.errorCallback_("Unsupported file format.");
}
}
else {
self.errorCallback_(error);
}
}
);
}
/**
* @return {Op} id に対応した op を返す
*/
getOp(id, resolution=0){
return this.parser_ ? this.parser_.getOp(id, resolution) : null;
}
getOpFromRID(rid, resolution=0){
return this.parser_ ? this.parser_.getOpFromRID(rid, resolution) : null;
}
get lastID(){
return this.parser_ ? this.parser_.lastID : 0;
}
get lastRID(){
return this.parser_ ? this.parser_.lastRID : 0;
}
get laneMap(){
return this.parser_ ? this.parser_.laneMap : {};
}
get stageLevelMap(){
return this.parser_ ? this.parser_.stageLevelMap : null;
}
// パイプライン中の統計を計算し,終わったら finish に渡す
async statsBody_(lastID, update, finish, statsList){
let sleepTimer = 0;
let SLEEP_INTERVAL = 50000;
let GIVE_UP_TIME = 1000;
let stats = statsList.shift();
for (let i = 0; i < lastID; i++) {
let op = this.getOp(i);
if (op == null) {
continue;
}
stats.update(op);
if (!stats.isDetected && i > GIVE_UP_TIME) {
console.log(`Gave up analyzing this file (${stats.name})`);
this.statsBody_(lastID, update, finish, statsList);
return;
}
// 一定時間毎に setTimeout でその他の処理への切り替えを入れる
if (sleepTimer > SLEEP_INTERVAL) {
sleepTimer = 0;
update(i / lastID, i / SLEEP_INTERVAL);
await new Promise(r => setTimeout(r, 0));
if (this.closed_){
break;
}
}
sleepTimer++;
}
if (!stats.isDetected) {
console.log(`Gave up analyzing this file (${stats.name})`);
this.statsBody_(lastID, update, finish, statsList);
return;
}
console.log(`Finished stats processing ('${stats.name}')`);
stats.finish();
finish(stats.stats);
}
async stats(update, finish){
let statsList = CreateStats(this.lastID, this.lastRID, this.parser_.lastCycle);
this.statsBody_(this.lastID, update, finish, statsList);
}
}
module.exports.Konata = Konata;