void BuildQueueInit(BuildQueue* queue, const BuildQueueConfig* config) { CHECK(config->m_MaxExpensiveCount > 0 && config->m_MaxExpensiveCount <= config->m_ThreadCount); MutexInit(&queue->m_Lock); CondInit(&queue->m_WorkAvailable); // Compute queue capacity. Allocate space for a power of two number of // indices that's at least one larger than the max number of nodes. Because // the queue is treated as a ring buffer, we want W=R to mean an empty // buffer. uint32_t capacity = NextPowerOfTwo(config->m_MaxNodes + 1); MemAllocHeap* heap = config->m_Heap; queue->m_Queue = HeapAllocateArray<int32_t>(heap, capacity); queue->m_QueueReadIndex = 0; queue->m_QueueWriteIndex = 0; queue->m_QueueCapacity = capacity; queue->m_Config = *config; queue->m_PendingNodeCount = 0; queue->m_FailedNodeCount = 0; queue->m_QuitSignalled = false; queue->m_ExpensiveRunning = 0; queue->m_ExpensiveWaitCount = 0; queue->m_ExpensiveWaitList = HeapAllocateArray<NodeState*>(heap, capacity); CHECK(queue->m_Queue); if (queue->m_Config.m_ThreadCount > kMaxBuildThreads) { Log(kWarning, "too many build threads (%d) - clamping to %d", queue->m_Config.m_ThreadCount, kMaxBuildThreads); queue->m_Config.m_ThreadCount = kMaxBuildThreads; } Log(kDebug, "build queue initialized; ring buffer capacity = %u", queue->m_QueueCapacity); // Block all signals on the main thread. SignalBlockThread(true); SignalHandlerSetCondition(&queue->m_WorkAvailable); // Create build threads. for (int i = 0, thread_count = config->m_ThreadCount; i < thread_count; ++i) { ThreadState* thread_state = &queue->m_ThreadState[i]; ThreadStateInit(thread_state, queue, MB(64), MB(32), i); if (i > 0) { Log(kDebug, "starting build thread %d", i); queue->m_Threads[i] = ThreadStart(BuildThreadRoutine, thread_state); } } }
//-------------------------------------------------------------------------- // CondCreate // // This function grabs a condition variable from the system-wide pool of // condition variables and associates the specified lock with // it. It should also initialize all the fields that need to initialized. // The lock being associated should be a valid lock, which means that // it should have been obtained via previous call to LockCreate(). // // If for some reason a condition variable cannot be created (no more // condition variables left, or the specified lock is not a valid lock), // this function should return INVALID_COND (see synch.h). Otherwise it // should return handle of the condition variable. //-------------------------------------------------------------------------- cond_t CondCreate(lock_t lock) { cond_t c; uint32 intrval; if (lock < 0) return SYNC_FAIL; // grabbing a cond should be an atomic operation intrval = DisableIntrs(); for(c=0; c<MAX_LOCKS; c++) { if (conds[c].inuse==0) { conds[c].inuse = 1; break; } } RestoreIntrs(intrval); if(c==MAX_CONDS) return SYNC_FAIL; if (CondInit(&conds[c]) != SYNC_SUCCESS) return SYNC_FAIL; conds[c].lock = &locks[lock]; return c; }
TInt CTestCondwait::TestCond411() { int errsum=0, err = 0; int retval = 0; ThreadData lThreadData; sem_t lSignalSemaphore; sem_t lSuspendSemaphore; sem_t lTestSemaphore; pthread_mutex_t lTestMutex; pthread_cond_t lTestCondVar; pthread_condattr_t lCondAttr; pthread_mutexattr_t lTestMutexAttr; pthread_mutexattr_t defaultattr; pthread_mutexattr_t errorcheckattr; pthread_mutexattr_t recursiveattr; pthread_mutexattr_init(&defaultattr); pthread_mutexattr_init(&errorcheckattr); pthread_mutexattr_init(&recursiveattr); pthread_mutexattr_settype(&errorcheckattr,PTHREAD_MUTEX_ERRORCHECK); pthread_mutexattr_settype(&recursiveattr,PTHREAD_MUTEX_RECURSIVE); pthread_mutex_t l_staticmutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t l_errorcheckmutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; pthread_mutex_t l_recursivemutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; pthread_cond_t l_staticcondvar = PTHREAD_COND_INITIALIZER; CommonData lCommonData; lCommonData.iStaticMutex = &l_staticmutex; lCommonData.iErrorCheckMutex = &l_errorcheckmutex; lCommonData.iRecursiveMutex = &l_recursivemutex; lCommonData.iStaticCondVar = &l_staticcondvar; retval = sem_init(&lSignalSemaphore,0,0); if(retval != 0) { return retval; } retval = sem_init(&lSuspendSemaphore,0,0); if(retval != 0) { return retval; } lThreadData.iSignalSemaphore = &lSignalSemaphore; lThreadData.iSuspendSemaphore = &lSuspendSemaphore; lThreadData.iTestSemaphore = &lTestSemaphore; lThreadData.iTestMutex = &lTestMutex; lThreadData.iTestMutexAttr = &lTestMutexAttr; lThreadData.iTestCondVar = &lTestCondVar; lThreadData.iDefaultAttr = &defaultattr; lThreadData.iErrorcheckAttr = &errorcheckattr; lThreadData.iRecursiveAttr = &recursiveattr; lThreadData.iCondAttr = &lCondAttr; for (int loop = 0; loop < EThreadMain; loop++) { g_spinFlag[loop] = true; } lThreadData.iSuspending = false; lThreadData.iSpinCounter = 0; lThreadData.iCurrentCommand = -1; lThreadData.iSelf = EThreadMain; lThreadData.iValue = 0; lThreadData.iRetValue = 0; lThreadData.ierrno = 0; lThreadData.iExpectederrno = 0; lThreadData.iTimes = 0; lThreadData.iStopped = false; lThreadData.iCommonData = &lCommonData; retval = CondInit(&lThreadData); retval = MutexInitNULL(&lThreadData); fp=func; retval = ThreadCreate(&lThreadData, (void*) EThread1); WaitTillSuspended(&lThreadData, (void*) EThread1); fp=func1; retval = ThreadCreate(&lThreadData, (void*) EThread2); retval = ThreadDestroy(&lThreadData, (void*) EThread1); retval = ThreadDestroy(&lThreadData, (void*) EThread2); retval = MutexDestroy(&lThreadData); retval = CondDestroy(&lThreadData); StopThread(&lThreadData); err = pthread_cond_destroy(&l_staticcondvar); if(err != EINVAL) { errsum += err; } err = pthread_mutex_destroy(&l_recursivemutex); if(err != EINVAL) { errsum += err; } err = pthread_mutex_destroy(&l_errorcheckmutex); if(err != EINVAL) { errsum += err; } err = pthread_mutex_destroy(&l_staticmutex); if(err != EINVAL) { errsum += err; } err = pthread_mutexattr_destroy(&recursiveattr); if(err != EINVAL) { errsum += err; } err = pthread_mutexattr_destroy(&errorcheckattr); if(err != EINVAL) { errsum += err; } err = pthread_mutexattr_destroy(&defaultattr); if(err != EINVAL) { errsum += err; } err = sem_destroy(&lSignalSemaphore); if(err != EINVAL) { errsum += err; } err = sem_destroy(&lSuspendSemaphore); if(err != EINVAL) { errsum += err; } return retval+errsum; }
int main(int argc, char *argv[]) { int i, OutputNumber = 0, d; int ni, ntot; char ParameterFile[MAXLINELENGTH]; if (argc == 1) PrintUsage (argv[0]); strcpy (ParameterFile, ""); for (i = 1; i < argc; i+=d) { d=1; if (*(argv[i]) == '+') { if (strspn (argv[i], \ "+S#D") \ != strlen (argv[i])) PrintUsage (argv[0]); if (strchr (argv[i], '#')) { d=2; ArrayNb = atoi(argv[i+1]); EarlyOutputRename = YES; if (ArrayNb <= 0) { masterprint ("Incorrect Array number after +# flag\n"); PrintUsage (argv[0]); } } if (strchr (argv[i], 'D')) { d=2; strcpy (DeviceFile, argv[i+1]); DeviceFileSpecified = YES; } if (strchr (argv[i], 'S')) { d=2; StretchNumber = atoi(argv[i+1]); StretchOldOutput = YES; } } if (*(argv[i]) == '-') { if (strspn (argv[i], \ "-tofCmkspSVBD0#") \ != strlen (argv[i])) PrintUsage (argv[0]); if (strchr (argv[i], 't')) TimeInfo = YES; if (strchr (argv[i], 'f')) ForwardOneStep = YES; if (strchr (argv[i], '0')) OnlyInit = YES; if (strchr (argv[i], 'C')) { EverythingOnCPU = YES; #ifdef GPU mastererr ("WARNING: Forcing execution of all functions on CPU\n"); #else mastererr ("WARNING: Flag -C meaningless for a CPU built\n"); #endif } if (strchr (argv[i], 'm')) { Merge = YES; } if (strchr (argv[i], 'k')) { Merge = NO; } if (strchr (argv[i], 'o')) { RedefineOptions = YES; ParseRedefinedOptions (argv[i+1]) ; d=2; } if (strchr (argv[i], 's')) { Restart = YES; d=2; NbRestart = atoi(argv[i+1]); if ((NbRestart < 0)) { masterprint ("Incorrect restart number\n"); PrintUsage (argv[0]); } } if (strchr (argv[i], '#')) { d=2; ArrayNb = atoi(argv[i+1]); if (ArrayNb <= 0) { masterprint ("Incorrect Array number after -# flag\n"); PrintUsage (argv[0]); } } if (strchr (argv[i], 'p')) { PostRestart = YES; } if (strchr (argv[i], 'S')) { Restart_Full = YES; d=2; NbRestart = atoi(argv[i+1]); if ((NbRestart < 0)) { masterprint ("Incorrect restart number\n"); PrintUsage (argv[0]); } } if (strchr (argv[i], 'V')) { Dat2vtk = YES; Restart_Full = YES; d=2; NbRestart = atoi(argv[i+1]); if ((NbRestart < 0)) { masterprint ("Incorrect output number\n"); PrintUsage (argv[0]); } } if (strchr (argv[i], 'B')) { Vtk2dat = YES; Restart_Full = YES; d=2; NbRestart = atoi(argv[i+1]); if ((NbRestart < 0)) { masterprint ("Incorrect output number\n"); PrintUsage (argv[0]); } } if (strchr (argv[i], 'D')) { d=2; DeviceManualSelection = atoi(argv[i+1]); } } else strcpy (ParameterFile, argv[i]); } #ifdef WRITEGHOSTS if (Merge == YES) { mastererr ("Cannot merge outputs when dumping ghost values.\n"); mastererr ("'make nofulldebug' could fix this problem.\n"); mastererr ("Using the -k flag could be another solution.\n"); prs_exit (1); } #endif if (ParameterFile[0] == 0) PrintUsage (argv[0]); #ifdef MPICUDA EarlyDeviceSelection(); #endif MPI_Init (&argc, &argv); MPI_Comm_rank (MPI_COMM_WORLD, &CPU_Rank); MPI_Comm_size (MPI_COMM_WORLD, &CPU_Number); CPU_Master = (CPU_Rank == 0 ? 1 : 0); #ifndef MPICUDA SelectDevice(CPU_Rank); #endif InitVariables (); MPI_Barrier(MPI_COMM_WORLD); ReadDefaultOut (); ReadVarFile (ParameterFile); if (strcmp (PLANETCONFIG, "NONE") != 0) ThereArePlanets = YES; if (ORBITALRADIUS > 1.0e-30){ YMIN *= ORBITALRADIUS; YMAX *= ORBITALRADIUS; DT *= sqrt(ORBITALRADIUS*ORBITALRADIUS*ORBITALRADIUS); } SubsDef (OUTPUTDIR, DefaultOut); /* This must be placed ***BEFORE*** reading the input files in case of a restart */ if ((ArrayNb) && (EarlyOutputRename == YES)) { i = strlen(OUTPUTDIR); if (OUTPUTDIR[i-1] == '/') OUTPUTDIR[i-1] = 0;//Remove trailing slash if any sprintf (OUTPUTDIR, "%s%06d/", OUTPUTDIR, ArrayNb); //Append numerical suffix /* There is no need to perform the wildcard (@) substitution. This has already been done */ printf ("\n\n***\n\nNew Output Directory is %s\n\n***\n\n", OUTPUTDIR); MakeDir(OUTPUTDIR); /*Create the output directory*/ } MakeDir(OUTPUTDIR); /*Create the output directory*/ #if !defined(X) NX = 1; #endif #if !defined(Y) NY = 1; #endif #if !defined(Z) NZ = 1; #endif SelectWriteMethod(); #if !defined(Y) && !defined(Z) if (CPU_Rank==1){ prs_error ("You cannot split a 1D mesh in x. Sequential runs only!"); } if (CPU_Number > 1) { MPI_Finalize(); prs_exit(EXIT_FAILURE); } #endif ListVariables ("variables.par"); //Writes all variables defined in set up ListVariablesIDL ("IDL.var"); ChangeArch(); /*Changes the name of the main functions ChangeArch adds _cpu or _gpu if GPU is activated.*/ split(&Gridd); /*Split mesh over PEs*/ InitSpace(); WriteDim(); InitSurfaces(); LightGlobalDev(); /* Copy light arrays to the device global memory */ CreateFields(); // Allocate all fields. Sys = InitPlanetarySystem(PLANETCONFIG); ListPlanets(); if(Corotating) OMEGAFRAME = GetPsysInfo(FREQUENCY); OMEGAFRAME0 = OMEGAFRAME; /* We need to keep track of initial azimuthal velocity to correct the target velocity in Stockholm's damping prescription. We copy the value above *after* rescaling, and after any initial correction to OMEGAFRAME (which is used afterwards to build the initial Vx field. */ if(Restart == YES || Restart_Full == YES) { CondInit (); //Needed even for restarts: some setups have custom //definitions (eg potential for setup MRI) or custom //scaling laws (eg. setup planetesimalsRT). begin_i = RestartSimulation(NbRestart); if (ThereArePlanets) { PhysicalTime = GetfromPlanetFile (NbRestart, 9, 0); OMEGAFRAME = GetfromPlanetFile (NbRestart, 10, 0); RestartPlanetarySystem (NbRestart, Sys); } } else { if (ThereArePlanets) EmptyPlanetSystemFiles (); CondInit(); // Initialize set up // Note: CondInit () must be called only ONCE (otherwise some // custom scaling laws may be applied several times). } if (StretchOldOutput == YES) { StretchOutput (StretchNumber); } FARGO_SAFE(comm(ENERGY)); //Very important for isothermal cases! /* This must be placed ***after*** reading the input files in case of a restart */ if ((ArrayNb) && (EarlyOutputRename == NO)) { i = strlen(OUTPUTDIR); if (OUTPUTDIR[i-1] == '/') OUTPUTDIR[i-1] = 0;//Remove trailing slash if any sprintf (OUTPUTDIR, "%s%06d/", OUTPUTDIR, ArrayNb); //Append numerical suffix /* There is no need to perform the wildcard (@) substitution. This has already been done */ printf ("\n\n***\n\nNew Output Directory is %s\n\n***\n\n", OUTPUTDIR); MakeDir(OUTPUTDIR); /*Create the output directory*/ ListVariables ("variables.par"); //Writes all variables defined in set up ListVariablesIDL ("IDL.var"); InitSpace(); WriteDim (); } DumpToFargo3drc(argc, argv); FillGhosts(PrimitiveVariables()); #ifdef STOCKHOLM FARGO_SAFE(init_stockholm()); #ifdef STOCKHOLMACC FARGO_SAFE(ComputeVymed(Vy)); FARGO_SAFE(ComputeRhomed(Density)); Write2D(Density0_avg, "density0_2d_avg.dat", OUTPUTDIR, GHOSTINC); Write2D(Vy0_avg, "vy0_2d_avg.dat", OUTPUTDIR, GHOSTINC); #endif #endif #ifdef GHOSTSX masterprint ("\n\nNew version with ghost zones in X activated\n"); #else masterprint ("Standard version with no ghost zones in X\n"); #endif #ifdef TIMER clock_t begin_timer_time, end_timer_time; real timer_time_elapsed; #endif ntot = NTOTINIT; for (ni = 0; ni<NITER; ni++) { // Iteration loop ntot = (ni == 0) ? NTOTINIT : NTOT; masterprint ("Start of %d iteration\n", ni); masterprint ("Evolving waves for %d DT (DT = %lg)\n", ntot,DT); for (i = begin_i; i<=ntot; i++) { // MAIN LOOP #ifdef TIMER if (i==begin_i) { begin_timer_time = clock(); } #endif if (NINTERM * (TimeStep = (i / NINTERM)) == i) { TimeStepIter = ni; #if defined(MHD) && defined(DEBUG) FARGO_SAFE(ComputeDivergence(Bx, By, Bz)); #endif if (ThereArePlanets) WritePlanetSystemFile(TimeStep, NO); #ifndef NOOUTPUTS WriteOutputsAndDisplay(ALL); if(CPU_Master) printf("OUTPUTS %d at date t = %f OK\n", TimeStep, PhysicalTime); #endif if (TimeInfo == YES) GiveTimeInfo (TimeStep); } if (NSNAP != 0) { if (NSNAP * (TimeStep = (i / NSNAP)) == i) { WriteOutputsAndDisplay(SPECIFIC); } } AlgoGas(FALSE); MonitorGlobal (MONITOR2D | MONITORY | MONITORY_RAW| \ MONITORSCALAR | MONITORZ | MONITORZ_RAW); if (ThereArePlanets) { WriteTorqueAndWork(TimeStep, 0); WritePlanetSystemFile(TimeStep, YES); SolveOrbits (Sys); } #ifdef TIMER if (i==begin_i) { end_timer_time = clock(); timer_time_elapsed =( (double)(end_timer_time-begin_timer_time))/CLOCKS_PER_SEC; masterprint("time for time_step was %g s\n",timer_time_elapsed); } #endif } masterprint ("End of %d iteration\n", ni); AlgoGas(TRUE); masterprint ("Computing steady state\n"); compute_steady_state(); add_avgs(); output_steady_state(ni); clear_averages(); } MPI_Finalize(); printf("End of simulation!\n"); return 0; }