int main(int argc, char *argv[]) { sthread_t thr1, thr2; if (sthread_init() == -1) fprintf(stderr, "%s: sthread_init: %s\n", argv[0], strerror(errno)); if (sthread_create(&thr1, threadmain, (void *)1) == -1) fprintf(stderr, "%s: sthread_create: %s\n", argv[0], strerror(errno)); if (sthread_create(&thr2, threadmain, (void *)2) == -1) fprintf(stderr, "%s: sthread_create: %s\n", argv[0], strerror(errno)); sleep(1); sthread_wake(thr1); sleep(1); sthread_wake(thr2); sleep(1); sthread_wake(thr1); sthread_wake(thr2); sleep(1); return 0; }
int sthread_sem_up(sthread_sem_t *sem)//will increment the value of semaphore by 1 if nobody is being blocked on it; if there are threads waiting for the semaphore, it should wake up one of the waiting threads; these two steps must also be atomic. { while (test_and_set(sem->mutex)) sched_yield(); sthread_t thread = pop(sem->sem_queue); if (thread) { sthread_wake(thread); } else { sem->count++; } *(sem->mutex) = 0; return 0; }
/* up()-> It is called by a thread when a semaphore is released. If the waiting queue is empty then just increment sem->count else remove and wake up the first thread on the waiting queue. */ int sthread_sem_up(sthread_sem_t *sem) { lock(); if (sem->sthread_count <= 0) { sem->count++; unlock(); } else { struct Node *longestWaitingThread = removeNode(sem); struct Node temp; temp.data = longestWaitingThread->data; free(longestWaitingThread); unlock(); sthread_wake(temp.data); } return 0; }
int sthread_mutex_unlock(sthread_mutex_t *mutex,int tid) { //enable if you want to test other thread unable to get lock... // sleep(1); int ret_val; if(mutex->lock==1){ if(mutex->tid==tid){ //check counter if(mutex->counter==0){ mutex->lock = 0; ret_val = 0; if(isWaitingEmpty(mutex)){ printf("No threads waiting\n"); } else{ //wake up the mutex in waiting that is in front sthread_wake(mutex->waiting[mutex->front]); //dequeue the mutex dequeueWait(mutex); } } else if(mutex->counter>0){ mutex->counter = mutex->counter - 1; printf("Thread %d, making recursive call to unlock lock\n",tid); sthread_mutex_unlock(mutex,tid); } } mutex->lock=0; ret_val = 0; } else{ ret_val = -1; } return ret_val; }
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; } }