void init_proxy() {
		
		 steque_init(&fldes_queue);
		
		// create segment

		
		for (int i = 0; i < segments; i++) {
			
			char str_id[16] = "";

			sprintf(str_id, "%d", i);
			segment_id = (char*) malloc((strlen(str_id) + strlen(SHAREDMPATH) + 1) * sizeof(char));
			bzero(segment_id, (strlen(str_id) + strlen(SHAREDMPATH) + 1) * sizeof(char));
			strcpy(segment_id, SHAREDMPATH);
			strcat(segment_id, str_id);

			shm_unlink(segment_id);
			fprintf(stdout, "Created Segment ID: %s\n", segment_id);
			fflush(stdout);
			steque_enqueue(&fldes_queue, segment_id);
		}
	
		fldes_queue_size = steque_size(&fldes_queue);
        max_fldes_queue_size = steque_size(&fldes_queue);
//		fprintf(stdout, "init queue done.\n");

}
Exemple #2
0
/*
 The gtthread_exit() function is analogous to pthread_exit.
*/
void gtthread_exit(void* retval) {
  sigprocmask(SIG_BLOCK, &vtalrm, NULL);
  gtthread_t *thread = steque_front(&g_threads_steque);
  thread->is_finished = 1;
  
  if(retval != NULL)
    thread->retval = retval;
  
  /* If this was the last thread in the queue, clean up and exit */
  if(steque_size(&g_threads_steque) == 1) {
    gtthread_t *dead_thread;
    int num = steque_size(&g_dead_threads_steque);

    while(num > 0) {
      dead_thread = steque_front(&g_dead_threads_steque);
      if(dead_thread->context && dead_thread->context->uc_stack.ss_sp)
        free(dead_thread->context->uc_stack.ss_sp);
      if(dead_thread->context)
        free(dead_thread->context);
      if(dead_thread->id == 0)
        free(dead_thread);

      if(steque_size(&g_dead_threads_steque) > 1)
        steque_cycle(&g_dead_threads_steque);
      num--;
    }
	
    if(thread->context)
      free(thread->context); 

    // Main thread was the only one that was dynamically allocated.
    if(thread->id == 0)
      free(thread);

    steque_destroy(&g_threads_steque);
    steque_destroy(&g_dead_threads_steque);
    steque_destroy(&g_cancelatorium);
    steque_destroy(&g_join_steque);


    /*
    So apparently we can't free the stack of the thread that is running.
    */
    // if(thread->context && thread->context->uc_stack.ss_sp)
      //  free(thread->context->uc_stack.ss_sp);
    exit(0);
    }
  
  sigprocmask(SIG_UNBLOCK, &vtalrm, NULL);
  alarm_safe_yield();
}
gtthread_blk_t *get_thread(gtthread_t tID){

  int queue_len, i;
  gtthread_blk_t *tmp, *ret;
  int match = 0;

  DEBUG_MSG("get_thread, tID: %ld\n", tID);

  queue_len = steque_size(&thread_queue);
  
  for(i = 0; i < queue_len; i++){

    tmp = (gtthread_blk_t *)steque_pop(&thread_queue);
    steque_enqueue(&thread_queue, tmp);

    if(tmp->tID == tID){
      ret = tmp;
      match = 1;
    } 

  }

  if(!match)
    DEBUG_MSG("No Match!\n");

  return ret;

}
Exemple #4
0
/**
 * Cycles through the join_steque to update the waiting status of any threads that may
 * be waiting on a thread to join. 
 */
static void joininator(gtthread_t *joinee) {
  int i;
  for(i=0; i<steque_size(&g_join_steque); i++) {
    gtthread_t *curr = steque_front(&g_join_steque);
    
    if(curr->wait_tid == joinee->id) {
      curr->is_joined = 1;
      curr->joinee = joinee;
    }
    
    steque_cycle(&g_join_steque);
  }
}
Exemple #5
0
/* Find a thread by its id */
static gtthread_int_t * find_thread(gtthread_t thread) {
  int queue_len;
  int i;
  gtthread_int_t *item;

  queue_len = steque_size(&threads);

  for (i = 0; i < queue_len; i++) {
    item = (gtthread_int_t *) steque_pop(&threads);
    steque_enqueue(&threads, item);
    if (item->id == thread) {
      return item;
    }
  }

  return NULL;
}
Exemple #6
0
void print_run_queue(void) {
  int queue_len;
  int i;
  gtthread_int_t *item;

  queue_len = steque_size(&run_queue);

  for (i = 0; i < queue_len; i++) {
    item = (gtthread_int_t *) steque_pop(&run_queue);
    steque_enqueue(&run_queue, item);
    printf("%d->", (int) item->id);
    fflush(stdout);
  }

  printf("\n");
  fflush(stdout);
}
void list_thread(){

  int queue_len, i;
  gtthread_blk_t *tmp; 

  DEBUG_MSG("----------------------------------------------\n");

  queue_len = steque_size(&thread_queue);
  
  for(i = 0; i < queue_len; i++){

    tmp = (gtthread_blk_t *)steque_pop(&thread_queue);

    DEBUG_MSG("tmp->tID: %ld, state: %d, context: %x\n", tmp->tID, tmp->state, &tmp->uctx);

    steque_enqueue(&thread_queue, tmp);

  }
  DEBUG_MSG("----------------------------------------------\n");

}
Exemple #8
0
/* to find thread with threadId in the globalQ */
gtthread* getThread(gtthread_t threadId)
{
  int size = steque_size(&globalQ);
  int i = 0;
  gtthread *temp, *returnThread;

  returnThread = NULL;
 /* Get front of queue in temp, compare id
    Do this till you find a match, save it in returnThread and continue loop to restore
    original order  */
  while(i < size)
  {
	temp = (gtthread *) steque_front(&globalQ);
	if(temp -> id == threadId)
	{
		returnThread = temp;
	}
	steque_cycle(&globalQ);
	i++;
  }

  return returnThread;
}
Exemple #9
0
/**
 * Helper function for yield.
 */
static void yield_helper(int is_alarm_safe) {
  if(is_alarm_safe)
    sigprocmask(SIG_BLOCK, &vtalrm, NULL);
  
  // Don't need to do anything if there's just one thread in the queue.
  if(steque_size(&g_threads_steque) == 1)
    return;
  
  gtthread_t *old_thread = steque_pop(&g_threads_steque);
  gtthread_t *new_thread = NULL;
  
  /* Find an eligible new thread - i.e., a thread that isn't queued for cancelation. */
  if(!is_alarm_safe)
    sigprocmask(SIG_BLOCK, &vtalrm, NULL);
  
  while(steque_size(&g_threads_steque) > 0) {
    new_thread = steque_front(&g_threads_steque);
    
    /* Cancels threads when it's their turn to run */
    int i;
    int canceled=0;
    for(i=0; i < steque_size(&g_cancelatorium); i++) {
      if((long) steque_front(&g_cancelatorium) == new_thread->id) {
        new_thread->is_finished = 1;
        new_thread->retval = (void *) -1;
        steque_pop(&g_cancelatorium);
        steque_pop(&g_threads_steque);
        steque_enqueue(&g_dead_threads_steque, new_thread);
        
        canceled=1;

        joininator(new_thread); // Attempt to join the thread you just canceled.
        break;
      }
      if(steque_size(&g_cancelatorium) > 0)
        steque_cycle(&g_cancelatorium);
    }
    
    if(!canceled)
      break;
  }
  
  /* If the thread that yielded finsihed executing, put it in the finished steque. */
  if(old_thread->is_finished) {
    steque_enqueue(&g_dead_threads_steque, old_thread);
    joininator(old_thread);
  } else {
    steque_enqueue(&g_threads_steque, old_thread);
  }
  
  if(!is_alarm_safe)
    sigprocmask(SIG_UNBLOCK, &vtalrm, NULL);
  
  // All threads have finished running. Is this necessary?
  if(steque_size(&g_threads_steque) == 0)
    exit(0);
  
  // Don't context switch if the original thread is the only one left in the queue.
  if(gtthread_equal(*((gtthread_t *) steque_front(&g_threads_steque)), *old_thread))
    return;
  
  if(is_alarm_safe) {
    T.it_value.tv_usec = global_period; // Reset timer so that the next period can start immediately.
    sigprocmask(SIG_UNBLOCK, &vtalrm, NULL);
  }
  
  swapcontext(old_thread->context, new_thread->context);
}
Exemple #10
0
/*
 The gtthread_join() function is analogous to pthread_join.
 All gtthreads are joinable.
*/
int gtthread_join(gtthread_t thread, void **status) {
  sigprocmask(SIG_BLOCK, &vtalrm, NULL);
  gtthread_t *self = steque_front(&g_threads_steque);
  sigprocmask(SIG_UNBLOCK, &vtalrm, NULL);
  
  /* The range [0, g_thread_id) indicates the range of thread ids that have ever belonged to valid threads.
  Also can't join with self. */
  if(thread.id >= g_thread_id || thread.id == self->id)
    return 1;
  
  sigprocmask(SIG_BLOCK, &vtalrm, NULL);
  self->is_joined = 0;
  self->wait_tid = thread.id;
  sigprocmask(SIG_BLOCK, &vtalrm, NULL);
  int found_among_dead = 0;
  
  /* First look for joinee among threads that have already terminated. */
  int i;
  for(i=0; i<steque_size(&g_dead_threads_steque); i++) {
    sigprocmask(SIG_BLOCK, &vtalrm, NULL);
    gtthread_t *curr = steque_front(&g_dead_threads_steque);
    sigprocmask(SIG_UNBLOCK, &vtalrm, NULL);
    
    if(curr->id == self->wait_tid) {
      found_among_dead = 1;
      sigprocmask(SIG_BLOCK, &vtalrm, NULL);
      self->joinee = curr;
      self->is_joined = 1;
      sigprocmask(SIG_UNBLOCK, &vtalrm, NULL);
      break;
    }
    
    sigprocmask(SIG_BLOCK, &vtalrm, NULL);
    steque_cycle(&g_dead_threads_steque);
    sigprocmask(SIG_UNBLOCK, &vtalrm, NULL);
  }
  
  /* If we haven't found it, wait until it terminates. */
  if(!found_among_dead) {
    // First check to see that the thread I am waiting on is not already waiting on me.
    for(i=0; i<steque_size(&g_join_steque); i++) {
      sigprocmask(SIG_BLOCK, &vtalrm, NULL);
      gtthread_t *curr = steque_front(&g_join_steque);
      sigprocmask(SIG_UNBLOCK, &vtalrm, NULL);
      
      if(curr->wait_tid == self->id && curr->id == self->wait_tid) {
        sigprocmask(SIG_BLOCK, &vtalrm, NULL);
        self->is_joined = -1;
        self->wait_tid = -1L;
        sigprocmask(SIG_UNBLOCK, &vtalrm, NULL);
        return 1;
      }
      sigprocmask(SIG_BLOCK, &vtalrm, NULL);
      steque_cycle(&g_join_steque);
      sigprocmask(SIG_UNBLOCK, &vtalrm, NULL);
    }
    
    // If joinee isn't already waiting on me, enqueue myself in the join queue...
    sigprocmask(SIG_BLOCK, &vtalrm, NULL);
    steque_enqueue(&g_join_steque, self);
    sigprocmask(SIG_UNBLOCK, &vtalrm, NULL);
    
    // ... and wait until joinee terminates.
    while(!self->is_joined)
    alarm_safe_yield();
  }
  
  if(status)
    *status = self->joinee->retval;
  
  sigprocmask(SIG_BLOCK, &vtalrm, NULL);
  self->joinee = NULL;
  self->wait_tid = -1L;
  self->is_joined = -1;
  sigprocmask(SIG_UNBLOCK, &vtalrm, NULL);
  
  /* Remove yourself from the join steque, if you put yourself there. */
  if(!found_among_dead) {
    for(i=0; i<steque_size(&g_join_steque); i++) {
      sigprocmask(SIG_BLOCK, &vtalrm, NULL);
      gtthread_t *curr = steque_front(&g_join_steque);
      sigprocmask(SIG_UNBLOCK, &vtalrm, NULL);
      
      if(gtthread_equal(*self, *curr)) {
        steque_pop(&g_join_steque);
        break;
      }
      if(steque_size(&g_join_steque) > 0) {
        sigprocmask(SIG_BLOCK, &vtalrm, NULL);
        steque_cycle(&g_join_steque);
        sigprocmask(SIG_UNBLOCK, &vtalrm, NULL);
      }
    }
  }
  
  return 0;
}