Skip to content
Snippets Groups Projects
Commit c42ba229 authored by Mathieu Valois's avatar Mathieu Valois
Browse files

Merge OMP branch

parents dfc1fc5b ce535e43
No related branches found
No related tags found
No related merge requests found
# Version de cmake demandée.
cmake_minimum_required(VERSION 2.8)
find_package(Threads REQUIRED)
find_package(OpenMP)
# Chemin des répertoires contenant les fichiers entêtes.
include_directories(include)
......@@ -10,8 +10,7 @@ include_directories(include)
set(EXECUTABLE_OUTPUT_PATH bin/${CMAKE_BUILD_TYPE})
# Option du compilateur pour supporter C 2011.
set(CMAKE_CXX_FLAGS "-pedantic -Wall -std=c++11 -Wextra -O3")
set(CMAKE_LD_FLAGS "-lpthread")
set(CMAKE_CXX_FLAGS "-pedantic -Wall -std=c++11 -Wextra -O3 -fopenmp")
add_executable(cppack
src/core/Statsgen.cpp
......
......@@ -26,21 +26,14 @@ class ProgressThread : public QThread
{
Q_OBJECT
void run() {
unsigned int progress = 0;
uint64_t processed = 0;
const std::vector<ThreadData>& td = _s.getThreadsData();
int progress = 0;
while(!_s.allStarted()){
msleep(500);
}
const uint64_t nblines = td.back().lineEnd;
const uint64_t nblines = _s.getNbLines();
while(!_s.allFinished()){
processed = 0;
for(ThreadData t : td){
processed += t.total_counter;
}
progress = (int) percentage(processed, nblines);
progress = (int) percentage(_s.getProcessed(), nblines);
_qpb.setValue(progress);
msleep(500);
}
......
......@@ -17,7 +17,6 @@
#include <string>
#include <iostream>
#include <thread>
#include "Policy.h"
#include "SecurityRules.h"
......@@ -86,14 +85,7 @@ public:
* @brief Number of threads the user wants to use
* @param nb: number of usable threads
*/
inline void setNbThread(const int& nb) {
int max = std::thread::hardware_concurrency();
if (nb > max) {
nbThread = max;
} else {
nbThread = nb;
}
}
inline void setNbThread(const int& nb) { nbThread = nb; }
void configureThread(ThreadData& td) const;
......@@ -128,34 +120,21 @@ public:
*/
void print_stats();
inline uint64_t getTotalCounter() const { return td[0].total_counter; }
inline uint64_t getTotalFilter() const { return td[0].total_filter; }
inline uint64_t getNbSecurePasswords() const { return td[0].sr.nbSecurePassword; }
inline int getNbThreads() const { return nbThread; }
inline const IntOccurrence& getStatsLength() const { return td[0].length; }
inline const StringOccurrence& getStatsCharsets() const { return td[0].charactersets; }
inline const StringOccurrence& getStatsSimple() const { return td[0].simplemasks; }
inline const StringOccurrence& getStatsAdvanced() const { return td[0].advancedmasks; }
inline const std::vector<ThreadData>& getThreadsData() const { return td; }
inline bool allFinished() const { return finished == nbThread; }
inline uint64_t getNbLines() const { return nblines; }
inline uint64_t getProcessed() const { return processed; }
inline const ThreadData& getResults() const { return results; }
inline bool allFinished() const { return finished; }
inline bool allStarted() const { return started; }
bool operator==(const Statsgen& other) const;
/**
* @brief Given parameters in threadarg, compute statistics on partition of the file
* @param threadarg : parameters and result storage
*/
static void* generate_stats_thread(void * threadarg);
void handle_password(const std::string& password, const uint64_t& nbPasswords, ThreadData& td) const;
private:
std::string filename;
// results of the computation
ThreadData results;
// Data computed from within a thread, for read-accessibility
std::vector<ThreadData> td;
// Filters
int hiderare = 0; // Hide low statistics
int top = 10; // Show only a top of statistics
std::regex current_regex; // Regex for the interesting passwords
......@@ -170,8 +149,12 @@ private:
// Security policy
SecurityRules _sr = { 0, 8, 0, 1, 1, 1 };
// threads which have finished
uint finished = 0;
// nb lines processed
uint64_t nblines = 0;
// nb lines processed
uint64_t processed = 0;
// all threads have finished
uint finished = false;
// all threads have been started
bool started = false;
};
......
......@@ -11,6 +11,7 @@
typedef std::unordered_map<std::string, uint64_t> StringOccurrence;
typedef std::unordered_map<int, uint64_t> IntOccurrence;
/**
* @brief minimal number of digits of a password, etc.
*/
......@@ -61,4 +62,6 @@ struct ThreadData {
SecurityRules sr;
};
#pragma omp declare reduction(dataSum: ThreadData : omp_out += omp_in ) initializer(omp_priv(omp_orig))
#endif // THREAD_DATA_H
\ No newline at end of file
......@@ -14,7 +14,7 @@
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <thread>
#include <omp.h>
#include "Statsgen.h"
......@@ -58,55 +58,38 @@ void Statsgen::configureThread(ThreadData& td) const {
}
int Statsgen::generate_stats() {
td = vector<ThreadData>(nbThread);
processed = 0;
finished = false;
results = ThreadData();
finished = 0;
started = false;
uint64_t nbline = 0;
nbline = nbline_file(filename);
if (!nbline){ // error reading the file
configureThread(results);
omp_set_num_threads(nbThread);
nblines = nbline_file(filename);
if (!nblines){ // error reading the file
cerr << "[ERROR] Empty file or not existing file" << endl;
return 0;
}
vector<pthread_t> threads(nbThread);
for(uint i = 0; i < nbThread; i++ ) {
td[i].thread_id = i + 1;
configureThread(td[i]);
if(i == 0){
td[i].lineBegin = 0;
}
else{
td[i].lineBegin = td[i-1].lineEnd + 1;
}
td[i].lineEnd = (i+1)*nbline/nbThread;
if(debug_enabled){
cerr << "[DEBUG] " << "Thread " << td[i].thread_id << " analyse : " << td[i].lineBegin << " --> " << td[i].lineEnd << endl;
started = true;
#pragma omp parallel reduction(dataSum:results)
{
#pragma omp single
{
nbThread = omp_get_num_threads();
}
uint thread_id = omp_get_thread_num();
ifstream inputfile(filename);
string line;
for(uint numline = 0; numline < nblines; ++numline){
getline(inputfile, line);
if((numline % nbThread) == thread_id){
handle_password(line, 1, results);
#pragma omp atomic
++processed;
}
int rc = pthread_create(&threads[i], NULL, generate_stats_thread, (void *)&td[i] );
if (rc) {
cerr << "[ERROR] unable to create thread," << rc << endl;
exit(-1);
}
}
started = true;
void *status;
for(uint i = 0; i < nbThread; i++ ) {
int rc = pthread_join(threads[i], &status);
if (rc) {
cerr << "[ERROR] unable to join," << rc << endl;
exit(-1);
}
results += td[i];
finished++;
}
finished = true;
if (!results.total_counter) {
cerr << "[ERROR] Empty file or not existing file" << endl;
......@@ -232,63 +215,32 @@ pair<uint, uint> get_masks(const string& password, PasswordStats& c){
return make_pair(sizeSimpleMask, sizeAdvancedMask);
}
void handle_password(const string& password, const uint64_t& nbPasswords, ThreadData* my_data){
my_data->total_counter += nbPasswords;
if(my_data->use_regex && !regex_match(password,my_data->current_regex)){
void Statsgen::handle_password(const string& password, const uint64_t& nbPasswords, ThreadData& my_data) const {
my_data.total_counter += nbPasswords;
if(my_data.use_regex && !regex_match(password,my_data.current_regex)){
return;
}
PasswordStats c;
pair<uint, uint> masks = get_masks(password, c);
if(c.pol.satisfies(my_data->sr, password.size())){
my_data->sr.nbSecurePassword++;
if(c.pol.satisfies(my_data.sr, password.size())){
my_data.sr.nbSecurePassword++;
}
if (masks.first > my_data->limitSimplemask) {
if (masks.first > my_data.limitSimplemask) {
c.simplemask_string = "othermasks";
}
if (masks.second > my_data->limitAdvancedmask) {
if (masks.second > my_data.limitAdvancedmask) {
c.advancedmask_string = "othermasks";
}
my_data->total_filter += nbPasswords;
my_data->length[ password.size() ] += nbPasswords;
my_data->charactersets[ c.pol ] += nbPasswords;
my_data->simplemasks[ c.simplemask_string ] += nbPasswords;
my_data->advancedmasks[ c.advancedmask_string ] += nbPasswords;
my_data->minMaxValue.updateMinMax(c.pol);
}
void* Statsgen::generate_stats_thread(void* threadarg) {
ThreadData* my_data = (ThreadData *) threadarg;
ifstream readfile(my_data->filename);
uint64_t nbline = 0;
string line;
string password;
uint64_t nbPasswords;
while(getline(readfile, line)){
++nbline;
if (nbline < my_data->lineBegin){ continue; }
if (nbline > my_data->lineEnd){ break; }
if (line.size() == 0){ continue; }
if (my_data->withcount) {
istringstream is(line);
is >> nbPasswords;
is >> password;
}
else {
nbPasswords = 1;
password = line;
}
handle_password(password, nbPasswords, my_data);
}
readfile.close();
pthread_exit(NULL);
my_data.total_filter += nbPasswords;
my_data.length[ password.size() ] += nbPasswords;
my_data.charactersets[ c.pol ] += nbPasswords;
my_data.simplemasks[ c.simplemask_string ] += nbPasswords;
my_data.advancedmasks[ c.advancedmask_string ] += nbPasswords;
my_data.minMaxValue.updateMinMax(c.pol);
}
bool Statsgen::operator==(const Statsgen& o) const {
......
......@@ -156,10 +156,11 @@ void MainWindow::disableWithCount()
}
double MainWindow::initGraphicalStats(QBarSeries * barLength, QPieSeries * pieCharset, QPieSeries* pieSimple, QPieSeries* pieAdvanced, double & percentageTotal, double & percentageSecurity) {
double total = stats.getTotalCounter();
double filter = stats.getTotalFilter();
const ThreadData& results = stats.getResults();
double total = results.total_counter;
double filter = results.total_filter;
percentageTotal = percentage(filter, total);
percentageSecurity = percentage(stats.getNbSecurePasswords(), total);
percentageSecurity = percentage(results.sr.nbSecurePassword, total);
/* LENGTH HISTOGRAM */
multimap<uint64_t, int, greater<uint64_t>> reverseL = flip_map<int>(results.length);
......@@ -261,7 +262,7 @@ QVBoxLayout* MainWindow::drawPieChart(QPieSeries* qps, QVBoxLayout* layout, cons
void MainWindow::handleResults()
{
const ThreadData& results = stats.getResults();
progressThread->terminate();
progressThread->wait();
ui->progressBar->setValue(100);
......@@ -313,9 +314,9 @@ void MainWindow::handleResults()
/* LABELS */
ui->AnalyzedLabel->setText("Number of analyzed passwords: "
+ QString::number(stats.getTotalFilter(), 'g', 2)
+ QString::number(results.total_filter, 'g', 2)
+ " on a total of "
+ QString::number(stats.getTotalFilter(), 'g', 2)
+ QString::number(results.total_counter, 'g', 2)
+ " passwords (" + QString::number(percentageTotal) + "%)");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment