Add clock offset parser

This commit is contained in:
Rodrigo Arias 2023-01-20 11:55:40 +01:00 committed by Rodrigo Arias Mallo
parent 894e972a65
commit fe5f16bb7a
4 changed files with 243 additions and 0 deletions

138
src/emu/clkoff.c Normal file
View 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
View 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 */

View File

@ -17,3 +17,4 @@ unit_test(prv.c)
#unit_test(ovni_model.c) #unit_test(ovni_model.c)
unit_test(emu_trace.c) unit_test(emu_trace.c)
unit_test(emu.c) unit_test(emu.c)
unit_test(clkoff.c)

73
test/unit/clkoff.c Normal file
View 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;
}