Beispiel #1
0
int sthread_mutex_lock(sthread_mutex_t *mutex)
{
    sthread_t ptr_this_thread = sthread_self();
    //fighting for the right to modify Q
    while(test_and_set(&mutex->M)){}
    //after this I am now the only one
    //to modify the passed in mutex
    //therefore I should go ahead and
    //modify the lock and Q if needed

    //check if I should go into critical
    //section
    struct queue *pQ = &mutex->Q;
    if(Q_empty(pQ))
    {
        //lock available
        Q_push(pQ, ptr_this_thread);
        mutex->M = 0; // I am done with Q; others can come and look / change Q.
        return 0; //this_thread will go into critical section
    }
    else
    {
        //lock not available
        //there are someone or myself before me in the Q
        //if it is myself in criticle section
            //I shoud not wait for myself to wake myself up
            //I will increment counter and keep running in criticle seciton
        //else
            //someone else is before me in the Q 
            //either he is sleeping (he is not the 1st)
            //or he is in the critical section now (he is the 1st and 
            //I am the 2nd in Q)
                //either way I should go to bed and wait for him to wake me up
        if(Q_first(pQ)->ptr_thread == ptr_this_thread)
        {
            Q_first(pQ)->count++; //Trying to acquire the lock own by myself
                                 //take down this attempt and keep myself in
                                 //criticle section
            mutex->M = 0; //I am done with lock; others can now check / modify lock.
        }
        else
        {
            Q_push(pQ, ptr_this_thread);
            mutex->M = 0;
            sthread_suspend();  //Other thread is in criticle section
                        //I should go to bed and sleep 
            return 0;   //the moment I am woken up will
                        //return 0 to caller
        }
        
    }
}
Beispiel #2
0
struct q_member * Q_pop(struct queue *pQ)
{
    if(Q_empty(pQ))
        //instant fail
        return NULL;
    else
    {
        pQ->size--;
        struct q_member * p_first = Q_first(pQ);
        pQ->head = (pQ->head + 1 % MAX_Q_SIZE);
        return p_first;
    }
}
Beispiel #3
0
int sthread_mutex_trylock(sthread_mutex_t *mutex)
{
    sthread_t ptr_this_thread = sthread_self();
    //fighting for the right to modify Q
    while(test_and_set(&mutex->M)){}
    //after this I am now the only one
    //to modify the passed in mutex
    //therefore I should go ahead and
    //modify the lock and Q if needed

    //check if I should go into critical
    //section
    struct queue *pQ = &mutex->Q;
    if(Q_empty(pQ))
    {
        //lock available
        Q_push(pQ, ptr_this_thread);
        mutex->M = 0; // I am done with Q; others can come and look / change Q.
        //this_thread will go into critical section
        return 0;
    }
    else
    {
        //lock not available
        if(Q_first(pQ)->ptr_thread == ptr_this_thread)
        {
            Q_first(pQ)->count++;//Trying to acquire the lock own by myself
                                 //take down this attempt and keep myself in
                                 //criticle section
            mutex->M = 0; //I am done with lock; others can now check / modify lock.
        }
        //do not block caller
        //return non-zero indication lock not available
        return -1;
    }

}
Beispiel #4
0
int sthread_mutex_unlock(sthread_mutex_t *mutex)
{
    //fighting for the right to modify Q
    while(test_and_set(&mutex->M) == 1){}
    //I am the only one checking mutex
    //can modify Q
    struct queue *pQ = &mutex->Q;
    if(Q_first(pQ)->count == 1)
    {
        Q_pop(pQ);
        if(Q_empty(pQ) == 0)
        {
            //Queue is not empty
            //there are other threads sleeping
            //int the Q
            sthread_wake(Q_first(pQ)->ptr_thread);
        }
        else
        {
            //I am the last one int the Q
            //Do nothing
        }
        return 0;
    }
    else if( Q_first(pQ)->count > 1)
    {
        //I have acquired the lock owned by me 
        //more than once need to unlock 
        Q_first(pQ)->count--;
    }
    else
    {
        // printf("Bad!! count is 0 or less\n");
        return -1;
    }
}
Beispiel #5
0
//
// Add the points two the two initial triangles of a Tin tile from
// file. Also add points from neighbor boundary arrays to the
// triangulation to have boundary consistancy
//
TIN_TILE *initTilePoints(TIN_TILE *tt, double e, short useNodata){

  // First two tris
  TRIANGLE *first = tt->t;
  TRIANGLE *second = tt->t->p1p3;

  // Get back to the beginning of the tile data file
  rewind(tt->gridFile);

  // Now build list of points in the triangle
  // Create a dummy tail for both point lists
  first->points = Q_init();
  second->points = Q_init();
  first->maxE = DONE;
  second->maxE = DONE;
  
  // Build the two point lists
  register int row, col;
  ELEV_TYPE maxE_first=0;
  ELEV_TYPE maxE_second=0;
  ELEV_TYPE tempE = 0;
  
  R_POINT temp;
  
  // iterate through all points and distribute them to the 
  // two triangles
  for(row=0;row<tt->nrows;row++) {
    temp.x=row+tt->iOffset;
    for(col=0;col<tt->ncols;col++) {
      temp.y=col+tt->jOffset;
      fread(&temp.z,sizeof(ELEV_TYPE), 1, tt->gridFile);
      // Only set Z values for corner points since they already exist
      if(row==0 && col==0){
	tt->nw->z = temp.z;
	continue;
      }
      if(row==0 && col==tt->ncols-1){
	tt->ne->z = temp.z;
	continue;
      }
      if(row==tt->nrows-1 && col==tt->ncols-1){
	tt->se->z = temp.z;
	continue;
      } 
      if(row==tt->nrows-1 && col==0){
	tt->sw->z = temp.z;
	continue;
      }	
      //Ignore edge points if internal tile
      if(tt->iOffset != 0 && row == 0)
	continue;
      if(tt->jOffset != 0 && col == 0)
	continue;
      
      //Skip nodata or change it to min-1
      if(temp.z == tt->nodata){
	if(!useNodata)
      	  continue;
	else
	  temp.z = tt->min-1;
      }

      // Add to the first triangle's list
      if(inTri2D(first->p1, first->p2, first->p3, &temp)) {
	
	Q_insert_elem_head(first->points, temp);

	//Update max error
	tempE = findError(temp.x,temp.y,temp.z,first);
	if (tempE > maxE_first) {
	  maxE_first = tempE;
	  assert(Q_first(first->points));
	  // store pointer to triangle w/ max err
	  first->maxE = &Q_first(first->points)->e;
	  first->maxErrorValue = tempE;
	}
      }
      // Add to the second triangle's list
      else {

	assert(inTri2D(second->p1, second->p2, second->p3, &temp));

	Q_insert_elem_head(second->points, temp);

	//Update max error
	tempE = findError(temp.x,temp.y,temp.z,second);
	if (tempE > maxE_second) {
	  maxE_second = tempE;
	  assert(Q_first(second->points));
	  // store pointer to triangle w/ max err
	  second->maxE = &Q_first(second->points)->e; 
	  second->maxErrorValue = tempE;
	}

      }

    }//for col
  }//for row
  //end distribute points among initial triangles

  DEBUG {checkPointList(first); checkPointList(second);}

  // First triangle has no points with error > e, mark as done
  if (first->maxE == DONE){
    Q_free_queue(first->points);
    first->points = NULL;
    first->maxErrorValue = 0;
  }
  // Insert max error point into the PQ
  else
    PQ_insert(tt->pq,first);

  // Second triangle has no points with error > e, mark as done
  if (second->maxE == DONE){
    Q_free_queue(second->points);
    second->points = NULL;
    second->maxErrorValue = 0;
  }
  // Insert max error point into the PQ
  else
    PQ_insert(tt->pq,second);


  // Initialize point pointer arrays
  // At most points can have (tl*tl)-2*tl points in it
  // At most bPoints and rPoints can have tl points
  tt->points = (R_POINT **)malloc( ((tt->nrows * tt->ncols) - 
				  (tt->nrows + tt->ncols)) * 
				 sizeof(R_POINT*));
  tt->bPoints = (R_POINT **)malloc( tt->ncols * sizeof(R_POINT*));
  tt->rPoints = (R_POINT **)malloc( tt->nrows * sizeof(R_POINT*));  

  // Add points to point pointer array
  tt->points[0]=tt->nw;//nw
  tt->bPoints[0]=tt->sw;//sw
  tt->bPoints[1]=tt->se;//se
  tt->rPoints[0]=tt->ne;//ne
  tt->rPoints[1]=tt->se;//se
  tt->pointsCount = 1;
  tt->bPointsCount = 2;
  tt->rPointsCount = 2;

  //
  // Add boundary points to the triangulation
  //
  int i;
  COORD_TYPE prevX = 0,prevY = 0;
  TRIANGLE *t1,*t2, *s, *sp;
  s = tt->t;
  sp = tt->t->p1p3;

  if(tt->left != NULL){
    // The first & last point in this array are corner points for this
    // tile so we ignore them
 
    for(i = 1; i < tt->left->rPointsCount-1; i++){
      assert(s && tt->pq && tt->left->rPoints[i]);
      assert(prevX <=  tt->left->rPoints[i]->x &&
	     prevY <=  tt->left->rPoints[i]->y);
      assert(tt->left->rPoints[i] != tt->nw &&
	     tt->left->rPoints[i] != tt->ne &&
	     tt->left->rPoints[i] != tt->sw &&
	     tt->left->rPoints[i] != tt->se);
      
      // add 2 tris in s
      t1 = addTri(tt, s->p1, tt->left->rPoints[i], s->p3,
		  NULL,whichTri(s,s->p1,s->p3,tt),NULL);
      assert(t1);
      t2 = addTri(tt, tt->left->rPoints[i], s->p2, s->p3,
		  NULL,t1,whichTri(s,s->p2,s->p3,tt));
      assert(t2);
      // Verify that t1 and t2 are really inside s
      triangleCheck(s,t1,t2,NULL);
      // Distribute points in the 2 triangles
      if(s->maxE != DONE){
	s->p1p2 = s->p1p3 = s->p2p3 = NULL;
	distrPoints(t1,t2,NULL,s,NULL,e,tt);
	//Mark triangle s for deletion from pq before distrpoints so we
	//can include its maxE in the newly created triangle
	
	PQ_delete(tt->pq,s->pqIndex);
      }
      else{
	// Since distrpoints normally fixes corner we need to do it here
	if(s == tt->t){
	  updateTinTileCorner(tt,t1,t2,NULL);
	}
	t1->maxE = t2->maxE = DONE;
	t1->points = t2->points = NULL;
      }
      
      
      removeTri(s);
      tt->numTris++;
      tt->numPoints++;
      // Now split the next lowest boundary triangle
      s = t2;
      
      // Should we enforce Delaunay here?

      prevX = tt->left->rPoints[i]->x;
      prevY = tt->left->rPoints[i]->y;
    }
    
  }
  
  if(tt->top != NULL){
    // The first & last point in this array are corner points for this
    // tile so we ignore them
    s = sp;
    prevX = prevY = 0;
    for(i = 1; i < tt->top->bPointsCount-1; i++){
      assert(s && tt->pq && tt->top->bPoints[i]);
      assert(prevX <=  tt->top->bPoints[i]->x &&
	     prevY <=  tt->top->bPoints[i]->y);
      
      // add 2 tris in s
      t1 = addTri(tt, s->p1, tt->top->bPoints[i], s->p3,
		  NULL,whichTri(s,s->p1,s->p3,tt),NULL);
      assert(t1);
      t2 = addTri(tt, tt->top->bPoints[i], s->p2, s->p3,
		  NULL,t1,whichTri(s,s->p2,s->p3,tt));
      assert(t2);
      // Verify that t1 and t2 are really inside s
      triangleCheck(s,t1,t2,NULL);
      // Distribute points in the 2 triangles
      if(s->maxE != DONE){
	distrPoints(t1,t2,NULL,s,NULL,e,tt);
	//Mark triangle sp for deletion from pq before distrpoints so we
	//can include its maxE in the newly created triangle
	s->p1p2 = s->p1p3 = s->p2p3 = NULL;
	PQ_delete(tt->pq,s->pqIndex);

      }
      else{
	// Since distrpoints normally fixes corner we need to do it here
	if(s == tt->t){
	  updateTinTileCorner(tt,t1,t2,NULL);
	}
	t1->maxE = t2->maxE = DONE;
	t1->points = t2->points = NULL;
      }
      
      
      removeTri(s);
      tt->numTris++;
      tt->numPoints++;
      // Now split the next lowest boundary triangle
      s = t2;
      
      // Should we enforce Delaunay here?
      
      prevX = tt->top->bPoints[i]->x;
      prevY = tt->top->bPoints[i]->y;
    }
    
  }
  return tt;
}