void sem_wait(struct sem *s){ while(1){ while(tas(&(s->lock))!=0){ } if(s->count>0){ // printf("got here\n"); (s->count)--; s->lock=0; return; } else{ //set signal // printf("waiting with procnum:%i\n",my_procnum); s->waiting[my_procnum]=1; s->semqueue[my_procnum]=getpid(); sigset_t mask; sigfillset (&mask); sigdelset (&mask, SIGUSR1); sigdelset (&mask, SIGINT); sigprocmask (SIG_BLOCK, &mask, NULL); signal(SIGUSR1, sighand); s->lock=0; sigsuspend (&mask); sigprocmask (SIG_UNBLOCK, &mask, NULL); } } }
int canlock(Lock *lk) { if(tas(&lk->val)) return 0; return 1; }
int my_mutex_lock(my_mutex_t *mutex) //TTAS { if(mutex == NULL) { printf("Mutexlock: Invalid mutex in my_mutex_lock\n"); return -1; } //exponential back off with delay useconds_t backoff_delay = 5; while(TRUE) { if(mutex->count == 0) { //if new lock request while(mutex->status == 1) {//its set so dont do anything //do nothing ; } if(tas(&mutex->status) == 0) { //checking for status first, if previous val is 0 then write 1 mutex->count++; mutex->th_id = pthread_self(); return 0; } } else if(mutex->th_id == pthread_self()) {//if locking thread tryng again printf("Mutexlock: Already locked by this in my_mutex_lock\n"); return 0; } usleep(backoff_delay); //sleep for delay time if (backoff_delay < 40) { backoff_delay *= 2; } } return -1; }
static Chan* consopen(Chan *c, int omode) { c->aux = nil; c = devopen(c, omode, consdir, nelem(consdir), devgen); switch((ulong)c->qid.path){ case Qkprint: if(tas(&kprintinuse) != 0){ c->flag &= ~COPEN; error(Einuse); } if(kprintoq == nil){ kprintoq = qopen(8*1024, Qcoalesce, 0, 0); if(kprintoq == nil){ c->flag &= ~COPEN; error(Enomem); } qnoblock(kprintoq, 1); }else qreopen(kprintoq); c->iounit = qiomaxatomic; break; } return c; }
/** * Fastpath TATAS acquire. The return value is how long we spent spinning */ inline int tatas_acquire(tatas_lock_t* lock) { if (!tas(lock)) { return 0; } return tatas_acquire_slowpath(lock); }
void sem_wait(struct sem *s) { s->pids[my_procnum] = getpid(); while (1) { while (tas(&s->lock)); // block all signals except sigint and sigusr1 if (signal(SIGUSR1,sigusr1_handler) == SIG_ERR) perror("Failed to set signal handler"); sigset_t mask; sigfillset(&mask); sigdelset(&mask, SIGUSR1); sigdelset(&mask, SIGINT); if (s->count > 0) { s->count--; s->pstatus[my_procnum] = 0; s->lock = 0; return; } else { s->lock = 0; s->pstatus[my_procnum] = 1; sigsuspend(&mask); } } }
int my_spinlock_lockTTAS(my_spinlock_t *mutex) { //The second version will employ a Test-And-TestAnd-Set (TTAS) technique. if(mutex == NULL) { printf("Spinlock: Invalid mutex in my_spinlock_lockTTAS\n"); return -1; } while(TRUE) { if(mutex->count == 0) { //if new lock request while(mutex->status == 1) {//its set so dont do anything //do nothing ; } if(tas(&mutex->status) == 0) { //checking for status first, if previous val is 0 then write 1 mutex->count++; mutex->th_id = pthread_self(); return 0; } } else if(mutex->th_id == pthread_self()) {//if locking thread tryng again printf("Spinlock: Already locked by this in my_spinlock_lockTTAS\n"); return 0; } } return -1; }
/*** Slowpath TATAS acquire. This performs exponential backoff */ inline int tatas_acquire_slowpath(tatas_lock_t* lock) { int b = 64; do { backoff(&b); } while (tas(lock)); return b; }
void sem_inc(struct sem *s){ while(tas(&(s->spinlock)) != 0) ; if (++s->sem_count > 0 && s->numWaiters > 0){ --(s->numWaiters); kill(s->waitingPIDs[(s->nextReadWaiter)++], SIGUSR1); s->nextReadWaiter %= MAX_SUPPORTED_PROCS; } s->spinlock = 0; }
int sem_try(struct sem *s){ while (tas(&(s->spinlock)) != 0) ; if (s->sem_count > 0){ s->sem_count --; s->spinlock = 0; return 1; } s->spinlock = 0; return 0; }
void ilock(Lock *l) { ulong x; ulong pc; pc = getcallerpc(&l); lockstats.locks++; x = splhi(); if(tas(&l->key) != 0){ lockstats.glare++; /* * Cannot also check l->pc, l->m, or l->isilock here * because they might just not be set yet, or * (for pc and m) the lock might have just been unlocked. */ for(;;){ lockstats.inglare++; splx(x); while(l->key) ; x = splhi(); if(tas(&l->key) == 0) goto acquire; } } acquire: m->ilockdepth++; if(up) up->lastilock = l; l->sr = x; l->pc = pc; l->p = up; l->isilock = 1; l->m = MACHP(m->machno); #ifdef LOCKCYCLES l->lockcycles = -lcycles(); #endif }
int sem_try(struct sem *s) { int ret; while (tas(&s->lock)); if (s->count > 0) { s->count--; ret = 1; } else ret = 0; s->lock = 0; return ret; }
void sem_inc(struct sem *s) { while (tas(&s->lock)); s->count++; int i; for (i = 0; i < NUMPROC; i++) { if (s->pstatus[i]) { kill(s->pids[i], SIGUSR1); break; } } s->lock = 0; }
int sem_try(struct sem *s){ while(tas(&(s->lock))!=0){ } if(s->count>0){ (s->count)--; s->lock=0; return 1; } else{ s->lock=0; return 0; } }
int sem_try(struct sem *s) { sigset_t all, oldset; sigfillset(&all); sigprocmask(SIG_BLOCK, &all, &oldset); //block signals in critical region while(tas(&(s->lock))); //spin int retval = 0; if(s->count > 0) { s->count--; retval = 1; } s->lock = 0; sigprocmask(SIG_SETMASK, &oldset, NULL); return retval; }
void sem_inc(struct sem *s){ while(tas(&(s->lock))!=0){} (s->count)++; // printf("the count is:%i\n",s->count); int i; for(i=0;i<N_PROC;i++){ if(s->waiting[i]==1){ s->waiting[i]=0; // fprintf(stderr,"sending signal\n"); kill(s->semqueue[i],SIGUSR1); break; } } s->lock=0; }
static Chan* sdopen(Chan* c, int omode) { SDpart *pp; SDunit *unit; SDev *sdev; uchar tp; c = devopen(c, omode, 0, 0, sdgen); if((tp = TYPE(c->qid)) != Qctl && tp != Qraw && tp != Qpart) return c; sdev = sdgetdev(DEV(c->qid)); if(sdev == nil) error(Enonexist); unit = sdev->unit[UNIT(c->qid)]; switch(TYPE(c->qid)){ case Qctl: c->qid.vers = unit->vers; break; case Qraw: c->qid.vers = unit->vers; if(tas(&unit->rawinuse) != 0){ c->flag &= ~COPEN; decref(&sdev->r); error(Einuse); } unit->state = Rawcmd; break; case Qpart: qlock(&unit->ctl); if(waserror()){ qunlock(&unit->ctl); c->flag &= ~COPEN; decref(&sdev->r); nexterror(); } pp = &unit->part[PART(c->qid)]; c->qid.vers = unit->vers+pp->vers; qunlock(&unit->ctl); poperror(); break; } decref(&sdev->r); return c; }
void sem_inc(struct sem *s) { while(tas(&(s->lock))); //spin sigset_t all, oldset; sigfillset(&all); sigprocmask(SIG_BLOCK, &all, &oldset); //block signals in critical region s->count++; int i; for(i = 0; i < N_PROC; i++) { if(s->cpus[i] != 0) { kill(s->cpus[i], SIGUSR1); //wake next cpu s->cpus[i] = 0; break; } } sigprocmask(SIG_SETMASK, &oldset, NULL); s->lock = 0; }
int my_mutex_trylock(my_mutex_t *mutex) { if(mutex == NULL) { printf("Mutexlock: Invalid mutex in my_mutex_trylock\n"); return -1; } if(mutex->status == 0) {//try to take lock if(tas(&mutex->status) == 0) { //if initial value returned is 0 that means its set mutex->count++; mutex->th_id = pthread_self(); return 0; } } printf("Mutexlock: Lock is already taken in my_mutex_trylock\n"); return -1; }
int my_queuelock_lock(my_queuelock_t *mutex) { if(mutex == NULL) { printf("Queuelock: Invalid mutex in my_queuelock_lock\n"); return -1; } // for queue lock we will be using the functionality of checking // thread status using TTAS as well as the ticket number check // this ensure the thread safe execution with the ability of // queue based fairness unsigned long next_to_serve, previous; while(TRUE) { if(mutex->count == 0) { //if new lock request while(mutex->status == 1) {}; //if already processed then wait if(tas(&mutex->status) == 0) { // else set to 1 that its been addressed previous = mutex->next; //last value of ticket next_to_serve = cas(&mutex->current,previous,mutex->next++); //fetch next ticket while(mutex->current != next_to_serve) { //check if current to serve is next ticket sleep(next_to_serve - mutex->current); //if not equal then wait if (mutex->current == next_to_serve) { // recheck mutex->count++; //increase count addressing the thread mutex->th_id = pthread_self(); return 0; } } mutex->count++; //increase mutex->th_id = pthread_self(); return 0; } } else if(mutex->th_id == pthread_self()) {//if locking thread tryng again return 0 printf("Queuelock: Already locked by this in my_queuelock_lock\n"); return 0; } } return -1; }
void sem_wait(struct sem *s){ for(;;){ while (tas(&(s->spinlock)) != 0) ; if (s->sem_count > 0){ s->sem_count --; s->spinlock = 0; break; } s->waitingPIDs[(s->nextNewWaiter)++] = (int) getpid(); s->nextNewWaiter %= MAX_SUPPORTED_PROCS; ++(s->numWaiters); sigset_t new_mask; sigfillset(&new_mask); sigprocmask(SIG_BLOCK, &new_mask, NULL); sigdelset(&new_mask,SIGUSR1); signal(SIGUSR1, handler); s->spinlock = 0; sigsuspend(&new_mask); } }
int canlock(Lock *l) { if(up) inccnt(&up->nlocks); if(tas(&l->key)){ if(up) deccnt(&up->nlocks); return 0; } if(up) up->lastlock = l; l->pc = getcallerpc(&l); l->p = up; l->m = MACHP(m->machno); l->isilock = 0; #ifdef LOCKCYCLES l->lockcycles = -lcycles(); #endif return 1; }
void sem_wait(struct sem *s) { sigset_t all, usr_only, oldset; struct sigaction oldaction; sigfillset(&all); sigfillset(&usr_only); sigdelset(&usr_only, SIGUSR1); sigdelset(&usr_only, SIGINT); //allow ctrl-c sigprocmask(SIG_BLOCK, &all, &oldset); //block signals in critical region for(;;) { while(tas(&(s->lock))); //wait for lock if(s->count > 0) { s->count--; s->lock = 0; break; } else { //block s->cpus[my_procnum] = getpid(); s->lock = 0; sigsuspend(&usr_only); //returns when semaphore increments } } sigprocmask(SIG_SETMASK, &oldset, NULL); //restore original mask }
int my_queuelock_trylock(my_queuelock_t *mutex) { if(mutex == NULL) { printf("Queuelock: Invalid mutex in my_queuelock_trylock\n"); return -1; } if(mutex->status == 0) { if(tas(&mutex->status) == 0) { unsigned long next_to_serve; next_to_serve = cas(&mutex->current+1,mutex->next,mutex->next++); if (mutex->current == next_to_serve) { mutex->count++; mutex->th_id = pthread_self(); return 0; } } } printf("Queuelock: Lock is already taken in my_queuelock_trylock\n"); return -1; }
int my_spinlock_lockTAS(my_spinlock_t *mutex) { //For the spinlock the first version will directly use the TAS atomic operations if(mutex == NULL) { printf("Spinlock: Invalid mutex in my_spinlock_lockTAS\n"); return -1; } while(TRUE) { if(mutex->count == 0) { //if new lock request while(tas(&mutex->status) == 1) { //its set so dont do anything //do nothing ; } mutex->count++; mutex->th_id = pthread_self(); return 0; } else if(mutex->th_id == pthread_self()) {//if locking thread tryng again printf("Spinklock: Already locked by this in my_spinlock_lockTAS\n"); return 0; } } return -1; }
void lock(Lock *lk) { while(tas(&lk->val)) _SLEEP(0); }
void RequestHandler::respond(QTcpSocket* client,DatabaseController &db){ string method = Message<string,int>::getMethod(msg); if(method.compare(Message<string,int>::saveTask) == 0 ){ Message<TA,Task> m(msg); TA t(m.returnA()); Task tas(m.returnB()); db.saveTask(t, tas); client->write("true",1000); return; }else if(method.compare(Message<string,int>::deleteTask) == 0 ){ Message<Task,string> m(msg); Task t(m.returnA()); db.deleteTask(t); client->write("true",1000); return; }else if(method.compare(Message<string,int>::saveEval)== 0){ Message<TA,Evaluation> m(msg); TA t(m.returnA()); Evaluation e(m.returnB()); db.saveEvaluation(e); client->write("true",1000); return; }else if(method.compare(Message<string,int>::deleteEval) == 0){ Message<Evaluation,string> m(msg); Evaluation e(m.returnA()); db.deleteEvaluation(e); client->write("true",1000); return; }else if(method.compare(Message<string,int>::getEval)==0){ Message<Task,string> m(msg); Task t(m.returnA()); Evaluation e = db.getEvaluation(t); Message<Evaluation,string> f(Message<string,int>::reTurn,e); string s = f.toString(); cout<<"sending back message: "<<s<<endl; client->write(s.c_str(),1000); return; }else if(method.compare(Message<string,int>::viewTaskListForCourse)==0){ Message<TA,Course> m(msg); Course c(m.returnB()); TA t(m.returnA()); vector<Task> mytasks = db.getTaskListForTACourse(t,c); Message<Task,string> f(mytasks); string s = f.toString(); cout<<"sending back message: "<<s<<endl; client->write(s.c_str(),1000); return; }else if(method.compare(Message<string,int>::viewTaList)==0){ Message<Course,string> m(msg); Course c(m.returnA()); vector<TA> myTas = db.getTAList(c); Message<TA,string> f(myTas); string s = f.toString(); cout<<"sending back message: "<<s<<endl; client->write(s.c_str(),1000); return; }else if(method.compare(Message<string,int>::viewCourseList)==0){ Message<Instructor,string> m(msg); Instructor teacher(m.returnA()); vector<Course> mycourses = db.getCourseList(teacher); Message<Course,string> f(mycourses); string s = f.toString(); cout<<"sending back message: "<<s<<endl; client->write(s.c_str(),1000); return; }else if (method.compare(Message<string,int>::getTa)==0){ Message<TA,string> m(msg); TA myTa(m.returnA()); TA newT = db.loginTA(myTa.getEmail()); Message<TA,string> f(newT.toString()); string s = f.toString(); cout<<"sending back message: "<<s<<endl; client->write(s.c_str(),1000); }else if (method.compare(Message<string,int>::getInstructor)==0){ Message<Instructor,string> m(msg); Instructor myInstruct(m.returnA()); Instructor newT = db.loginInstructor(myInstruct.getEmail()); Message<Instructor,string> f(newT.toString()); string s = f.toString(); cout<<"sending back message: "<<s<<endl; client->write(s.c_str(),1000); }else if (method.compare(Message<string,int>::getCurrentCourse)==0){ Message<TA,string> m(msg); TA t(m.returnA()); Course c = db.getCurrentCourse(t); Message<TA,string> f(c.toString()); string s = f.toString(); cout<<"sending back message: "<<s<<endl; client->write(s.c_str(),1000); } }
int main(int argc, char ** argv) { if (argc > 1) { readFile(); return 0; } int fd; if ((fd = open("testfile.txt", O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE)) < 0) { fprintf(stderr, "Couldn't open testfile.txt: %s\n", strerror(errno)); exit(1); } char * buf = "some text"; if (write(fd, buf, 10) < 0) { fprintf(stderr, "Couldn't write to testfile.txt: %s\n", strerror(errno)); exit(1); } struct stat sb; if (fstat(fd, &sb) < 0) { fprintf(stderr, "Couldn't get stats of file: %s\n", strerror(errno)); exit(1); } if ((map = mmap(0, sb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) < 0) { fprintf(stderr, "Couldn't map to file testfile.txt: %s\n", strerror(errno)); close(fd); exit(1); } map[0] = 0; int i; int inFork = 0; int status; map[1] = 0; struct rusage ru; for (i = 0; i < N_PROC; ++i) { pid_t pid; switch(pid = fork()) { case 0: { inFork = 1; int j; for (j = 0; j < 100000; ++j) { while (tas(&map[1]) != 0) ; map[0] += 1; map[1] = 0; } break; } case -1: fprintf(stderr, "Couldn't fork process: %s\n", strerror(errno)); exit(1); break; default: { break; } } if (inFork) { break; } } if (close(fd) < 0) { fprintf(stderr, "Couldn't close testfile.txt: %s\n", strerror(errno)); exit(1); } return 0; }
int lock(Lock *l) { int i; ulong pc; pc = getcallerpc(&l); lockstats.locks++; if(up) inccnt(&up->nlocks); /* prevent being scheded */ if(tas(&l->key) == 0){ if(up) up->lastlock = l; l->pc = pc; l->p = up; l->isilock = 0; #ifdef LOCKCYCLES l->lockcycles = -lcycles(); #endif return 0; } if(up) deccnt(&up->nlocks); lockstats.glare++; for(;;){ lockstats.inglare++; i = 0; while(l->key){ if(conf.nmach < 2 && up && up->edf && (up->edf->flags & Admitted)){ /* * Priority inversion, yield on a uniprocessor; on a * multiprocessor, the other processor will unlock */ print("inversion %#p pc %#lux proc %lud held by pc %#lux proc %lud\n", l, pc, up ? up->pid : 0, l->pc, l->p ? l->p->pid : 0); up->edf->d = todget(nil); /* yield to process with lock */ } if(i++ > 100000000){ i = 0; lockloop(l, pc); } } if(up) inccnt(&up->nlocks); if(tas(&l->key) == 0){ if(up) up->lastlock = l; l->pc = pc; l->p = up; l->isilock = 0; #ifdef LOCKCYCLES l->lockcycles = -lcycles(); #endif return 1; } if(up) deccnt(&up->nlocks); } }
main(int argc, char *argv[]) { int fd; unsigned long *sharedInt; pid_t pid; size_t size = sizeof(unsigned long)*2; int procNum = 0; int numCores = 4; int numIterations = 10000000; int temp; // used for incrementing the int in shared memory fd = shm_open("/myregion", O_RDWR | O_CREAT | O_TRUNC, 0766); if (fd < 0) reportError("Error creating shared memory object"); // Used to avoid bus error if(ftruncate(fd,size) < 0) reportError("Error truncating shared memory object"); sharedInt = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (sharedInt == MAP_FAILED) reportError("Error creating mmap"); *sharedInt = 0L; /* Initialize the number */ for(procNum = 0; procNum < numCores; procNum++) { pid=fork(); if(pid == 0) { for(temp = 0; temp < numIterations; temp++) (*sharedInt)++; exit(0); } } while(wait(NULL) != -1); printf("First test complete.\n"); printf("The value in memory should be %d.\n", numCores*numIterations); printf("The value we have is: %lu\n\n", *sharedInt); volatile char *lock = (char*) sharedInt+sizeof(unsigned long); *lock = 0; // Reset test... *sharedInt = 0L; for(procNum = 0; procNum < numCores; procNum++) { pid = fork(); if (pid == 0) { for(temp = 0; temp < numIterations; temp++) { while(tas(lock)); (*sharedInt)++; *lock = 0; } exit(0); } } while(wait(NULL) != -1); printf("Second test complete.\n"); printf("The value in memory should be %d.\n", numCores*numIterations); printf("The value we have is: %lu\n", *sharedInt); return 0; }