Beispiel #1
0
int main()
{
    int ndx, odx;
    void* status = (void*)100;
    printf("test thread create, cancel, join\n");
    printf("main: enter\n");
    gtthread_init(period);
    gtthread_yield();
    for(odx=0; odx<10; ++odx) {
        //gtthread_create( &t[odx], thrX, (void*)odx);
        //gtthread_create( &t[odx], thrR, (void*)odx);
        gtthread_create( &t[odx], thrY, (void*)odx);
    }
    gtthread_yield();
    for(ndx=0; ndx<20; ++ndx) {
            usleep(100*1000);
            puts(">");
            gtthread_yield();
    }
    for(odx=0; odx<10; ++odx) {
        gtthread_join( t[odx], &status);
        printf("thread %d return %d\n",odx,(long)status);
    }
    printf("main: exit\n");
    fflush(stdout);
    return EXIT_SUCCESS;
}
Beispiel #2
0
int main() {
	gtthread_t t1, t2, t3, t4, t5;

	gtthread_init(1000);
	gtthread_mutex_init(&gttm);

	gtthread_create(&t1, func1, (void*) 1);
	gtthread_create(&t2, func1, (void*) 2);
	gtthread_join(t1, NULL);
	gtthread_join(t2, NULL);

	gtthread_mutex_lock(&gttm);
	gtthread_create(&t3, func2, (void*) 3);
	gtthread_create(&t4, func2, (void*) 4);
	printf("This should print before threads 3 and 4 finish\n");
	gtthread_mutex_unlock(&gttm);
	gtthread_join(t3, NULL);
	gtthread_join(t4, NULL);

	printf("Testing yield with one schedulable thread... ");
	gtthread_yield();
	gtthread_yield();
	gtthread_yield();
	printf("done!\n");

	printf("Deadlocking with thread 5...\n");
	gtthread_mutex_lock(&gttm);
	gtthread_create(&t5, func3, NULL);
	gtthread_join(t5, NULL);
	gtthread_mutex_unlock(&gttm);
	printf("!!! ERROR !!! Failed to deadlock with thread 5\n");

	return 0;
}
Beispiel #3
0
int main()
{
    int ndx, tdx;
    void* status = (void*)100;
    int result;
    printf("test thread create N, join N\n");
    printf("main: enter\n");
    gtthread_init(period);
    gtthread_yield();
    for(tdx=0; tdx<1000; ++tdx) {
        gtthread_create( &t[tdx], thrX, (void*)tdx);
        //gtthread_create( &t[tdx], thrR, (void*)tdx);
        //gtthread_create( &t[tdx], thrY, (void*)tdx);
    }
    puts(">");
    gtthread_yield();
    for(tdx=0; tdx<1000; ++tdx) {
        result = gtthread_join( t[tdx], &status);
        if(result) printf("main.join %d\n",result);
        printf("thread %d return %d\n",tdx,(long)status);
    }
    printf("main: exit\n");
    fflush(stdout);
    return EXIT_SUCCESS;
}
Beispiel #4
0
void *philosopher(void *arg){
	short i;
	gtthread_mutex_t f1,f2;
	switch((int)arg){
		case 1: f1=m5; f2=m1;break;
		case 2: f1=m2; f2=m1;break;
		case 3: f1=m3; f2=m2;break;
		case 4: f1=m4; f2=m3;break;
		case 5: f1=m5; f2=m4;break;
	}
	while(1){
		printf("Philosopher #%d tries to acquire fork %lu\n",(int)arg,f1);
		gtthread_mutex_lock(&f1);
		printf("Philosopher #%d tries to acquire fork %lu\n",(int)arg,f2);
		gtthread_mutex_lock(&f2);
		printf("Philosopher #%d eating with fork %lu and %lu\n",(int)arg,f1,f2);
		gtthread_yield();
		i=rand()%9999;
		while(--i>0);
		printf("Philosopher #%d releasing fork %lu\n",(int)arg,f2);
		gtthread_mutex_unlock(&f2);
		printf("Philosopher #%d releasing fork %lu\n",(int)arg,f1);
		gtthread_mutex_unlock(&f1);
		printf("Philosopher #%d thinking\n",(int)arg);
		gtthread_yield();
		i=rand()%9999;
		while(--i>0);
	}
}
Beispiel #5
0
void *func1(void *arg) {
	gtthread_t *gtt = (gtthread_t*) arg;
	gtthread_yield(); // ensure that the global is set first
	gtthread_yield();
	gtthread_yield();
	int res = gtthread_equal(g_gtt, *gtt);
	printf("First test is equal:      %s\n", res ? "correct" : "incorrect");
	return NULL;
}
Beispiel #6
0
void *func2(void *arg) {
	gtt_tuple *tuple = (gtt_tuple*) arg;
	gtthread_yield(); // ensure that the tuple is set first
	gtthread_yield();
	gtthread_yield();
	int res = gtthread_equal(tuple->gtt1, tuple->gtt2);
	printf("Second test is not equal: %s\n", !res ? "correct" : "incorrect");
	return NULL;
}
Beispiel #7
0
void *func3(void *arg) {
	gtthread_t gtt = gtthread_self();
	gtthread_yield(); // ensure that the global is set first
	gtthread_yield();
	gtthread_yield();
	int res = gtthread_equal(g_gtt, gtt);
	printf("Third test is equal:      %s\n", res ? "correct" : "incorrect");
	gtthread_t *ret = malloc(sizeof(gtt));
	memcpy(ret, &gtt, sizeof(gtt));
	return ret;
}
int gtthread_join(gtthread_t thread, void **status){
  int i = 0;
  steque_node_t* current;
  //TODO: No need to block and unblock signals?
  if (gtthread_equal(thread, gtthread_self())){
    printf("cannot join same thread\n");
    return -1;
  }

  //Searching for node with gtthread_t thread
  current = q->front;
  for (i = 0; (i < q->N); i++) {
    if(gtthread_equal(thread, ((node_t*)current -> item) -> id)) {
      break;
    }
    current = current -> next;
  }

  //Checking for canceled thread, blocking otherwise
  while (1){
    if (((node_t*)current -> item) -> canceled == 1){
      if(status != NULL){
        *status = ((node_t*)current -> item) -> returns;
      }
      break;
    }
    gtthread_yield();
  }     

  return 0;
}
/*
  The gtthread_join() function is analogous to pthread_join.
  All gtthreads are joinable.
 */
int gtthread_join(gtthread_t thread, void **status){

  gtthread_blk_t *join;

  DEBUG_MSG("gtthread_join\n"); 

  sigprocmask(SIG_BLOCK, &vtalrm, NULL);                        // disable alarm signal
  join = get_thread(thread);
  sigprocmask(SIG_UNBLOCK, &vtalrm, NULL);                      // enable alarm signal

  if(join == NULL)
    return FAIL;

  while(join->state != TERMINATED){
    DEBUG_MSG("Thread # %ld join: not TERMINATED!\n", join->tID); 
    gtthread_yield();
  }

  DEBUG_MSG("Thread # %ld join: TERMINATED!\n", join->tID); 
  //sigprocmask(SIG_BLOCK, &vtalrm, NULL);                        // disable alarm signal

  join->state = JOINED;
  if (status != NULL)
    *status = join->retval;

  //sigprocmask(SIG_UNBLOCK, &vtalrm, NULL);                        // enable alarm signal

  return SUCCESS;

}
Beispiel #10
0
void *thr3(void *in) {
  int i, j = 0;
  void *ret;
  gtthread_t t4;

  printf("thr3 started with parameter %d\n", (int) in);
  fflush(stdout);

  gtthread_create(&t4, thr4, (void *) 4);

  for (i = 0; i < LOOP_MAX; i++) { 
    printf("thr3!\n");
    fflush(stdout);
    j++;

    if (i % YIELD_VAL == 0) {
      gtthread_yield();
    }

  }

  gtthread_join(t4, &ret);
  printf("thr4 joined thr3 with value %d!\n", (int) ret);
  fflush(stdout);

  printf("thr3 finished with parameter %d\n", (int) in);
  fflush(stdout);

  return (void *) j + 3;
}
Beispiel #11
0
void *thr2(void *in) {
  int i, j = 0;
  void *ret;
  gtthread_t t5;

  printf("thr2 started with parameter %d\n", (int) in);
  fflush(stdout);

  gtthread_create(&t5, thr5, NULL);

  for (i = 0; i < (LOOP_MAX + (LOOP_MAX / 2)); i++) { 
    printf("thr2!\n");
    fflush(stdout);
    j++;
    if (i % YIELD_VAL == 0) {
      gtthread_yield();
    }
  }

  gtthread_join(t5, NULL);
  printf("thr5 joined thr2 with value %d!\n", (int) ret);
  fflush(stdout);

  printf("thr2 finished with parameter %d\n", (int) in);
  fflush(stdout);

  return (void *) j + 2;
}
Beispiel #12
0
void *thr4(void *in) {
  int i, j = 0;

  printf("thr4 started with parameter %d\n", (int) in);
  fflush(stdout);

  for (i = 0; i < LOOP_MAX; i++) { 
    printf("thr4!\n");
    fflush(stdout);
    j++;

    gtthread_mutex_lock(&count_lock);
    count++;
    gtthread_mutex_unlock(&count_lock);

    if (i % YIELD_VAL == 0) {
      gtthread_yield();
    }
  }

  printf("thr4 finished with parameter %d\n", (int) in);
  fflush(stdout);

  return (void *) j + 4;
}
Beispiel #13
0
void *func1(void *arg) {
	long x = (long) arg;
	for(int i = 5; i; --i) {
		gtthread_yield();
		printf("Message from thr%ld\n", x);
	}
	return NULL;
}
/* see man pthread_join(3) */
int  gtthread_join(gtthread_t thread, void **status){
	gtid_t thread_id;
	dlink_t* temp_dlink;

	thread_id = thread.threadid;
	BlockSignals();
	temp_dlink = FindNode(schedule_queue,thread_id);
	if(temp_dlink == NULL){
		return -1;
	}
	else if(temp_dlink == schedule_queue->begin)
	{
		while(schedule_queue->main_exited==0){
			UnblockSignals();
			gtthread_yield();
			BlockSignals();
		}
		if(temp_dlink->thread_block->cancelled==1){
					*status = (void*)(int)-1;
		}
		else if(status!=NULL){
			*status = temp_dlink->thread_block->returnval;
		}
		UnblockSignals();
		return 0;
	}
	else{

		while(!(temp_dlink->thread_block->exited || temp_dlink->thread_block->finished|| temp_dlink->thread_block->cancelled)){
			UnblockSignals();
			gtthread_yield();
			BlockSignals();
		}
		if(temp_dlink->thread_block->cancelled==1){
			if(status!=NULL){
				*status = (void*)(int)-1;
			}
		}
		else if(status!=NULL){
			*status = temp_dlink->thread_block->returnval;
		}
		UnblockSignals();
		return 0;
	}
}
Beispiel #15
0
int main() {
  int i;
  gtthread_t t1, t2, t3, t6;
  void *ret;

  gtthread_mutex_init(&count_lock);

  gtthread_init(5);
  gtthread_create(&t1, thr1, (void *) 1);
  gtthread_create(&t2, thr2, (void *) 2);
  gtthread_create(&t3, thr3, (void *) 3);
  gtthread_create(&t6, thr6, (void *) 6);

  for (i = 0; i < LOOP_MAX; i++) {
    printf("Main thread!\n");
    fflush(stdout);

    gtthread_mutex_lock(&count_lock);
    count++;
    gtthread_mutex_unlock(&count_lock);

    if (i % YIELD_VAL == 0) {
      gtthread_yield();
    }
  }

  printf("main waiting for thr1...\n");
  fflush(stdout);
  gtthread_join(t1, &ret);
  printf("thr1 joined main with value %d!\n", (int) ret);
  fflush(stdout);

  gtthread_cancel(t2);
  printf("thr2 cancelled!\n");
  fflush(stdout);

  printf("main waiting for thr3...\n");
  fflush(stdout);
  gtthread_join(t3, &ret);
  printf("thr3 joined main with value %d!\n", (int) ret);
  fflush(stdout);

  printf("main waiting for thr6...\n");
  fflush(stdout);
  gtthread_join(t6, &ret);
  printf("thr6 joined main with value %d!\n", (int) ret);
  fflush(stdout);

  gtthread_mutex_lock(&count_lock);
  printf("Final count value: %lu\n", count);
  fflush(stdout);
  gtthread_mutex_unlock(&count_lock);

  gtthread_mutex_destroy(&count_lock);
  return EXIT_SUCCESS;
}
Beispiel #16
0
void *thrX(void *in)
{
    int ndx;
    int th = (int)(long)in;
    int dur = (int)hold[th];
    printf("thrX: enter\n"); fflush(stdout);
    for(ndx=0; ndx<10; ++ndx) {
        gtthread_mutex_lock(&m[0]);
printf("thrX: lock %d\n",th); fflush(stdout);
        gtthread_yield();
        usleep(dur*1000);
printf("thrX: unlock %d\n",th); fflush(stdout);
        gtthread_mutex_unlock(&m[0]);
        gtthread_yield();
    }
    printf("thrX: exit\n"); fflush(stdout);
    gtthread_exit(in);
    return in;
}
Beispiel #17
0
void *thrH(void *in)
{
    int ndx;
    int th = (int)in;
    int dur = (int)hold[th];
    gtthread_mutex_t* mtx = m[0];
    printf("thrH: enter\n"); fflush(stdout);
    for(ndx=0; ndx<10; ++ndx) {
        gtthread_mutex_lock(mutex);
printf("thrH: lock %d\n",th); fflush(stdout);
        gtthread_yield();
        usleep(dur*1000);
        gtthread_yield();
printf("thrH: unlock %d\n",th); fflush(stdout);
        gtthread_mutex_unlock(mutex);
        gtthread_yield();
    }
    printf("thrH: exit\n"); fflush(stdout);
    return in;
}
Beispiel #18
0
void *thrY(void *in)
{
    int ndx;
    printf("thrY: enter\n"); fflush(stdout);
    for(ndx=0; ndx<5; ++ndx) {
        usleep(10*1000);
        puts("Y");
        gtthread_yield();
    }
    printf("thrY: exit\n"); fflush(stdout);
    return in;
}
Beispiel #19
0
void* thr2(void *in) {
  gtthread_mutex_lock(&g_mutex);
  gtthread_mutex_unlock(&g_mutex);
  int k = 0;
  for (k = 0; k < 5; ++k) {
    gtthread_mutex_lock(&g_mutex);
    printf("thr2 hello\n");
    gtthread_mutex_unlock(&g_mutex);
    gtthread_yield();
  }
  return NULL;
}
Beispiel #20
0
void *thrR(void *in)
{
    int ndx;
    printf("thrR: enter\n"); fflush(stdout);
    ++steps[(long)in];
    for(ndx=0; ndx<10; ++ndx) {
        usleep(100*1000);
        puts("R");
        gtthread_yield();
    }
    printf("thrR: exit\n"); fflush(stdout);
    return in;
}
Beispiel #21
0
void* worker(void* arg)
{
	int i;

	gtthread_mutex_lock(&g_mutex);
	for(i=0; i < 3; i++)
	{
		printf("thread %ld\n", (long)arg);
		gtthread_yield();
	}
	gtthread_mutex_unlock(&g_mutex);
        return NULL;
}
/*
  The gtthread_create() function mirrors the pthread_create() function,
  only default attributes are always assumed.
 */
int gtthread_create(gtthread_t *thread,
        void *(*start_routine)(void *),
        void *arg){

  ucontext_t uctx;
  gtthread_blk_t *th_blk;

  DEBUG_MSG("gtthread_create\n"); 

  //sigprocmask(SIG_BLOCK, &vtalrm, NULL);                          // disable alarm signal

  /************************* Initialize the context *************************************/


  if(getcontext(&uctx) == -1) 
    return FAIL;

  uctx.uc_stack.ss_sp = (char*) malloc(SIGSTKSZ);
  uctx.uc_stack.ss_size = SIGSTKSZ;
  uctx.uc_link = NULL;

  makecontext(&uctx, (void (*) (void))(thread_handler), 2, start_routine, arg);      // modify the context 


  /************************** Initialize the thread block *************************************/

  th_blk = (gtthread_blk_t *)malloc(sizeof(gtthread_blk_t));
  if(th_blk == NULL)
    return FAIL;

  th_blk->tID = thread_ID++;
  th_blk->state = READY;
  th_blk->uctx = uctx;

  if(th_blk->uctx.uc_stack.ss_size == SIGSTKSZ)
    DEBUG_MSG("Correct assign\n"); 

  /********************************************************************************************/

  steque_enqueue(&thread_queue, th_blk);                          // add the thread to the scheduler queue

  //sigprocmask(SIG_UNBLOCK, &vtalrm, NULL);                        // enable alarm signal

  *thread = th_blk->tID;

  //list_thread();
  gtthread_yield();

  return SUCCESS;
}
Beispiel #23
0
void *thr5(void *in) {
  int i, j = 0;

  for (i = 0; i < LOOP_MAX; i++) { 
    printf("thr5!\n");
    fflush(stdout);
    j++;

    if (i % YIELD_VAL == 0) {
      gtthread_yield();
    }
  }

  return (void *) 5;
}
Beispiel #24
0
int main() {
    printf("test6b. Should print 'main hello' then 'thr1 hello' and 'thr2 hello' for 5 times interleaving (but no mixed up prints e.g. 'th1 thr2 hello hello')\n");

    gtthread_init(50000L);
    gtthread_mutex_init(&g_mutex);
    gtthread_mutex_lock(&g_mutex);

    gtthread_create( &t1, thr1, NULL);
    gtthread_create( &t2, thr2, NULL);
    gtthread_yield();
    printf("main hello\n");
    gtthread_mutex_unlock(&g_mutex);
    gtthread_join(t2, NULL);
    gtthread_join(t1, NULL);
    return EXIT_SUCCESS;
}
Beispiel #25
0
void *func2(void *arg) {
	long x = (long) arg;
	volatile int y;
	for(int i = 5; i; --i) {
		gtthread_mutex_lock(&gttm);
		gtthread_yield();
		char *dst = buffer, *src = "\tThis is a locked message from thread ";
		while((*dst++ = *src++)) {
			y = 5000000;
			while(--y);
		}
		printf("%s%ld\n", buffer, x);
		memset(buffer, ' ', 50);
		gtthread_mutex_unlock(&gttm);
	}
	return NULL;
}
/*
  The gtthread_exit() function is analogous to pthread_exit.
 */
void gtthread_exit(void* retval){

  gtthread_blk_t *term;

  DEBUG_MSG("gtthread_exit\n");

  sigprocmask(SIG_BLOCK, &vtalrm, NULL);                        // disable alarm signal

  term = (gtthread_blk_t *)steque_front(&thread_queue);
  if(term->state != RUNNING)
  {
    DEBUG_MSG("ERROR state when gtthread_exit: term->state != RUNNING\n");
    return;
  }

  term->state = TERMINATED;
  term->retval = retval;

  sigprocmask(SIG_UNBLOCK, &vtalrm, NULL);                        // enable alarm signal
  gtthread_yield();

}
int gtthread_mutex_lock(gtthread_mutex_t *mutex){
	
	blockTimer();
	
	// Possibly reentrant lock
	if(mutex->mutex_owner == current_context->thread_id && mutex->mutex_lock==1){
		unblockTimer();
		return 0;
	}

	// Wait till the lock is free 
	while(mutex->mutex_lock == 1 && mutex->mutex_owner != current_context->thread_id){
		unblockTimer();
		gtthread_yield();
		blockTimer();
	};
	mutex->mutex_lock = 1;
	mutex->mutex_owner = current_context->thread_id;

	unblockTimer();
	return 0;
}