fix atomic buffer
diff --git a/ODIN_II/SRC/include/AtomicBuffer.hpp b/ODIN_II/SRC/include/AtomicBuffer.hpp index 5692e1d..4556c64 100644 --- a/ODIN_II/SRC/include/AtomicBuffer.hpp +++ b/ODIN_II/SRC/include/AtomicBuffer.hpp
@@ -3,6 +3,7 @@ #include <atomic> #include <thread> +#include <assert.h> /** * Odin use -1 internally, so we need to go back on forth @@ -13,23 +14,30 @@ #define BUFFER_SIZE 4 //use something divisible by 4 since the compact buffer can contain 4 value #define CONCURENCY_LIMIT (BUFFER_SIZE-1) // access to cycle -1 with an extra pdding cell +#define BUFFER_ARRAY_SIZE(input_size) (((input_size/4) + ((input_size%4)?1:0))) + class AtomicBuffer { private: - struct BitFields - { - uint8_t i0:2; - uint8_t i1:2; - uint8_t i2:2; - uint8_t i3:2; - } bits[BUFFER_SIZE/4]; + uint8_t bits[BUFFER_ARRAY_SIZE(BUFFER_SIZE)]; - std::atomic<bool> lock; - int32_t cycle; + std::atomic_flag lock = ATOMIC_FLAG_INIT; - uint8_t to_val(data_t val_in) + int64_t cycle; + + template<typename T> + uint8_t to_val(T val_in) { - return (val_in == 0)? 0: (val_in == 1)? 1 : 2; + switch(val_in) + { + case 0: //fallthrough + case '0': return 0; + + case 1: //fallthrough + case '1': return 1; + + default: return 2; + } } template<typename T> @@ -64,113 +72,112 @@ void lock_it() { - std::atomic_thread_fence(std::memory_order_acquire); - while(lock.exchange(true, std::memory_order_relaxed)) + uint8_t count = 0; + while(lock.test_and_set(std::memory_order_acquire)) { - std::this_thread::yield(); + count = (count + 1) % ((uint8_t)128); + if(!count) + std::this_thread::yield(); } } void unlock_it() { - lock.exchange(false, std::memory_order_relaxed); - std::atomic_thread_fence(std::memory_order_relaxed); + lock.clear(std::memory_order_release); } - uint8_t get_bits(int64_t index) + template<typename CYCLE_T> + uint8_t get_addr(CYCLE_T in) + { + int64_t cycle_in = static_cast<int64_t>(in) % static_cast<int64_t>(size()); + uint8_t casted_addr = static_cast<uint8_t>(cycle_in); + return (casted_addr/4); + } + + template<typename CYCLE_T> + uint8_t get_index(CYCLE_T in) + { + int64_t cycle_in = static_cast<int64_t>(in) % static_cast<int64_t>(size()); + uint8_t casted_addr = static_cast<uint8_t>(cycle_in); + return (uint8_t)((casted_addr%4) * 2); + } + + template<typename CYCLE_T> + data_t get_bits(CYCLE_T index) { - uint8_t modindex = (uint8_t)(index%(BUFFER_SIZE)); - uint8_t address = modindex/4; - uint8_t bit_index = modindex%4; - switch(bit_index) - { - case 0: return (uint8_t)(this->bits[address].i0); - case 1: return (uint8_t)(this->bits[address].i1); - case 2: return (uint8_t)(this->bits[address].i2); - case 3: return (uint8_t)(this->bits[address].i3); - default: return (uint8_t)0x3; - } + uint8_t addr = get_addr(index); + uint8_t id = get_index(index); + uint8_t bitset = bits[addr]; + + bitset = (uint8_t)(bitset >> id); + bitset = (uint8_t)(bitset & 0x3); + + return val(bitset); } - void set_bits(int64_t index, uint8_t value) + template<typename CYCLE_T, typename VAL_T> + void set_bits(CYCLE_T index, VAL_T value) { - uint8_t modindex = (uint8_t)(index%(BUFFER_SIZE)); - uint8_t address = modindex/4; - uint8_t bit_index = modindex%4; - - value = value&0x3; - - switch(bit_index) - { - case 0: this->bits[address].i0 = (uint8_t)(value&0x3); break; - case 1: this->bits[address].i1 = (uint8_t)(value&0x3); break; - case 2: this->bits[address].i2 = (uint8_t)(value&0x3); break; - case 3: this->bits[address].i3 = (uint8_t)(value&0x3); break; - default: break; - } + uint8_t addr = get_addr(index); + uint8_t id = get_index(index); + uint8_t value_in = to_val(value); + + uint8_t reset_mask = (uint8_t)(0x3); + reset_mask = (uint8_t)(reset_mask << id); + reset_mask = (uint8_t)(~reset_mask); + + value_in = (uint8_t)(value_in << id); + + bits[addr] = (uint8_t)(bits[addr] & reset_mask); + bits[addr] = (uint8_t)(bits[addr] | value_in); } + + void lock_free_update_cycle( int64_t cycle_in) + { + assert(is_greater_cycle(cycle_in)); + this->cycle = cycle_in; + } + + bool is_greater_cycle(int64_t cycle_in) + { + return (cycle_in >= this->cycle); + } + public: AtomicBuffer(data_t value_in) { - this->lock = false; this->cycle = -1; - this->init_all_values(value_in); + for(size_t i=0; i<size(); i++) + set_bits( i, value_in); + } + + uint8_t size() + { + return (BUFFER_ARRAY_SIZE(BUFFER_SIZE)*4); } void print() { - for(int i=0; i<BUFFER_SIZE; i++) + for(size_t i=0; i<size(); i++) printf("%c",val_c(get_bits(i))); printf("\n"); } - void init_all_values( data_t value) + void init_all_values( data_t value_in) { - this->lock = false; - for(int i=0; i<BUFFER_SIZE; i++) - set_bits( i, to_val(value)); - } + lock_it(); + for(size_t i=0; i<size(); i++) + set_bits( i, value_in); + unlock_it(); - int64_t lock_free_get_cycle() - { - return (int64_t)this->cycle; - } - - void lock_free_update_cycle( int64_t cycle_in) - { - //if (cycle_in > this->cycle) - this->cycle = (int32_t)cycle_in; - } - - data_t lock_free_get_value( int64_t cycle_in) - { - return val(get_bits( cycle_in)); - } - - void lock_free_update_value( data_t value_in, int64_t cycle_in) - { - if (cycle_in > this->cycle) - { - set_bits( cycle_in, to_val(value_in) ); - lock_free_update_cycle( cycle_in); - } - } - - void lock_free_copy_foward_one_cycle( int64_t cycle_in) - { - if (cycle_in > this->cycle) - { - set_bits( cycle_in+1, get_bits(cycle_in) ); - lock_free_update_cycle( cycle_in ); - } } int64_t get_cycle() { lock_it(); - int64_t value = lock_free_get_cycle(); + int64_t value = this->cycle; unlock_it(); return value; } @@ -185,7 +192,7 @@ data_t get_value( int64_t cycle_in) { lock_it(); - data_t value = lock_free_get_value( cycle_in); + data_t value = get_bits( cycle_in); unlock_it(); return value; } @@ -193,18 +200,12 @@ void update_value( data_t value_in, int64_t cycle_in) { lock_it(); - lock_free_update_value( value_in, cycle_in); - unlock_it(); - - } - - void copy_foward_one_cycle( int64_t cycle_in) - { - lock_it(); - lock_free_copy_foward_one_cycle( cycle_in); + lock_free_update_cycle( cycle_in ); + set_bits( cycle_in, value_in ); unlock_it(); } }; #endif +
diff --git a/ODIN_II/verify_odin.sh b/ODIN_II/verify_odin.sh index 2112c65..e87c93c 100755 --- a/ODIN_II/verify_odin.sh +++ b/ODIN_II/verify_odin.sh
@@ -60,14 +60,55 @@ # Exit Functions function exit_program() { + failed_dir=${NEW_RUN_DIR}/simulation_failures + log_file="${failed_dir}.log" + + if [ -f ${log_file} ] + then + echo "Simulation failures" + + for failed_benchmark in $(cat ${log_file}) + do + target_dir=$(dirname ${failed_dir}/${failed_benchmark}) + target_link=$(basename ${failed_benchmark}) + + echo ${target_dir}/${target_link} + + mkdir -p ${target_dir} + if [ ! -e ${target_dir}/${target_link} ]; then + ln -s ${NEW_RUN_DIR}/${failed_benchmark} ${target_dir}/${target_link} + fi + + FAILURE=$(( ${FAILURE} + 1 )) + done + fi + + failed_dir=${NEW_RUN_DIR}/synthesis_failures + log_file="${failed_dir}.log" + + if [ -f ${log_file} ] + then + echo "Synthesis failures" + + for failed_benchmark in $(cat ${log_file}) + do + target_dir=$(dirname ${failed_dir}/${failed_benchmark}) + target_link=$(basename ${failed_benchmark}) + + echo ${target_dir}/${target_link} + + mkdir -p ${target_dir} + if [ ! -e ${target_dir}/${target_link} ]; then + ln -s ${NEW_RUN_DIR}/${failed_benchmark} ${target_dir}/${target_link} + fi + + FAILURE=$(( ${FAILURE} + 1 )) + done + fi + if [ "_${FAILURE}" != "_0" ] then echo "Failed ${FAILURE} benchmarks" - echo "" - cat ${NEW_RUN_DIR}/test_failures.log - echo "" - echo "View Failure log in ${NEW_RUN_DIR}/test_failures.log" - else echo "no run failure!" fi @@ -85,7 +126,7 @@ pkill odin_II &> /dev/null pkill ${THIS_SCRIPT_EXEC} &> /dev/null #should be dead by now - exit 120 + exit_program ${FAILURE} done } @@ -213,27 +254,6 @@ } -function mv_failed() { - failed_dir=$1 - log_file="${failed_dir}.log" - - if [ -e ${log_file} ] - then - for failed_benchmark in $(cat ${log_file}) - do - target_dir=$(dirname ${failed_dir}/${failed_benchmark}) - target_link=$(basename ${failed_benchmark}) - - mkdir -p ${target_dir} - echo "Linking failed benchmark ${failed_benchmark} -> in failures ${target_link}" - - ln -s ${NEW_RUN_DIR}/${failed_benchmark} ${target_dir}/${target_link} - FAILURE=$(( ${FAILURE} + 1 )) - done - cat ${log_file} >> ${NEW_RUN_DIR}/test_failures.log - fi -} - ######################################### # Helper Functions function flag_is_number() { @@ -503,7 +523,7 @@ if [ "_${with_custom_args}" == "_1" ] then - global_odin_failure="${NEW_RUN_DIR}/odin_failures" + global_odin_failure="${NEW_RUN_DIR}/synthesis_failures" for dir in ${benchmark_dir}/* do @@ -542,7 +562,6 @@ #run the custon command echo " ========= Synthesizing Circuits" find ${NEW_RUN_DIR}/${bench_type}/ -name odin_param | xargs -n1 -P$threads -I test_cmd ${SHELL} -c '$(cat test_cmd)' - mv_failed ${global_odin_failure} ############################################ # run benchmarks @@ -666,7 +685,6 @@ then echo " ========= Synthesizing Circuits" find ${NEW_RUN_DIR}/${bench_type}/ -name cmd_param | xargs -n1 -P$threads -I test_cmd ${SHELL} -c '$(cat test_cmd)' - mv_failed ${global_synthesis_failure} fi if [ "${_SIMULATE}" == "on" ] @@ -708,9 +726,6 @@ mv ${sim_output_vectors} ${BM_DIR}/${BM_NAME} done - - # move the failed runs - mv_failed ${global_simulation_failure} fi fi