#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include <string.h>
#include "../libmicro.h"
#include <membership.h>
#include <grp.h>
#if DEBUG
# define debug(fmt, args...) (void) fprintf(stderr, fmt "\n" , ##args)
#else
# define debug(fmt, args...)
#endif
extern int gL1CacheEnabled;
typedef struct {
} tsd_t;
#define BUFSIZE 200
#define INVALID_ID -1
static gid_t gid_min = INVALID_ID;
static int gid_range = 0;
int
benchmark_init()
{
debug("benchmark_init");
(void) sprintf(lm_optstr, "l:g:");
lm_tsdsize = sizeof (tsd_t);
lm_defB = 100;
(void) sprintf(lm_usage,
"\n ------- getgrgid specific options (default: *)\n"
" [-g GID range (min-max)]\n"
"\n" );
return (0);
}
int
parse_range(gid_t *min, int *offset, char *buf)
{
char *value, *tmp_ptr = strdup(buf);
int range=0;
debug("parse_range");
value = strsep(&tmp_ptr, "-");
*min = atoi(value);
debug("min = %d", *min);
if (tmp_ptr) {
value = strsep(&tmp_ptr, "-");
range = atoi(value);
if (range < *min) {
printf("max id should be larger than min id\n");
return -1;
}
*offset = range - *min + 1;
debug("range = %d", *offset);
}
else {
printf("argument should be in the form of min-max\n");
return -1;
}
return 0;
}
int
benchmark_optswitch(int opt, char *optarg)
{
debug("benchmark_optswitch");
switch (opt) {
case 'l':
gL1CacheEnabled = atoi(optarg);
break;
case 'g': return parse_range( &gid_min, &gid_range, optarg);
break;
default:
return -1;
}
return 0;
}
int
benchmark_initrun()
{
debug("\nbenchmark_initrun");
return (0);
}
int
benchmark(void *tsd, result_t *res)
{
int i, err;
struct group *grp = NULL;
res->re_errors = 0;
debug("in to benchmark - optB = %i", lm_optB);
for (i = 0; i < lm_optB; i++) {
gid_t gid = gid_min + random() % gid_range ;
if (lm_optT > 1) {
struct group gd;
struct group *grp_ptr = &gd;
struct group *tmp_ptr;
char gbuf[BUFSIZE];
err = getgrgid_r( gid, grp_ptr, gbuf, BUFSIZE, &tmp_ptr);
if (err) {
debug("error: GID %d -> %s", gid, strerror(err));
res->re_errors++;
}
else if (!tmp_ptr) {
debug("not found: GID %d", gid);
res->re_errors++;
}
}
else {
errno = 0;
grp = getgrgid( gid );
if (!grp) {
if (errno) {
debug("error: GID %d -> %s", gid, strerror(errno));
res->re_errors++;
}
else {
debug("not found: GID %d", gid);
res->re_errors++;
}
}
}
}
res->re_count = i;
return (0);
}
int
benchmark_finirun(void *tsd)
{
debug("benchmark_finirun ");
return (0);
}
char *
benchmark_result()
{
static char result = '\0';
debug("benchmark_result");
return (&result);
}