Add clock offset parser
This commit is contained in:
parent
894e972a65
commit
fe5f16bb7a
138
src/emu/clkoff.c
Normal file
138
src/emu/clkoff.c
Normal file
@ -0,0 +1,138 @@
|
||||
#include "clkoff.h"
|
||||
|
||||
#include "common.h"
|
||||
#include <errno.h>
|
||||
|
||||
static struct clkoff_entry *
|
||||
cfind(struct clkoff *off, const char *name)
|
||||
{
|
||||
struct clkoff_entry *entry = NULL;
|
||||
|
||||
HASH_FIND_STR(off->entries, name, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
static int
|
||||
cadd(struct clkoff *table, struct clkoff_entry e)
|
||||
{
|
||||
if (cfind(table, e.name) != NULL) {
|
||||
err("entry with name '%s' already exists\n", e.name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct clkoff_entry *entry = calloc(1, sizeof(struct clkoff_entry));
|
||||
if (entry == NULL) {
|
||||
err("calloc failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(entry, &e, sizeof(*entry));
|
||||
|
||||
HASH_ADD_STR(table->entries, name, entry);
|
||||
table->nentries++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
cparse(struct clkoff *table, FILE *file)
|
||||
{
|
||||
/* Ignore header line */
|
||||
char buf[1024];
|
||||
if (fgets(buf, 1024, file) == NULL) {
|
||||
err("missing header line in clock offset\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int line = 1; ; line++) {
|
||||
errno = 0;
|
||||
struct clkoff_entry e = { 0 };
|
||||
|
||||
if (fgets(buf, 1024, file) == NULL)
|
||||
break;
|
||||
|
||||
/* Empty line */
|
||||
if (buf[0] == '\n')
|
||||
continue;
|
||||
|
||||
int ret = sscanf(buf, "%ld %s %lf %lf %lf",
|
||||
&e.index, e.name,
|
||||
&e.median, &e.mean, &e.stdev);
|
||||
|
||||
if (ret == EOF && errno == 0)
|
||||
break;
|
||||
|
||||
if (ret == EOF && errno != 0) {
|
||||
err("fscanf() failed in line %d\n", line);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret != 5) {
|
||||
err("fscanf() read %d instead of 5 fields in line %d\n",
|
||||
ret, line);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cadd(table, e) != 0) {
|
||||
err("cannot add entry of line %d\n",
|
||||
line);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
cindex(struct clkoff *table)
|
||||
{
|
||||
if (table->nentries < 1) {
|
||||
err("no entries\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
table->index = calloc(table->nentries, sizeof(struct clkoff_entry *));
|
||||
|
||||
if (table->index == NULL) {
|
||||
err("calloc failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct clkoff_entry *e;
|
||||
int i = 0;
|
||||
for (e = table->entries; e; e = e->hh.next)
|
||||
table->index[i++] = e;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
clkoff_init(struct clkoff *table, FILE *file)
|
||||
{
|
||||
memset(table, 0, sizeof(struct clkoff));
|
||||
|
||||
if (cparse(table, file) != 0) {
|
||||
err("clkoff_init: failed parsing clock table\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create index array */
|
||||
if (cindex(table) != 0) {
|
||||
err("clkoff_init: failed indexing table\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
clkoff_count(struct clkoff *table)
|
||||
{
|
||||
return table->nentries;
|
||||
}
|
||||
|
||||
struct clkoff_entry *
|
||||
clkoff_get(struct clkoff *table, int i)
|
||||
{
|
||||
return table->index[i];
|
||||
}
|
31
src/emu/clkoff.h
Normal file
31
src/emu/clkoff.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
#ifndef CLKOFF_H
|
||||
#define CLKOFF_H
|
||||
|
||||
#include "uthash.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <linux/limits.h>
|
||||
|
||||
struct clkoff_entry {
|
||||
int64_t index;
|
||||
char name[PATH_MAX];
|
||||
double median;
|
||||
double mean;
|
||||
double stdev;
|
||||
UT_hash_handle hh;
|
||||
};
|
||||
|
||||
struct clkoff {
|
||||
int nentries;
|
||||
struct clkoff_entry *entries;
|
||||
struct clkoff_entry **index;
|
||||
};
|
||||
|
||||
int clkoff_init(struct clkoff *table, FILE *file);
|
||||
int clkoff_count(struct clkoff *table);
|
||||
struct clkoff_entry *clkoff_get(struct clkoff *table, int i);
|
||||
|
||||
#endif /* CLKOFF_H */
|
@ -17,3 +17,4 @@ unit_test(prv.c)
|
||||
#unit_test(ovni_model.c)
|
||||
unit_test(emu_trace.c)
|
||||
unit_test(emu.c)
|
||||
unit_test(clkoff.c)
|
||||
|
73
test/unit/clkoff.c
Normal file
73
test/unit/clkoff.c
Normal file
@ -0,0 +1,73 @@
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include "emu/clkoff.h"
|
||||
#include "common.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static int
|
||||
test_ok(void)
|
||||
{
|
||||
char table_str[] =
|
||||
"rank hostname offset_median offset_mean offset_std\n"
|
||||
"0 s09r2b21 0 0.000000 0.000000\n"
|
||||
"1 s09r2b22 -451607967 -451608083.500000 316.087397\n"
|
||||
"2 s09r2b23 4526 4542.200000 124.33432\n"
|
||||
"3 s09r2b24 342455 342462.300000 342.39755\n";
|
||||
|
||||
FILE *f = fmemopen(table_str, ARRAYLEN(table_str), "r");
|
||||
|
||||
if (f == NULL)
|
||||
die("fmemopen failed\n");
|
||||
|
||||
struct clkoff table;
|
||||
clkoff_init(&table);
|
||||
if (clkoff_load(&table, f) != 0)
|
||||
die("clkoff_load failed\n");
|
||||
|
||||
if (clkoff_count(&table) != 4)
|
||||
die("clkoff_count failed\n");
|
||||
|
||||
struct clkoff_entry *entry = clkoff_get(&table, 3);
|
||||
if (entry == NULL)
|
||||
die("clkoff_get returned NULL\n");
|
||||
|
||||
if (entry->index != 3)
|
||||
die("clkoff_get returned wrong index\n");
|
||||
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_dup(void)
|
||||
{
|
||||
static char table_str[] =
|
||||
"rank hostname offset_median offset_mean offset_std\n"
|
||||
"0 s09r2b21 0 0.000000 0.000000\n"
|
||||
"1 s09r2b22 -451607967 -451608083.500000 316.087397\n"
|
||||
"2 s09r2b23 4526 4542.200000 124.33432\n"
|
||||
"3 s09r2b23 342455 342462.300000 342.39755\n";
|
||||
|
||||
FILE *f = fmemopen(table_str, ARRAYLEN(table_str), "r");
|
||||
|
||||
if (f == NULL)
|
||||
die("fmemopen failed\n");
|
||||
|
||||
struct clkoff table;
|
||||
|
||||
clkoff_init(&table);
|
||||
if (clkoff_load(&table, f) == 0)
|
||||
die("clkoff_load didn't fail\n");
|
||||
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test_ok();
|
||||
test_dup();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user