void *hello(void *t)
{
    ///int *reps = (int*)t;
    int i = 0;

    // initialize thread specific data for each thread
    int* id = (int*)malloc(sizeof(int));
    assert(id);
    *id = mythread_self();
    mythread_setspecific(id_key, id);

    //set name
    char* name = (char*)malloc(sizeof(char)*MAX_NAME_LENGTH);
    assert(name);
    memset(name, '\0', MAX_NAME_LENGTH);
    sprintf(name, "worker-%d", mythread_self()); 
    mythread_setspecific(name_key,name);

    // user specific data 
    for (; i < mythread_self(); i++) {
	printf("Thread-%d:Hello thread:%d\n", mythread_self(), i);
	sleep(1);
	mythread_yield();
    }
    printf("Thread specific data for %d thread is %d and worker name is %s\n", mythread_self(), *((int *)mythread_getspecific(id_key)), (char*)mythread_getspecific(name_key));
    return NULL;
}
void *thread_function(void *arg)
{
	int rc, i;
	mythread_t thread,childthread ;
	struct threadValues *value;
	value = (struct threadValues *)arg;
        thread=mythread_self();
        printf("This is thread %d before yielding\n",thread.tid);

	for(i=0; i < MAX_KEYS; i++)
	{
		printf("\nSettig values %d %d for key %d by thread %d", value->v1, value->v2, i, thread.tid);
		rc = mythread_setspecific(keys[i], value);
		if(rc != 0)
		{
			printf("\nmythread_setspecific call error for thread = %d", keys[i]);
		}
	}
	rc=mythread_create(&childthread,NULL,&printingfunction,NULL);
	rc=mythread_yield();
	printf("this is thread %d after yield\n",thread.tid);
	//rc = mythread_yield();
   	getData();
	return NULL;
}
Esempio n. 3
0
int mythread_mutex_lock(mythread_mutex_t *mutex)
{
	int lockstatus;

	mythread_enter_kernel();
	mutex->noofwaitingthreads=mutex->noofwaitingthreads+1;
	mythread_leave_kernel();

	if(mutex->lockvariable==-1)// if the lock was already destroyed then return the error code
	{
		return 1; // error code
	}

	lockstatus=testandtestandset(&(mutex->lockvariable)); // a lockstatus of 0 denotes a successful acquiring of lock 
	
	while(lockstatus==1) // if the lock acquiring fails after 100 tries , then the thread is blocked and put in a queue until lock becomes available
	{
		mythread_enter_kernel();
		mutex->noofblockedthreads=mutex->noofblockedthreads+1;
		mythread_block((mutex->blocked_threads),0);// actual 0
		lockstatus=testandtestandset(&(mutex->lockvariable)); // thread that returns from the block state tries to acquire the lock again
	}

	mythread_enter_kernel();
	mutex->owner_thread=mythread_self();
	mythread_leave_kernel();
	return lockstatus;
}
Esempio n. 4
0
void *mythread_getspecific(mythread_key_t key)
{
	int i;
	struct list_node* start;
	mythread_t tcb;
	const void *value;
	for(i=0; i< tsd_key_counter; i++)
	{
		if(globalTSD[i].key == key)
		{
			start = globalTSD[i].ptr;
			tcb = mythread_self();
			value = search_lnode(start, tcb);
			if(value == NULL)
			{	
                                write(1,"\nmythread_getspecific - Thread specific data value is not associated with the key",82);
                                return NULL;
                        }
			//printf("\nmythread_getspecific - Thread specific data value found with this key - %d", ((mythread_t *) value)->tid);
			return ((void *)value);
		}
	}
	//if key not found in the global array
	write(1, "\nmythread_getspecific - key not found in the global array\n",60);
	return NULL;
}
Esempio n. 5
0
int mythread_leave_kernel(){
	
	mythread_t self = mythread_self();

repeat:	
	
		if(self->reschedule == 1){ 
			self->reschedule = 0;
			/* Reschedule here*/
			if(mythread_readyq()!=NULL && self->attr.attr == 0){
				/*The threads time is up and since there's some thread waiting in readyq, it needs to
				preempt itself */
				mythread_scheduler();
			}
			else{
				/*If  Ready queue is empty or time is not up, continue executing
				*/
				mythread_leave_kernel_nonpreemptive();
			}
		}
		else{
			mythread_leave_kernel_nonpreemptive();
		}
	/* Check again in case of a rescheduling since leaving kernel */
	if(self->reschedule == 1){
		mythread_enter_kernel();
		goto repeat;
	}
	return 0;
}
Esempio n. 6
0
void *barrierTest(void* arg){
  mythread_enter_kernel();
  printf("Going to sleep...%ld\n",mythread_self());
  mythread_leave_kernel();
  //sleep(5);
  mythread_barrier_wait(&mybarrier);
  mythread_enter_kernel();
  printf("Moving towards new barrier... %ld\n",mythread_self());
  mythread_leave_kernel();

  mythread_barrier_wait(&mybarrier);
  mythread_enter_kernel();
  printf("%ld exiting... %ld\n",mythread_self());
  mythread_leave_kernel();
  mythread_exit(NULL);
}
Esempio n. 7
0
int mythread_scheduler(){
	mythread_t self = mythread_self();
	/*Limiting number of priority queues to 10 */

	if(self->preemptions < 10){
		self->preemptions += 1;
	}
	self->attr.attr = pow(2,self->preemptions); /*Since preemptions = invocation -1  */
	mythread_block(mythread_readyq(),1);
	return 0;	
}
Esempio n. 8
0
void* thread_func(void *args) {
	int t = 0;
	char buf[10];

	mythread_t self = mythread_self();

	sprintf(buf, "%ld", (long) args);
	mythread_mutex_lock(&mutex);
	strcat(actualOutput, buf);
	mythread_mutex_unlock(&mutex);
}
void getData() {
        int i;
        mythread_t tcb;
        for(i=0; i < MAX_KEYS; i++)
        {
                struct threadValues *value = mythread_getspecific(keys[i]);
                printf("\nmythread_getspecific call for key = %d, values=%d %d\n", keys[i], value->v1, value->v2);
                if (value == NULL)
                        printf("\nmythread_setspecific call error for thread = %d", keys[i]);

                tcb = mythread_self();
        }
}
Esempio n. 10
0
/* Thread function */
void *thread_function ()
{
	int c = 0;
	while (1)
	{
		if (c < 3000)
		{
			if (c%2 == 0)
			{	
				int k = 1;
				while(k<100000) //While loops to simulate preemptions by making threads run for longer
					k++; 
					
				c++; 		// Each thread will update this variable
								
			}
			else
			{
				int k = 1;
				while(k<200000) //While loops to simulate preemptions by making threads run for longer
					k++;
				c++; 		
			}

			
		}
		else 
			break;
	
	}

	mythread_enter_kernel();
	printf("Thread with tid %ld has been pre-empted: %d times! \n", mythread_self(), mythread_self()->preemptions);
	mythread_leave_kernel_nonpreemptive();

}
Esempio n. 11
0
int mythread_setspecific(mythread_key_t key, const void *value)
{
        int i;
        lnode* start;
	lnode* new_lnode;
        int rc;
        mythread_t tcb;
	for(i=0; i < tsd_key_counter; i++)
        {
                if((globalTSD[i].key) == key)
                {
                        tcb = mythread_self();
			new_lnode = create_lnode(tcb, value);
                        if(globalTSD[i].ptr == NULL)
                        {
                                globalTSD[i].ptr = new_lnode;
				rc = 0;
                        }
                        else
                        {
                                start = globalTSD[i].ptr;
				/*passing tcb and value to check if a value already exists for this thread.
				*If it does, just change the value in that node and delete the new node
				*/
                                rc = append_lnode(start, new_lnode, /*key,*/ tcb, value);
                        }
                        if(rc == 0)
                        {
                                //printf("\nmythread_setspecific: value for this thread added successfully with key - %d\n",key);
                                return 0;
                        }
                        else if (rc == 1)
			{
				/*if the thread specific data value already existed,then it is updated to the new value*/
				printf("\nmythread_setspecific: value for this thread updated with key %d\n",key);
				return 0;
			}
			else
                        {
                                printf("\nmythread_setspecific - EINVAL: Invalid key. Failed to add with key %d\n",key);
                                return -1;
                        }
                }
        }
        write(1,"\nmythread_setspecific - EINVAL: Invalid key\n",45); 
        return -1;
}
Esempio n. 12
0
void myhandler(int signal){
	
	mythread_queue_t rq_head,temp, runq_head;
	rq_head = *mythread_readyq();
	runq_head = *mythread_runq();
	temp = runq_head;
	mythread_t self = mythread_self();

	/*Every thread will set its reschudle flag on receiving a signal*/
	self->reschedule = 1;
	
	if(rq_head != NULL){
		(self->attr.attr)--; 
		/*On every signal (SIGALRM/SIGUSR1) the attr which denotes its remaining quanta is decremented
		This happens only if there is atleast one thread in readyq. 
		*/
		mythread_enter_kernel();
		if(signal == SIGALRM){
			do{
				if(temp->item != self){
					syscall(SYS_tkill, ((mythread_t)(temp->item))->tid, SIGUSR1);
				}
				temp = temp ->next;
			}
			while(temp!=runq_head);
		}

		 
		/*Only one thread will enter the kernel and reschedule the remaining ones which did not enter the kernel. 
		 * While doing so, the thread will set the reschedule flag of these threads to 0
		 * We need to check this condition before letting the threads enter the scheduler via mythread_leave_kernel() 
		*/
		 
		if(self->reschedule == 0){
			mythread_leave_kernel_nonpreemptive();
		}
		else{
			
			mythread_leave_kernel();
		}
	}
	/*Ready queue is empty so let this thread continue running without any interruptions*/
	return;
}
/* Uses dispatcher to yeild the next Ready thread */
int mythread_yield()
{
	mythread_t *self_tcb =  queue_search_elementbyId(mythread_queue_globalVar, mythread_self().tid);

	/* Using yield_futex so that no other thread yields when one thread is yielding */
	futex_down(&yield_futex);

	if (__dispatch_thread(self_tcb) == -1) {
		futex_up(&yield_futex);
		return 0;
	}
	/* Release the yield futex */
	futex_up(&yield_futex);

	/* Sleep till another process wakes us up */
	futex_down(&self_tcb->futex);

	return 0;
}
Esempio n. 14
0
int mythread_mutex_lock (mythread_mutex_t *mutex)
{
  // if mutex is not poinitng to anything valid then return EINVAL
  if (!mutex)
    return EINVAL;

  if (mutex->value == -1)
    return EINVAL;


  int retry = 0;
  while (1)
  {
    mythread_enter_kernel();
    // check if lock is available for atmost 50 times
    while ((mutex->value == 1) && (retry < RETRY_MAX))
    {
       retry++;
    }

    // if we waited for 50 times and lock still not avaialable then break from he loop and block the current thread.
    if (retry == RETRY_MAX)
    {
      break;
    }
    
    // if lock is avaialable, grab it atomically using compare and swap function  
    if (compare_and_swap (&mutex->value, 1, 0)==0)
    {
      // update the current owner to mutex to current thread
      mutex->thread = mythread_self();
      mythread_leave_kernel();

      return 0; // success
    }    
  } // end of while loop
  
 // if lock is not available after 50 tries, block the current thread.
  mythread_block (&mutex->queue, BLOCKED);
  
  return 0; // success 
}
Esempio n. 15
0
int mythread_init_sched(){

	/* Set the new_mask for SIGUSR1 and SIGALRM */
	mythread_t self = mythread_self();
	self->preemptions = 0;
	(self->attr).attr = pow(2.0,self->preemptions);

	sigemptyset(&new_mask);
	sigaddset(&new_mask,SIGUSR1);
	sigaddset(&new_mask,SIGALRM);
	sigprocmask(SIG_UNBLOCK,&new_mask,&old_mask);
	
	
	new_action.sa_handler = myhandler;
	new_action.sa_mask = new_mask;
	new_action.sa_flags = 0;

	/* Install signal handler for SIGUSR1 */
	if(sigaction(SIGUSR1,&new_action,&old_action)<0){
		perror("Error in installing handler for SIGUSR1\n");
		return -1;
	}
	
	/* Install signal handler for SIGALRM */
	if(sigaction(SIGALRM,&new_action,&old_action)<0){
		perror("Error in installing handler for SIGUSR1\n");
		return -1;
	}
	
	if(timer_set == 0){
		timer_set = 1;
		struct itimerval timer;
		struct timeval timerval;
		timerval.tv_sec=0;
		timerval.tv_usec=10000;
		timer.it_interval=timerval;
		timer.it_value=timerval;
		setitimer(ITIMER_REAL, &timer, NULL);
	}
	return 0;
}
Esempio n. 16
0
void * printingfunction (void * argument)
{
mythread_t mythread = mythread_self();
printf("this is printing function %d\n",mythread.tid);
}