Skip to content

Commit

Permalink
Integrate dudect to analyze O(1) time complexity
Browse files Browse the repository at this point in the history
Dudect is a tool to deterimine whether a piece of code runs in constant
time or not by given different inputs and measure the execution time.

From the lab requirements, `q_insert_tail` and `q_size` are required to
meet O(1) time complexity. To test if the function runs in constant
time, simply open the option with `option simulation 1`, then run either
`it` or `size`.
  • Loading branch information
afcidk committed Feb 7, 2020
1 parent 8550c69 commit bcddcf8
Show file tree
Hide file tree
Showing 16 changed files with 568 additions and 48 deletions.
10 changes: 7 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
CC = gcc
CFLAGS = -O1 -g -Wall -Werror
CFLAGS = -O1 -g -Wall -Werror -Idudect -I.

GIT_HOOKS := .git/hooks/applied
DUT_DIR := dudect
all: $(GIT_HOOKS) qtest

# Control the build verbosity
Expand All @@ -24,14 +25,16 @@ $(GIT_HOOKS):
@scripts/install-git-hooks
@echo

OBJS := qtest.o report.o console.o harness.o queue.o
OBJS := qtest.o report.o console.o harness.o queue.o \
random.o dudect/constant.o dudect/fixture.o dudect/ttest.o
deps := $(OBJS:%.o=.%.o.d)

qtest: $(OBJS)
$(VECHO) " LD\t$@\n"
$(Q)$(CC) $(LDFLAGS) -o $@ $^
$(Q)$(CC) $(LDFLAGS) -o $@ $^ -lm

%.o: %.c
@mkdir -p .$(DUT_DIR)
$(VECHO) " CC\t$@\n"
$(Q)$(CC) -o $@ $(CFLAGS) -c -MMD -MF .$@.d $<

Expand All @@ -58,6 +61,7 @@ valgrind: valgrind_existence

clean:
rm -f $(OBJS) $(deps) *~ qtest /tmp/qtest.*
rm -rf .$(DUT_DIR)
rm -rf *.dSYM
(cd traces; rm -f *~)

Expand Down
4 changes: 3 additions & 1 deletion console.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "report.h"

/* Some global values */
int simulation = 0;
static cmd_ptr cmd_list = NULL;
static param_ptr param_list = NULL;
static bool block_flag = false;
Expand Down Expand Up @@ -54,7 +55,7 @@ static int fd_max = 0;
/* Parameters */
static int err_limit = 5;
static int err_cnt = 0;
static int echo = 0;
static bool echo = 0;

static bool quit_flag = false;
static char *prompt = "cmd> ";
Expand Down Expand Up @@ -98,6 +99,7 @@ void init_cmd()
add_cmd("log", do_log_cmd, " file | Copy output to file");
add_cmd("time", do_time_cmd, " cmd arg ... | Time command execution");
add_cmd("#", do_comment_cmd, " ... | Display comment");
add_param("simulation", &simulation, "Start/Stop simulation mode", NULL);
add_param("verbose", &verblevel, "Verbosity level", NULL);
add_param("error", &err_limit, "Number of errors until exit", NULL);
add_param("echo", &echo, "Do/don't echo commands", NULL);
Expand Down
4 changes: 4 additions & 0 deletions console.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#ifndef LAB0_CONSOLE_H
#define LAB0_CONSOLE_H
#include <stdbool.h>

/* Implementation of simple command-line interface */

/* Simulation flag of console option */
extern bool simulation;

/* Each command defined in terms of a function */
typedef bool (*cmd_function)(int argc, char *argv[]);

Expand Down
84 changes: 84 additions & 0 deletions dudect/constant.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#include "constant.h"
#include <assert.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "cpucycles.h"
#include "queue.h"
#include "random.h"

/* Allow random number range from 0 to 65535 */
const size_t chunk_size = 16;
/* Number of measurements per test */
const size_t number_measurements = 150;
const int drop_size = 20;
/* Maintain a queue independent from the qtest since
* we do not want the test to affect the original functionality
*/
static queue_t *q = NULL;
static char random_string[100][8];
static int random_string_iter = 0;
enum { test_insert_tail, test_size };

/* Implement the necessary queue interface to simulation */
void init_dut(void)
{
q = NULL;
}

char *get_random_string(void)
{
random_string_iter = (random_string_iter + 1) % number_measurements;
return random_string[random_string_iter];
}

void prepare_inputs(uint8_t *input_data, uint8_t *classes)
{
randombytes(input_data, number_measurements * chunk_size);
for (size_t i = 0; i < number_measurements; i++) {
classes[i] = randombit();
if (classes[i] == 0)
*(uint16_t *) (input_data + i * chunk_size) = 0x00;
}

for (size_t i = 0; i < 100; ++i) {
/* Generate random string */
randombytes((uint8_t *) random_string[i], 7);
random_string[i][7] = 0;
}
}

void measure(int64_t *before_ticks,
int64_t *after_ticks,
uint8_t *input_data,
int mode)
{
assert(mode == test_insert_tail || mode == test_size);
if (mode == test_insert_tail) {
for (size_t i = drop_size; i < number_measurements - drop_size; i++) {
char *s = get_random_string();
dut_new();
dut_insert_head(
get_random_string(),
*(uint16_t *) (input_data + i * chunk_size) % 10000);
before_ticks[i] = cpucycles();
dut_insert_tail(s, 1);
after_ticks[i] = cpucycles();
dut_free();
}
} else {
for (size_t i = drop_size; i < number_measurements - drop_size; i++) {
dut_new();
dut_insert_head(
get_random_string(),
*(uint16_t *) (input_data + i * chunk_size) % 10000);
before_ticks[i] = cpucycles();
dut_size(1);
after_ticks[i] = cpucycles();
dut_free();
}
}
}
42 changes: 42 additions & 0 deletions dudect/constant.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#ifndef DUDECT_CONSTANT_H
#define DUDECT_CONSTANT_H

#include <stdint.h>
#define dut_new() \
{ \
q = q_new(); \
}

#define dut_size(n) \
do { \
for (int i = 0; i < n; ++i) \
q_size(q); \
} while (0);

#define dut_insert_head(s, n) \
do { \
int j = n; \
while (j--) \
q_insert_head(q, s); \
} while (0);

#define dut_insert_tail(s, n) \
do { \
int j = n; \
while (j--) \
q_insert_tail(q, s); \
} while (0);

#define dut_free() \
{ \
q_free(q); \
}

void init_dut();
void prepare_inputs(uint8_t *input_data, uint8_t *classes);
void measure(int64_t *before_ticks,
int64_t *after_ticks,
uint8_t *input_data,
int mode);

#endif
12 changes: 12 additions & 0 deletions dudect/cpucycles.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <stdint.h>
// http://www.intel.com/content/www/us/en/embedded/training/ia-32-ia-64-benchmark-code-execution-paper.html
inline int64_t cpucycles(void)
{
#if defined(__i386__) || defined(__x86_64__)
unsigned int hi, lo;
__asm__ volatile("rdtsc\n\t" : "=a"(lo), "=d"(hi));
return ((int64_t) lo) | (((int64_t) hi) << 32);
#else
#error Unsupported Architecture
#endif
}
Loading

0 comments on commit bcddcf8

Please sign in to comment.