示例#1
0
static ERTS_INLINE void
notify_new_message(Process *receiver)
{
    ERTS_SMP_LC_ASSERT(ERTS_PROC_LOCK_STATUS
		       & erts_proc_lc_my_proc_locks(receiver));

    ACTIVATE(receiver);

    switch (receiver->status) {
    case P_GARBING:
	switch (receiver->gcstatus) {
	case P_SUSPENDED:
	    goto suspended;
	case P_WAITING:
	    goto waiting;
	default:
	    break;
	}
	break;
    case P_SUSPENDED:
    suspended:
	receiver->rstatus = P_RUNABLE;
	break;
    case P_WAITING:
    waiting:
	erts_add_to_runq(receiver);
	break;
    default:
	break;
    }
}
示例#2
0
/*
 * restituisce un puntatore ad un publication record preallocato
 * se tutti i P_RECORD_PER_CPU sono utilizzati si attende l'evasione di una
 * richiesta che liberi un publication record
 */
static pub_record *get_pub_record(fc_dl_skiplist_t *p, int cpu){
	pub_record **array = p->p_record_array[cpu];
	int idx = p->p_record_idx[cpu];

	while(1){
		if(!IS_ACTIVE(array[idx])){
			ACTIVATE(array[idx]);
			p->p_record_idx[cpu] = (p->p_record_idx[cpu] + 1) % P_RECORD_PER_CPU;
			return array[idx];
		}
		/* nessun publication record libero: tento di diventare un combiner */
		fc_dl_sl_wait_response(p);
	}
}
int DISTRIBUTE(DataCell **dataGrid, Automata *CAList, unsigned *activeCount,
               double *gridMetadata){
/*DISTRIBUTE_01 IMMEDIATELY UPDATES Cellular Automata and shares lava EVENLY to
                all lower neighbors NOT-PROPORTIONAL TO SLOPE.
                The Center Cell will SHARE ALL VOLUME of lava it contains ABOVE
                the RESIDUAL VOLUME.
*/
/*Module: DISTRIBUTE
          Distributes lava from central cells which have a residual amount of
          lava to lower cells in a neighborhood.
          Arguments:
            dataCell dataGrid     - a 2D Global Data Grid
            Automata CAList       - a cellular automata list of active cells
            unsigned activeCount  - the number of elements within CAList
            double   gridMetadata - geometry of the Global Data Grid
          
          Algorithm:
            Until counter reaches the most recently activated cell in CAList:
              IF CAList[counter] (center cell) has enough lava to spread:
                Identify cells in local neighborhood which can receive lava
                IF there are cells:
                  Define volume to advect away from center cell
                  Calculate Cell-Cell elevation reliefs and sum them
                  FOR each neighbor:
                    Determine Effective center cell - neighbor Cell relief
                    If neighbor cell is not in CAList, append with ACTIVATE
                    Determine volume to add to neighbor cell
                    Add thickness of lava to neighbor cell
                  Reduce lava volume in center cell by total volume distributed
              Increment counter and test against number of cells in CAList
          
          Return total number of active cells and updated CAList with pointers
*/

	/*VARIABLES******************************************************************/
	/*Center Cell counter, used to cycle through all active Cells (1-N). Does not
	  start at 0, because CAList[0] would look inactive in dataGrid.active.     */
	unsigned c = 1;

	/*Neighborhood Variables*/
	Automata *neighborCAList;   /*CA List containing neighbor information       */
	int      neighborCount;     /*Number of lava-accepting cells in neighborhood*/
	double   neighborDist[8];   /*Weight: NESW cells = 1, corner cells = 2^-0.5 */
	double   neighborRelief[8]; /*Cell-Cell elevation difference*/
	double   neighborEffRelief; /*Cell-Cell elev difference * neigh. dist weight*/
	double   totalRelief;       /*summed Cell-Cell elevation differences        */
	unsigned n, NCol,NRow;      /*neighbor counter, grid location               */
	
	double   volumeDistribute;  /*lava volume to advect away from center cell   */
	char     parentCode;        /*bitwise parent-child relationship code        */
	
	
	/****************************************************************************/
	/*MAIN CELL DISTRIBUTE LOOP**************************************************/
	/****************************************************************************/
	/*for all entries in active Cellular Automata list (c <= activeCount)*/
	do { 
		/*If center cell has more lava than the residual thickness, advect lava*/
		if(CAList[c].thickness > 0) {
			
			/*MODULE: NEIGHBOR_ID****************************************************/
			/*        Identifies lower, valid-to-spread-to cells in the center cell
			          neighborhood.*/
			neighborCAList = NEIGHBOR_ID(CAList[c],     /*Automata Center Cell      */
			                             dataGrid,      /*DataCell Global Data Grid */
			                             gridMetadata,  /*double   grid data        */
			                             CAList,        /*Automata Active Cell List */
			                             &neighborCount /*Number of ID'd Neighbors  */
			                            );
			
			/*Check for Error flag (NEIGHBOR_ID returns <0 value)*/
			if(neighborCount==-1) //OFF THE MAP Error.
				return 2;
			if(neighborCount<0) {
				fprintf(stderr, 
				       "ERROR [DISTRIBUTE]: Error flag returned from [NEIGHBOR_ID].\n");
				return 1;
			}
			
			/*If there are found neighbors (neighborCount>0)*/
			else if(neighborCount){
				/*define amount of lava to be spread away from center cell*/
				volumeDistribute = CAList[c].thickness;
				
				/*LOOP THROUGH NEIGHBORS ONCE to find Cell-Cell reliefs, total Relief*/
				totalRelief = 0;
				for(n=0;n<neighborCount;n++) {
					/*Distance factor: NESW cells are weighted at 1, 
					  Corner cells at 2^-0.5. This makes corner cells receive less lava*/
					neighborDist[n] = (double) 1.0/sqrt(
					                  (abs(neighborCAList[n].row-CAList[c].row)+
					                   abs(neighborCAList[n].col-CAList[c].col)));
					
					/*Add EFFECTIVE relief of cell to totalRelief*/
					totalRelief += neighborDist[n];
				}
				
				
				/*LOOP THROUGH NEIGHBORS AGAIN to activate new cells, distribute lava*/
				for(n=0;n<neighborCount;n++) {
					
					NRow = neighborCAList[n].row; /*Current neighbor's grid location*/
					NCol = neighborCAList[n].col;
					
					/*Neighbor's Effective elevation difference from center cell*/
					neighborEffRelief = neighborDist[n]; /*Slope-blind just use distance*/
					
					
					/*if neighbor not in active list, Activate neighbor cell*/
					if(!dataGrid[NRow][NCol].active){
						/*Parent bit-code is 8-bits, denotes which cell(s) is the "parent"*/
						/*swap bits: (0th bit = parent is right;1st= p. is down;
						              2nd bit = parent is left; 3rd=p. is up;
						              4th bit = parent is right-down; 5rd=p. is left-down;
						              6th bit = parent is left-up;    7rd=p. is right-up;)
						 If neighbor to activate is DOWN, its parent (current cell) is UP.*/
						
						parentCode = 0; /*reset parent code*/
						if     ((NCol<CAList[c].col)&&(NRow>CAList[c].row))
							parentCode |= 1 << 4; /*Switch Right-Down bit (Bit 4) to ON*/
						else if((NCol>CAList[c].col)&&(NRow>CAList[c].row))
							parentCode |= 1 << 5;
						else if((NCol>CAList[c].col)&&(NRow<CAList[c].row))
							parentCode |= 1 << 6;
						else if((NCol<CAList[c].col)&&(NRow<CAList[c].row))
							parentCode |= 1 << 7;
						else if(NCol<CAList[c].col) parentCode |= 1 << 0;
						else if(NRow>CAList[c].row) parentCode |= 1 << 1;
						else if(NCol>CAList[c].col) parentCode |= 1 << 2;
						else if(NRow<CAList[c].row) parentCode |= 1 << 3;
						
						/*MODULE: ACTIVATE*************************************************/
						/*        Appends a cell to the CA List with Global Data Grid info*/
						
						*activeCount = ACTIVATE(dataGrid,     /*DataCell Global Data Grid */
						                        CAList,       /*Automata CA List          */
						                        NRow,         /*unsigned Row Location     */
						                        NCol,         /*unsigned Column Location  */
						                        *activeCount, /*unsigned No. Cells in List*/
						                        parentCode,   /*char     Parent Code      */
						                        0             /*char     Vent Code: 0=not */
						                       );
						
						/*Check for Error Flag (Active Count should never be 0 or less)*/
						if(*activeCount<=0){
							fprintf(stderr, "\nError [DISTRIBUTE]: Error from [ACTIVATE]\n");
							return 1;
						}
					} /*End IF neighbor cell is not yet active*/
					
					
					/*SPREAD LAVA TO NEIGHBOR NOW****************************************/
					/*Add Lava based on amount available to share and Effective Relief*/
					/*Change both flow thickness and effective elevation*/
					CAList[dataGrid[NRow][NCol].active].thickness +=
					       volumeDistribute * neighborEffRelief / totalRelief;
					CAList[dataGrid[NRow][NCol].active].elev      +=
					       volumeDistribute * neighborEffRelief / totalRelief;
					
				} /*End FOR all neighbors*/
				
				/*REMOVE ALREADY SPREAD LAVA FROM CENTER CELL**************************/
				/*Change both flow thickness and effective elevation*/
				CAList[c].elev -= volumeDistribute;
				CAList[c].thickness -= volumeDistribute;
				
			} /*End IF there are lava-accepting neighbors*/
			
			/*free neighbor list from memory*/
			free(neighborCAList);
			
		} /*End IF lava is thick enough to advect (CAList[c].thickness > 0)*/
		
		c++; /*Move to next cell*/
	} while(c <= *activeCount); /*Keep looping until all cells have been tested*/
	
	/*return 0 for a successful round of distribution.*/
	return 0;
}
int DISTRIBUTE(DataCell **dataGrid, Automata *CAList, unsigned *activeCount,
               double *gridMetadata){
/*DISTRIBUTE_04 Updates Cellular Automata ALL AT ONCE and determines how much
                lava to share between neighbors PROPORTIONAL TO SLOPE. 
                The Center Cell will SHARE MAXIMUM VOLUME of lava that keeps it
                AT OR ABOVE Neighboring cells.
*/
/*Module: DISTRIBUTE
          Distributes lava from central cells which have a residual amount of
          lava to lower cells in a neighborhood.
          Arguments:
            dataCell dataGrid     - a 2D Global Data Grid
            Automata CAList       - a cellular automata list of active cells
            unsigned activeCount  - the number of elements within CAList
            double   gridMetadata - geometry of the Global Data Grid
          
          Algorithm:
            Until counter = the cell count in CAList when module was called:
              IF CAList[counter] (center cell) has enough lava to spread:
                Identify cells in local neighborhood which can receive lava
                IF there are cells:
                  Define volume to advect away from center cell
                  Calculate Cell-Cell elevation reliefs and sum them
                  FOR each neighbor:
                    Determine Effective center cell - neighbor Cell relief
                    If neighbor cell is not in CAList, append with ACTIVATE
                    Determine volume to add to neighbor cell
                    Add thickness of lava to neighbor's  IN  transition property
                  Add total vol. distributed to center's OUT transition property
              Increment counter and test against number of cells in CAList
            
            For all cells in CAList:
              update lava thicknesses with transition properties
              reset transition properties
          
          Return total number of active cells and updated CAList with pointers
          
          The volume to distribute from the center cell is calculated as 
          the minimum of:
          1) The amount of lava above the residual thickness within the cell
          2) a*b/(a+b)
               where a = The summed Center Cell-Neighbor Cell Relief
                     b = the minimum Center Cell-Neighbor Cell Relief
          This guarantees that the center cell will not give lava to the point
          that it is below its neighbors.
*/
	
	/*VARIABLES******************************************************************/
	/*Center Cell counter, used to cycle through all active Cells (1-N). Does not
	  start at 0, because CAList[0] would look inactive in dataGrid.active.     */
	unsigned c = 1;
	/*This module only distributes lava away from already active cells, uses init.
	  active counter as c max in main do-while loop.                            */
	unsigned initialActiveCount = *activeCount;

	/*Neighborhood Variables*/
	Automata *neighborCAList;   /*CA List containing neighbor information       */
	int      neighborCount;     /*Number of lava-accepting cells in neighborhood*/
	double   neighborDist[8];   /*Weight: NESW cells = 1, corner cells = 2^-0.5 */
	double   neighborRelief[8]; /*Cell-Cell elevation difference*/
	double   minNeighborRelief; /*minimum C2C elev diff, used to calc. volDistr.*/
	double   neighborEffRelief; /*Cell-Cell elev difference * neigh. dist weight*/
	double   totalRelief;       /*summed Cell-Cell elevation differences        */
	unsigned n, NCol,NRow;      /*neighbor counter, grid location               */
	
	double   volumeDistribute;  /*lava volume to advect away from center cell   */
	char     parentCode;        /*bitwise parent-child relationship code        */
	
	
	/****************************************************************************/
	/*MAIN CELL DISTRIBUTE LOOP**************************************************/
	/****************************************************************************/
	/*for all entries in active Cellular Automata list (c <= initialActiveCount)*/
	do { 
		/*If center cell has more lava than the residual thickness, advect lava*/
		if(CAList[c].thickness > 0) {
			
			/*MODULE: NEIGHBOR_ID****************************************************/
			/*        Identifies lower, valid-to-spread-to cells in the center cell
			          neighborhood.*/
			neighborCAList = NEIGHBOR_ID(CAList[c],     /*Automata Center Cell      */
			                             dataGrid,      /*DataCell Global Data Grid */
			                             gridMetadata,  /*double   grid data        */
			                             CAList,        /*Automata Active Cell List */
			                             &neighborCount /*Number of ID'd Neighbors  */
			                            );
			
			/*Check for Error flag (NEIGHBOR_ID returns <0 value)*/
			if(neighborCount<0) {
				printf("ERROR [DISTRIBUTE]: Error flag returned from [NEIGHBOR_ID].\n");
				return(-1);
			}
			
			
			/*If there are found neighbors (neighborCount>0)*/
			else if(neighborCount){
				/*define maximum amount of lava to be spread away from center cell*/
				volumeDistribute = CAList[c].thickness;
				
				/*LOOP THROUGH NEIGHBORS ONCE to find Cell-Cell reliefs, total Relief*/
				totalRelief = 0;
				minNeighborRelief = 0; /*(a-n_1)*/
				for(n=0;n<neighborCount;n++) {
					/*Distance factor: NESW cells are weighted at 1, 
					  Corner cells at 2^-0.5. This makes corner cells receive less lava*/
					neighborDist[n] = (double) 1.0/sqrt(
					                  (abs(neighborCAList[n].row-CAList[c].row)+
					                   abs(neighborCAList[n].col-CAList[c].col)));
					
					/*Actual center cell to neighbor cell relief in meters*/
					neighborRelief[n] = CAList[c].elev-neighborCAList[n].elev;
					/*Test to see if this neighborRelief is smallest*/
					if (n==0) minNeighborRelief=neighborRelief[n];
					else if  (minNeighborRelief>neighborRelief[n])
					          minNeighborRelief=neighborRelief[n];
					
					/*Add EFFECTIVE relief of cell to totalRelief*/
					totalRelief += neighborDist[n] * neighborRelief[n];
				}
				
				/*CHECK DISTRIBUTE VOLUME******/
				/*Reduce volume to spread to safety volume if it is too large.*/
				if (volumeDistribute > 
				    (minNeighborRelief*totalRelief/(minNeighborRelief+totalRelief))
				   )
				    volumeDistribute =
				    minNeighborRelief*totalRelief/(minNeighborRelief+totalRelief);
				
				/*LOOP THROUGH NEIGHBORS AGAIN to activate new cells, distribute lava*/
				for(n=0;n<neighborCount;n++) {
					
					NRow = neighborCAList[n].row; /*Current neighbor's grid location*/
					NCol = neighborCAList[n].col;
					
					/*Neighbor's Effective elevation difference from center cell*/
					neighborEffRelief = neighborDist[n] * neighborRelief[n];
					
					
					/*if neighbor not in active list, Activate neighbor cell*/
					if(!dataGrid[NRow][NCol].active){
						/*Parent bit-code is 8-bits, denotes which cell(s) is the "parent"*/
						/*swap bits: (0th bit = parent is right;1st= p. is down;
						              2nd bit = parent is left; 3rd=p. is up;
						              4th bit = parent is right-down; 5rd=p. is left-down;
						              6th bit = parent is left-up;    7rd=p. is right-up;)
						 If neighbor to activate is DOWN, its parent (current cell) is UP.*/
						
						parentCode = 0; /*reset parent code*/
						if     ((NCol<CAList[c].col)&&(NRow>CAList[c].row))
							parentCode |= 1 << 4; /*Switch Right-Down bit (Bit 4) to ON*/
						else if((NCol>CAList[c].col)&&(NRow>CAList[c].row))
							parentCode |= 1 << 5;
						else if((NCol>CAList[c].col)&&(NRow<CAList[c].row))
							parentCode |= 1 << 6;
						else if((NCol<CAList[c].col)&&(NRow<CAList[c].row))
							parentCode |= 1 << 7;
						else if(NCol<CAList[c].col) parentCode |= 1 << 0;
						else if(NRow>CAList[c].row) parentCode |= 1 << 1;
						else if(NCol>CAList[c].col) parentCode |= 1 << 2;
						else if(NRow<CAList[c].row) parentCode |= 1 << 3;
						
						/*MODULE: ACTIVATE*************************************************/
						/*        Appends a cell to the CA List with Global Data Grid info*/
						
						*activeCount = ACTIVATE(dataGrid,     /*DataCell Global Data Grid */
						                        CAList,       /*Automata CA List          */
						                        NRow,         /*unsigned Row Location     */
						                        NCol,         /*unsigned Column Location  */
						                        *activeCount, /*unsigned No. Cells in List*/
						                        parentCode,   /*char     Parent Code      */
						                        0             /*char     Vent Code: 0=not */
						                       );
						
						/*Check for Error Flag (Active Count should never be 0 or less)*/
						if(*activeCount<=0){
							printf("\nError [DISTRIBUTE]: Error from [ACTIVATE]\n");
							return(-1);
						}
					} /*End IF neighbor cell is not yet active*/
					
					
					/*DETERMINE AMOUNT OF LAVA TO SPREAD TO NEIGHBOR FOR LATER***********/
					/*add lava based on amount to share and neighborEffRelief*/
					CAList[dataGrid[NRow][NCol].active].lava_in +=
					       volumeDistribute * neighborEffRelief / totalRelief;
					
				} /*End FOR all neighbors*/
				
				/*DETERMINE AMOUNT OF LAVA TO REMOVE FROM CENTER CELL FOR LATER********/
				CAList[c].lava_out += volumeDistribute;
				
			} /*End IF there are lava-accepting neighbors*/
			
			/*free neighbor list from memory*/
			free(neighborCAList);
			
		} /*End IF lava is thick enough to advect (CAList[c].thickness > 0)*/
		
		c++; /*Move to next cell*/
	} while(c <= initialActiveCount); /*Keep looping until cells which were     */
	                                  /*already active at start have been tested*/
	
	/*UPDATE ALL CELL LAVA LEVELS*/
	for(c=1;c<=*activeCount;c++) {
		/*Change both flow thickness and effective elevation*/
		CAList[c].elev      += CAList[c].lava_in;
		CAList[c].thickness += CAList[c].lava_in;
		
		CAList[c].elev      -= CAList[c].lava_out;
		CAList[c].thickness -= CAList[c].lava_out;
		
		/*Reset transition properties*/
		CAList[c].lava_in    = CAList[c].lava_out = 0.0;
	}
	
	/*return 0 for a successful round of distribution.*/
	return(0);
}
int INIT_FLOW (DataCell **dataGrid, Automata ***CAList, VentArr *ventList,
               unsigned *CAListCount, unsigned *CAListSize, unsigned ventCount,
               unsigned **activects, double *gridInfo, double *totalVolume) {
/* Module INIT_FLOW
	creates Cellular Automata Lists (active cell list)
	checks that all vents are within DEM area
	adds vent locations to CA List
	add all vent volumes to calculate total incoming volume
	
	args: data array, *CA lists, vent array, *CA List Count, *CA List Size,
	      vent count, *Cell counts, DEM metadata, *total volume in
	
	DEM transform data (gridInfo) format:
		[0] lower left x
		[1] w-e pixel resolution, column size
		[2] number of columns
		[3] lower left y
		[4] number of lines/rows
		[5] n-s pixel resolution, row size
*/
	
	unsigned ventRow, ventCol;
	Automata **IFCAList; /*working array for CAList in Init_Flow module*/
	unsigned *IFactivects; /*working array for active counts*/
	int i,j,k;
	double minResidual = 0;
	double randElev;
	double maxCellsPossible;
	
	*totalVolume = 0;
	
	/*DATA GRID PREPARATION*/
	/* 1. Find minimum residual in entire grid (to safely calculate maximum number
	      of cells)
	   2. Calculate DEM elevations based on elevation and uncertainty*/
	k=0;
	for(i=0;i<gridInfo[4];i++) {
		for(j=0;j<gridInfo[2];j++) {
			/*if first cell, assign modal thickness as min and iterate k*/
			if ((k++)==0)	minResidual = dataGrid[i][j].residual;
			/*if cell modal thickness is less than min, rewrite min.*/
			else if (minResidual > dataGrid[i][j].residual)
				minResidual = dataGrid[i][j].residual;
			
			/*RANDOMIZE ELEVATIONS IF NEEDED*/
			/*if elev_uncert is essentially 0 (within Double Precision of 0), copy
			  DEM elevation to the Flow Elevation.*/
			if(dataGrid[i][j].elev_uncert < 1e-8)
				dataGrid[i][j].elev = dataGrid[i][j].dem_elev; /*copy DEM elev to flow elev*/
			/*If elevation uncertainty is not 0, produce a random elevation*/
			else {
				/*This produces a pseudorandom number w/ box-muller method
				  for a pdf with mean 0, STD 1.0 (M_PI comes from the math library)*/
				randElev = sqrt(-2 * log((rand()+1.0)/(RAND_MAX+1.0)))*
				              cos(2*M_PI*((rand()+1.0)/(RAND_MAX+1.0)));
				/*scale random number by uncertainty (scale the STD)*/
				randElev *= dataGrid[i][j].elev_uncert;
				/*apply to the DEM value (translate the mean)*/
				randElev += dataGrid[i][j].dem_elev;
				dataGrid[i][j].elev = randElev;
			}
		}
	}
	/*Error check that all flow thicknesses are positive!*/
	if (minResidual<=1e-8) {
		printf("\nERROR [INIT_FLOW]:");
		printf(" Minimum Modal thickness (Residual Thickness) is <= 0!\n");
		return(-1);
	}
	
	/*CELLULAR AUTOMATA LIST PREPARATION*****************************************/
	/*While no parellelization is in effect, scale CA List Size to the model*/
	/*The MOST cells a flow can inundate is 3*(total volume/residual volume)+2*/
	maxCellsPossible = 0.0;
	for(i=0;i<ventCount;i++) maxCellsPossible += ventList[i].totalvolume;
	maxCellsPossible *= (3/(gridInfo[1] * gridInfo[5] * minResidual));
	maxCellsPossible += 2;
	*CAListSize = (unsigned) maxCellsPossible;
	
	/*Do a preliminary check to make sure there are fewer vents than the worker size.
	  If there are more vents than the first worker, it's doubtful this simulation
	  can work, so we'll nip that possibility in the bud right here.*/
	if(ventCount >= *CAListSize) {
		printf("\nERROR [INIT_FLOW]:");
		printf(" Too many vents (%u)! Max # of vents is %u\n",ventCount,*CAListSize);
		return(-1);
	}
	
	/*ARRAY DECLARATION*/
	/*Declare 2 Cellular Automata lists of size CAListSize 
	  (a main list and a spare)*/
	*CAListCount = 2;
	printf("Allocating Memory for Active Cell Lists... ");
	*CAList = ACTIVELIST_INIT(*CAListCount,*CAListSize);
	IFCAList = *CAList;
	
	/*Declare an array of Active Counters for each CA List, initialize at 0*/
	printf("and counters...");
	if((*activects=
       (unsigned*)malloc((unsigned)(*CAListCount + 1)*sizeof(unsigned)))==NULL){
		printf("\nERROR [INIT_FLOW]:");
		printf(" No more memory! Tried to create Active Count List\n");
		return(-1);
	}
	printf(" Done.\n");
	IFactivects = *activects;
	
	/*Declare Active List Counts to 0 (No Active Cells yet)*/
	for(i=1;i<=*CAListCount;i++) IFactivects[i]=0;
	
	/*LOAD VENTS INTO CA LIST****************************************************/
	for(i=0;i<ventCount;i++) {
		/*check that each vent is inside global grid*/
		if((ventRow = (unsigned)
		  ((ventList[i].northing-gridInfo[3])/gridInfo[5])) <= 0) {
			printf("\nERROR [INIT_FLOW]:");
			printf(" Vent not within region covered by DEM! (SOUTH of region)\n");
			printf(" Vent #%u at cell: [%u][%u].\n",
			       (i+1),
			       ventRow,
			       (unsigned) ((ventList[i].easting-gridInfo[0])/gridInfo[1]));
			return (-1);
		}
		else if(ventRow >= gridInfo[4]) {
			printf("\nERROR [INIT_FLOW]:");
			printf(" Vent not within region covered by DEM! (NORTH of region)\n");
			printf(" Vent #%u at cell: [%u][%u].\n",
			       (i+1),
			       ventRow,
			       (unsigned) ((ventList[i].easting-gridInfo[0])/gridInfo[1]));
			return (-1);
		}
		else if((ventCol = (unsigned) 
		       ((ventList[i].easting-gridInfo[0])/gridInfo[1])) <= 0) {
			printf("\nERROR [INIT_FLOW]:");
			printf(" Vent not within region covered by DEM! (WEST of region)\n");
			printf(" Vent #%u at cell: [%u][%u].\n",
			       (i+1),
			       ventRow,
			       ventCol);
			return (-1);
		}
		else if(ventCol >= gridInfo[2]) {
			printf("\nERROR [INIT_FLOW]:");
			printf(" Vent not within region covered by DEM! (EAST of region)\n");
			printf(" Vent #%u at cell: [%u][%u].\n",
			       (i+1),
			       ventRow,
			       ventCol);
			return (-1);
		}
		
		/*Activate vents in CA list*/
		/*MODULE: ACTIVATE*********************************************************/
		/*        Appends a cell to the CA List using data from a Global Data Grid*/
		
		IFactivects[1] = ACTIVATE(dataGrid,       /*DataCell Global Data Grid     */
		                          IFCAList[1],    /*Automata CA List              */
		                          ventRow,        /*unsigned Cell Row Location    */
		                          ventCol,        /*unsigned Cell Column Location */
		                          IFactivects[1], /*unsigned No. Cells in CA List */
		                          0,              /*char     Parent Code: 0=none  */
		                          1               /*char     Vent Code: 1=vent    */
		                         );
		
		/*Check for Error Flags*/
		/*Check that activect of first worker has been updated (ct should be i+1)*/
		if(IFactivects[1]<=i){
			printf("\nError [INIT_FLOW]: Error flag returned from [ACTIVATE]\n");
			return(-1);
		}
		
		/*Print vent location to standard output*/
		if (i==0) { /*Print first time a vent is loaded*/
			printf("\nVents Loaded into Lava Flow Active List:\n");
		}
		printf(" #%u [%u][%u] %15.3f cu. m.\n",
		       (i+1),ventRow,ventCol,ventList[i].totalvolume);
		
		/*Add current vent's volume to total volume in.*/
		*totalVolume += ventList[i].totalvolume;
	}
	
	/*Print total volume.*/
	printf("----------------------------------------\n");
	printf("Total Volume: %15.3f cu. m.\n", *totalVolume);
	
	return(0);
}
示例#6
0
void
erts_send_message(Process* sender,
		  Process* receiver,
		  ErtsProcLocks *receiver_locks,
		  Eterm message,
		  unsigned flags)
{
    Uint msize;
    ErlHeapFragment* bp = NULL;
    Eterm token = NIL;

    BM_STOP_TIMER(system);
    BM_MESSAGE(message,sender,receiver);
    BM_START_TIMER(send);

    if (SEQ_TRACE_TOKEN(sender) != NIL && !(flags & ERTS_SND_FLG_NO_SEQ_TRACE)) {
        Eterm* hp;

        BM_SWAP_TIMER(send,size);
	msize = size_object(message);
        BM_SWAP_TIMER(size,send);

	seq_trace_update_send(sender);
	seq_trace_output(SEQ_TRACE_TOKEN(sender), message, SEQ_TRACE_SEND, 
			 receiver->id, sender);
	bp = new_message_buffer(msize + 6 /* TUPLE5 */);
	hp = bp->mem;

        BM_SWAP_TIMER(send,copy);
	token = copy_struct(SEQ_TRACE_TOKEN(sender),
			    6 /* TUPLE5 */,
			    &hp,
			    &bp->off_heap);

	message = copy_struct(message, msize, &hp, &bp->off_heap);
        BM_MESSAGE_COPIED(msize);
        BM_SWAP_TIMER(copy,send);

        erts_queue_message(receiver,
			   receiver_locks,
			   bp,
			   message,
			   token);
        BM_SWAP_TIMER(send,system);
#ifdef HYBRID
    } else {
        ErlMessage* mp = message_alloc();
        BM_SWAP_TIMER(send,copy);
#ifdef INCREMENTAL
        /* TODO: During GC activate processes if the message relies in
         * the fromspace and the sender is active. During major
         * collections add the message to the gray stack if it relies
         * in the old generation and the sender is active and the
         * receiver is inactive.

        if (!IS_CONST(message) && (ma_gc_flags & GC_CYCLE) &&
            (ptr_val(message) >= inc_fromspc &&
            ptr_val(message) < inc_fromend) && INC_IS_ACTIVE(sender))
            INC_ACTIVATE(receiver);
        else if (!IS_CONST(message) && (ma_gc_flags & GC_CYCLE) &&
            (ptr_val(message) >= global_old_heap &&
            ptr_val(message) < global_old_hend) &&
            INC_IS_ACTIVE(sender) && !INC_IS_ACTIVE(receiver))
            Mark message in blackmap and add it to the gray stack
        */

         if (!IS_CONST(message))
            INC_ACTIVATE(receiver);
#endif
        LAZY_COPY(sender,message);
        BM_SWAP_TIMER(copy,send);
        ERL_MESSAGE_TERM(mp) = message;
        ERL_MESSAGE_TOKEN(mp) = NIL;
        mp->next = NULL;
	LINK_MESSAGE(receiver, mp);
        ACTIVATE(receiver);

        if (receiver->status == P_WAITING) {
            erts_add_to_runq(receiver);
        } else if (receiver->status == P_SUSPENDED) {
            receiver->rstatus = P_RUNABLE;
        }
        if (IS_TRACED_FL(receiver, F_TRACE_RECEIVE)) {
            trace_receive(receiver, message);
        }

        BM_SWAP_TIMER(send,system);
        return;
#else
    } else if (sender == receiver) {