diff --git a/.gitignore b/.gitignore index 047925c..d5e5e94 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ *.o *.tar.gz *.d +*.a tmp patches ChangeLog diff --git a/Makefile b/Makefile index 3a82407..7dc8281 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,8 @@ VPATH += src/sigwaittest: VPATH += src/svsematest: VPATH += src/pmqtest: VPATH += src/backfire: -VPATH += src/lib +VPATH += src/lib: +VPATH += src/libdl: VPATH += src/hackbench %.o: %.c @@ -61,7 +62,7 @@ all: $(TARGETS) hwlatdetect # Include dependency files, automatically generate them if needed. -include $(sources:.c=.d) -cyclictest: cyclictest.o librttest.a +cyclictest: cyclictest.o librttest.a dl_syscalls.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) $(NUMA_LIBS) signaltest: signaltest.o librttest.a @@ -74,7 +75,7 @@ hwlatdetect: src/hwlatdetect/hwlatdetect.py chmod +x src/hwlatdetect/hwlatdetect.py ln -s src/hwlatdetect/hwlatdetect.py hwlatdetect -rt-migrate-test: rt-migrate-test.o +rt-migrate-test: rt-migrate-test.o dl_syscalls.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) ptsematest: ptsematest.o librttest.a diff --git a/src/cyclictest/cyclictest.c b/src/cyclictest/cyclictest.c index 11b6cea..2aef54c 100644 --- a/src/cyclictest/cyclictest.c +++ b/src/cyclictest/cyclictest.c @@ -38,6 +38,8 @@ #include "rt-utils.h" +#include "dl_syscalls.h" + #define DEFAULT_INTERVAL 1000 #define DEFAULT_DISTANCE 500 @@ -107,6 +109,8 @@ extern int clock_nanosleep(clockid_t __clock_id, int __flags, #define KVARNAMELEN 32 #define KVALUELEN 32 +#define CPU_USAGE 1.0 + int enable_events; static char *policyname(int policy); @@ -138,6 +142,8 @@ struct thread_param { unsigned long interval; int cpu; int node; + int num_threads; + }; /* Struct for statistics */ @@ -174,6 +180,7 @@ static int use_nsecs = 0; static int refresh_on_max; static int force_sched_other; static int priospread = 0; +static float cpu_usage = CPU_USAGE; static pthread_cond_t refresh_on_max_cond = PTHREAD_COND_INITIALIZER; static pthread_mutex_t refresh_on_max_lock = PTHREAD_MUTEX_INITIALIZER; @@ -678,6 +685,7 @@ void *timerthread(void *param) { struct thread_param *par = param; struct sched_param schedp; + struct sched_param2 schedp2; struct sigevent sigev; sigset_t sigset; timer_t timer; @@ -718,11 +726,24 @@ void *timerthread(void *param) tspec.it_interval = interval; } - memset(&schedp, 0, sizeof(schedp)); - schedp.sched_priority = par->prio; - if (setscheduler(0, par->policy, &schedp)) - fatal("timerthread%d: failed to set priority to %d\n", par->cpu, par->prio); + if(par->policy == SCHED_DEADLINE) + { + memset(&schedp2, 0, sizeof(schedp2)); + schedp2.sched_priority = par->prio; + schedp2.sched_runtime = (par->interval / par->num_threads) * cpu_usage; + schedp2.sched_period = par->interval; + schedp2.sched_deadline = par->interval; + if (sched_setscheduler2(0, SCHED_DEADLINE, &schedp2)) + fatal("timerthread%d: failed to set priority to %d\n", par->cpu, par->prio); + } + else + { + memset(&schedp, 0, sizeof(schedp)); + schedp.sched_priority = par->prio; + if (setscheduler(0, par->policy, &schedp)) + fatal("timerthread%d: failed to set priority to %d\n", par->cpu, par->prio); + } /* Get current time */ clock_gettime(par->clock, &now); @@ -925,6 +946,8 @@ static void display_help(int error) " to modify value to minutes, hours or days\n" "-E --event event tracing (used with -b)\n" "-f --ftrace function trace (when -b is active)\n" + "-g USAGE --cpu-usage USAGE when using SCHED_DEADLINE total task runtimes\n" + " are allowed to use only USAGE(default 1.0) of cpu\n" "-h --histogram=US dump a latency histogram to stdout after the run\n" " (with same priority about many threads)\n" " US is the max time to be be tracked in microseconds\n" @@ -955,7 +978,7 @@ static void display_help(int error) " format: n:c:v n=tasknum c=count v=value in us\n" "-w --wakeup task wakeup tracing (used with -b)\n" "-W --wakeuprt rt task wakeup tracing (used with -b)\n" - "-y POLI --policy=POLI policy of realtime thread, POLI may be fifo(default) or rr\n" + "-y POLI --policy=POLI policy of realtime thread, POLI may be fifo(default), rr or dl(use SCHED_DEADLINE)\n" " format: --policy=fifo(default) or --policy=rr\n" "-S --smp Standard SMP testing: options -a -t -n and\n" " same priority of all threads\n" @@ -1006,6 +1029,8 @@ static void handlepolicy(char *polname) policy = SCHED_FIFO; else if (strncasecmp(polname, "rr", 2) == 0) policy = SCHED_RR; + else if (strncasecmp(polname, "dl", 2) == 0) + policy = SCHED_DEADLINE; else /* default policy if we don't recognize the request */ policy = SCHED_OTHER; } @@ -1030,6 +1055,9 @@ static char *policyname(int policy) case SCHED_IDLE: policystr = "idle"; break; + case SCHED_DEADLINE: + policystr = "dl"; + break; } return policystr; } @@ -1083,9 +1111,10 @@ static void process_options (int argc, char *argv[]) {"numa", no_argument, NULL, 'U'}, {"latency", required_argument, NULL, 'e'}, {"priospread", no_argument, NULL, 'Q'}, + {"cpu-usage", required_argument, NULL, 'g'}, {NULL, 0, NULL, 0} }; - int c = getopt_long(argc, argv, "a::b:Bc:Cd:Efh:H:i:Il:MnNo:O:p:PmqQrsSt::uUvD:wWT:y:e:", + int c = getopt_long(argc, argv, "a::b:Bc:Cd:Efg:h:H:i:Il:MnNo:O:p:PmqQrsSt::uUvD:wWT:y:e:", long_options, &option_index); if (c == -1) break; @@ -1111,6 +1140,7 @@ static void process_options (int argc, char *argv[]) case 'd': distance = atoi(optarg); break; case 'E': enable_events = 1; break; case 'f': tracetype = FUNCTION; ftrace = 1; break; + case 'g': cpu_usage = atof(optarg); break; case 'H': histofall = 1; /* fall through */ case 'h': histogram = atoi(optarg); break; case 'i': interval = atoi(optarg); break; @@ -1255,12 +1285,12 @@ static void process_options (int argc, char *argv[]) priority = num_threads+1; } - if (priority && (policy != SCHED_FIFO && policy != SCHED_RR)) { + if (priority && (policy != SCHED_FIFO && policy != SCHED_RR && policy != SCHED_DEADLINE)) { fprintf(stderr, "policy and priority don't match: setting policy to SCHED_FIFO\n"); policy = SCHED_FIFO; } - if ((policy == SCHED_FIFO || policy == SCHED_RR) && priority == 0) { + if ((policy == SCHED_FIFO || policy == SCHED_RR || policy == SCHED_DEADLINE) && priority == 0) { fprintf(stderr, "defaulting realtime priority to %d\n", num_threads+1); priority = num_threads+1; @@ -1565,7 +1595,7 @@ int main(int argc, char **argv) } par->prio = priority; - if (priority && (policy == SCHED_FIFO || policy == SCHED_RR)) + if (priority && (policy == SCHED_FIFO || policy == SCHED_RR || policy == SCHED_DEADLINE)) par->policy = policy; else { par->policy = SCHED_OTHER; @@ -1585,6 +1615,7 @@ int main(int argc, char **argv) par->max_cycles = max_cycles; par->stats = stat; par->node = node; + par->num_threads = num_threads; switch (setaffinity) { case AFFINITY_UNSPECIFIED: par->cpu = -1; break; case AFFINITY_SPECIFIED: par->cpu = affinity; break; diff --git a/src/include/dl_syscalls.h b/src/include/dl_syscalls.h new file mode 120000 index 0000000..a9fc486 --- /dev/null +++ b/src/include/dl_syscalls.h @@ -0,0 +1 @@ +../libdl/dl_syscalls.h \ No newline at end of file diff --git a/src/libdl/COPYING b/src/libdl/COPYING new file mode 100644 index 0000000..4e4f51b --- /dev/null +++ b/src/libdl/COPYING @@ -0,0 +1,345 @@ +The following is the original GNU GPL v2 under which schedtool is released. +schedtool is (c) by Freek, 2004, 2005, 2006, 2007 + +-- -- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/src/libdl/Makefile b/src/libdl/Makefile new file mode 100644 index 0000000..8086359 --- /dev/null +++ b/src/libdl/Makefile @@ -0,0 +1,47 @@ +# go on and adjust here if you don't like those flags +CFLAGS=-Os -s -pipe -DDEBUG +#CFLAGS=-Wall -Os -fomit-frame-pointer -s -pipe -DDEBUG +CC=$(CROSS_COMPILE)gcc +# likewise, if you want to change the destination prefix +DESTPREFIX=/usr/local +DESTDIR=lib +TARGET=libdl +DOCS=COPYING README +RELEASE=$(shell basename `pwd`) + +all: static shared + +clean: + rm -f *.o $(TARGET).so* $(TARGET).a + +distclean: clean + rm -f *~ *.s + +install: all + install -d $(DESTPREFIX)/$(DESTDIR) + install -c $(TARGET) $(DESTPREFIX)/$(DESTDIR) + +install-doc: + install -d $(DESTPREFIX)/share/doc/libdl + install -c $(DOCS) $(DESTPREFIX)/share/doc/libdl + +release: distclean release_gz release_bz2 + @echo --- $(RELEASE) released --- + +release_gz: distclean + @echo Building tar.gz + ( cd .. ; tar czf $(RELEASE).tar.gz $(RELEASE) ) + +release_bz2: distclean + @echo Building tar.bz2 + ( cd .. ; tar cjf $(RELEASE).tar.bz2 $(RELEASE) ) + +static: $(TARGET).o + $(AR) rcs $(TARGET).a $(TARGET).o + +shared: $(TARGET).o + $(CC) -shared -Wl,-soname,$(TARGET).so.1 -o $(TARGET).so.1.0.0 $(TARGET).o + +$(TARGET).o: dl_syscalls.h dl_syscalls.c + $(CC) -fPIC $(CFLAGS) -c dl_syscalls.c -o $(TARGET).o + diff --git a/src/libdl/README b/src/libdl/README new file mode 100644 index 0000000..1592716 --- /dev/null +++ b/src/libdl/README @@ -0,0 +1,54 @@ +Libdl +Copyright (C) 2009-2010 Dario Faggioli +Release under GPL, version 2 (see COPYING) +Use at your own risk. + +ABOUT +----- + +Libdl provides what is needed to use the SCHED_DEADLINE scheduling +policy and all its features from an userspace program. +This is needed since the new system calls, flags, etc. that make +it possible are not (yet? :-P) included in the standard library. + + +PREREQUISITES +------------- + +The new interface is only implemented by kernels patched to support +the SCHED_DEADLINE schedulign policy. + +Instructions on how to download and compile such a kernel are available +on the development Website of the project: + + http://gitorious.org/sched_deadline/pages/Home + + +USAGE +----- + +To compile the library as a static or shared object: + +$> make static or $> make shared or just $> make + +To install in the default path (/usr/local/lib): + +#> make install + +To customize the install path change DESTPREFIX and DESTDIR +in the Makefile. + +To statically include the files in your project: + - copy dl_syscalls.h and dl_syscalls.c in your header and + source folder; + - edit your Makefile so that targets where the new interface + is used depends on dl_syscall.c; + - compile and install it as usual. + + +CONTACT +------- + +For bug reporting, as well as for any other comment, feel free to +contact me at raistlin@linux.it. + diff --git a/src/libdl/dl_syscalls.c b/src/libdl/dl_syscalls.c new file mode 100644 index 0000000..cb4ec22 --- /dev/null +++ b/src/libdl/dl_syscalls.c @@ -0,0 +1,19 @@ +#include "dl_syscalls.h" +#include + +int sched_setscheduler2(pid_t pid, int policy, + const struct sched_param2 *param) +{ + return syscall(__NR_sched_setscheduler2, pid, policy, param); +} + +int sched_setparam2(pid_t pid, + const struct sched_param2 *param) +{ + return syscall(__NR_sched_setparam2, pid, param); +} + +int sched_getparam2(pid_t pid, struct sched_param2 *param) +{ + return syscall(__NR_sched_getparam2, pid, param); +} diff --git a/src/libdl/dl_syscalls.h b/src/libdl/dl_syscalls.h new file mode 100644 index 0000000..a458120 --- /dev/null +++ b/src/libdl/dl_syscalls.h @@ -0,0 +1,64 @@ +/* + * Libdl + * (C) Dario Faggioli , 2009, 2010 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License (COPYING file) for more details. + * + */ + +#ifndef __DL_SYSCALLS__ +#define __DL_SYSCALLS__ + +#include +#include +#include +#include + +#define SCHED_DEADLINE 6 + +/* XXX use the proper syscall numbers */ +#ifdef __x86_64__ +#define __NR_sched_setparam2 312 +#define __NR_sched_getparam2 313 +#define __NR_sched_setscheduler2 314 +#endif + +#ifdef __i386__ +#define __NR_sched_setparam2 349 +#define __NR_sched_getparam2 350 +#define __NR_sched_setscheduler2 351 +#endif + +#ifdef __arm__ +#define __NR_sched_setscheduler2 378 +#define __NR_sched_setparam2 379 +#define __NR_sched_getparam2 380 +#endif + +struct sched_param2 { + int sched_priority; + unsigned int sched_flags; + __u64 sched_runtime; + __u64 sched_deadline; + __u64 sched_period; + + __u64 __unused[12]; +}; + +int sched_setscheduler2(pid_t pid, int policy, + const struct sched_param2 *param); + +int sched_setparam2(pid_t pid, + const struct sched_param2 *param); + +int sched_getparam2(pid_t pid, struct sched_param2 *param); + +#endif /* __DL_SYSCALLS__ */ + diff --git a/src/rt-migrate-test/rt-migrate-test.c b/src/rt-migrate-test/rt-migrate-test.c index e3c7a09..fd75568 100644 --- a/src/rt-migrate-test/rt-migrate-test.c +++ b/src/rt-migrate-test/rt-migrate-test.c @@ -45,12 +45,15 @@ #include #include +#include "dl_syscalls.h" + #define gettid() syscall(__NR_gettid) #ifndef VERSION_STRING #define VERSION_STRING 0.3 #endif + int nr_tasks; int lfd; @@ -109,6 +112,15 @@ static void ftrace_write(const char *fmt, ...) #define PROGRESS_CHARS 70 +/* + * The period is the sleep time of the main thread + its wcet. + * The other threads should fit in the period, + * since run_interval should be much lower than interval, + * even if we don't use SCHED_DEADLINE + */ +#define PERIOD (nano2usec(interval)+50000) +#define POLICY SCHED_FIFO + static unsigned long long interval = INTERVAL; static unsigned long long run_interval = RUN_INTERVAL; static unsigned long long max_err = MAX_ERR; @@ -116,6 +128,7 @@ static int nr_runs = NR_RUNS; static int prio_start = PRIO_START; static int check; static int stop; +static int policy = POLICY; static unsigned long long now; @@ -181,6 +194,7 @@ static void usage(char **argv) printf("%s %1.2f\n", p, VERSION_STRING); printf("Usage:\n" "%s nr_tasks\n\n" + "-y sched --policy sched use scheduler sched(dl or fifo) \n" "-p prio --prio prio base priority to start RT tasks with (2) \n" "-r time --run-time time Run time (ms) to busy loop the threads (20)\n" "-s time --sleep-time time Sleep time (ms) between intervals (100)\n" @@ -199,6 +213,7 @@ static void parse_options (int argc, char *argv[]) /** Options for getopt */ static struct option long_options[] = { {"prio", required_argument, NULL, 'p'}, + {"policy", required_argument, NULL, 'y'}, {"run-time", required_argument, NULL, 'r'}, {"sleep-time", required_argument, NULL, 's'}, {"maxerr", required_argument, NULL, 'm'}, @@ -207,7 +222,7 @@ static void parse_options (int argc, char *argv[]) {"help", no_argument, NULL, '?'}, {NULL, 0, NULL, 0} }; - int c = getopt_long (argc, argv, "p:r:s:m:l:ch", + int c = getopt_long (argc, argv, "p:r:s:m:l:y:g:ch", long_options, &option_index); if (c == -1) break; @@ -220,6 +235,12 @@ static void parse_options (int argc, char *argv[]) case 'l': nr_runs = atoi(optarg); break; case 'm': max_err = usec2nano(atoi(optarg)); break; case 'c': check = 1; break; + case 'y': + if(strncasecmp(optarg, "dl", 2) == 0) + policy = SCHED_DEADLINE; + else + policy = SCHED_FIFO; + break; case '?': case 'h': usage(argv); @@ -331,18 +352,41 @@ static unsigned long busy_loop(unsigned long long start_time) do { l++; time = get_time(); - } while ((time - start_time) < RUN_INTERVAL); + } while ((time - start_time) < run_interval); return l; } +static void timespec_add(struct timespec * a, const struct timespec * b) +{ + a->tv_nsec += b->tv_nsec; + a->tv_sec += b->tv_sec; + if(a->tv_nsec > 1000000000) + { + a->tv_nsec -= 1000000000; + a->tv_sec += 1; + } + +} + void *start_task(void *data) { long id = (long)data; unsigned long long start_time; + + struct sched_param param = { .sched_priority = id + prio_start, }; + + struct sched_param2 param2 = { + .sched_priority = 0, + .sched_runtime = 2*nano2usec(run_interval), + .sched_period = PERIOD, + .sched_deadline = PERIOD - (id+1)*nano2usec(run_interval), + + }; + int ret; int high = 0; cpu_set_t cpumask; @@ -350,6 +394,7 @@ void *start_task(void *data) int cpu = 0; unsigned long l; long pid; + struct timespec t_next, t_period; ret = sched_getaffinity(0, sizeof(save_cpumask), &save_cpumask); if (ret < 0) @@ -361,10 +406,24 @@ void *start_task(void *data) if (id == nr_tasks-1) high = 1; - ret = sched_setscheduler(0, SCHED_FIFO, ¶m); - if (ret < 0 && !id) - fprintf(stderr, "Warning, can't set priorities\n"); + if (policy == SCHED_DEADLINE) + { + ret = sched_setscheduler2(0, SCHED_DEADLINE, ¶m2); + if (ret < 0 && !id) + fprintf(stderr, "Warning, can't set priorities\n"); + } + else + { + ret = sched_setscheduler(0, policy, ¶m); + if (ret < 0 && !id) + fprintf(stderr, "Warning, can't set priorities\n"); + } + t_period.tv_sec = PERIOD / 1000000; + t_period.tv_nsec = usec2nano(PERIOD / 1000000); + + pthread_barrier_wait(&start_barrier); + clock_gettime(CLOCK_MONOTONIC_RAW, &t_next); while (!done) { if (high) { /* rotate around the CPUS */ @@ -381,6 +440,8 @@ void *start_task(void *data) l = busy_loop(start_time); record_time(id, start_time, l); pthread_barrier_wait(&end_barrier); + timespec_add(&t_next, &t_period); + clock_nanosleep(CLOCK_MONOTONIC_RAW, TIMER_ABSTIME, &t_next, NULL); } return (void*)pid; @@ -461,7 +522,11 @@ int main (int argc, char **argv) long i; int ret; struct timespec intv; + struct sched_param param; + struct sched_param2 param2; + + struct timespec t_next, t_period; parse_options(argc, argv); @@ -472,6 +537,7 @@ int main (int argc, char **argv) else nr_tasks = count_cpus() + 1; + threads = malloc(sizeof(*threads) * nr_tasks); if (!threads) perr("malloc"); @@ -530,19 +596,34 @@ int main (int argc, char **argv) /* up our prio above all tasks */ memset(¶m, 0, sizeof(param)); - param.sched_priority = nr_tasks + prio_start; - if (sched_setscheduler(0, SCHED_FIFO, ¶m)) - fprintf(stderr, "Warning, can't set priority of main thread!\n"); + if(policy == SCHED_DEADLINE) + { + param2.sched_priority = nr_tasks + prio_start; + param2.sched_runtime = 50000; + param2.sched_period = PERIOD; + param2.sched_deadline = PERIOD; + if (sched_setscheduler2(0, SCHED_DEADLINE, ¶m2)) + fprintf(stderr, "Warning, can't set priority of main thread!\n"); + } + else + { + param.sched_priority = nr_tasks + prio_start; + if (sched_setscheduler(0, policy, ¶m)) + fprintf(stderr, "Warning, can't set priority of main thread!\n"); + } - intv.tv_sec = nano2sec(INTERVAL); - intv.tv_nsec = INTERVAL % sec2nano(1); + intv.tv_sec = nano2sec(interval); + intv.tv_nsec = interval % sec2nano(1); print_progress_bar(0); setup_ftrace_marker(); + pthread_barrier_wait(&start_barrier); + clock_gettime(CLOCK_MONOTONIC_RAW, &t_next); + for (loop=0; loop < nr_runs; loop++) { unsigned long long end; @@ -563,6 +644,9 @@ int main (int argc, char **argv) pthread_barrier_wait(&end_barrier); + timespec_add(&t_next, &t_period); + clock_nanosleep(CLOCK_MONOTONIC_RAW, TIMER_ABSTIME, &t_next, NULL); + if (stop || (check && check_times(loop))) { loop++; nr_runs = loop;