#include <fcntl.h> #include <unistd.h> #include <stdio.h> #include "tests.h" #include "litmus.h" TESTCASE(lock_fmlp_nesting, PSN_EDF | GSN_EDF | P_FP, "FMLP no nesting allowed") { int fd, od, od2; SYSCALL( fd = open(".fmlp_locks", O_RDONLY | O_CREAT, S_IRUSR) ); SYSCALL( sporadic_partitioned(10, 100, 0) ); SYSCALL( task_mode(LITMUS_RT_TASK) ); SYSCALL( od = open_fmlp_sem(fd, 0) ); SYSCALL( od2 = open_fmlp_sem(fd, 1) ); SYSCALL( litmus_lock(od) ); SYSCALL( litmus_unlock(od) ); SYSCALL( litmus_lock(od2) ); SYSCALL( litmus_unlock(od2) ); SYSCALL( litmus_lock(od) ); SYSCALL_FAILS(EBUSY, litmus_lock(od2)); SYSCALL( litmus_unlock(od) ); SYSCALL( litmus_lock(od2) );
/* typically, main() does a couple of things: * 1) parse command line parameters, etc. * 2) Setup work environment. * 3) Setup real-time parameters. * 4) Transition to real-time mode. * 5) Invoke periodic or sporadic jobs. * 6) Transition to background mode. * 7) Clean up and exit. * * The following main() function provides the basic skeleton of a single-threaded * LITMUS^RT real-time task. In a real program, all the return values should be * checked for errors. */ int main(int argc, char** argv) { int do_exit; int PERIOD, EXEC_COST, CPU; int sCounter; int counter; int pCounter; int ret; /* The task is in background mode upon startup. */ /***** * 1) Command line paramter parsing would be done here. */ if (argc !=5){ fprintf(stderr, "Usage: base_task EXEC_COST PERIOD COUNTER CPU \n COUNTER: print info every COUNTER times called \n"); exit(1); } EXEC_COST = atoi(argv[1]); PERIOD = atoi(argv[2]); sCounter = atoi(argv[3]); CPU = atoi(argv[4]); /***** * 2) Work environment (e.g., global data structures, file data, etc.) would * be setup here. */ counter = 0; pCounter = 0; /***** * 3) Setup real-time parameters. * In this example, we create a sporadic task that does not specify a * target partition (and thus is intended to run under global scheduling). * If this were to execute under a partitioned scheduler, it would be assigned * to the first partition (since partitioning is performed offline). */ CALL( init_litmus() ); /* CALL( sporadic_global(EXEC_COST, PERIOD) ); */ /* To specify a partition, use sporadic_partitioned(). * Example: * * sporadic_partitioned(EXEC_COST, PERIOD, CPU); * * where CPU ranges from 0 to "Number of CPUs" - 1. */ CALL( sporadic_partitioned(EXEC_COST, PERIOD, CPU) ); /***** * 4) Transition to real-time mode. */ CALL( task_mode(LITMUS_RT_TASK) ); /* The task is now executing as a real-time task if the call didn't fail. */ this_rt_id = gettid(); ret = wait_for_ts_release(); /***** * 5) Invoke real-time jobs. */ do { /* Wait until the next job is released. */ sleep_next_period(); /* Invoke job. */ do_exit = job(&counter, &pCounter, sCounter ); } while (!do_exit); /***** * 6) Transition to background mode. */ CALL( task_mode(BACKGROUND_TASK) ); /***** * 7) Clean up, maybe print results and stats, and exit. */ return 0; }