Skip to content

Commit

Permalink
Made file access in SimHitPrinter thread safe
Browse files Browse the repository at this point in the history
Since multiple instances of SimHitPrinter all share the same output
file via a static and those instances can be running on different
threads the file has to be protected by a mutex. In addition,
the creation of the file itself is done in a thread safe way.
  • Loading branch information
Dr15Jones committed Jun 22, 2015
1 parent 800bd18 commit 510591a
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 8 deletions.
3 changes: 2 additions & 1 deletion SimG4CMS/Muon/interface/SimHitPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "DataFormats/GeometryVector/interface/LocalPoint.h"

#include<fstream>
#include <atomic>

class SimHitPrinter {
public:
Expand All @@ -34,7 +35,7 @@ class SimHitPrinter {
void printLocal(LocalPoint,LocalPoint) const;
void printGlobal(GlobalPoint) const;
private:
static std::ofstream * theFile;
static std::atomic<std::ofstream*> theFile;
};

#endif
Expand Down
35 changes: 28 additions & 7 deletions SimG4CMS/Muon/src/SimHitPrinter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,25 @@

#include<iomanip>
#include<iostream>
#include <memory>
#include <mutex>

std::ofstream * SimHitPrinter::theFile(0);
std::atomic<std::ofstream *> SimHitPrinter::theFile(nullptr);

namespace {
std::mutex fileMutex;
}

SimHitPrinter::SimHitPrinter(std::string filename){
if (theFile) return;
const char* theName = filename.c_str();
theFile = new std::ofstream(theName, std::ios::out);
auto f = std::make_unique<std::ofstream>(theName, std::ios::out);

std::ofstream* previous = nullptr;
if(theFile.compare_exchange_strong(previous,f.get()) ) {
//this thread was the first one to try to set the value
f.release();
}
}

SimHitPrinter::~SimHitPrinter(){
Expand All @@ -21,6 +33,8 @@ void SimHitPrinter::startNewSimHit(std::string s){
std::cout.setf(std::ios::scientific,std::ios::floatfield);
std::cout.precision(6);
std::cout << "SimHit in "<<s<<std::endl;

std::lock_guard<std::mutex> guard{fileMutex};
(*theFile).width(10);
(*theFile).setf(std::ios::right,std::ios::adjustfield);
(*theFile).setf(std::ios::scientific|std::ios::uppercase|std::ios::showpos,std::ios::floatfield);
Expand All @@ -29,11 +43,13 @@ void SimHitPrinter::startNewSimHit(std::string s){
}

void SimHitPrinter::startNewEvent(int num){
std::lock_guard<std::mutex> guard{fileMutex};
(*theFile) << "Event "<<num<<std::endl;
}

void SimHitPrinter::printId(int id) const{
std::cout << " Id: "<<id<<std::endl;
std::lock_guard<std::mutex> guard{fileMutex};
(*theFile) << " id ";
(*theFile).width(10);
(*theFile).setf(std::ios::right,std::ios::adjustfield);
Expand All @@ -42,6 +58,7 @@ void SimHitPrinter::printId(int id) const{

void SimHitPrinter::printTrack(int id) const{
std::cout << " Track: "<<id<<std::endl;
std::lock_guard<std::mutex> guard{fileMutex};
(*theFile) << " trk ";
(*theFile).width(10);
(*theFile).setf(std::ios::right,std::ios::adjustfield);
Expand All @@ -50,34 +67,38 @@ void SimHitPrinter::printTrack(int id) const{

void SimHitPrinter::printPabs(float pabs) const{
std::cout << " Pabs: "<<pabs<<std::endl;
std::lock_guard<std::mutex> guard{fileMutex};
(*theFile) << " p "<<pabs;
}

void SimHitPrinter::printEloss(float eloss) const{
std::cout << " Eloss: "<<eloss<<std::endl;
std::lock_guard<std::mutex> guard{fileMutex};
(*theFile) << " e "<<eloss;
}

void SimHitPrinter::printLocal(LocalPoint localen,LocalPoint localex) const{
std::cout << " Local(en/ex): "<<localen.x()<<" "<< localen.y()<<" "
<<localen.z()<<" / "<<localex.x()<<" "<< localex.y()<<" "
<<localex.z()<<std::endl;
std::lock_guard<std::mutex> guard{fileMutex};
(*theFile).width(10);
(*theFile).setf(std::ios::right,std::ios::adjustfield);
(*theFile).setf(std::ios::floatfield);
(*theFile).precision(6);
std::cout << " Local(en/ex): "<<localen.x()<<" "<< localen.y()<<" "
<<localen.z()<<" / "<<localex.x()<<" "<< localex.y()<<" "
<<localex.z()<<std::endl;
(*theFile) << " en/ex "<<localen.x()<<" "<< localen.y()<<" "
<<localen.z()<<" / "<<localex.x()<<" "<< localex.y()<<" "
<<localex.z();
}

void SimHitPrinter::printGlobal(GlobalPoint global) const {
std::cout << " Global(en): "<<global.x()<<" "<< global.y()<<" "
<<global.z()<<std::endl;
std::lock_guard<std::mutex> guard{fileMutex};
(*theFile).width(10);
(*theFile).setf(std::ios::right,std::ios::adjustfield);
(*theFile).setf(std::ios::floatfield);
(*theFile).precision(6);
std::cout << " Global(en): "<<global.x()<<" "<< global.y()<<" "
<<global.z()<<std::endl;
(*theFile) << " gl "<<global.x()<<" "<< global.y()<<" "
<<global.z()<<std::endl;
}

0 comments on commit 510591a

Please sign in to comment.