3
A brief file description
5
@section license License
7
Licensed to the Apache Software Foundation (ASF) under one
8
or more contributor license agreements. See the NOTICE file
9
distributed with this work for additional information
10
regarding copyright ownership. The ASF licenses this file
11
to you under the Apache License, Version 2.0 (the
12
"License"); you may not use this file except in compliance
13
with the License. You may obtain a copy of the License at
15
http://www.apache.org/licenses/LICENSE-2.0
17
Unless required by applicable law or agreed to in writing, software
18
distributed under the License is distributed on an "AS IS" BASIS,
19
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
See the License for the specific language governing permissions and
21
limitations under the License.
25
#include "InkAPIInternal.h"
35
#define DIAGS_LOG_FILE "diags.log"
37
void syslog_thr_init(void)
41
//////////////////////////////////////////////////////////////////////////////
43
// void reconfigure_diags()
45
// This function extracts the current diags configuration settings from
46
// records.config, and rebuilds the Diags data structures.
48
//////////////////////////////////////////////////////////////////////////////
56
// initial value set to 0 or 1 based on command line tags
57
c.enabled[DiagsTagType_Debug] = (diags->base_debug_tags != NULL);
58
c.enabled[DiagsTagType_Action] = (diags->base_action_tags != NULL);
60
c.enabled[DiagsTagType_Debug] = 1;
61
c.enabled[DiagsTagType_Action] = 1;
62
diags->show_location = 1;
64
// read output routing values
65
for (i = 0; i < DiagsLevel_Count; i++) {
67
c.outputs[i].to_stdout = 0;
68
c.outputs[i].to_stderr = 1;
69
c.outputs[i].to_syslog = 1;
70
c.outputs[i].to_diagslog = 1;
73
//////////////////////////////
74
// clear out old tag tables //
75
//////////////////////////////
77
diags->deactivate_all(DiagsTagType_Debug);
78
diags->deactivate_all(DiagsTagType_Action);
80
//////////////////////////////////////////////////////////////////////
82
//////////////////////////////////////////////////////////////////////
84
if (diags->base_debug_tags)
85
diags->activate_taglist(diags->base_debug_tags, DiagsTagType_Debug);
86
if (diags->base_action_tags)
87
diags->activate_taglist(diags->base_action_tags, DiagsTagType_Action);
89
////////////////////////////////////
90
// change the diags config values //
91
////////////////////////////////////
92
#if !defined(__GNUC__) && !defined(hpux)
95
memcpy(((void *) &diags->config), ((void *) &c), sizeof(DiagsConfigState));
101
init_diags(const char *bdt, const char *bat)
104
char diags_logpath[500];
105
strcpy(diags_logpath, DIAGS_LOG_FILE);
107
diags_log_fp = fopen(diags_logpath, "w");
110
status = setvbuf(diags_log_fp, NULL, _IOLBF, 512);
112
fclose(diags_log_fp);
117
diags = NEW(new Diags(bdt, bat, diags_log_fp));
119
if (diags_log_fp == NULL) {
120
Warning("couldn't open diags log file '%s', " "will not log to this file", diags_logpath);
123
Status("opened %s", diags_logpath);
128
#define MAX_DISK_THREADS 200
130
#define MIN_OFFSET (32*1024)
132
#define MIN_OFFSET (8*1024)
135
{ READ_MODE, WRITE_MODE, RANDOM_READ_MODE };
138
volatile int n_accessors = 0;
139
int orig_n_accessors;
140
AIO_Device *dev[MAX_DISK_THREADS];
142
extern RecInt cache_config_threads_per_disk;
146
int hotset_size = 20;
147
double hotset_frequency = 0.9;
149
int disk_size = 4000;
150
int read_size = 1024;
151
char *disk_path[MAX_DISK_THREADS];
154
int threads_per_disk = 1;
155
int delete_disks = 0;
160
double seq_read_percent = 0.0;
161
double seq_write_percent = 0.0;
162
double rand_read_percent = 0.0;
163
double real_seq_read_percent = 0.0;
164
double real_seq_write_percent = 0.0;
165
double real_rand_read_percent = 0.0;
166
int seq_read_size = 0;
167
int seq_write_size = 0;
168
int rand_read_size = 0;
170
struct AIO_Device:public Continuation
176
ink_hrtime time_start, time_end;
183
AIO_Device(ProxyMutex * m):Continuation(m)
186
io = new_AIOCallback();
188
SET_HANDLER(&AIO_Device::do_hotset);
190
int select_mode(double p)
192
if (p < real_seq_read_percent)
194
else if (p < real_seq_read_percent + real_seq_write_percent)
197
return RANDOM_READ_MODE;
199
void do_touch_data(off_t orig_len, off_t orig_offset)
203
unsigned int len = (unsigned int) orig_len;
204
unsigned int offset = (unsigned int) orig_offset;
205
offset = offset % 1024;
207
unsigned *x = (unsigned *) b;
208
for (unsigned j = 0; j < (len / sizeof(int)); j++) {
210
offset = (offset + 1) % 1024;
213
int do_check_data(off_t orig_len, off_t orig_offset)
217
unsigned int len = (unsigned int) orig_len;
218
unsigned int offset = (unsigned int) orig_offset;
219
offset = offset % 1024;
220
unsigned *x = (unsigned *) buf;
221
for (unsigned j = 0; j < (len / sizeof(int)); j++) {
224
offset = (offset + 1) % 1024;
228
int do_hotset(int event, Event * e);
229
int do_fd(int event, Event * e);
236
/* dump timing info */
237
printf("Writing summary info\n");
239
printf("----------\n");
240
printf("parameters\n");
241
printf("----------\n");
242
printf("%d disks\n", n_disk_path);
243
printf("%d chains\n", chains);
244
printf("%d threads_per_disk\n", threads_per_disk);
246
printf("%0.1f percent %d byte seq_reads by volume\n", seq_read_percent * 100.0, seq_read_size);
247
printf("%0.1f percent %d byte seq_writes by volume\n", seq_write_percent * 100.0, seq_write_size);
248
printf("%0.1f percent %d byte rand_reads by volume\n", rand_read_percent * 100.0, rand_read_size);
252
printf("%0.1f percent %d byte seq_reads by count\n", real_seq_read_percent * 100.0, seq_read_size);
253
printf("%0.1f percent %d byte seq_writes by count\n", real_seq_write_percent * 100.0, seq_write_size);
254
printf("%0.1f percent %d byte rand_reads by count\n", real_rand_read_percent * 100.0, rand_read_size);
256
printf("-------------------------\n");
257
printf("individual thread results\n");
258
printf("-------------------------\n");
259
double total_seq_reads = 0;
260
double total_seq_writes = 0;
261
double total_rand_reads = 0;
262
double total_secs = 0.0;
263
for (int i = 0; i < orig_n_accessors; i++) {
264
double secs = (dev[i]->time_end - dev[i]->time_start) / 1000000000.0;
265
double ops_sec = (dev[i]->seq_reads + dev[i]->seq_writes + dev[i]->rand_reads) / secs;
266
printf("%s: #sr:%d #sw:%d #rr:%d %0.1f secs %0.1f ops/sec\n",
267
dev[i]->path, dev[i]->seq_reads, dev[i]->seq_writes, dev[i]->rand_reads, secs, ops_sec);
269
total_seq_reads += dev[i]->seq_reads;
270
total_seq_writes += dev[i]->seq_writes;
271
total_rand_reads += dev[i]->rand_reads;
273
printf("-----------------\n");
274
printf("aggregate results\n");
275
printf("-----------------\n");
276
total_secs /= orig_n_accessors;
277
float sr = (total_seq_reads * seq_read_size) / total_secs;
278
sr /= 1024.0 * 1024.0;
279
float sw = (total_seq_writes * seq_write_size) / total_secs;
280
sw /= 1024.0 * 1024.0;
281
float rr = (total_rand_reads * rand_read_size) / total_secs;
282
rr /= 1024.0 * 1024.0;
283
printf("%f ops %0.2f mbytes/sec %0.1f ops/sec %0.1f ops/sec/disk seq_read\n",
284
total_seq_reads, sr, total_seq_reads / total_secs, total_seq_reads / total_secs / n_disk_path);
285
printf("%f ops %0.2f mbytes/sec %0.1f ops/sec %0.1f ops/sec/disk seq_write\n",
286
total_seq_writes, sw, total_seq_writes / total_secs, total_seq_writes / total_secs / n_disk_path);
287
printf("%f ops %0.2f mbytes/sec %0.1f ops/sec %0.1f ops/sec/disk rand_read\n",
288
total_rand_reads, rr, total_rand_reads / total_secs, total_rand_reads / total_secs / n_disk_path);
289
printf("%0.2f total mbytes/sec\n", sr + sw + rr);
290
printf("----------------------------------------------------------\n");
293
for (int i = 0; i < n_disk_path; i++)
294
unlink(disk_path[i]);
299
AIO_Device::do_hotset(int event, Event * e)
301
off_t max_offset = ((off_t) disk_size) * 1024 * 1024;
302
io->aiocb.aio_lio_opcode = LIO_WRITE;
303
io->aiocb.aio_fildes = fd;
304
io->aiocb.aio_offset = MIN_OFFSET + hotset_idx * max_size;
305
do_touch_data(seq_read_size, io->aiocb.aio_offset);
306
ink_assert(!do_check_data(seq_read_size, io->aiocb.aio_offset));
308
fprintf(stderr, "Starting hotset document writing \n");
309
if (io->aiocb.aio_offset > max_offset) {
311
"Finished hotset documents [%d] offset [%6.0f] size [%6.0f]\n",
312
hotset_idx, (float) MIN_OFFSET, (float) max_size);
313
SET_HANDLER(&AIO_Device::do_fd);
314
eventProcessor.schedule_imm(this);
317
io->aiocb.aio_nbytes = seq_read_size;
318
io->aiocb.aio_buf = buf;
320
io->thread = mutex->thread_holding;
321
ink_assert(ink_aio_write(io) >= 0);
327
AIO_Device::do_fd(int event, Event * e)
330
time_start = ink_get_hrtime();
331
fprintf(stderr, "Starting the aio_testing \n");
333
if ((ink_get_hrtime() - time_start) > (run_time * HRTIME_SECOND)) {
334
time_end = ink_get_hrtime();
335
ink_atomic_increment(&n_accessors, -1);
336
if (n_accessors <= 0)
341
off_t max_offset = ((off_t) disk_size) * 1024 * 1024; // MB-GB
342
off_t max_hotset_offset = ((off_t) hotset_size) * 1024 * 1024; // MB-GB
343
off_t seq_read_point = ((off_t) MIN_OFFSET);
344
off_t seq_write_point = ((off_t) MIN_OFFSET) + max_offset / 2 + write_after * 1024 * 1024;
345
seq_write_point += (id % n_disk_path) * (max_offset / (threads_per_disk * 4));
346
if (seq_write_point > max_offset)
347
seq_write_point = MIN_OFFSET;
349
if (io->aiocb.aio_lio_opcode == LIO_READ) {
350
ink_assert(!do_check_data(io->aiocb.aio_nbytes, io->aiocb.aio_offset));
352
memset((void *) buf, 0, max_size);
353
io->aiocb.aio_fildes = fd;
354
io->aiocb.aio_buf = buf;
356
io->thread = mutex->thread_holding;
358
switch (select_mode(drand48())) {
360
io->aiocb.aio_offset = seq_read_point;
361
io->aiocb.aio_nbytes = seq_read_size;
362
io->aiocb.aio_lio_opcode = LIO_READ;
363
ink_assert(ink_aio_read(io) >= 0);
364
seq_read_point += seq_read_size;
365
if (seq_read_point > max_offset)
366
seq_read_point = MIN_OFFSET;
370
io->aiocb.aio_offset = seq_write_point;
371
io->aiocb.aio_nbytes = seq_write_size;
372
io->aiocb.aio_lio_opcode = LIO_WRITE;
373
do_touch_data(seq_write_size, ((int) seq_write_point) % 1024);
374
ink_assert(ink_aio_write(io) >= 0);
375
seq_write_point += seq_write_size;
376
seq_write_point += write_skip;
377
if (seq_write_point > max_offset)
378
seq_write_point = MIN_OFFSET;
382
case RANDOM_READ_MODE:{
383
// fprintf(stderr, "random read started \n");
388
if (f < hotset_frequency)
389
o = (off_t) p *max_hotset_offset;
391
o = (off_t) p *(max_offset - rand_read_size);
394
o = (o + (seq_read_size - 1)) & (~(seq_read_size - 1));
395
io->aiocb.aio_offset = o;
396
io->aiocb.aio_nbytes = rand_read_size;
397
io->aiocb.aio_lio_opcode = LIO_READ;
398
ink_assert(ink_aio_read(io) >= 0);
407
else if (strcmp(field_name, #_s) == 0) { \
409
cout << "reading " #_s " = " \
414
read_config(const char *config_filename)
416
std::ifstream fin(config_filename);
417
char field_name[256];
418
char field_value[256];
420
if (!fin.rdbuf()->is_open()) {
421
fin.open("sample.cfg");
422
if (!fin.rdbuf()->is_open()) {
423
cout << "cannot open config files " << config_filename << endl;
428
field_name[0] = '\0';
433
PARAM(hotset_frequency)
439
PARAM(seq_read_percent)
440
PARAM(seq_write_percent)
441
PARAM(rand_read_percent)
443
PARAM(seq_write_size)
444
PARAM(rand_read_size)
447
PARAM(threads_per_disk)
449
else if (strcmp(field_name, "disk_path") == 0) {
450
assert(n_disk_path < MAX_DISK_THREADS);
452
disk_path[n_disk_path] = strdup(field_value);
453
cout << "reading disk_path = " << disk_path[n_disk_path] << endl;
457
assert(read_size > 0);
458
int t = seq_read_size + seq_write_size + rand_read_size;
459
real_seq_read_percent = seq_read_percent;
460
real_seq_write_percent = seq_write_percent;
461
real_rand_read_percent = rand_read_percent;
463
real_seq_read_percent *= t / seq_read_size;
465
real_seq_write_percent *= t / seq_write_size;
467
real_rand_read_percent *= t / rand_read_size;
468
float tt = real_seq_read_percent + real_seq_write_percent + real_rand_read_percent;
469
real_seq_read_percent = real_seq_read_percent / tt;
470
real_seq_write_percent = real_seq_write_percent / tt;
471
real_rand_read_percent = real_rand_read_percent / tt;
476
main(int argc, char *argv[])
481
init_diags("", NULL);
482
RecProcessInit(RECM_STAND_ALONE);
483
ink_event_system_init(EVENT_SYSTEM_MODULE_VERSION);
484
eventProcessor.start(ink_number_of_processors());
486
ink_aio_init(AIO_MODULE_VERSION);
489
if (!read_config(argv[1]))
492
max_size = seq_read_size;
493
if (seq_write_size > max_size)
494
max_size = seq_write_size;
495
if (rand_read_size > max_size)
496
max_size = rand_read_size;
498
cache_config_threads_per_disk = threads_per_disk;
499
orig_n_accessors = n_disk_path * threads_per_disk;
501
for (i = 0; i < n_disk_path; i++) {
502
for (int j = 0; j < threads_per_disk; j++) {
503
dev[n_accessors] = new AIO_Device(new_ProxyMutex());
504
dev[n_accessors]->id = i * threads_per_disk + j;
505
dev[n_accessors]->path = disk_path[i];
506
dev[n_accessors]->seq_reads = 0;
507
dev[n_accessors]->seq_writes = 0;
508
dev[n_accessors]->rand_reads = 0;
509
dev[n_accessors]->fd = open(dev[n_accessors]->path, O_RDWR | O_CREAT, 0600);
510
fchmod(dev[n_accessors]->fd, S_IRWXU | S_IRWXG);
511
if (dev[n_accessors]->fd < 0) {
512
perror(disk_path[i]);
515
dev[n_accessors]->buf = (char *) valloc(max_size);
516
eventProcessor.schedule_imm(dev[n_accessors]);
521
this_thread()->execute();