<commit_before>///////////////////////////////////////////////////////////////////////////////
// Macro to setup AliPerformanceTask for
// TPC performance QA to run on PWGPP QA train.
//
// Input: ESDs, ESDfriends (optional), Kinematics (optional), TrackRefs (optional)
// ESD and MC input handlers must be attached to AliAnalysisManager
// to run default configuration.
//
// By default 1 performance components are added to
// the task:
// 0. AliPerformanceTPC (TPC cluster and track and event information)
// 1. AliPerformanceMatch (TPC and ITS/TRD matching and TPC eff w.r.t ITS)
// 2. AliPerformanceMatch (TPC and ITS/TRD matching and TPC eff w.r.t TPC)
// 3. AliPerformancedEdx (TPC dEdx information)
// 4. AliPerformanceRes (TPC track resolution w.r.t MC at DCA)
// 5. AliPerformanceEff (TPC track reconstruction efficiency, MC primaries)
// 6. AliPerformanceMatch (Comparison of TPC constrain and global tracking)
//
// Usage on the analysis train (default configuration):
// gSystem->Load("libANALYSIS");
// gSystem->Load("libANALYSISalice");
// gSystem->Load("libTPCcalib");
// gSystem->Load("libTender");
// gSystem->Load("libPWGPP");
//
// gROOT->LoadMacro("$ALICE_PHYSICS/PWGPP/TPC/macros/AddTaskPerformanceTPCdEdxQA.C");
// AliPerformanceTask *tpcQA = AddTaskPerformanceTPCdEdxQA("kFALSE","kTRUE","kFALSE","triggerClass",kFALSE);
//
// Output:
// TPC.Performance.root file with TPC performance components is created.
//
// Each of the components contains THnSparse generic histograms which
// have to be analysed (post-analysis) by using Analyse() function.
// Each component contains such function.
//
//30.09.2010 -  J.Otwinowski@gsi.de
//22.09.2011 -  jochen@thaeder.de - Updated
///////////////////////////////////////////////////////////////////////////////

//____________________________________________
AliPerformanceTask* AddTaskPerformanceTPCdEdxQA(Bool_t bUseMCInfo=kFALSE, Bool_t bUseESDfriend=kTRUE,
						Bool_t highMult = kFALSE, const char *triggerClass=0,
						Bool_t bUseHLT = kFALSE, Bool_t bUseTOF = kFALSE, Bool_t bTPCTrackingOnly = kFALSE,
						Bool_t bDoEffTpcSec = kFALSE)
{
  Char_t *taskName[] = {"TPC", "HLT"};
  Char_t *taskName2[] = {"", "_Tracking"};
  Int_t idx = 0, idx2 = 0;
  if (bUseHLT) idx = 1;
  if (bTPCTrackingOnly) idx2 = 1;

  //
  // Add AliPerformanceTask with TPC performance components
  //
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if(!mgr) {
    Error("AddTaskPerformanceTPCdEdxQA","AliAnalysisManager not set!");
    return NULL;
  }

  TString type = mgr->GetInputEventHandler()->GetDataType();
  if (!type.Contains("ESD")) {
    Error("AddTaskPerformanceTPCdEdxQA", "ESD input handler needed!");
    return NULL;
  }

  AliMCEventHandler* mchandler = new AliMCEventHandler;
    mchandler->SetReadTR(kFALSE);
    mgr->SetMCtruthEventHandler(mchandler);
  if (!mchandler && bUseMCInfo) {
    Error("AddTaskPerformanceTPCdEdxQA", "MC input handler needed!");
    return NULL;
  }

  //
  // Add HLT Event
  //
  if (bUseHLT) {
    AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*>(mgr->GetInputEventHandler());
    esdH->SetReadHLT();
  }

  //
  // Create task
  //
  AliPerformanceTask *task = new AliPerformanceTask("PerformanceQA",Form("%s%s Performance",taskName[idx], taskName2[idx2]));
  if (!task) {
    Error("AddTaskPerformanceTPCdEdxQA", Form("%s%s performance task cannot be created!",taskName[idx], taskName2[idx2]));
    return NULL;
  }
  task->SetUseMCInfo(bUseMCInfo);
  task->SetUseESDfriend(bUseESDfriend);
  //  task->SetUseTerminate(kFALSE);
  task->SetUseHLT(bUseHLT);

  //
  // Add task to analysis manager
  //
  mgr->AddTask(task);

  //
  // Create TPC-ESD track reconstruction cuts
  // MB tracks
  //
  AliRecInfoCuts *pRecInfoCutsTPC = new AliRecInfoCuts("pRecInfoCutsTPC");
  if(pRecInfoCutsTPC) {
    pRecInfoCutsTPC->SetMaxDCAToVertexXY(3.0);
    pRecInfoCutsTPC->SetMaxDCAToVertexZ(3.0);
    pRecInfoCutsTPC->SetRequireSigmaToVertex(kFALSE);
    pRecInfoCutsTPC->SetRequireTPCRefit(kFALSE);
    pRecInfoCutsTPC->SetAcceptKinkDaughters(kFALSE);
    pRecInfoCutsTPC->SetMinNClustersTPC(70);
    pRecInfoCutsTPC->SetMaxChi2PerClusterTPC(4.);
    pRecInfoCutsTPC->SetDCAToVertex2D(kTRUE);

    pRecInfoCutsTPC->SetHistogramsOn(kFALSE);
  }
  else {
    Error("AddTaskPerformanceTPCdEdxQA", "AliRecInfoCutsTPC cannot be created!");
    return NULL;
  }

  //
  // Create TPC-MC track reconstruction cuts
  //
  AliMCInfoCuts  *pMCInfoCuts = new AliMCInfoCuts("pMCInfoCuts");
  if(pMCInfoCuts) {
    pMCInfoCuts->SetMinTrackLength(70);
  }
  else {
    Error("AddTaskPerformanceTPCdEdxQA", "AliMCInfoCuts cannot be created!");
    return NULL;
  }

  //
  // Create performance objects for TPC and set cuts
  //
  enum { kTPC = 0, kTPCITS, kConstrained, kTPCInner, kTPCOuter, kTPCSec };

  if (bTPCTrackingOnly == kFALSE) {
  //
  // TPC performance
  //
  AliPerformanceTPC *pCompTPC0 = new AliPerformanceTPC("AliPerformanceTPC","AliPerformanceTPC",kTPC,kFALSE,-1,highMult);
  if(!pCompTPC0) {
    Error("AddTaskPerformanceTPCdEdxQA", "Cannot create AliPerformanceTPC");
  }
  pCompTPC0->SetAliRecInfoCuts(pRecInfoCutsTPC);
  pCompTPC0->SetAliMCInfoCuts(pMCInfoCuts);
  //  pCompTPC0->SetUseTrackVertex(kFALSE);
  pCompTPC0->SetUseTrackVertex(kTRUE);
  pCompTPC0->SetUseHLT(bUseHLT);
  pCompTPC0->SetUseTOFBunchCrossing(bUseTOF);

  //
  // TPC ITS match
  //
  AliPerformanceMatch *pCompMatch1 = new AliPerformanceMatch("AliPerformanceMatchTPCITS","AliPerformanceMatchTPCITS",0,kFALSE);
  if(!pCompMatch1) {
    Error("AddTaskPerformanceTPCdEdxQA", "Cannot create AliPerformanceMatchTPCITS");
  }
  pCompMatch1->SetAliRecInfoCuts(pRecInfoCutsTPC);
  pCompMatch1->SetAliMCInfoCuts(pMCInfoCuts);
  pCompMatch1->SetUseTOFBunchCrossing(bUseTOF);

  //
  // ITS TPC match
  //
  AliPerformanceMatch *pCompMatch2 = new AliPerformanceMatch("AliPerformanceMatchITSTPC","AliPerformanceMatchITSTPC",1,kFALSE);
  if(!pCompMatch2) {
    Error("AddTaskPerformanceTPCdEdxQA", "Cannot create AliPerformanceMatchITSTPC");  }
  pCompMatch2->SetAliRecInfoCuts(pRecInfoCutsTPC);
  pCompMatch2->SetAliMCInfoCuts(pMCInfoCuts);
  pCompMatch2->SetUseTOFBunchCrossing(bUseTOF);

  //
  // dEdx
  //
  AliPerformanceDEdx *pCompDEdx3 = new AliPerformanceDEdx("AliPerformanceDEdxTPCInner","AliPerformanceDEdxTPCInner",kTPCInner,kFALSE);
  if(!pCompDEdx3) {
    Error("AddTaskPerformanceTPCdEdxQA", "Cannot create AliPerformanceDEdxTPCInner");
  }
  pCompDEdx3->SetAliRecInfoCuts(pRecInfoCutsTPC);
  pCompDEdx3->SetAliMCInfoCuts(pMCInfoCuts);
  //pCompDEdx3->SetUseTrackVertex(kFALSE);
  pCompDEdx3->SetUseTrackVertex(kTRUE);
  } //end bTPCTrackingOnly == kFALSE

  //
  // Resolution ------------------------------------------------------------------------------------
  //

  AliPerformanceRes *pCompRes4 = new AliPerformanceRes(bTPCTrackingOnly ? "AliPerformanceResTPC" : "AliPerformanceRes",
						       "AliPerformanceRes", bTPCTrackingOnly == kTRUE ? kTPCInner : kTPC,kFALSE);
  if(!pCompRes4) {
    Error("AddTaskPerformanceTPC", "Cannot create AliPerformanceRes");
  }

  pCompRes4->SetAliRecInfoCuts(pRecInfoCutsTPC);
  pCompRes4->SetAliMCInfoCuts(pMCInfoCuts);
  pCompRes4->SetUseTrackVertex(bTPCTrackingOnly == kTRUE ? kFALSE : kTRUE);

  //
  // Efficiency ------------------------------------------------------------------------------------
  //

  AliPerformanceEff *pCompEff5 = new AliPerformanceEff(bTPCTrackingOnly ? "AliPerformanceEffTPC" : "AliPerformanceEff",
						       "AliPerformanceEff",kTPC,kFALSE);
  if(!pCompEff5) {
    Error("AddTaskPerformanceTPC", "Cannot create AliPerformanceEff");
  }

  if (bTPCTrackingOnly)
  {
    //For low pt tracks, HLT finds only short track segments.
    //Hence, for the tpc-tracking only tracking-efficiency, we lower the minimum number of hits per reconstructed TPC track
    AliRecInfoCuts *pRecInfoCutsTPC2 = new AliRecInfoCuts("pRecInfoCutsTPC2");
    *pRecInfoCutsTPC2 = pRecInfoCutsTPC2;
    pRecInfoCutsTPC2->SetMinNClustersTPC(20);
    pCompEff5->SetAliRecInfoCuts(pRecInfoCutsTPC2);
  }
  else
  {
    pCompEff5->SetAliRecInfoCuts(pRecInfoCutsTPC);
  }
  pCompEff5->SetAliMCInfoCuts(pMCInfoCuts);
  pCompEff5->SetUseTrackVertex(bTPCTrackingOnly == kTRUE ? kFALSE : kTRUE);

  AliPerformanceEff *pCompEff5Sec;
  if (bDoEffTpcSec)
  {
	  pCompEff5Sec = new AliPerformanceEff(bTPCTrackingOnly ? "AliPerformanceEffSecTPC" : "AliPerformanceEffSec",
						       "AliPerformanceEffSec",kTPCSec,kFALSE);
	  if(!pCompEff5Sec) {
		  Error("AddTaskPerformanceTPC", "Cannot create AliPerformanceEff");
	  }

	  pCompEff5Sec->SetAliRecInfoCuts(pRecInfoCutsTPC);
	  pCompEff5Sec->SetAliMCInfoCuts(pMCInfoCuts);
	  pCompEff5Sec->SetUseTrackVertex(bTPCTrackingOnly == kTRUE ? kFALSE : kTRUE);
  }

  //
  // TPC Constrain to vertex
  //
  if (bTPCTrackingOnly == kFALSE) {
  AliPerformanceMatch *pCompConstrain6 = new AliPerformanceMatch("AliPerformanceMatchTPCConstrain","AliPerformanceMatchTPCConstrain",2,kFALSE);
  if(!pCompConstrain6) {
    Error("AddTaskPerformanceTPCdEdxQA", "Cannot create AliPerformanceMatchTPCConstrain");  }
  pCompConstrain6->SetAliRecInfoCuts(pRecInfoCutsTPC);
  pCompConstrain6->SetAliMCInfoCuts(pMCInfoCuts);
  pCompConstrain6->SetUseTOFBunchCrossing(bUseTOF);
  } //end bTPCTrackingOnly == kFALSE

  //
  // Add components to the performance task
  //
  if (bTPCTrackingOnly == kFALSE) {
  if(!bUseMCInfo) {
    pCompTPC0->SetTriggerClass(triggerClass);
    pCompMatch1->SetTriggerClass(triggerClass);
    pCompMatch2->SetTriggerClass(triggerClass);
    pCompDEdx3->SetTriggerClass(triggerClass);
    pCompConstrain6->SetTriggerClass(triggerClass);
  }
  task->AddPerformanceObject( pCompTPC0 );
  task->AddPerformanceObject( pCompMatch1 );
  task->AddPerformanceObject( pCompMatch2 );
  task->AddPerformanceObject( pCompDEdx3 );
  task->AddPerformanceObject( pCompConstrain6 );
  } //end bTPCTrackingOnly == kFALSE
  if(bUseMCInfo)   {
      task->AddPerformanceObject( pCompRes4 );
      task->AddPerformanceObject( pCompEff5 );
	  if (bDoEffTpcSec) task->AddPerformanceObject( pCompEff5Sec );
  }

  //
  // Create containers for input
  //
  mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());

  //
  // Create containers for output
  //

  AliAnalysisDataContainer *coutput = mgr->CreateContainer(Form("%s%sQA", taskName[idx], taskName2[idx2]), TList::Class(),
							   AliAnalysisManager::kOutputContainer,
							   Form("%s:%s_%s", mgr->GetCommonFileName(), taskName[idx],task->GetName()));

  AliAnalysisDataContainer *coutput2  = mgr->CreateContainer(Form("%s%sQASummary", taskName[idx], taskName2[idx2]), TTree::Class(),
							     AliAnalysisManager::kParamContainer,
							     Form("trending.root:Summary%sQA", taskName[idx]));

  mgr->ConnectOutput(task, 1, coutput);
  mgr->ConnectOutput(task, 0, coutput2);

return task;
}
<commit_msg>only create MC event handler when needed<commit_after>///////////////////////////////////////////////////////////////////////////////
// Macro to setup AliPerformanceTask for
// TPC performance QA to run on PWGPP QA train.
//
// Input: ESDs, ESDfriends (optional), Kinematics (optional), TrackRefs (optional)
// ESD and MC input handlers must be attached to AliAnalysisManager
// to run default configuration.
//
// By default 1 performance components are added to
// the task:
// 0. AliPerformanceTPC (TPC cluster and track and event information)
// 1. AliPerformanceMatch (TPC and ITS/TRD matching and TPC eff w.r.t ITS)
// 2. AliPerformanceMatch (TPC and ITS/TRD matching and TPC eff w.r.t TPC)
// 3. AliPerformancedEdx (TPC dEdx information)
// 4. AliPerformanceRes (TPC track resolution w.r.t MC at DCA)
// 5. AliPerformanceEff (TPC track reconstruction efficiency, MC primaries)
// 6. AliPerformanceMatch (Comparison of TPC constrain and global tracking)
//
// Usage on the analysis train (default configuration):
// gSystem->Load("libANALYSIS");
// gSystem->Load("libANALYSISalice");
// gSystem->Load("libTPCcalib");
// gSystem->Load("libTender");
// gSystem->Load("libPWGPP");
//
// gROOT->LoadMacro("$ALICE_PHYSICS/PWGPP/TPC/macros/AddTaskPerformanceTPCdEdxQA.C");
// AliPerformanceTask *tpcQA = AddTaskPerformanceTPCdEdxQA("kFALSE","kTRUE","kFALSE","triggerClass",kFALSE);
//
// Output:
// TPC.Performance.root file with TPC performance components is created.
//
// Each of the components contains THnSparse generic histograms which
// have to be analysed (post-analysis) by using Analyse() function.
// Each component contains such function.
//
//30.09.2010 -  J.Otwinowski@gsi.de
//22.09.2011 -  jochen@thaeder.de - Updated
///////////////////////////////////////////////////////////////////////////////

//____________________________________________
AliPerformanceTask* AddTaskPerformanceTPCdEdxQA(Bool_t bUseMCInfo=kFALSE, Bool_t bUseESDfriend=kTRUE,
						Bool_t highMult = kFALSE, const char *triggerClass=0,
						Bool_t bUseHLT = kFALSE, Bool_t bUseTOF = kFALSE, Bool_t bTPCTrackingOnly = kFALSE,
						Bool_t bDoEffTpcSec = kFALSE)
{
  Char_t *taskName[] = {"TPC", "HLT"};
  Char_t *taskName2[] = {"", "_Tracking"};
  Int_t idx = 0, idx2 = 0;
  if (bUseHLT) idx = 1;
  if (bTPCTrackingOnly) idx2 = 1;

  //
  // Add AliPerformanceTask with TPC performance components
  //
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if(!mgr) {
    Error("AddTaskPerformanceTPCdEdxQA","AliAnalysisManager not set!");
    return NULL;
  }

  TString type = mgr->GetInputEventHandler()->GetDataType();
  if (!type.Contains("ESD")) {
    Error("AddTaskPerformanceTPCdEdxQA", "ESD input handler needed!");
    return NULL;
  }

	if (bUseMCInfo)
	{
  	AliMCEventHandler* mchandler = new AliMCEventHandler;
    mchandler->SetReadTR(kFALSE);
    mgr->SetMCtruthEventHandler(mchandler);
  	if (!mchandler)
		{
    	Error("AddTaskPerformanceTPCdEdxQA", "MC input handler needed!");
    	return NULL;
		}
  }

  //
  // Add HLT Event
  //
  if (bUseHLT) {
    AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*>(mgr->GetInputEventHandler());
    esdH->SetReadHLT();
  }

  //
  // Create task
  //
  AliPerformanceTask *task = new AliPerformanceTask("PerformanceQA",Form("%s%s Performance",taskName[idx], taskName2[idx2]));
  if (!task) {
    Error("AddTaskPerformanceTPCdEdxQA", Form("%s%s performance task cannot be created!",taskName[idx], taskName2[idx2]));
    return NULL;
  }
  task->SetUseMCInfo(bUseMCInfo);
  task->SetUseESDfriend(bUseESDfriend);
  //  task->SetUseTerminate(kFALSE);
  task->SetUseHLT(bUseHLT);

  //
  // Add task to analysis manager
  //
  mgr->AddTask(task);

  //
  // Create TPC-ESD track reconstruction cuts
  // MB tracks
  //
  AliRecInfoCuts *pRecInfoCutsTPC = new AliRecInfoCuts("pRecInfoCutsTPC");
  if(pRecInfoCutsTPC) {
    pRecInfoCutsTPC->SetMaxDCAToVertexXY(3.0);
    pRecInfoCutsTPC->SetMaxDCAToVertexZ(3.0);
    pRecInfoCutsTPC->SetRequireSigmaToVertex(kFALSE);
    pRecInfoCutsTPC->SetRequireTPCRefit(kFALSE);
    pRecInfoCutsTPC->SetAcceptKinkDaughters(kFALSE);
    pRecInfoCutsTPC->SetMinNClustersTPC(70);
    pRecInfoCutsTPC->SetMaxChi2PerClusterTPC(4.);
    pRecInfoCutsTPC->SetDCAToVertex2D(kTRUE);

    pRecInfoCutsTPC->SetHistogramsOn(kFALSE);
  }
  else {
    Error("AddTaskPerformanceTPCdEdxQA", "AliRecInfoCutsTPC cannot be created!");
    return NULL;
  }

  //
  // Create TPC-MC track reconstruction cuts
  //
  AliMCInfoCuts  *pMCInfoCuts = new AliMCInfoCuts("pMCInfoCuts");
  if(pMCInfoCuts) {
    pMCInfoCuts->SetMinTrackLength(70);
  }
  else {
    Error("AddTaskPerformanceTPCdEdxQA", "AliMCInfoCuts cannot be created!");
    return NULL;
  }

  //
  // Create performance objects for TPC and set cuts
  //
  enum { kTPC = 0, kTPCITS, kConstrained, kTPCInner, kTPCOuter, kTPCSec };

  if (bTPCTrackingOnly == kFALSE) {
  //
  // TPC performance
  //
  AliPerformanceTPC *pCompTPC0 = new AliPerformanceTPC("AliPerformanceTPC","AliPerformanceTPC",kTPC,kFALSE,-1,highMult);
  if(!pCompTPC0) {
    Error("AddTaskPerformanceTPCdEdxQA", "Cannot create AliPerformanceTPC");
  }
  pCompTPC0->SetAliRecInfoCuts(pRecInfoCutsTPC);
  pCompTPC0->SetAliMCInfoCuts(pMCInfoCuts);
  //  pCompTPC0->SetUseTrackVertex(kFALSE);
  pCompTPC0->SetUseTrackVertex(kTRUE);
  pCompTPC0->SetUseHLT(bUseHLT);
  pCompTPC0->SetUseTOFBunchCrossing(bUseTOF);

  //
  // TPC ITS match
  //
  AliPerformanceMatch *pCompMatch1 = new AliPerformanceMatch("AliPerformanceMatchTPCITS","AliPerformanceMatchTPCITS",0,kFALSE);
  if(!pCompMatch1) {
    Error("AddTaskPerformanceTPCdEdxQA", "Cannot create AliPerformanceMatchTPCITS");
  }
  pCompMatch1->SetAliRecInfoCuts(pRecInfoCutsTPC);
  pCompMatch1->SetAliMCInfoCuts(pMCInfoCuts);
  pCompMatch1->SetUseTOFBunchCrossing(bUseTOF);

  //
  // ITS TPC match
  //
  AliPerformanceMatch *pCompMatch2 = new AliPerformanceMatch("AliPerformanceMatchITSTPC","AliPerformanceMatchITSTPC",1,kFALSE);
  if(!pCompMatch2) {
    Error("AddTaskPerformanceTPCdEdxQA", "Cannot create AliPerformanceMatchITSTPC");  }
  pCompMatch2->SetAliRecInfoCuts(pRecInfoCutsTPC);
  pCompMatch2->SetAliMCInfoCuts(pMCInfoCuts);
  pCompMatch2->SetUseTOFBunchCrossing(bUseTOF);

  //
  // dEdx
  //
  AliPerformanceDEdx *pCompDEdx3 = new AliPerformanceDEdx("AliPerformanceDEdxTPCInner","AliPerformanceDEdxTPCInner",kTPCInner,kFALSE);
  if(!pCompDEdx3) {
    Error("AddTaskPerformanceTPCdEdxQA", "Cannot create AliPerformanceDEdxTPCInner");
  }
  pCompDEdx3->SetAliRecInfoCuts(pRecInfoCutsTPC);
  pCompDEdx3->SetAliMCInfoCuts(pMCInfoCuts);
  //pCompDEdx3->SetUseTrackVertex(kFALSE);
  pCompDEdx3->SetUseTrackVertex(kTRUE);
  } //end bTPCTrackingOnly == kFALSE

  //
  // Resolution ------------------------------------------------------------------------------------
  //

  AliPerformanceRes *pCompRes4 = new AliPerformanceRes(bTPCTrackingOnly ? "AliPerformanceResTPC" : "AliPerformanceRes",
						       "AliPerformanceRes", bTPCTrackingOnly == kTRUE ? kTPCInner : kTPC,kFALSE);
  if(!pCompRes4) {
    Error("AddTaskPerformanceTPC", "Cannot create AliPerformanceRes");
  }

  pCompRes4->SetAliRecInfoCuts(pRecInfoCutsTPC);
  pCompRes4->SetAliMCInfoCuts(pMCInfoCuts);
  pCompRes4->SetUseTrackVertex(bTPCTrackingOnly == kTRUE ? kFALSE : kTRUE);

  //
  // Efficiency ------------------------------------------------------------------------------------
  //

  AliPerformanceEff *pCompEff5 = new AliPerformanceEff(bTPCTrackingOnly ? "AliPerformanceEffTPC" : "AliPerformanceEff",
						       "AliPerformanceEff",kTPC,kFALSE);
  if(!pCompEff5) {
    Error("AddTaskPerformanceTPC", "Cannot create AliPerformanceEff");
  }

  if (bTPCTrackingOnly)
  {
    //For low pt tracks, HLT finds only short track segments.
    //Hence, for the tpc-tracking only tracking-efficiency, we lower the minimum number of hits per reconstructed TPC track
    AliRecInfoCuts *pRecInfoCutsTPC2 = new AliRecInfoCuts("pRecInfoCutsTPC2");
    *pRecInfoCutsTPC2 = pRecInfoCutsTPC2;
    pRecInfoCutsTPC2->SetMinNClustersTPC(20);
    pCompEff5->SetAliRecInfoCuts(pRecInfoCutsTPC2);
  }
  else
  {
    pCompEff5->SetAliRecInfoCuts(pRecInfoCutsTPC);
  }
  pCompEff5->SetAliMCInfoCuts(pMCInfoCuts);
  pCompEff5->SetUseTrackVertex(bTPCTrackingOnly == kTRUE ? kFALSE : kTRUE);

  AliPerformanceEff *pCompEff5Sec;
  if (bDoEffTpcSec)
  {
	  pCompEff5Sec = new AliPerformanceEff(bTPCTrackingOnly ? "AliPerformanceEffSecTPC" : "AliPerformanceEffSec",
						       "AliPerformanceEffSec",kTPCSec,kFALSE);
	  if(!pCompEff5Sec) {
		  Error("AddTaskPerformanceTPC", "Cannot create AliPerformanceEff");
	  }

	  pCompEff5Sec->SetAliRecInfoCuts(pRecInfoCutsTPC);
	  pCompEff5Sec->SetAliMCInfoCuts(pMCInfoCuts);
	  pCompEff5Sec->SetUseTrackVertex(bTPCTrackingOnly == kTRUE ? kFALSE : kTRUE);
  }

  //
  // TPC Constrain to vertex
  //
  if (bTPCTrackingOnly == kFALSE) {
  AliPerformanceMatch *pCompConstrain6 = new AliPerformanceMatch("AliPerformanceMatchTPCConstrain","AliPerformanceMatchTPCConstrain",2,kFALSE);
  if(!pCompConstrain6) {
    Error("AddTaskPerformanceTPCdEdxQA", "Cannot create AliPerformanceMatchTPCConstrain");  }
  pCompConstrain6->SetAliRecInfoCuts(pRecInfoCutsTPC);
  pCompConstrain6->SetAliMCInfoCuts(pMCInfoCuts);
  pCompConstrain6->SetUseTOFBunchCrossing(bUseTOF);
  } //end bTPCTrackingOnly == kFALSE

  //
  // Add components to the performance task
  //
  if (bTPCTrackingOnly == kFALSE) {
  if(!bUseMCInfo) {
    pCompTPC0->SetTriggerClass(triggerClass);
    pCompMatch1->SetTriggerClass(triggerClass);
    pCompMatch2->SetTriggerClass(triggerClass);
    pCompDEdx3->SetTriggerClass(triggerClass);
    pCompConstrain6->SetTriggerClass(triggerClass);
  }
  task->AddPerformanceObject( pCompTPC0 );
  task->AddPerformanceObject( pCompMatch1 );
  task->AddPerformanceObject( pCompMatch2 );
  task->AddPerformanceObject( pCompDEdx3 );
  task->AddPerformanceObject( pCompConstrain6 );
  } //end bTPCTrackingOnly == kFALSE
  if(bUseMCInfo)   {
      task->AddPerformanceObject( pCompRes4 );
      task->AddPerformanceObject( pCompEff5 );
	  if (bDoEffTpcSec) task->AddPerformanceObject( pCompEff5Sec );
  }

  //
  // Create containers for input
  //
  mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());

  //
  // Create containers for output
  //

  AliAnalysisDataContainer *coutput = mgr->CreateContainer(Form("%s%sQA", taskName[idx], taskName2[idx2]), TList::Class(),
							   AliAnalysisManager::kOutputContainer,
							   Form("%s:%s_%s", mgr->GetCommonFileName(), taskName[idx],task->GetName()));

  AliAnalysisDataContainer *coutput2  = mgr->CreateContainer(Form("%s%sQASummary", taskName[idx], taskName2[idx2]), TTree::Class(),
							     AliAnalysisManager::kParamContainer,
							     Form("trending.root:Summary%sQA", taskName[idx]));

  mgr->ConnectOutput(task, 1, coutput);
  mgr->ConnectOutput(task, 0, coutput2);

return task;
}
<|endoftext|>


<commit_before>#include "Andersen.h"

#include "Polymer.h"
#include "Monomer.h"
#include "consts.h"
#include "Rand.h"
using namespace consts;

#include<cmath>

using namespace std;

Andersen::Andersen(Polymer &poly, double dtime, double nu) :
Thermostat(poly,dtime),
m_nu(nu) {
	update_temp();
}

double Andersen::update_temp() {
	m_sigma = sqrt(m_poly.temp() / m_poly.monomer_mass);

	return m_sigma;
}

double  Andersen::dtime(double delta_time) {
	Thermostat::dtime(delta_time);
	m_dtime2 = m_dtime / 2;
	m_nu_dt = m_nu*m_dtime;

	return m_dtime;
}

void  Andersen::propagate() {
	// velocity verlet
	for (auto& m : m_poly.monomers) {
		m.velocity += m_dtime2*m.force / m_poly.monomer_mass;
		m.position += m_dtime*m.velocity;
	}

	m_poly.update_forces();

	for (auto& m : m_poly.monomers) {
		m.velocity += m_dtime2*m.force / m_poly.monomer_mass;
	}

	//Andersen
	for (auto& m : m_poly.monomers) {
		if (m_nu_dt > Rand::real_uniform())
			m.velocity = m_sigma*Rand::real_normal();
	}
}
<commit_msg>Anpassung an Thermostat Klasse<commit_after>#include "Andersen.h"

#include "Polymer.h"
#include "Monomer.h"
#include "consts.h"
#include "Rand.h"
using namespace consts;

#include<cmath>

using namespace std;

Andersen::Andersen(Polymer &poly, double delta_time, double nu) :
Thermostat(poly,delta_time),
m_nu(nu) {
	dtime(delta_time);
}

double Andersen::update_temp() {
	m_sigma = sqrt(m_poly.temp() / m_poly.monomer_mass);

	return m_sigma;
}

double  Andersen::dtime(double delta_time) {
	Thermostat::dtime(delta_time);
	m_dtime2 = m_dtime / 2;
	m_nu_dt = m_nu*m_dtime;

	return m_dtime;
}

void  Andersen::propagate() {
	// velocity verlet
	for (auto& m : m_poly.monomers) {
		m.velocity += m_dtime2*m.force / m_poly.monomer_mass;
		m.position += m_dtime*m.velocity;
	}

	m_poly.update_forces();

	for (auto& m : m_poly.monomers) {
		m.velocity += m_dtime2*m.force / m_poly.monomer_mass;
	}

	//Andersen
	for (auto& m : m_poly.monomers) {
		if (m_nu_dt > Rand::real_uniform())
			m.velocity = m_sigma*Rand::real_normal();
	}
}
<|endoftext|>


<commit_before>using func_p = void(*)();

//Labels to the arrays of constructors and destructors placed by the linker
extern "C" func_p start_ctors, end_ctors, start_dtors, end_dtors;

//Constructs all static objects
void static_construct()
{
    for(auto fp = &start_ctors; fp < &end_ctors; ++fp)
        (*fp)();
}

//Destructs all static objects
void static_destruct()
{
    for(auto fp = &start_dtors; fp < &end_dtors; ++fp)
        (*fp)();
}
<commit_msg>Destruct static elements in reverse order<commit_after>using func_p = void(*)();

//Labels to the arrays of constructors and destructors placed by the linker
extern "C" func_p start_ctors, end_ctors, start_dtors, end_dtors;

//Constructs all static objects
void static_construct()
{
    for(auto fp = &start_ctors; fp < &end_ctors; ++fp)
        (*fp)();
}

//Destructs all static objects
void static_destruct()
{
    for(auto fp = &end_dtors-1; fp >= &start_dtors; --fp)
        (*fp)();
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013-2014 Chun-Ying Huang
 *
 * This file is part of GamingAnywhere (GA).
 *
 * GA is free software; you can redistribute it and/or modify it
 * under the terms of the 3-clause BSD License as published by the
 * Free Software Foundation: http://directory.fsf.org/wiki/License:BSD_3Clause
 *
 * GA is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the 3-clause BSD License along with GA;
 * if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <MPEG1or2AudioRTPSink.hh>
#include <MPEG4GenericRTPSink.hh>
#include <AC3AudioRTPSink.hh>
#include <SimpleRTPSink.hh>
#include <VorbisAudioRTPSink.hh>
#include <H264VideoRTPSink.hh>
#include <H265VideoRTPSink.hh>
#include <VP8VideoRTPSink.hh>
#include <TheoraVideoRTPSink.hh>
#include <T140TextRTPSink.hh>
#include <H264VideoStreamDiscreteFramer.hh>
#include <H265VideoStreamDiscreteFramer.hh>
#include <H264VideoStreamFramer.hh>
#include <H265VideoStreamFramer.hh>

#include "ga-common.h"
#include "ga-conf.h"
#include "rtspconf.h"
#include "encoder-common.h"
#include "ga-mediasubsession.h"
#include "ga-audiolivesource.h"
#include "ga-videolivesource.h"

GAMediaSubsession
::GAMediaSubsession(UsageEnvironment &env, int cid, const char *mimetype, portNumBits initialPortNum, Boolean multiplexRTCPWithRTP)
		: OnDemandServerMediaSubsession(env, True/*reuseFirstSource*/, initialPortNum, multiplexRTCPWithRTP) {
	this->mimetype = strdup(mimetype);
	this->channelId = cid;
}

GAMediaSubsession * GAMediaSubsession
::createNew(UsageEnvironment &env, int cid, const char *mimetype,
		portNumBits initialPortNum,
		Boolean multiplexRTCPWithRTP) {
	return new GAMediaSubsession(env, cid, mimetype, initialPortNum, multiplexRTCPWithRTP);
}

FramedSource* GAMediaSubsession
::createNewStreamSource(unsigned clientSessionId,
			unsigned& estBitrate) {
	FramedSource *result = NULL;
	struct RTSPConf *rtspconf = rtspconf_global();
	if(strncmp("audio/", this->mimetype, 6) == 0) {
		estBitrate = rtspconf->audio_bitrate / 1000; /* Kbps */
		result = GAAudioLiveSource::createNew(envir(), this->channelId);
	} else if(strncmp("video/", this->mimetype, 6) == 0) {
		//estBitrate = 500; /* Kbps */
		estBitrate = ga_conf_mapreadint("video-specific", "b") / 1000; /* Kbps */
		OutPacketBuffer::increaseMaxSizeTo(300000);
		result = GAVideoLiveSource::createNew(envir(), this->channelId);
	}
	do if(result != NULL) {
		if(strcmp("video/H264", this->mimetype) == 0) {
#ifdef DISCRETE_FRAMER
			result = H264VideoStreamDiscreteFramer::createNew(envir(), result);
#else
			result = H264VideoStreamFramer::createNew(envir(), result);
#endif
			break;
		}
		if(strcmp("video/H265", this->mimetype) == 0) {
#ifdef DISCRETE_FRAMER
			result = H265VideoStreamDiscreteFramer::createNew(envir(), result);
#else
			result = H265VideoStreamFramer::createNew(envir(), result);
#endif
			break;
		}
	} while(0);
	return result;
}

// "estBitrate" is the stream's estimated bitrate, in kbps
RTPSink* GAMediaSubsession
::createNewRTPSink(Groupsock* rtpGroupsock,
			unsigned char rtpPayloadTypeIfDynamic,
			FramedSource* inputSource) {
	RTPSink *result = NULL;
	struct RTSPConf *rtspconf = rtspconf_global();
	const char *mimetype = this->mimetype;
	//
	if(strcmp(mimetype, "audio/MPEG") == 0) {
		result = MPEG1or2AudioRTPSink::createNew(envir(), rtpGroupsock);
	} else if(strcmp(mimetype, "audio/AAC") == 0) {
		// TODO: not implememted
		ga_error("GAMediaSubsession: %s NOT IMPLEMENTED\n", mimetype);
		exit(-1);
	} else if(strcmp(mimetype, "audio/AC3") == 0) {
		result = AC3AudioRTPSink
			::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic,
					rtspconf->audio_samplerate);
	} else if(strcmp(mimetype, "audio/OPUS") == 0) {
		result = SimpleRTPSink
			::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic,
					rtspconf->audio_samplerate,
					"audio", "OPUS", 2, False/*only 1 Opus 'packet' in each RTP packet*/);
	} else if(strcmp(mimetype, "audio/VORBIS") == 0) {
		u_int8_t* identificationHeader = NULL; unsigned identificationHeaderSize = 0;
		u_int8_t* commentHeader = NULL; unsigned commentHeaderSize = 0;
		u_int8_t* setupHeader = NULL; unsigned setupHeaderSize = 0;
		// TODO: not implememted
		ga_error("GAMediaSubsession: %s NOT IMPLEMENTED\n", mimetype);
		exit(-1);
		result = VorbisAudioRTPSink
			::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic,
					rtspconf->audio_samplerate,
					rtspconf->audio_channels,
					identificationHeader, identificationHeaderSize,
					commentHeader, commentHeaderSize,
					setupHeader, setupHeaderSize);
	} else if(strcmp(mimetype, "video/THEORA") == 0) {
		u_int8_t* identificationHeader = NULL; unsigned identificationHeaderSize = 0;
		u_int8_t* commentHeader = NULL; unsigned commentHeaderSize = 0;
		u_int8_t* setupHeader = NULL; unsigned setupHeaderSize = 0;
		// TODO: not implememted
		ga_error("GAMediaSubsession: %s NOT IMPLEMENTED\n", mimetype);
		exit(-1);
		result = TheoraVideoRTPSink
			::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic,
					identificationHeader, identificationHeaderSize,
					commentHeader, commentHeaderSize,
					setupHeader, setupHeaderSize);
	} else if(strcmp(mimetype, "video/H264") == 0) {
		ga_module_t *m = encoder_get_vencoder();
		unsigned profile_level_id = 0;
		u_int8_t* SPS = NULL; int SPSSize = 0;
		u_int8_t* PPS = NULL; int PPSSize = 0;
		//
		SPS = (u_int8_t*) m->option1((void*) this->channelId, &SPSSize);
		PPS = (u_int8_t*) m->option2((void*) this->channelId, &PPSSize);
		if (SPSSize >= 1/*'profile_level_id' offset within SPS*/ + 3/*num bytes needed*/) {
			profile_level_id = (SPS[1]<<16) | (SPS[2]<<8) | SPS[3];
		}
		ga_error("GAMediaSubsession: %s SPS=%p(%d); PPS=%p(%d); profile_level_id=%x\n",
			mimetype,
			SPS, SPSSize, PPS, PPSSize, profile_level_id);
		result = H264VideoRTPSink::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic,
				SPS, SPSSize, PPS, PPSSize/*, profile_level_id*/);
	} else if(strcmp(mimetype, "video/H265") == 0) {
		ga_module_t *m = encoder_get_vencoder();
		u_int8_t* VPS = NULL; int VPSSize = 0;
		u_int8_t* SPS = NULL; int SPSSize = 0;
		u_int8_t* PPS = NULL; int PPSSize = 0;
		// TODO: not implememted
#if 0
		ga_error("GAMediaSubsession: %s NOT IMPLEMENTED\n", mimetype);
		exit(-1);
#endif
		SPS = (u_int8_t*) m->option1((void*) this->channelId, &SPSSize);
		PPS = (u_int8_t*) m->option2((void*) this->channelId, &PPSSize);
		VPS = (u_int8_t*) m->option3((void*) this->channelId, &VPSSize);
		ga_error("GAMediaSubsession: %s SPS=%p(%d); PPS=%p(%d); VPS=%p(%d)\n",
			mimetype,
			SPS, SPSSize, PPS, PPSSize, VPS, VPSSize);
		result = H265VideoRTPSink::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic,
				VPS, VPSSize, SPS, SPSSize, PPS, PPSSize/*,
				profileSpace, profileId, tierFlag, levelId,
				interopConstraintsStr*/);
	} else if(strcmp(mimetype, "video/VP8") == 0) {
		result = VP8VideoRTPSink::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic);
	}
	if(result == NULL) {
		ga_error("GAMediaSubsession: create RTP sink for %s failed.\n", mimetype);
	}
	return result;
}

<commit_msg>increase max frame size to 600K<commit_after>/*
 * Copyright (c) 2013-2014 Chun-Ying Huang
 *
 * This file is part of GamingAnywhere (GA).
 *
 * GA is free software; you can redistribute it and/or modify it
 * under the terms of the 3-clause BSD License as published by the
 * Free Software Foundation: http://directory.fsf.org/wiki/License:BSD_3Clause
 *
 * GA is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the 3-clause BSD License along with GA;
 * if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <MPEG1or2AudioRTPSink.hh>
#include <MPEG4GenericRTPSink.hh>
#include <AC3AudioRTPSink.hh>
#include <SimpleRTPSink.hh>
#include <VorbisAudioRTPSink.hh>
#include <H264VideoRTPSink.hh>
#include <H265VideoRTPSink.hh>
#include <VP8VideoRTPSink.hh>
#include <TheoraVideoRTPSink.hh>
#include <T140TextRTPSink.hh>
#include <H264VideoStreamDiscreteFramer.hh>
#include <H265VideoStreamDiscreteFramer.hh>
#include <H264VideoStreamFramer.hh>
#include <H265VideoStreamFramer.hh>

#include "ga-common.h"
#include "ga-conf.h"
#include "rtspconf.h"
#include "encoder-common.h"
#include "ga-mediasubsession.h"
#include "ga-audiolivesource.h"
#include "ga-videolivesource.h"

GAMediaSubsession
::GAMediaSubsession(UsageEnvironment &env, int cid, const char *mimetype, portNumBits initialPortNum, Boolean multiplexRTCPWithRTP)
		: OnDemandServerMediaSubsession(env, True/*reuseFirstSource*/, initialPortNum, multiplexRTCPWithRTP) {
	this->mimetype = strdup(mimetype);
	this->channelId = cid;
}

GAMediaSubsession * GAMediaSubsession
::createNew(UsageEnvironment &env, int cid, const char *mimetype,
		portNumBits initialPortNum,
		Boolean multiplexRTCPWithRTP) {
	return new GAMediaSubsession(env, cid, mimetype, initialPortNum, multiplexRTCPWithRTP);
}

FramedSource* GAMediaSubsession
::createNewStreamSource(unsigned clientSessionId,
			unsigned& estBitrate) {
	FramedSource *result = NULL;
	struct RTSPConf *rtspconf = rtspconf_global();
	if(strncmp("audio/", this->mimetype, 6) == 0) {
		estBitrate = rtspconf->audio_bitrate / 1000; /* Kbps */
		result = GAAudioLiveSource::createNew(envir(), this->channelId);
	} else if(strncmp("video/", this->mimetype, 6) == 0) {
		//estBitrate = 500; /* Kbps */
		estBitrate = ga_conf_mapreadint("video-specific", "b") / 1000; /* Kbps */
		OutPacketBuffer::increaseMaxSizeTo(600000);
		result = GAVideoLiveSource::createNew(envir(), this->channelId);
	}
	do if(result != NULL) {
		if(strcmp("video/H264", this->mimetype) == 0) {
#ifdef DISCRETE_FRAMER
			result = H264VideoStreamDiscreteFramer::createNew(envir(), result);
#else
			result = H264VideoStreamFramer::createNew(envir(), result);
#endif
			break;
		}
		if(strcmp("video/H265", this->mimetype) == 0) {
#ifdef DISCRETE_FRAMER
			result = H265VideoStreamDiscreteFramer::createNew(envir(), result);
#else
			result = H265VideoStreamFramer::createNew(envir(), result);
#endif
			break;
		}
	} while(0);
	return result;
}

// "estBitrate" is the stream's estimated bitrate, in kbps
RTPSink* GAMediaSubsession
::createNewRTPSink(Groupsock* rtpGroupsock,
			unsigned char rtpPayloadTypeIfDynamic,
			FramedSource* inputSource) {
	RTPSink *result = NULL;
	struct RTSPConf *rtspconf = rtspconf_global();
	const char *mimetype = this->mimetype;
	//
	if(strcmp(mimetype, "audio/MPEG") == 0) {
		result = MPEG1or2AudioRTPSink::createNew(envir(), rtpGroupsock);
	} else if(strcmp(mimetype, "audio/AAC") == 0) {
		// TODO: not implememted
		ga_error("GAMediaSubsession: %s NOT IMPLEMENTED\n", mimetype);
		exit(-1);
	} else if(strcmp(mimetype, "audio/AC3") == 0) {
		result = AC3AudioRTPSink
			::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic,
					rtspconf->audio_samplerate);
	} else if(strcmp(mimetype, "audio/OPUS") == 0) {
		result = SimpleRTPSink
			::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic,
					rtspconf->audio_samplerate,
					"audio", "OPUS", 2, False/*only 1 Opus 'packet' in each RTP packet*/);
	} else if(strcmp(mimetype, "audio/VORBIS") == 0) {
		u_int8_t* identificationHeader = NULL; unsigned identificationHeaderSize = 0;
		u_int8_t* commentHeader = NULL; unsigned commentHeaderSize = 0;
		u_int8_t* setupHeader = NULL; unsigned setupHeaderSize = 0;
		// TODO: not implememted
		ga_error("GAMediaSubsession: %s NOT IMPLEMENTED\n", mimetype);
		exit(-1);
		result = VorbisAudioRTPSink
			::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic,
					rtspconf->audio_samplerate,
					rtspconf->audio_channels,
					identificationHeader, identificationHeaderSize,
					commentHeader, commentHeaderSize,
					setupHeader, setupHeaderSize);
	} else if(strcmp(mimetype, "video/THEORA") == 0) {
		u_int8_t* identificationHeader = NULL; unsigned identificationHeaderSize = 0;
		u_int8_t* commentHeader = NULL; unsigned commentHeaderSize = 0;
		u_int8_t* setupHeader = NULL; unsigned setupHeaderSize = 0;
		// TODO: not implememted
		ga_error("GAMediaSubsession: %s NOT IMPLEMENTED\n", mimetype);
		exit(-1);
		result = TheoraVideoRTPSink
			::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic,
					identificationHeader, identificationHeaderSize,
					commentHeader, commentHeaderSize,
					setupHeader, setupHeaderSize);
	} else if(strcmp(mimetype, "video/H264") == 0) {
		ga_module_t *m = encoder_get_vencoder();
		unsigned profile_level_id = 0;
		u_int8_t* SPS = NULL; int SPSSize = 0;
		u_int8_t* PPS = NULL; int PPSSize = 0;
		//
		SPS = (u_int8_t*) m->option1((void*) this->channelId, &SPSSize);
		PPS = (u_int8_t*) m->option2((void*) this->channelId, &PPSSize);
		if (SPSSize >= 1/*'profile_level_id' offset within SPS*/ + 3/*num bytes needed*/) {
			profile_level_id = (SPS[1]<<16) | (SPS[2]<<8) | SPS[3];
		}
		ga_error("GAMediaSubsession: %s SPS=%p(%d); PPS=%p(%d); profile_level_id=%x\n",
			mimetype,
			SPS, SPSSize, PPS, PPSSize, profile_level_id);
		result = H264VideoRTPSink::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic,
				SPS, SPSSize, PPS, PPSSize/*, profile_level_id*/);
	} else if(strcmp(mimetype, "video/H265") == 0) {
		ga_module_t *m = encoder_get_vencoder();
		u_int8_t* VPS = NULL; int VPSSize = 0;
		u_int8_t* SPS = NULL; int SPSSize = 0;
		u_int8_t* PPS = NULL; int PPSSize = 0;
		// TODO: not implememted
#if 0
		ga_error("GAMediaSubsession: %s NOT IMPLEMENTED\n", mimetype);
		exit(-1);
#endif
		SPS = (u_int8_t*) m->option1((void*) this->channelId, &SPSSize);
		PPS = (u_int8_t*) m->option2((void*) this->channelId, &PPSSize);
		VPS = (u_int8_t*) m->option3((void*) this->channelId, &VPSSize);
		ga_error("GAMediaSubsession: %s SPS=%p(%d); PPS=%p(%d); VPS=%p(%d)\n",
			mimetype,
			SPS, SPSSize, PPS, PPSSize, VPS, VPSSize);
		result = H265VideoRTPSink::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic,
				VPS, VPSSize, SPS, SPSSize, PPS, PPSSize/*,
				profileSpace, profileId, tierFlag, levelId,
				interopConstraintsStr*/);
	} else if(strcmp(mimetype, "video/VP8") == 0) {
		result = VP8VideoRTPSink::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic);
	}
	if(result == NULL) {
		ga_error("GAMediaSubsession: create RTP sink for %s failed.\n", mimetype);
	}
	return result;
}

<|endoftext|>


<commit_before>// This example is a demonstration of the Lebwohl-Lasher model in an NVT ensemble
// and basic usage of the API. It has a very basic command line interface to
// illustrate a possible use case.

// Include the pertinent header files.
#include "../src/Ensembles/NVTEnsemble.h"
#include "../src/Models/LebwohlLasherModel.h"
#include "../src/Moves/SphereUnitVectorMove.h"

// Includes for parsing using stringstream.
#include <iostream>
#include <sstream>

// Function definition of our basic input parser.
// // A very basic input parser.
int parse_input(char const* args[], int& latticeSize,
                int& iterations,
                double& temperature,
                std::string& modelFile,
                std::string& SitesFile);

// The main program expects a user to input the lattice size, reduced temperature,
// number of iterations and specify an output file (csv) for model properties and
// site properties.
int main(int argc, char const* argv[])
{
	int latticeSize, iterations;
	double temperature;
	std::string modelFile, sitesFile;

	// We expect a certain number of arugments.
	if(argc != 6)
	{
		std::cerr << "Program syntax:" << argv[0] <<
		" lattice-size temperature iterations model-outputfile site-outputfile" <<
		std::endl;
		return 0;
	}

	// Exit on parsing error.
	if(parse_input(argv, latticeSize, iterations, temperature, modelFile, sitesFile) != 0)
		return -1;

	// Initialize the Lebwohl-Lasher lattice model. The constructor takes in one
	// required argument which is the lattice size - the length of one dimension.
	// The model initializes the required number of sites in the appropriate locations,
	// defines the nearest-neighbors and provides an initial spin.
	Models::LebwohlLasherModel model(latticeSize, latticeSize, latticeSize);

	// Initialize the NVT ensemble. For this particular ensemble, it requires a reference to
	// the model and the temperature. The template parametr for the ensemble is the type
	// returned by the DrawSample method of the model - in this case it is a site.
	//Ensembles::NVTEnsemble<Site> ensemble(model, temperature);

	// Initialize the moves. These are the different Monte-Carlo moves we would like
	// to perform on the model above. In this case, we want to pick a random unit
	// vector on a sphere. A "Move" class operates on a site within model in an ensemble.
	Moves::SphereUnitVectorMove move;

	//ensemble.AddMove(move);

	// Sweep for iterations
	//for (int i = 0; i < iterations; i++)
		//ensemble.Sweep();

	return 0;
}

// A very basic input parser.
int parse_input(char const* args[], int& latticeSize,
                int& iterations,
                double& temperature,
                std::string& modelFile,
                std::string& SitesFile)
{
	std::stringstream ss;

	// Parse input
	ss.clear();
	ss.str(args[1]);
	if(!(ss >> latticeSize))
	{
		std::cerr << "Invalid lattice size. Must be an integer." << std::endl;
		return -1;
	}

	ss.clear();
	ss.str(args[2]);
	if(!(ss >> temperature))
	{
		std::cerr << "Invalid temperature. Must be a double." << std::endl;
		return -1;
	}

	ss.clear();
	ss.str(args[3]);
	if(!(ss >> iterations))
	{
		std::cerr << "Invalid iterations. Must be an integer." << std::endl;
		return -1;
	}

	ss.clear();
	ss.str(args[4]);
	if(!(ss >> modelFile))
	{
		std::cerr << "Invalid output file. Must be a string." << std::endl;
		return -1;
	}

	ss.clear();
	ss.str(args[5]);
	if(!(ss >> SitesFile))
	{
		std::cerr << "Invalid output file. Must be a string." << std::endl;
		return -1;
	}

	return 0;
}
<commit_msg>Update LL NVT example<commit_after>// This example is a demonstration of the Lebwohl-Lasher model in an NVT ensemble
// and basic usage of the API. It has a very basic command line interface to
// illustrate a possible use case.

// Include the pertinent header files.
#include "../src/Ensembles/NVTEnsemble.h"
#include "../src/ForceFields/ForceFieldManager.h"
#include "../src/ForceFields/LebwohlLasherFF.h"
#include "../src/Moves/MoveManager.h"
#include "../src/Moves/SphereUnitVectorMove.h"
#include "../src/Particles/Site.h"
#include "../src/Simulation/CSVObserver.h"
#include "../src/Simulation/ConsoleObserver.h"
#include "../src/Worlds/SimpleLatticeWorld.h"

// Includes for parsing using stringstream.
#include <iostream>
#include <sstream>

using namespace SAPHRON;

// Function definition of our basic input parser.
// // A very basic input parser.
int parse_input(char const* args[], int& latticeSize,
                int& iterations,
                double& temperature,
                std::string& filePrefix);

// The main program expects a user to input the lattice size, reduced temperature,
// number of iterations and specify an output file prefix (csv) for logged properties.
int main(int argc, char const* argv[])
{
	int latticeSize, iterations;
	double temperature;
	std::string filePrefix;

	// We expect a certain number of arugments.
	if(argc != 5)
	{
		std::cerr << "Program syntax:" << argv[0] <<
		" lattice-size temperature iterations outputfile-prefix" <<
		std::endl;
		return 0;
	}

	// Exit on parsing error.
	if(parse_input(argv, latticeSize, iterations, temperature, filePrefix) != 0)
		return -1;

	// Initialize a simple cubic lattice "world". This defines the type of box for our simulation.
	// The constructor takes in the lattice dimensions and an optional seed for the pseudo random
	// number generator.
	SimpleLatticeWorld world(latticeSize, latticeSize, latticeSize, 1);

	// Initialize a site. This will represent an individual spin on the lattice in our world.
	// The constructor takes in an initial position, director and species type (string). Note that
	// the position is irrelevant since this site will be copied and configured appropriately for
	// the system.
	Site site1({ 0, 0, 0 }, { 1.0, 0, 0 }, "E1");

	// Now we configure the world but providing a reference to our spin and telling it to fill the
	// box entirely with that site. We then configure connectivity through neighbor list
	// initialization.
	world.ConfigureParticles({ &site1 }, { 1.0 });
	world.ConfigureNeighborList();

	// Initialize the Lebwohl-Lasher (LL) force field and add it to an instance of the forcefield
	// manager. The LL forcefield takes in two arguments. An anisotropic interaction energy and
	// an isotropic term as well. See header file for details.
	LebwohlLasherFF ff(1.0, 0);
	ForceFieldManager ffm;
	ffm.AddForceField("E1", "E1", ff);

	// Initialize the move we want to perform on our sites, then add it to an instance of the
	// move manager. The only argument the constructor takes is a seed for the PRNG.
	SphereUnitVectorMove move1(33);
	MoveManager mm;
	mm.PushMove(move1);

	// Initialize the "observers". These are effectively the loggers that will be monitoring the
	// simulation. We want to print out some information to the console to monitor the run,
	// but store more details in a CSV file format.
	SimFlags flags1;
	flags1.temperature = 1;
	flags1.iterations = 1;
	flags1.energy = 1;
	ConsoleObserver console(flags1, 1000);

	SimFlags flags2;
	flags2.temperature = 1;
	flags2.iterations = 1;
	flags2.energy = 1;
	CSVObserver csv(filePrefix, flags2, 500);

	// Initialize the NVT ensemble. For this particular ensemble, it requires a reference to world,
	// the forcefield manager and the move manager. It also takes in a temperature and RNG seed.
	NVTEnsemble ensemble(world, ffm, mm, temperature, 45);

	// Run the simulation.
	ensemble.Run(iterations);

	return 0;
}

// A very basic input parser.
int parse_input(char const* args[], int& latticeSize,
                int& iterations,
                double& temperature,
                std::string& filePrefix)
{
	std::stringstream ss;

	// Parse input
	ss.clear();
	ss.str(args[1]);
	if(!(ss >> latticeSize))
	{
		std::cerr << "Invalid lattice size. Must be an integer." << std::endl;
		return -1;
	}

	ss.clear();
	ss.str(args[2]);
	if(!(ss >> temperature))
	{
		std::cerr << "Invalid temperature. Must be a double." << std::endl;
		return -1;
	}

	ss.clear();
	ss.str(args[3]);
	if(!(ss >> iterations))
	{
		std::cerr << "Invalid iterations. Must be an integer." << std::endl;
		return -1;
	}

	ss.clear();
	ss.str(args[4]);
	if(!(ss >> filePrefix))
	{
		std::cerr << "Invalid output file prefix. Must be a string." << std::endl;
		return -1;
	}

	return 0;
}
<|endoftext|>


<commit_before>#include "user_space_wrappers.h"
#include "core.h"
#include "sync_client.h"
#include "core_manager.h"
#include "log.h"

CAPI_return_t SimGetCoreID(int *core_id)
{
   *core_id = g_core_manager->getCurrentCoreID();
   return 0;
}

void SimInitializeThread()
{
   g_core_manager->initializeThread();
}

void SimInitializeCommId(int comm_id)
{
   g_core_manager->initializeCommId(comm_id);
}

void SimMutexInit(carbon_mutex_t *mux)
{
   Core *core = g_core_manager->getCurrentCore();
   if (core) core->getSyncClient()->mutexInit(mux);
}

void SimMutexLock(carbon_mutex_t *mux)
{
   Core *core = g_core_manager->getCurrentCore();
   if (core) core->getSyncClient()->mutexLock(mux);
}

void SimMutexUnlock(carbon_mutex_t *mux)
{
   Core *core = g_core_manager->getCurrentCore();
   if (core) core->getSyncClient()->mutexUnlock(mux);
}

void SimCondInit(carbon_cond_t *cond)
{
   Core *core = g_core_manager->getCurrentCore();
   if (core) core->getSyncClient()->condInit(cond);
}

void SimCondWait(carbon_cond_t *cond, carbon_mutex_t *mux)
{
   Core *core = g_core_manager->getCurrentCore();
   if (core) core->getSyncClient()->condWait(cond, mux);
}

void SimCondSignal(carbon_cond_t *cond)
{
   Core *core = g_core_manager->getCurrentCore();
   if (core) core->getSyncClient()->condSignal(cond);
}

void SimCondBroadcast(carbon_cond_t *cond)
{
   Core *core = g_core_manager->getCurrentCore();
   if (core) core->getSyncClient()->condBroadcast(cond);
}

void SimBarrierInit(carbon_barrier_t *barrier, UINT32 count)
{
   Core *core = g_core_manager->getCurrentCore();
   if (core) core->getSyncClient()->barrierInit(barrier, count);
}

void SimBarrierWait(carbon_barrier_t *barrier)
{
   Core *core = g_core_manager->getCurrentCore();
   if (core) core->getSyncClient()->barrierWait(barrier);
}

CAPI_return_t SimSendW(CAPI_endpoint_t sender, CAPI_endpoint_t receiver,
                       char *buffer, int size)
{
   Core *core = g_core_manager->getCurrentCore();

   UInt32 sending_core = g_config->getCoreFromCommId(sender);
   UInt32 receiving_core = g_config->getCoreFromCommId(receiver);

   return core ? core->coreSendW(sending_core, receiving_core, buffer, size) : -1;
}

CAPI_return_t SimRecvW(CAPI_endpoint_t sender, CAPI_endpoint_t receiver,
                       char *buffer, int size)
{
   Core *core = g_core_manager->getCurrentCore();

   UInt32 sending_core = g_config->getCoreFromCommId(sender);
   UInt32 receiving_core = g_config->getCoreFromCommId(receiver);

   return core ? core->coreRecvW(sending_core, receiving_core, buffer, size) : -1;
}

<commit_msg>[user_space] Add logging to CAPI functions.<commit_after>#include "user_space_wrappers.h"
#include "core.h"
#include "sync_client.h"
#include "core_manager.h"
#include "log.h"

CAPI_return_t SimGetCoreID(int *core_id)
{
   *core_id = g_core_manager->getCurrentCoreID();
   return 0;
}

void SimInitializeThread()
{
   g_core_manager->initializeThread();
}

void SimInitializeCommId(int comm_id)
{
   g_core_manager->initializeCommId(comm_id);
}

void SimMutexInit(carbon_mutex_t *mux)
{
   Core *core = g_core_manager->getCurrentCore();
   if (core) core->getSyncClient()->mutexInit(mux);
}

void SimMutexLock(carbon_mutex_t *mux)
{
   Core *core = g_core_manager->getCurrentCore();
   if (core) core->getSyncClient()->mutexLock(mux);
}

void SimMutexUnlock(carbon_mutex_t *mux)
{
   Core *core = g_core_manager->getCurrentCore();
   if (core) core->getSyncClient()->mutexUnlock(mux);
}

void SimCondInit(carbon_cond_t *cond)
{
   Core *core = g_core_manager->getCurrentCore();
   if (core) core->getSyncClient()->condInit(cond);
}

void SimCondWait(carbon_cond_t *cond, carbon_mutex_t *mux)
{
   Core *core = g_core_manager->getCurrentCore();
   if (core) core->getSyncClient()->condWait(cond, mux);
}

void SimCondSignal(carbon_cond_t *cond)
{
   Core *core = g_core_manager->getCurrentCore();
   if (core) core->getSyncClient()->condSignal(cond);
}

void SimCondBroadcast(carbon_cond_t *cond)
{
   Core *core = g_core_manager->getCurrentCore();
   if (core) core->getSyncClient()->condBroadcast(cond);
}

void SimBarrierInit(carbon_barrier_t *barrier, UINT32 count)
{
   Core *core = g_core_manager->getCurrentCore();
   if (core) core->getSyncClient()->barrierInit(barrier, count);
}

void SimBarrierWait(carbon_barrier_t *barrier)
{
   Core *core = g_core_manager->getCurrentCore();
   if (core) core->getSyncClient()->barrierWait(barrier);
}

CAPI_return_t SimSendW(CAPI_endpoint_t sender, CAPI_endpoint_t receiver,
                       char *buffer, int size)
{
   Core *core = g_core_manager->getCurrentCore();

   LOG_PRINT_EXPLICIT(-1, USERSPACEWRAPPERS, "SimSendW - sender: %d, recv: %d", sender, receiver);

   UInt32 sending_core = g_config->getCoreFromCommId(sender);
   UInt32 receiving_core = g_config->getCoreFromCommId(receiver);

   return core ? core->coreSendW(sending_core, receiving_core, buffer, size) : -1;
}

CAPI_return_t SimRecvW(CAPI_endpoint_t sender, CAPI_endpoint_t receiver,
                       char *buffer, int size)
{
   Core *core = g_core_manager->getCurrentCore();

   LOG_PRINT_EXPLICIT(-1, USERSPACEWRAPPERS, "SimRecvW - sender: %d, recv: %d", sender, receiver);

   UInt32 sending_core = g_config->getCoreFromCommId(sender);
   UInt32 receiving_core = g_config->getCoreFromCommId(receiver);

   return core ? core->coreRecvW(sending_core, receiving_core, buffer, size) : -1;
}

<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

#include "occa.hpp"

int main(int argc, char **argv){

  /* hard code platform and device number */
  int plat = 0;
  int dev = 0;

  occa::device device;
  device.setup("OpenCL", plat, dev);

  // build jacobi kernel from source file
  const char *functionName = "";

  // build Jacobi kernel
  occa::kernel simple = device.buildKernelFromSource("simple.occa", "simple");

  // size of array
  int N = 256;

  // set thread array for Jacobi iteration
  int T = 32;
  int dims = 1;
  occa::dim inner(T);
  occa::dim outer((N+T-1)/T);
  simple.setWorkingDims(dims, inner, outer);

  // allocate array on HOST
  float *h_x = (float*) malloc(sz);
  for(int n=0;n<N;++n)
    h_x[n] = 123;

  // allocate array on DEVICE (copy from HOST)
  size_t sz = T*sizeof(float);
  occa::memory c_x = device.malloc(sz, h_x);

  // queue kernel
  simple(N, c_x);

  // copy result to HOST
  c_x.toHost(h_x);

  /* print out results */
  for(int n=0;n<N;++n)
    printf("h_x[%d] = %g\n", n, h_x[n]);

  exit(0);

}
<commit_msg>tweak<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

#include "occa.hpp"

int main(int argc, char **argv){

  /* hard code platform and device number */
  int plat = 0;
  int dev = 0;

  occa::device device;
  device.setup("OpenCL", plat, dev);

  // build jacobi kernel from source file
  const char *functionName = "";

  // build Jacobi kernel
  occa::kernel simple = device.buildKernelFromSource("simple.occa", "simple");

  // size of array
  int N = 256;

  // set thread array for Jacobi iteration
  int T = 32;
  int dims = 1;
  occa::dim inner(T);
  occa::dim outer((N+T-1)/T);
  simple.setWorkingDims(dims, inner, outer);

  size_t sz = N*sizeof(float);

  // allocate array on HOST
  float *h_x = (float*) malloc(sz);
  for(int n=0;n<N;++n)
    h_x[n] = 123;

  // allocate array on DEVICE (copy from HOST)
  occa::memory c_x = device.malloc(sz, h_x);

  // queue kernel
  simple(N, c_x);

  // copy result to HOST
  c_x.toHost(h_x);

  /* print out results */
  for(int n=0;n<N;++n)
    printf("h_x[%d] = %g\n", n, h_x[n]);

  exit(0);

}
<|endoftext|>


<commit_before>/*
	My C++ template
	Chandan Mittal
	handle: calmhandtitan
*/

#include "bits/stdc++.h"
#define sd(n) scanf("%d", &(n))
#define rep(i, x, n) for (size_t i = x, _n = (n); i < _n; ++i)
#define SZ(c) (int)(c).size()
#define lcm(a,b) (a*(b/__gcd(a,b)))
#define VI vector<int>
#define all(c) ((c).begin(), (c).end())
#define pb push_back
#define pii pair<int, int>
#define pip pair<int, pii>
#define F first
#define S second
#define mp make_pair
#define lli long long int
#define CLR(p) memset(p, 0, sizeof(p))
#define SET(p) memset(p, -1, sizeof(p))
#define INF 0x3f3f3f3f
using namespace std;

const int MOD = 1e9+7;
const int MAX = 100010;

int main()
{

    return 0;
}
<commit_msg>fixed a macro<commit_after>/*
	My C++ template
	Chandan Mittal
	handle: calmhandtitan
*/

#include "bits/stdc++.h"
#define sd(n) scanf("%d", &(n))
#define rep(i, x, n) for (size_t i = x, _n = (n); i < _n; ++i)
#define SZ(c) (int)(c).size()
#define lcm(a,b) (a*(b/__gcd(a,b)))
#define VI vector<int>
#define all(c) (c).begin(), (c).end()
#define pb push_back
#define pii pair<int, int>
#define pip pair<int, pii>
#define F first
#define S second
#define mp make_pair
#define lli long long int
#define CLR(p) memset(p, 0, sizeof(p))
#define SET(p) memset(p, -1, sizeof(p))
#define INF 0x3f3f3f3f
using namespace std;

const int MOD = 1e9+7;
const int MAX = 100010;

int main()
{

    return 0;
}
<|endoftext|>


<commit_before>#include <sstream>
#include <unistd.h>
#include <string.h>

#include "display.h"
#include "world.h"
#include "logging.h"
#include "utils.h"

using std::ostringstream;

#define PANE_WORLD_WIDTH      800
#define PANE_WORLD_HEIGHT     800
#define PANE_CTRL_WIDTH      600
#define PANE_CTRL_HEIGHT     800
#define PANE_SEPERATION 20

#define DISPLAY_WIDTH   (PANE_WORLD_WIDTH + PANE_SEPERATION + PANE_CTRL_WIDTH)
#define DISPLAY_HEIGHT  (PANE_WORLD_HEIGHT >= PANE_CTRL_HEIGHT ? PANE_WORLD_HEIGHT : PANE_CTRL_HEIGHT)

const double MAX_ZOOM = 31.99;
const double MIN_ZOOM = 0.51;
const double ZOOM_FACTOR = 1.1892071;

double zoom = 1.0 / ZOOM_FACTOR;
double center_x = world::WIDTH / 2;
double center_y = world::HEIGHT / 2;

int main_edit(string world_filename);

// -----------------  MAIN  ------------------------------------------------------------------------

int main(int argc, char **argv)
{
    bool opt_edit = false;
    string world_filename;

    // get options
    while (true) {
        char opt_char = getopt(argc, argv, "e");
        if (opt_char == -1) {
            break;
        }
        switch (opt_char) {
        case 'e':
            opt_edit = true;
            break;
        default:
            return 1;
        }
    }

    // get args
    world_filename = "world.dat";
    if ((argc - optind) >= 1) {
        world_filename = argv[optind];
    }

    // handle edit mode0
    if (opt_edit) {
        return main_edit(world_filename);
    }

    // terminate
    return 0;
}

// -----------------  EDIT  ------------------------------------------------------------------------

// XXX display ptr to current dir rate
// - display speed
// - set cursor, and direction
// - display cursor when in this mode, both in text and on display
//

int main_edit(string world_filename)
{
    enum mode { MAIN, CREATE_ROADS };

    const int MAX_MESSAGE_AGE = 200;
    //const int DELAY_MICROSECS = 1000000;  // XXX was 10000
    const int DELAY_MICROSECS = 10000;

    enum mode             mode = MAIN;
    struct display::event event = {display::EID_NONE,0,0};
    bool                  done = false;
    bool                  create_roads_active = false;
    double                create_road_x = 2000;
    double                create_road_y = 2000;
    double                create_road_dir = 0;
    int                   create_road_dir_idx = 5;
    string                message = "";
    int                   message_age = MAX_MESSAGE_AGE;
    double                avg_cycle_time = DELAY_MICROSECS;

    // create the display
    display d(DISPLAY_WIDTH, DISPLAY_HEIGHT);

    // create the world
    world w(d,world_filename);
    message = w.read_ok() ? "READ SUCCESS" : "READ FAILURE";
    message_age = 0;

    // loop
    while (!done) {
        // determine average cycle time
        {
            const int   MAX_TIMES=10;
            static long times[MAX_TIMES];
            memmove(times+1, times, (MAX_TIMES-1)*sizeof(long));
            times[0] = microsec_timer();
            if (times[MAX_TIMES-1] != 0) {
                avg_cycle_time = (times[0] - times[MAX_TIMES-1]) / (MAX_TIMES-1);
            }

            // XXX temp
            static int count;
            if ((++count % 100) == 0) {
                INFO("AVG CYCLE TIME " << avg_cycle_time / 1000. << endl);
            }
        }

        // start
        d.start(0, 0, PANE_WORLD_WIDTH, PANE_WORLD_HEIGHT,                                // pane 0: x,y,w,h
                PANE_WORLD_WIDTH+PANE_SEPERATION, 0, PANE_CTRL_WIDTH, PANE_CTRL_HEIGHT);  // pane 1: x,y,w,h

        // draw the world
        w.draw(0,center_x,center_y,zoom);

        // additional drawing: CREATE_ROADS mode
        if (mode == CREATE_ROADS) {
            ostringstream s;

            // xxx comments
            if (create_roads_active) {
                // xxx dont go off end of world
                w.create_road_slice(create_road_x, create_road_y, create_road_dir);  //xxx return distance

                create_road_dir += (create_road_dir_idx - 5) * 0.05;
                if (create_road_dir < 0) {
                    create_road_dir += 360;
                } else if (create_road_dir > 360) {
                    create_road_dir -= 360;
                }
            }

            d.text_draw("^", 1, 2*(create_road_dir_idx-1), 1);

            s.str("");
            if (create_roads_active) {
                int mph = 0.5 / avg_cycle_time * (3600000000.0 / 5280.0);
                s << "RUNNING - SPEED " << mph;
            } else {
                s << "STOPPED";
            }
            d.text_draw(s.str(), 5, 0, 1);

            s.str("");
            s << "X,Y,DIR: " << static_cast<int>(create_road_x) << " "
                             << static_cast<int>(create_road_y) << " "
                             << static_cast<int>(create_road_dir);
            d.text_draw(s.str(), 6, 0, 1);
        }

        // additional drawing: message box
        if (message_age < MAX_MESSAGE_AGE) {
            d.text_draw(message, 17, 0, 1);
            message_age++;
        }

        // register for events
        int eid_clear=-1, eid_write=-1, eid_reset=-1, eid_quit=-1, eid_quit_win=-1, eid_pan=-1, eid_zoom=-1;
        int eid_create_roads=-1;
        int eid_1=-1, eid_9=-1, eid_run=-1, eid_stop=-1, eid_done=-1;
        __attribute__((unused)) int eid_2=-1, eid_3=-1, eid_4=-1, eid_5=-1, eid_6=-1, eid_7=-1, eid_8=-1;

        eid_write        = d.text_draw("WRITE",        13,  0, 1, true);
        eid_quit         = d.text_draw("QUIT",         13, 10, 1, true);
        eid_reset        = d.text_draw("RESET",        15,  0, 1, true);
        eid_clear        = d.text_draw("CLEAR",        15, 10, 1, true);
        eid_quit_win     = d.event_register(display::ET_QUIT);
        eid_pan          = d.event_register(display::ET_MOUSE_MOTION, 0);
        eid_zoom         = d.event_register(display::ET_MOUSE_WHEEL, 0);
        switch (mode) {
        case MAIN:
            eid_create_roads = d.text_draw("CREATE_ROADS",  0, 0, 1, true);  // r,c,pid,event
            break;
        case CREATE_ROADS:
            eid_1     = d.text_draw("1",             0, 0, 1, true, '1');
            eid_2     = d.text_draw("2",             0, 2, 1, true, '2');
            eid_3     = d.text_draw("3",             0, 4, 1, true, '3');
            eid_4     = d.text_draw("4",             0, 6, 1, true, '4');
            eid_5     = d.text_draw("5",             0, 8, 1, true, '5');
            eid_6     = d.text_draw("6",             0,10, 1, true, '6');
            eid_7     = d.text_draw("7",             0,12, 1, true, '7');
            eid_8     = d.text_draw("8",             0,14, 1, true, '8');
            eid_9     = d.text_draw("9",             0,16, 1, true, '9');
            eid_run   = d.text_draw("RUN",           3, 0, 1, true, 'g');
            eid_stop  = d.text_draw("STOP",          3, 7, 1, true, 's');
            eid_done  = d.text_draw("DONE",          3,14, 1, true, 'd');
            break;
        }

        // finish/
        d.finish();

        // event handling
        event = d.event_poll();
        do {
            // common events
            if (event.eid == display::EID_NONE) {
                break;
            }
            if (event.eid == eid_quit_win || event.eid == eid_quit) {
                done = true;
                break;
            }
            if (event.eid == eid_clear) {
                w.clear();
                break;
            }
            if (event.eid == eid_write) {
                w.write();
                message = w.write_ok() ? "WRITE SUCCESS" : "WRITE FAILURE";
                message_age = 0;
                break;
            }
            if (event.eid == eid_reset) {
                w.read();
                message = w.read_ok() ? "READ SUCCESS" : "READ FAILURE";
                message_age = 0;
                break;
            }
            if (event.eid == eid_pan) {
                center_x -= (double)event.val1 * 8 / zoom;
                center_y -= (double)event.val2 * 8 / zoom;
                break;
            }
            if (event.eid == eid_zoom) {
                if (event.val2 < 0 && zoom > MIN_ZOOM) {
                    zoom /= ZOOM_FACTOR;
                }
                if (event.val2 > 0 && zoom < MAX_ZOOM) {
                    zoom *= ZOOM_FACTOR;
                }
                break;
            }

            // MAIN mode events
            if (mode == MAIN) {
                if (event.eid == eid_create_roads) {
                    mode = CREATE_ROADS;
                    break;
                }
            }

            // CREATE_ROADS mode events
            if (mode == CREATE_ROADS) {
                if (event.eid == eid_run) {
                    create_roads_active = true;
                    break;
                }
                if (event.eid == eid_stop) {
                    create_roads_active = false;
                    break;
                }
                if (event.eid == eid_done) {
                    create_roads_active = false;
                    mode = MAIN;
                    break;
                }
                if (event.eid >= eid_1 && event.eid <= eid_9) {
                    create_road_dir_idx = event.eid - eid_1 + 1;
                }
            }
        } while (0);

        // delay
        microsec_sleep(DELAY_MICROSECS);
    }

    return 0;
}
<commit_msg>comments<commit_after>// XXX add edit pixels
//   - on clear, reset cursor
//   - add ability to move cursor

// XXX EDIT display ptr to current dir rate
// - set cursor, and direction
// - display cursor when in this mode, both in text and on display

#include <sstream>
#include <unistd.h>
#include <string.h>

#include "display.h"
#include "world.h"
#include "logging.h"
#include "utils.h"

using std::ostringstream;

#define PANE_WORLD_WIDTH     800
#define PANE_WORLD_HEIGHT    800
#define PANE_CTRL_WIDTH      600
#define PANE_CTRL_HEIGHT     800
#define PANE_SEPERATION      20

#define DISPLAY_WIDTH   (PANE_WORLD_WIDTH + PANE_SEPERATION + PANE_CTRL_WIDTH)
#define DISPLAY_HEIGHT  (PANE_WORLD_HEIGHT >= PANE_CTRL_HEIGHT ? PANE_WORLD_HEIGHT : PANE_CTRL_HEIGHT)

const double ZOOM_FACTOR = 1.1892071;
const double MAX_ZOOM    = 64.0 - .01;
const double MIN_ZOOM    = (1.0 / ZOOM_FACTOR) + .01;

double zoom = 1.0 / ZOOM_FACTOR;
double center_x = world::WORLD_WIDTH / 2;
double center_y = world::WORLD_HEIGHT / 2;

int main_edit(string world_filename);

// -----------------  MAIN  ------------------------------------------------------------------------

int main(int argc, char **argv)
{
    bool opt_edit = false;
    string world_filename;

    // get options
    while (true) {
        char opt_char = getopt(argc, argv, "e");
        if (opt_char == -1) {
            break;
        }
        switch (opt_char) {
        case 'e':
            opt_edit = true;
            break;
        default:
            return 1;
        }
    }

    // get args
    world_filename = "world.dat";
    if ((argc - optind) >= 1) {
        world_filename = argv[optind];
    }

    // handle edit mode0
    if (opt_edit) {
        return main_edit(world_filename);
    }

    // terminate
    return 0;
}

// -----------------  EDIT  ------------------------------------------------------------------------

int main_edit(string world_filename)
{
    enum mode { MAIN, CREATE_ROADS };

    const int MAX_MESSAGE_AGE = 200;
    const int DELAY_MICROSECS = 10000;

    enum mode             mode = MAIN;
    struct display::event event = {display::EID_NONE,0,0};
    bool                  done = false;
    bool                  create_roads_run = false;
    double                create_road_x = 2048;
    double                create_road_y = 2048;
    double                create_road_dir = 0;
    int                   create_road_dir_idx = 5;
    string                message = "";
    int                   message_age = MAX_MESSAGE_AGE;
    double                avg_cycle_time = DELAY_MICROSECS;

    // create the display
    display d(DISPLAY_WIDTH, DISPLAY_HEIGHT);

    // create the world
    world w(d,world_filename);
    message = w.read_ok() ? "READ SUCCESS" : "READ FAILURE";
    message_age = 0;

    // loop
    while (!done) {
        // determine average cycle time
        // xxx make this a routine
        {
            const int   MAX_TIMES=10;
            static long times[MAX_TIMES];
            memmove(times+1, times, (MAX_TIMES-1)*sizeof(long));
            times[0] = microsec_timer();
            if (times[MAX_TIMES-1] != 0) {
                avg_cycle_time = (times[0] - times[MAX_TIMES-1]) / (MAX_TIMES-1);
            }

            // xxx temp
            static int count;
            if ((++count % 100) == 0) {
                INFO("AVG CYCLE TIME " << avg_cycle_time / 1000. << endl);
            }
        }

        // start display update
        d.start(0, 0, PANE_WORLD_WIDTH, PANE_WORLD_HEIGHT,                                // pane 0: x,y,w,h
                PANE_WORLD_WIDTH+PANE_SEPERATION, 0, PANE_CTRL_WIDTH, PANE_CTRL_HEIGHT);  // pane 1: x,y,w,h

        // draw world
        w.place_car_init();
        w.place_car(create_road_x, create_road_y, create_road_dir);
        w.draw(0,center_x,center_y,zoom);

        // draw for mode CREATE_ROADS
        if (mode == CREATE_ROADS) {
            ostringstream s;

            // xxx comments
            if (create_roads_run) {
                // xxx dont go off end of world
                // xxx return distance
                w.create_road_slice(create_road_x, create_road_y, create_road_dir);

                create_road_dir += (create_road_dir_idx - 5) * 0.05;
                if (create_road_dir < 0) {
                    create_road_dir += 360;
                } else if (create_road_dir > 360) {
                    create_road_dir -= 360;
                }
            }

            d.text_draw("^", 1, 2*(create_road_dir_idx-1), 1);

            s.str("");
            if (create_roads_run) {
                int mph = 0.5 / avg_cycle_time * (3600000000.0 / 5280.0);
                s << "RUNNING - SPEED " << mph;
            } else {
                s << "STOPPED";
            }
            d.text_draw(s.str(), 5, 0, 1);

            s.str("");
            s << "X,Y,DIR: " << static_cast<int>(create_road_x) << " "
                             << static_cast<int>(create_road_y) << " "
                             << static_cast<int>(create_road_dir);
            d.text_draw(s.str(), 6, 0, 1);
        }

        // draw the message box
        if (message_age < MAX_MESSAGE_AGE) {
            d.text_draw(message, 17, 0, 1);
            message_age++;
        }

        // draw and register events
        int eid_clear=-1, eid_write=-1, eid_reset=-1, eid_quit=-1, eid_quit_win=-1, eid_pan=-1, eid_zoom=-1;
        int eid_create_roads=-1;
        int eid_1=-1, eid_9=-1, eid_run=-1, eid_stop=-1, eid_done=-1;
        __attribute__((unused)) int eid_2=-1, eid_3=-1, eid_4=-1, eid_5=-1, eid_6=-1, eid_7=-1, eid_8=-1;

        eid_write    = d.text_draw("WRITE",        13,  0, 1, true);
        eid_quit     = d.text_draw("QUIT",         13, 10, 1, true);
        eid_reset    = d.text_draw("RESET",        15,  0, 1, true);
        eid_clear    = d.text_draw("CLEAR",        15, 10, 1, true);
        eid_quit_win = d.event_register(display::ET_QUIT);
        eid_pan      = d.event_register(display::ET_MOUSE_MOTION, 0);
        eid_zoom     = d.event_register(display::ET_MOUSE_WHEEL, 0);
        switch (mode) {
        case MAIN:
            eid_create_roads = d.text_draw("CREATE_ROADS",  0, 0, 1, true);  // r,c,pid,event
            break;
        case CREATE_ROADS:
            eid_1     = d.text_draw("1",             0, 0, 1, true, '1');
            eid_2     = d.text_draw("2",             0, 2, 1, true, '2');
            eid_3     = d.text_draw("3",             0, 4, 1, true, '3');
            eid_4     = d.text_draw("4",             0, 6, 1, true, '4');
            eid_5     = d.text_draw("5",             0, 8, 1, true, '5');
            eid_6     = d.text_draw("6",             0,10, 1, true, '6');
            eid_7     = d.text_draw("7",             0,12, 1, true, '7');
            eid_8     = d.text_draw("8",             0,14, 1, true, '8');
            eid_9     = d.text_draw("9",             0,16, 1, true, '9');
            eid_run   = d.text_draw("RUN",           3, 0, 1, true, 'g');
            eid_stop  = d.text_draw("STOP",          3, 7, 1, true, 's');
            eid_done  = d.text_draw("DONE",          3,14, 1, true, 'd');
            break;
        }

        // finish, updates the display
        d.finish();

        // event handling
        event = d.event_poll();
        do {
            // common events
            if (event.eid == display::EID_NONE) {
                break;
            }
            if (event.eid == eid_quit_win || event.eid == eid_quit) {
                done = true;
                break;
            }
            if (event.eid == eid_clear) {
                w.clear();
                break;
            }
            if (event.eid == eid_write) {
                w.write();
                message = w.write_ok() ? "WRITE SUCCESS" : "WRITE FAILURE";
                message_age = 0;
                break;
            }
            if (event.eid == eid_reset) {
                w.read();
                message = w.read_ok() ? "READ SUCCESS" : "READ FAILURE";
                message_age = 0;
                break;
            }
            if (event.eid == eid_pan) {
                center_x -= (double)event.val1 * 8 / zoom;
                center_y -= (double)event.val2 * 8 / zoom;
                break;
            }
            if (event.eid == eid_zoom) {
                if (event.val2 < 0 && zoom > MIN_ZOOM) {
                    zoom /= ZOOM_FACTOR;
                }
                if (event.val2 > 0 && zoom < MAX_ZOOM) {
                    zoom *= ZOOM_FACTOR;
                }
                break;
            }

            // MAIN mode events
            if (mode == MAIN) {
                if (event.eid == eid_create_roads) {
                    mode = CREATE_ROADS;
                    break;
                }
            }

            // CREATE_ROADS mode events
            if (mode == CREATE_ROADS) {
                if (event.eid == eid_run) {
                    create_roads_run = true;
                    break;
                }
                if (event.eid == eid_stop) {
                    create_roads_run = false;
                    break;
                }
                if (event.eid == eid_done) {
                    create_roads_run = false;
                    mode = MAIN;
                    break;
                }
                if (event.eid >= eid_1 && event.eid <= eid_9) {
                    create_road_dir_idx = event.eid - eid_1 + 1;
                }
            }
        } while (0);

        // delay
        microsec_sleep(DELAY_MICROSECS);
    }

    return 0;
}
<|endoftext|>


<commit_before>/*
 *   CrissCross
 *   A multi-purpose cross-platform library.
 *
 *   A product of Uplink Laboratories.
 *
 *   (c) 2006-2009 Steven Noonan.
 *   Licensed under the New BSD License.
 *
 */

#include <crisscross/universal_include.h>
#include <crisscross/debug.h>
#include <crisscross/mutex.h>

#ifndef TARGET_OS_NDSFIRMWARE

namespace CrissCross
{
	namespace System
	{
		Mutex::Mutex(MutexType _type)
			: m_type(_type)
		{
			m_lockCount = 0;
#ifdef TARGET_OS_WINDOWS
			InitializeCriticalSection(&m_mutex);
#else
			int error;
			error = pthread_mutexattr_init(&m_mutexAttr);
			CoreAssert(error == 0);
			int ptype = 0;
			switch (m_type)
			{
			case MUTEX_TYPE_NORMAL:
				ptype = PTHREAD_MUTEX_NORMAL;
				break;
			case MUTEX_TYPE_ERRORCHECK:
				ptype = PTHREAD_MUTEX_ERRORCHECK;
				break;
			case MUTEX_TYPE_RECURSIVE:
			default:
				ptype = PTHREAD_MUTEX_RECURSIVE;
				break;
			}
			error = pthread_mutexattr_settype(&m_mutexAttr, ptype);
			CoreAssert(error == 0);
			error = pthread_mutex_init(&m_mutex, &m_mutexAttr);
			CoreAssert(error == 0);
#endif
		}

		Mutex::~Mutex()
		{
			CoreAssert(m_lockCount == 0);
#ifdef TARGET_OS_WINDOWS
			DeleteCriticalSection(&m_mutex);
#else
			pthread_mutex_destroy(&m_mutex);
			pthread_mutexattr_destroy(&m_mutexAttr);
#endif
		}

		void Mutex::Lock()
		{
#ifdef TARGET_OS_WINDOWS
			EnterCriticalSection(&m_mutex);
#else
			int error = pthread_mutex_lock(&m_mutex);
			CoreAssert(error == 0);
#endif
			m_lockCount++;
		}

		void Mutex::Unlock()
		{
#ifdef TARGET_OS_WINDOWS
			LeaveCriticalSection(&m_mutex);
#else
			int error = pthread_mutex_unlock(&m_mutex);
			CoreAssert(error == 0);
#endif
			m_lockCount--;
		}

		MutexHolder::MutexHolder(Mutex *_mutex)
			: m_mutex(_mutex)
		{
			m_mutex->Lock();
		}

		MutexHolder::~MutexHolder()
		{
			m_mutex->Unlock();
		}

		ReadWriteLock::ReadWriteLock(bool _writePriority)
		{
#ifdef TARGET_OS_WINDOWS
			wrpriority = _writePriority;

			rdcount = rdwaiting = wrcount = wrwaiting = 0;

			InitializeCriticalSection(&rwcs);

			rdgreen = CreateEvent(NULL, FALSE, TRUE, NULL);
			wrgreen = CreateEvent(NULL, FALSE, TRUE, NULL);
#else
			int ret;
			ret = pthread_rwlockattr_init(&m_rwlockAttr);
			CoreAssert(ret == 0);
			ret = pthread_rwlockattr_setpshared(&m_rwlockAttr, PTHREAD_PROCESS_SHARED);
			CoreAssert(ret == 0);
			ret = pthread_rwlock_init(&m_rwlock, &m_rwlockAttr);
			CoreAssert(ret == 0);
#endif
		}

		ReadWriteLock::~ReadWriteLock()
		{
#ifdef TARGET_OS_WINDOWS
			CloseHandle(rdgreen);
			CloseHandle(wrgreen);
			DeleteCriticalSection(&rwcs);
#else
			pthread_rwlock_destroy(&m_rwlock);
			pthread_rwlockattr_destroy(&m_rwlockAttr);
#endif
		}

		bool ReadWriteLock::LockRead()
		{
#ifdef TARGET_OS_WINDOWS
			bool wait = false;
			DWORD timeout = INFINITE;

			do {
				EnterCriticalSection(&rwcs);

				//
				// acquire lock if
				//   - there are no active writers and
				//     - readers have priority or
				//     - writers have priority and there are no waiting writers
				//
				if(!wrcount && (!wrpriority || !wrwaiting)) {
					if(wait) {
						rdwaiting--;
						wait = false;
					}
					rdcount++;
				}
				else {
					if(!wait) {
						rdwaiting++;
						wait = true;
					}
					// always reset the event to avoid 100% CPU usage
					ResetEvent(rdgreen);
				}

				LeaveCriticalSection(&rwcs);

				if (wait) {
					if (WaitForSingleObject(rdgreen, timeout) != WAIT_OBJECT_0) {
						EnterCriticalSection(&rwcs);
						rdwaiting--;
						SetEvent(rdgreen); SetEvent(wrgreen);
						LeaveCriticalSection(&rwcs);
						return false;
					}
				}

			} while (wait);

			return true;
#else
			int ret = pthread_rwlock_rdlock(&m_rwlock);
			return (ret == 0);
#endif
		}

		bool ReadWriteLock::LockWrite()
		{
#ifdef TARGET_OS_WINDOWS
			bool wait = false;
			DWORD timeout = INFINITE;

			do {
				EnterCriticalSection(&rwcs);

				//
				// acquire lock if
				//   - there are no active readers nor writers and
				//     - writers have priority or
				//     - readers have priority and there are no waiting readers
				//
				if (!rdcount && !wrcount && (wrpriority || !rdwaiting)) {
					if(wait) {
						wrwaiting--;
						wait = false;
					}
					wrcount++;
				}
				else {
					if(!wait) {
						wrwaiting++;
						wait = true;
					}
					// always reset the event to avoid 100% CPU usage
					ResetEvent(wrgreen);
				}

				LeaveCriticalSection(&rwcs);

				if (wait) {
					if (WaitForSingleObject(wrgreen, timeout) != WAIT_OBJECT_0) {
						EnterCriticalSection(&rwcs);
						wrwaiting--;
						SetEvent(rdgreen); SetEvent(wrgreen);
						LeaveCriticalSection(&rwcs);
						return false;
					}
				}

			} while (wait);

			return true;
#else
			int ret = pthread_rwlock_wrlock(&m_rwlock);
			return (ret == 0);
#endif
		}

#ifdef TARGET_OS_WINDOWS
		void ReadWriteLock::UnlockRead()
		{
			EnterCriticalSection(&rwcs);

			rdcount--;

			// always release waiting threads (do not check for rdcount == 0)
			if (wrpriority) {
				if (wrwaiting)
					SetEvent(wrgreen);
				else if (rdwaiting)
					SetEvent(rdgreen);
			}
			else {
				if (rdwaiting)
					SetEvent(rdgreen);
				else if (wrwaiting)
					SetEvent(wrgreen);
			}

			LeaveCriticalSection(&rwcs);
		}

		void ReadWriteLock::UnlockWrite()
		{
			EnterCriticalSection(&rwcs);

			wrcount--;

			if (wrpriority) {
				if (wrwaiting)
					SetEvent(wrgreen);
				else if (rdwaiting)
					SetEvent(rdgreen);
			}
			else {
				if (rdwaiting)
					SetEvent(rdgreen);
				else if (wrwaiting)
					SetEvent(wrgreen);
			}

			LeaveCriticalSection(&rwcs);
		}
#else
		void ReadWriteLock::Unlock()
		{
			pthread_rwlock_unlock(&m_rwlock);
		}
#endif

		RWLockHolder::RWLockHolder(ReadWriteLock *_lock, RWLockHolderType _type)
			: m_lock(_lock), m_type(_type)
		{
			CoreAssert(_lock);
			switch(_type)
			{
			case LOCK_READ:
				m_lock->LockRead();
				break;
			case LOCK_WRITE:
				m_lock->LockWrite();
				break;
			default:
				CoreAssert(_type != LOCK_READ && _type != LOCK_WRITE);
			}
		}

		RWLockHolder::~RWLockHolder()
		{
#ifdef TARGET_OS_WINDOWS
			switch(m_type)
			{
			case LOCK_READ:
				m_lock->UnlockRead();
				break;
			case LOCK_WRITE:
				m_lock->UnlockWrite();
				break;
			default:
				CoreAssert(m_type != LOCK_READ && m_type != LOCK_WRITE);
			}
#else
			m_lock->Unlock();
#endif
		}
	}
}

#endif
<commit_msg>mutex.cpp: fix mixed line endings<commit_after>/*
 *   CrissCross
 *   A multi-purpose cross-platform library.
 *
 *   A product of Uplink Laboratories.
 *
 *   (c) 2006-2009 Steven Noonan.
 *   Licensed under the New BSD License.
 *
 */

#include <crisscross/universal_include.h>
#include <crisscross/debug.h>
#include <crisscross/mutex.h>

#ifndef TARGET_OS_NDSFIRMWARE

namespace CrissCross
{
	namespace System
	{
		Mutex::Mutex(MutexType _type)
			: m_type(_type)
		{
			m_lockCount = 0;
#ifdef TARGET_OS_WINDOWS
			InitializeCriticalSection(&m_mutex);
#else
			int error;
			error = pthread_mutexattr_init(&m_mutexAttr);
			CoreAssert(error == 0);
			int ptype = 0;
			switch (m_type)
			{
			case MUTEX_TYPE_NORMAL:
				ptype = PTHREAD_MUTEX_NORMAL;
				break;
			case MUTEX_TYPE_ERRORCHECK:
				ptype = PTHREAD_MUTEX_ERRORCHECK;
				break;
			case MUTEX_TYPE_RECURSIVE:
			default:
				ptype = PTHREAD_MUTEX_RECURSIVE;
				break;
			}
			error = pthread_mutexattr_settype(&m_mutexAttr, ptype);
			CoreAssert(error == 0);
			error = pthread_mutex_init(&m_mutex, &m_mutexAttr);
			CoreAssert(error == 0);
#endif
		}

		Mutex::~Mutex()
		{
			CoreAssert(m_lockCount == 0);
#ifdef TARGET_OS_WINDOWS
			DeleteCriticalSection(&m_mutex);
#else
			pthread_mutex_destroy(&m_mutex);
			pthread_mutexattr_destroy(&m_mutexAttr);
#endif
		}

		void Mutex::Lock()
		{
#ifdef TARGET_OS_WINDOWS
			EnterCriticalSection(&m_mutex);
#else
			int error = pthread_mutex_lock(&m_mutex);
			CoreAssert(error == 0);
#endif
			m_lockCount++;
		}

		void Mutex::Unlock()
		{
#ifdef TARGET_OS_WINDOWS
			LeaveCriticalSection(&m_mutex);
#else
			int error = pthread_mutex_unlock(&m_mutex);
			CoreAssert(error == 0);
#endif
			m_lockCount--;
		}

		MutexHolder::MutexHolder(Mutex *_mutex)
			: m_mutex(_mutex)
		{
			m_mutex->Lock();
		}

		MutexHolder::~MutexHolder()
		{
			m_mutex->Unlock();
		}

		ReadWriteLock::ReadWriteLock(bool _writePriority)
		{
#ifdef TARGET_OS_WINDOWS
			wrpriority = _writePriority;

			rdcount = rdwaiting = wrcount = wrwaiting = 0;

			InitializeCriticalSection(&rwcs);

			rdgreen = CreateEvent(NULL, FALSE, TRUE, NULL);
			wrgreen = CreateEvent(NULL, FALSE, TRUE, NULL);
#else
			int ret;
			ret = pthread_rwlockattr_init(&m_rwlockAttr);
			CoreAssert(ret == 0);
			ret = pthread_rwlockattr_setpshared(&m_rwlockAttr, PTHREAD_PROCESS_SHARED);
			CoreAssert(ret == 0);
			ret = pthread_rwlock_init(&m_rwlock, &m_rwlockAttr);
			CoreAssert(ret == 0);
#endif
		}

		ReadWriteLock::~ReadWriteLock()
		{
#ifdef TARGET_OS_WINDOWS
			CloseHandle(rdgreen);
			CloseHandle(wrgreen);
			DeleteCriticalSection(&rwcs);
#else
			pthread_rwlock_destroy(&m_rwlock);
			pthread_rwlockattr_destroy(&m_rwlockAttr);
#endif
		}

		bool ReadWriteLock::LockRead()
		{
#ifdef TARGET_OS_WINDOWS
			bool wait = false;
			DWORD timeout = INFINITE;

			do {
				EnterCriticalSection(&rwcs);

				//
				// acquire lock if
				//   - there are no active writers and
				//     - readers have priority or
				//     - writers have priority and there are no waiting writers
				//
				if(!wrcount && (!wrpriority || !wrwaiting)) {
					if(wait) {
						rdwaiting--;
						wait = false;
					}
					rdcount++;
				}
				else {
					if(!wait) {
						rdwaiting++;
						wait = true;
					}
					// always reset the event to avoid 100% CPU usage
					ResetEvent(rdgreen);
				}

				LeaveCriticalSection(&rwcs);

				if (wait) {
					if (WaitForSingleObject(rdgreen, timeout) != WAIT_OBJECT_0) {
						EnterCriticalSection(&rwcs);
						rdwaiting--;
						SetEvent(rdgreen); SetEvent(wrgreen);
						LeaveCriticalSection(&rwcs);
						return false;
					}
				}

			} while (wait);

			return true;
#else
			int ret = pthread_rwlock_rdlock(&m_rwlock);
			return (ret == 0);
#endif
		}

		bool ReadWriteLock::LockWrite()
		{
#ifdef TARGET_OS_WINDOWS
			bool wait = false;
			DWORD timeout = INFINITE;

			do {
				EnterCriticalSection(&rwcs);

				//
				// acquire lock if
				//   - there are no active readers nor writers and
				//     - writers have priority or
				//     - readers have priority and there are no waiting readers
				//
				if (!rdcount && !wrcount && (wrpriority || !rdwaiting)) {
					if(wait) {
						wrwaiting--;
						wait = false;
					}
					wrcount++;
				}
				else {
					if(!wait) {
						wrwaiting++;
						wait = true;
					}
					// always reset the event to avoid 100% CPU usage
					ResetEvent(wrgreen);
				}

				LeaveCriticalSection(&rwcs);

				if (wait) {
					if (WaitForSingleObject(wrgreen, timeout) != WAIT_OBJECT_0) {
						EnterCriticalSection(&rwcs);
						wrwaiting--;
						SetEvent(rdgreen); SetEvent(wrgreen);
						LeaveCriticalSection(&rwcs);
						return false;
					}
				}

			} while (wait);

			return true;
#else
			int ret = pthread_rwlock_wrlock(&m_rwlock);
			return (ret == 0);
#endif
		}

#ifdef TARGET_OS_WINDOWS
		void ReadWriteLock::UnlockRead()
		{
			EnterCriticalSection(&rwcs);

			rdcount--;

			// always release waiting threads (do not check for rdcount == 0)
			if (wrpriority) {
				if (wrwaiting)
					SetEvent(wrgreen);
				else if (rdwaiting)
					SetEvent(rdgreen);
			}
			else {
				if (rdwaiting)
					SetEvent(rdgreen);
				else if (wrwaiting)
					SetEvent(wrgreen);
			}

			LeaveCriticalSection(&rwcs);
		}

		void ReadWriteLock::UnlockWrite()
		{
			EnterCriticalSection(&rwcs);

			wrcount--;

			if (wrpriority) {
				if (wrwaiting)
					SetEvent(wrgreen);
				else if (rdwaiting)
					SetEvent(rdgreen);
			}
			else {
				if (rdwaiting)
					SetEvent(rdgreen);
				else if (wrwaiting)
					SetEvent(wrgreen);
			}

			LeaveCriticalSection(&rwcs);
		}
#else
		void ReadWriteLock::Unlock()
		{
			pthread_rwlock_unlock(&m_rwlock);
		}
#endif

		RWLockHolder::RWLockHolder(ReadWriteLock *_lock, RWLockHolderType _type)
			: m_lock(_lock), m_type(_type)
		{
			CoreAssert(_lock);
			switch(_type)
			{
			case LOCK_READ:
				m_lock->LockRead();
				break;
			case LOCK_WRITE:
				m_lock->LockWrite();
				break;
			default:
				CoreAssert(_type != LOCK_READ && _type != LOCK_WRITE);
			}
		}

		RWLockHolder::~RWLockHolder()
		{
#ifdef TARGET_OS_WINDOWS
			switch(m_type)
			{
			case LOCK_READ:
				m_lock->UnlockRead();
				break;
			case LOCK_WRITE:
				m_lock->UnlockWrite();
				break;
			default:
				CoreAssert(m_type != LOCK_READ && m_type != LOCK_WRITE);
			}
#else
			m_lock->Unlock();
#endif
		}
	}
}

#endif
<|endoftext|>


<commit_before>// Copyright © 2013, Université catholique de Louvain
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// *  Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
// *  Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#ifndef MOZART_WINDOWS
#  error "This program is Windows-specific, it must not be compiled on other platforms."
#endif

#include <iostream>
#include <windows.h>

inline
size_t nposToMinus1(size_t pos) {
  return pos == std::string::npos ? -1 : pos;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpszCmdLine, int nCmdShow) {
  // Compute ozengine.exe path from my own path
  char buffer[2048];
  GetModuleFileName(nullptr, buffer, sizeof(buffer));

  std::string myPath(buffer);
  size_t backslashPos = nposToMinus1(myPath.rfind('\\'));
  std::string ozenginePath =
    myPath.substr(0, backslashPos+1) + "ozengine.exe";

  // Construct the command line
  std::string cmdline = std::string("\"") + ozenginePath +
    "\" x-oz://system/Compile.ozf " + lpszCmdLine;

  // Execute ozengine
  STARTUPINFOA si;
  memset(&si, 0, sizeof(si));
  si.cb = sizeof(si);
  si.dwFlags = STARTF_USESTDHANDLES;

  SetHandleInformation(GetStdHandle(STD_INPUT_HANDLE),
                       HANDLE_FLAG_INHERIT,HANDLE_FLAG_INHERIT);
  SetHandleInformation(GetStdHandle(STD_OUTPUT_HANDLE),
                       HANDLE_FLAG_INHERIT,HANDLE_FLAG_INHERIT);
  SetHandleInformation(GetStdHandle(STD_ERROR_HANDLE),
                       HANDLE_FLAG_INHERIT,HANDLE_FLAG_INHERIT);
  si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
  si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  si.hStdError = GetStdHandle(STD_ERROR_HANDLE);

  PROCESS_INFORMATION pinf;
  if (!CreateProcessA(const_cast<char*>(ozenginePath.c_str()),
                      const_cast<char*>(cmdline.c_str()),
                      nullptr, nullptr, false, 0,
                      nullptr, nullptr, &si, &pinf)) {
    std::cerr << "panic: cannot start ozengine" << std::endl;
    return 254;
  }

  // Wait for completion
  WaitForSingleObject(pinf.hProcess, INFINITE);

  // Get the exit code
  DWORD exitCode;
  if (!GetExitCodeProcess(pinf.hProcess, &exitCode))
    exitCode = 255;

  // Close the handles
  CloseHandle(pinf.hProcess);
  CloseHandle(pinf.hThread);

  return exitCode;
}
<commit_msg>Fix non-displaying ozc messages in Windows<commit_after>// Copyright © 2013, Université catholique de Louvain
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// *  Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
// *  Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#ifndef MOZART_WINDOWS
#  error "This program is Windows-specific, it must not be compiled on other platforms."
#endif

#include <iostream>
#include <windows.h>

inline
size_t nposToMinus1(size_t pos) {
  return pos == std::string::npos ? -1 : pos;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpszCmdLine, int nCmdShow) {
  // Compute ozengine.exe path from my own path
  char buffer[2048];
  GetModuleFileName(nullptr, buffer, sizeof(buffer));

  std::string myPath(buffer);
  size_t backslashPos = nposToMinus1(myPath.rfind('\\'));
  std::string ozenginePath =
    myPath.substr(0, backslashPos+1) + "ozengine.exe";

  // Construct the command line
  std::string cmdline = std::string("\"") + ozenginePath +
    "\" x-oz://system/Compile.ozf " + lpszCmdLine;

  // Execute ozengine
  STARTUPINFOA si;
  memset(&si, 0, sizeof(si));
  si.cb = sizeof(si);
  si.dwFlags = STARTF_USESTDHANDLES;

  SetHandleInformation(GetStdHandle(STD_INPUT_HANDLE),
                       HANDLE_FLAG_INHERIT,HANDLE_FLAG_INHERIT);
  SetHandleInformation(GetStdHandle(STD_OUTPUT_HANDLE),
                       HANDLE_FLAG_INHERIT,HANDLE_FLAG_INHERIT);
  SetHandleInformation(GetStdHandle(STD_ERROR_HANDLE),
                       HANDLE_FLAG_INHERIT,HANDLE_FLAG_INHERIT);
  si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
  si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  si.hStdError = GetStdHandle(STD_ERROR_HANDLE);

  PROCESS_INFORMATION pinf;
  if (!CreateProcessA(const_cast<char*>(ozenginePath.c_str()),
                      const_cast<char*>(cmdline.c_str()),
                      nullptr, nullptr, true, 0,
                      nullptr, nullptr, &si, &pinf)) {
    std::cerr << "panic: cannot start ozengine" << std::endl;
    return 254;
  }

  // Wait for completion
  WaitForSingleObject(pinf.hProcess, INFINITE);

  // Get the exit code
  DWORD exitCode;
  if (!GetExitCodeProcess(pinf.hProcess, &exitCode))
    exitCode = 255;

  // Close the handles
  CloseHandle(pinf.hProcess);
  CloseHandle(pinf.hThread);

  return exitCode;
}
<|endoftext|>