#include #include #include #include /* for waitpid() */ #include "tests.h" #include "litmus.h" TESTCASE(not_lock_fmlp_be, GSN_EDF | PSN_EDF | P_FP, "don't let best-effort tasks lock FMLP semaphores") { int fd, od; SYSCALL( fd = open(".fmlp_locks", O_RDONLY | O_CREAT, S_IRUSR) ); SYSCALL( od = open_fmlp_sem(fd, 0) ); /* BE tasks may not lock FMLP semaphores */ SYSCALL_FAILS(EPERM, litmus_lock(od) ); /* tasks may not unlock resources they don't own */ SYSCALL_FAILS(EINVAL, litmus_unlock(od) ); SYSCALL( od_close(od) ); SYSCALL( close(fd) ); SYSCALL( remove(".fmlp_locks") ); } TESTCASE(not_lock_srp_be, PSN_EDF | P_FP, "don't let best-effort tasks open SRP semaphores") { int fd, od; SYSCALL( fd = open(".srp_locks", O_RDONLY | O_CREAT, S_IRUSR) ); /* BE tasks may not open SRP semaphores */ SYSCALL_FAILS(EPERM, od = open_srp_sem(fd, 0) ); SYSCALL( close(fd) ); SYSCALL( remove(".srp_locks") ); } TESTCASE(lock_srp, PSN_EDF | P_FP, "SRP acquisition and release") { int fd, od; SYSCALL( fd = open(".srp_locks", O_RDONLY | O_CREAT, S_IRUSR) ); SYSCALL( sporadic_partitioned(ms2ns(10), ms2ns(100), 0) ); SYSCALL( task_mode(LITMUS_RT_TASK) ); SYSCALL( od = open_srp_sem(fd, 0) ); SYSCALL( litmus_lock(od) ); SYSCALL( litmus_unlock(od) ); SYSCALL( litmus_lock(od) ); SYSCALL( litmus_unlock(od) ); SYSCALL( litmus_lock(od) ); SYSCALL( litmus_unlock(od) ); /* tasks may not unlock resources they don't own */ SYSCALL_FAILS(EINVAL, litmus_unlock(od) ); SYSCALL( od_close(od) ); SYSCALL( close(fd) ); SYSCALL( remove(".srp_locks") ); } TESTCASE(lock_fmlp, PSN_EDF | GSN_EDF | P_FP, "FMLP acquisition and release") { int fd, od; SYSCALL( fd = open(".fmlp_locks", O_RDONLY | O_CREAT, S_IRUSR) ); SYSCALL( sporadic_partitioned(ms2ns(10), ms2ns(100), 0) ); SYSCALL( task_mode(LITMUS_RT_TASK) ); SYSCALL( od = open_fmlp_sem(fd, 0) ); SYSCALL( litmus_lock(od) ); SYSCALL( litmus_unlock(od) ); SYSCALL( litmus_lock(od) ); SYSCALL( litmus_unlock(od) ); SYSCALL( litmus_lock(od) ); SYSCALL( litmus_unlock(od) ); /* tasks may not unlock resources they don't own */ SYSCALL_FAILS(EINVAL, litmus_unlock(od) ); SYSCALL( od_close(od) ); SYSCALL( close(fd) ); SYSCALL( remove(".fmlp_locks") ); } TESTCASE(lock_dflp, P_FP, "DFLP acquisition and release") { int fd, od, cpu = 1; SYSCALL( fd = open(".dflp_locks", O_RDONLY | O_CREAT, S_IRUSR) ); SYSCALL( sporadic_partitioned(ms2ns(10), ms2ns(100), 0) ); SYSCALL( task_mode(LITMUS_RT_TASK) ); SYSCALL( od = open_dflp_sem(fd, 0, cpu) ); SYSCALL( litmus_lock(od) ); SYSCALL( litmus_unlock(od) ); SYSCALL( litmus_lock(od) ); SYSCALL( litmus_unlock(od) ); SYSCALL( litmus_lock(od) ); SYSCALL( litmus_unlock(od) ); /* tasks may not unlock resources they don't own */ SYSCALL_FAILS(EINVAL, litmus_unlock(od) ); SYSCALL( od_close(od) ); SYSCALL( close(fd) ); SYSCALL( remove(".dflp_locks") ); } TESTCASE(dflp_bad_cpu, P_FP, "DFLP reject bad CPU parameter") { int fd, cpu = 0xbadca5e; SYSCALL( fd = open(".dflp_locks", O_RDONLY | O_CREAT, S_IRUSR) ); SYSCALL( sporadic_partitioned(ms2ns(10), ms2ns(100), 0) ); SYSCALL( task_mode(LITMUS_RT_TASK) ); SYSCALL_FAILS(EINVAL, open_dflp_sem(fd, 0, cpu) ); SYSCALL( close(fd) ); SYSCALL( remove(".dflp_locks") ); } TESTCASE(srp_lock_mode_change, P_FP | PSN_EDF, "SRP task becomes non-RT task while holding lock") { int fd, od; struct rt_task params; init_rt_task_param(¶ms); params.cpu = 0; params.exec_cost = ms2ns(10000); params.period = ms2ns(100000); params.relative_deadline = params.period; SYSCALL( fd = open(".locks", O_RDONLY | O_CREAT, S_IRUSR) ); params.priority = LITMUS_LOWEST_PRIORITY; SYSCALL( set_rt_task_param(gettid(), ¶ms) ); SYSCALL( be_migrate_to_cpu(params.cpu) ); SYSCALL( task_mode(LITMUS_RT_TASK) ); SYSCALL( od = open_srp_sem(fd, 0) ); SYSCALL( litmus_lock(od) ); SYSCALL( task_mode(BACKGROUND_TASK) ); be_migrate_to_cpu(1); SYSCALL( litmus_unlock(od) ); SYSCALL( od_close(od) ); SYSCALL( close(fd) ); SYSCALL( remove(".locks") ); } TESTCASE(dflp_lock_mode_change, P_FP, "DFLP task becomes non-RT task while holding lock") { int fd, od, cpu = 0; struct rt_task params; init_rt_task_param(¶ms); params.cpu = 1; params.exec_cost = ms2ns(10000); params.period = ms2ns(100000); params.relative_deadline = params.period; SYSCALL( fd = open(".locks", O_RDONLY | O_CREAT, S_IRUSR) ); params.priority = LITMUS_LOWEST_PRIORITY; SYSCALL( set_rt_task_param(gettid(), ¶ms) ); SYSCALL( be_migrate_to_cpu(params.cpu) ); SYSCALL( task_mode(LITMUS_RT_TASK) ); SYSCALL( od = open_dflp_sem(fd, 0, cpu) ); SYSCALL( litmus_lock(od) ); SYSCALL( task_mode(BACKGROUND_TASK) ); be_migrate_to_cpu(2); SYSCALL( litmus_unlock(od) ); SYSCALL( od_close(od) ); SYSCALL( close(fd) ); SYSCALL( remove(".locks") ); } TESTCASE(fmlp_lock_mode_change, P_FP | PSN_EDF | GSN_EDF, "FMLP task becomes non-RT task while holding lock") { int fd, od; int child, status; struct rt_task params; init_rt_task_param(¶ms); params.cpu = 0; params.exec_cost = ms2ns(10000); params.period = ms2ns(100000); params.relative_deadline = params.period; SYSCALL( fd = open(".locks", O_RDONLY | O_CREAT, S_IRUSR) ); child = FORK_TASK( params.priority = LITMUS_LOWEST_PRIORITY; SYSCALL( set_rt_task_param(gettid(), ¶ms) ); SYSCALL( be_migrate_to_cpu(params.cpu) ); SYSCALL( task_mode(LITMUS_RT_TASK) ); SYSCALL( od = open_fmlp_sem(fd, 0) ); SYSCALL( litmus_lock(od) ); SYSCALL( task_mode(BACKGROUND_TASK) ); SYSCALL( litmus_unlock(od) ); SYSCALL( od_close(od) ); exit(0); ); SYSCALL( waitpid(child, &status, 0) ); ASSERT( WIFEXITED(status) ); ASSERT( WEXITSTATUS(status) == 0 ); SYSCALL( close(fd) ); SYSCALL( remove(".locks") ); } TESTCASE(srp_lock_teardown, P_FP | PSN_EDF, "SRP task exits while holding lock") { int fd, od; int child, status; struct rt_task params; init_rt_task_param(¶ms); params.cpu = 0; params.exec_cost = ms2ns(10000); params.period = ms2ns(100000); params.relative_deadline = params.period; SYSCALL( fd = open(".locks", O_RDONLY | O_CREAT, S_IRUSR) ); exit(0); child = FORK_TASK( params.priority = LITMUS_LOWEST_PRIORITY; SYSCALL( set_rt_task_param(gettid(), ¶ms) ); SYSCALL( be_migrate_to_cpu(params.cpu) ); SYSCALL( task_mode(LITMUS_RT_TASK) ); SYSCALL( od = open_srp_sem(fd, 0) ); SYSCALL( litmus_lock(od) ); exit(123); ); SYSCALL( waitpid(child, &status, 0) ); ASSERT( WIFEXITED(status) ); ASSERT( WEXITSTATUS(status) == 123 ); SYSCALL( close(fd) ); SYSCALL( remove(".locks") ); } TESTCASE(fmlp_lock_teardown, P_FP | PSN_EDF | GSN_EDF, "FMLP task exits while holding lock") { int fd, od; int child, status; struct rt_task params; init_rt_task_param(¶ms); params.cpu = 0; params.exec_cost = ms2ns(10000); params.period = ms2ns(100000); params.relative_deadline = params.period; SYSCALL( fd = open(".locks", O_RDONLY | O_CREAT, S_IRUSR) ); exit(0); child = FORK_TASK( params.priority = LITMUS_LOWEST_PRIORITY; SYSCALL( set_rt_task_param(gettid(), ¶ms) ); SYSCALL( be_migrate_to_cpu(params.cpu) ); SYSCALL( task_mode(LITMUS_RT_TASK) ); SYSCALL( od = open_fmlp_sem(fd, 0) ); SYSCALL( litmus_lock(od) ); exit(123); ); SYSCALL( waitpid(child, &status, 0) ); ASSERT( WIFEXITED(status) ); ASSERT( WEXITSTATUS(status) == 123 ); SYSCALL( close(fd) ); SYSCALL( remove(".locks") ); } TESTCASE(dflp_lock_teardown, P_FP, "DFLP task exits while holding lock") { int fd, od, cpu = 0; int child, status; struct rt_task params; init_rt_task_param(¶ms); params.cpu = 1; params.exec_cost = ms2ns(10000); params.period = ms2ns(100000); params.relative_deadline = params.period; SYSCALL( fd = open(".locks", O_RDONLY | O_CREAT, S_IRUSR) ); exit(0); child = FORK_TASK( params.priority = LITMUS_LOWEST_PRIORITY; SYSCALL( set_rt_task_param(gettid(), ¶ms) ); SYSCALL( be_migrate_to_cpu(params.cpu) ); SYSCALL( task_mode(LITMUS_RT_TASK) ); SYSCALL( od = open_dflp_sem(fd, 0, cpu) ); SYSCALL( litmus_lock(od) ); exit(123); ); SYSCALL( waitpid(child, &status, 0) ); ASSERT( WIFEXITED(status) ); ASSERT( WEXITSTATUS(status) == 123 ); SYSCALL( close(fd) ); SYSCALL( remove(".locks") ); }