forked from sysprog21/lab0-c
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Integrate dudect to analyze O(1) time complexity
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
Showing
16 changed files
with
568 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
Oops, something went wrong.