int child_fn(int priority, int id) { sem_t *sem, *sem_1; if (set_my_prio(priority) == -1) exit(-1); sem = sem_open(semname, 0); if( sem == SEM_FAILED || sem == NULL ) { perror(ERROR_PREFIX "sem_open: sem"); return -1; } sem_1 = sem_open(semname_1, 0); if( sem_1 == SEM_FAILED || sem_1 == NULL ) { perror(ERROR_PREFIX "sem_open: sem_1"); return -1; } sem_wait(sem_1); fprintf(stderr, "child %d try to get lock, prio: %d\n", id, get_my_prio()); if (sem_wait(sem) == -1) { perror("Error at sem_wait"); fprintf(stderr, "Child %d: Cannot get lock", id); exit(-1); } fprintf(stderr, "child %d got lock\n", id); exit(0); }
int main() { #ifndef _POSIX_PRIORITY_SCHEDULING printf("_POSIX_PRIORITY_SCHEDULING not defined\n"); return PTS_UNTESTED; #endif sem_t *sem, *sem_1; int val = 3; /* for sem_1 to track the child state */ int priority; pid_t c_1, c_2, c_3, ret_pid; int retval = PTS_UNRESOLVED; int status; snprintf(semname, 20, "/" TEST "_%d", getpid()); /* Initial value of Semaphore is 1 */ sem = sem_open(semname, O_CREAT, 0777, 1); if( sem == SEM_FAILED || sem == NULL ) { perror(ERROR_PREFIX "sem_open"); return PTS_UNRESOLVED; } snprintf(semname_1, 20, "/" TEST "_%d_1", getpid()); sem_1 = sem_open(semname_1, O_CREAT, 0777, val); if( sem_1 == SEM_FAILED || sem_1 == NULL ) { perror(ERROR_PREFIX "sem_open: sem_1"); sem_unlink(semname); return PTS_UNRESOLVED; } /* The parent has highest priority */ priority = sched_get_priority_min(SCHED_FIFO) + 3; if (set_my_prio(priority) == -1) { retval = PTS_UNRESOLVED; goto clean_up; } /* Lock Semaphore */ if( sem_wait(sem) == -1 ) { perror(ERROR_PREFIX "sem_wait"); retval = PTS_UNRESOLVED; goto clean_up; } c_1 = fork(); if (c_1 == 0) { /* Child 1, should block */ child_fn(priority - 2, 1); } else if (c_1 < 0) { perror("Error at fork"); retval = PTS_UNRESOLVED; goto clean_up; } fprintf(stderr, "P: child_1:%d forked\n", c_1); sleep(1); c_2 = fork(); if (c_2 == 0) { /* Child 2 */ child_fn(priority - 1, 2); } else if (c_2 < 0) { perror("Error at fork"); retval = PTS_UNRESOLVED; goto clean_up; } fprintf(stderr, "P: child_2: %d forked\n", c_2); /* Make sure the two children has been waiting */ /* do { sleep(1); sem_getvalue(sem_1, &val); //printf("val = %d\n", val); } while (val != 1); */ c_3 = fork(); if (c_3 == 0) { /* Child 3 */ child_fn(priority - 1, 3); } fprintf(stderr, "P: child_3: %d forked\n", c_3); /* Make sure child 3 has been waiting for the lock */ /* do { sleep(1); sem_getvalue(sem_1, &val); //printf("val = %d\n", val); } while (val != 0); */ /* Ok, let's release the lock */ fprintf(stderr, "P: release lock\n"); sem_post(sem); ret_pid = wait(&status); if (ret_pid == c_2 && WIFEXITED(status) && WEXITSTATUS(status) == 0) { fprintf(stderr, "P: release lock\n"); sem_post(sem); ret_pid = wait(&status); if (ret_pid == c_3 && WIFEXITED(status) && WEXITSTATUS(status) == 0) { fprintf(stderr, "P: release lock\n"); sem_post(sem); ret_pid = wait(&status); if (ret_pid == c_1 && WIFEXITED(status) && WEXITSTATUS(status) == 0) { printf("Test Pass\n"); retval = PTS_PASS; goto clean_up; } printf("Test Fail: Expect child_1: %d, got %d\n", c_1, ret_pid); retval = PTS_FAIL; goto clean_up; } else { printf("Test Fail: Expect child_3: %d, got %d\n", c_3, ret_pid); retval = PTS_FAIL; sem_post(sem); while((wait(NULL) > 0)); goto clean_up; } } else { printf("Test Fail: Expect child_2: %d, got %d\n", c_2, ret_pid); retval = PTS_FAIL; sem_post(sem); sem_post(sem); while((wait(NULL) > 0)); goto clean_up; } clean_up: sem_close(sem); sem_close(sem_1); sem_unlink(semname); sem_unlink(semname_1); return retval; }
int main(void) { #ifndef _POSIX_PRIORITY_SCHEDULING printf("_POSIX_PRIORITY_SCHEDULING not defined\n"); return PTS_UNTESTED; #endif sem_t *sem, *sem_1; int val; int priority; pid_t c_1, c_2, c_3, ret_pid; int retval = PTS_UNRESOLVED; int status; snprintf(semname, sizeof(semname), "/" TEST "_%d", getpid()); sem = sem_open(semname, O_CREAT | O_EXCL, 0777, 1); if (sem == SEM_FAILED) { perror("sem_open(semname)"); return PTS_UNRESOLVED; } snprintf(semname_1, sizeof(semname_1), "/" TEST "_%d_1", getpid()); sem_1 = sem_open(semname_1, O_CREAT | O_EXCL, 0777, 3); if (sem_1 == SEM_FAILED) { perror("sem_open(semname_1)"); sem_unlink(semname); return PTS_UNRESOLVED; } /* The parent has highest priority */ priority = sched_get_priority_min(SCHED_FIFO) + 3; if (set_my_prio(priority) == -1) { retval = PTS_UNRESOLVED; goto clean_up; } /* Lock Semaphore */ if (sem_wait(sem) == -1) { perror("sem_wait()"); retval = PTS_UNRESOLVED; goto clean_up; } c_1 = fork(); switch (c_1) { case 0: child_fn(priority - 2, 1); break; case -1: perror("fork()"); retval = PTS_UNRESOLVED; goto clean_up; break; } fprintf(stderr, "P: child_1: %d forked\n", c_1); c_2 = fork(); switch (c_2) { case 0: child_fn(priority - 1, 2); break; case -1: perror("fork()"); retval = PTS_UNRESOLVED; goto clean_up; break; } fprintf(stderr, "P: child_2: %d forked\n", c_2); /* Make sure the two children has been waiting */ do { usleep(100); sem_getvalue(sem_1, &val); } while (val != 1); usleep(100); c_3 = fork(); switch (c_3) { case 0: child_fn(priority - 1, 3); break; case -1: perror("fork()"); retval = PTS_UNRESOLVED; goto clean_up; break; } fprintf(stderr, "P: child_3: %d forked\n", c_3); /* Make sure child 3 has been waiting for the lock */ do { usleep(100); sem_getvalue(sem_1, &val); } while (val != 0); usleep(100); /* Ok, let's release the lock */ fprintf(stderr, "P: release lock\n"); sem_post(sem); ret_pid = wait(&status); if (ret_pid == c_2 && WIFEXITED(status) && WEXITSTATUS(status) == 0) { fprintf(stderr, "P: release lock\n"); sem_post(sem); ret_pid = wait(&status); if (ret_pid == c_3 && WIFEXITED(status) && WEXITSTATUS(status) == 0){ fprintf(stderr, "P: release lock\n"); sem_post(sem); ret_pid = wait(&status); if (ret_pid == c_1 && WIFEXITED(status) && WEXITSTATUS(status) == 0) { printf("Test PASSED\n"); retval = PTS_PASS; goto clean_up; } printf("Test Fail: Expect child_1: %d, got %d\n", c_1, ret_pid); retval = PTS_FAIL; goto clean_up; } else { printf("Test Fail: Expect child_3: %d, got %d\n", c_3, ret_pid); retval = PTS_FAIL; sem_post(sem); while ((wait(NULL) > 0)); goto clean_up; } } else { printf("Test Fail: Expect child_2: %d, got %d\n", c_2, ret_pid); retval = PTS_FAIL; sem_post(sem); sem_post(sem); while ((wait(NULL) > 0)); goto clean_up; } clean_up: sem_close(sem); sem_close(sem_1); sem_unlink(semname); sem_unlink(semname_1); return retval; }