From Fredrik_Oestman at mentor.com Fri Jan 4 06:53:59 2013 From: Fredrik_Oestman at mentor.com (Oestman, Fredrik) Date: Fri, 4 Jan 2013 11:53:59 +0000 Subject: [lttng-dev] Cross-domain influence on overhead Message-ID: <524C960C5DFC794E82BE548D825F05CF5BC8AEAD@EU-MBX-04.mgc.mentorg.com> Hi, I've noticed the following somewhat puzzling effect on both Intel and ARM architecture computers: If all trace events are enabled in one domain only, either kernel or user space, and there are lots of static tracepoints instrumented in the other, then these inactive tracepoints start causing overhead of about the same magnitude as if they were active, as if trace events were enabled in this domain. Is there any obvious explanation to this behaviour? Cheers, Fredrik ?stman http://go.mentor.com/sourceryanalyzer/ From matthew.khouzam at ericsson.com Fri Jan 4 11:43:32 2013 From: matthew.khouzam at ericsson.com (Matthew Khouzam) Date: Fri, 4 Jan 2013 11:43:32 -0500 Subject: [lttng-dev] Unable to import big LTTng traces In-Reply-To: <50CA1992.9020706@voxpopuli.im> References: <50CA1992.9020706@voxpopuli.im> Message-ID: <50E706B4.7090509@ericsson.com> There is a limit to the actual size of the trace being imported depending on your ram, the parser reads an index and keeps it in memory. This requires approx 0.004% of the trace size using default settings. This means if you load a 1 tb trace, you need 400 mb of ram. 400 mb of ram needs about 16k of ram plus overhead so let's say 1-2 mb. Is it a kernel trace? if so then you're also building the state system at the same time and the statistics... this will take a short while. Normally under 2 minutes (I have a core 2 duo laptop with a 5400 rpm hdd and it takes 2min for 433 mb with no state system) , so a coffee/tea break, when you're back, you will have lightning fast views. :) Maybe we should put a more descriptive please wait message. On 12-12-13 01:08 PM, Alexandre Montplaisir wrote: > On 12-12-12 12:59 AM, Radhika Chowdary wrote: >> Hi >> >> I am using linuxtools plugins for importing LTTng traces. I have a trace >> folder of size 400MB and when I try to import it in the Traces folder it >> takes for ever to import it. At the bottom left corner I see Indexing... >> Events view gets populated soon but not others. > Hi, > > It is expected that the indexing phase takes a while for very large > trace. It could probably be optimized a bit too, since we haven't spent > much time on performance improvements. Good news is that once indexed, > it will be faster to reopen the same trace later on. > > We have not yet implemented a percentage progression monitor for the > indexing job. This is not trivial since it has to be implemented > differently depending on the trace type, but would definitely be nice to > have. > > If you use the latest master branch, the timestamps for the start and > end of the histogram are now correctly formatted, so it is possible to > know roughly where the indexing is at, provided you know the end time of > your trace. I'd suggest trying that out to make sure it's not stopping > at some point, which would be a bug. > >> Is there a limit on the size of traces that it can import? > There is no theoretical limit on the trace size that can be imported. It > is capped only by your patience ;) and the amount of available disk > space, since the index files can be quite big too. > > > Cheers, > Alex > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev From sysdcs at gmail.com Fri Jan 4 14:30:03 2013 From: sysdcs at gmail.com (Phil Wilshire) Date: Fri, 4 Jan 2013 14:30:03 -0500 Subject: [lttng-dev] System Hang Message-ID: Hi, Just getting back into lttng after quite a few years I need to set up a continuous trace on a system. Every 10 seconds I stop one session and start another to give me individual files for each 10 second segment. I originally intended to start the next session before stopping the previous but that was causing the sessond to hang. Ever so often I can start the trace and the trace file is generated but ongoing commands to lttng are ignored. The new trace file then grows until all the disk space is used. sessiond seems to be hung I have the kernel dmseg log attached and I also have the trace file if needed [ 345.223564] LTT state dump thread start [ 345.231033] LTT state dump end [ 353.586011] ring buffer relay-metadata: 3604 records written, 0 records overrun [ 353.590023] ring buffer relay-discard, cpu 0: 408474 records written, 0 records overrun [ 353.590237] ring buffer relay-discard, cpu 1: 390793 records written, 0 records overrun [ 353.590237] ring buffer relay-discard, cpu 2: 363560 records written, 0 records overrun [ 353.590685] ring buffer relay-discard, cpu 3: 518867 records written, 0 records overrun [ 355.720753] LTTng: state dump begin [ 355.720753] LTT state dump thread start [ 355.732034] LTT state dump end [ 364.111388] ring buffer relay-metadata: 3604 records written, 0 records overrun [ 364.120334] ring buffer relay-discard, cpu 0: 409693 records written, 0 records overrun [ 364.120334] ring buffer relay-discard, cpu 1: 401971 records written, 0 records overrun [ 364.121438] ring buffer relay-discard, cpu 2: 380074 records written, 0 records overrun [ 364.122187] ring buffer relay-discard, cpu 3: 524538 records written, 0 records overrun [ 366.259690] LTTng: state dump begin [ 366.259690] LTT state dump thread start [ 366.266253] LTT state dump end [ 374.633764] ring buffer relay-metadata: 3604 records written, 0 records overrun [ 374.640024] ring buffer relay-discard, cpu 0: 430919 records written, 0 records overrun [ 374.640024] ring buffer relay-discard, cpu 1: 387021 records written, 0 records overrun [ 374.641033] ring buffer relay-discard, cpu 2: 370007 records written, 0 records overrun [ 374.641033] ring buffer relay-discard, cpu 3: 528606 records written, 0 records overrun [ 376.795384] LTTng: state dump begin [ 376.795384] LTT state dump thread start [ 601.060274] INFO: task lttng-sessiond:2885 blocked for more than 120 seconds. [ 601.069038] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 601.077626] lttng-sessiond D ffff880074456b18 0 2885 1 0x10000000 [ 601.085210] ffff88006c0679f8 0000000000000082 0000000000000001 ffff88007b0a4140 [ 601.094031] ffff88006c0679a8 ffff880074456840 ffff88006c067fd8 ffff88006c067fd8 [ 601.105026] 0000000000011c80 ffff880074456840 0000000000000000 ffff88006c067a68 [ 601.112170] Call Trace: [ 601.116027] [] schedule+0x5b/0x5d [ 601.121025] [] lttng_statedump_start+0x5aa/0x623 [lttng_statedump] [ 601.129035] [] ? abort_exclusive_wait+0x8f/0x8f [ 601.136030] [] lttng_session_enable+0x52d/0x55b [lttng_tracer] [ 601.144034] [] ? abort_exclusive_wait+0x8f/0x8f [ 601.150039] [] lttng_session_ioctl+0x15f/0x225 [lttng_tracer] [ 601.158042] [] ? sock_recvmsg+0xa4/0xb9 [ 601.163185] [] ? lookup_page_cgroup+0x36/0x4d [ 601.169453] [] ? cpumask_any_but+0x29/0x38 [ 601.175508] [] ? trace_preempt_on+0x12/0x2f [ 601.182031] [] ? sub_preempt_count+0x97/0xc0 [ 601.187735] [] ? _raw_spin_unlock+0x2a/0x35 [ 601.193922] [] ? spin_unlock+0xe/0x10 [ 601.200027] [] ? do_wp_page+0x26f/0x563 [ 601.206028] [] ? trace_preempt_off+0x12/0x30 [ 601.212031] [] ? add_preempt_count+0xb4/0xcf [ 601.218043] [] ? handle_pte_fault+0x6c6/0x76c [ 601.223737] [] ? verify_iovec+0x52/0xa3 [ 601.229426] [] ? handle_mm_fault+0x199/0x1a9 [ 601.236033] [] ? do_page_fault+0x2f6/0x377 [ 601.242034] [] ? __event_probe__sys_mprotect+0xf5/0xf5 [lttng_tracer] [ 601.251031] [] vfs_ioctl+0x22/0x3a [ 601.256029] [] do_vfs_ioctl+0x3c4/0x407 [ 601.261188] [] ? fget_light+0x91/0x9d [ 601.267026] [] sys_ioctl+0x47/0x6a [ 601.272050] [] tracesys+0xd9/0xde cat /proc/cpuinfo processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 28 model name : Intel(R) Atom(TM) CPU D525 @ 1.80GHz stepping : 10 microcode : 0x107 cpu MHz : 1799.823 cache size : 512 KB physical id : 0 siblings : 4 core id : 0 cpu cores : 2 apicid : 0 initial apicid : 0 fpu : yes fpu_exception : yes cpuid level : 10 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good nopl aperfmperf pni dtes64 monitor ds_cpl tm2 ssse3 cx16 xtpr pdcm movbe lahf_lm dts bogomips : 1775.61 clflush size : 64 cache_alignment : 64 address sizes : 36 bits physical, 48 bits virtual power management: (repeated for 3 other cpus ) uname -a Linux 3.2.21-x510v1 #1 SMP PREEMPT Thu Dec 20 11:24:36 EST 2012 x86_64 GNU/Linux Script used to run trace ================================================= #!/bin/sh xx=`/bin/date +"%s"` yy="yy" zz="zz" log_xx=/home/pswuser/trace/log/psw-${xx}.log log_yy=/home/pswuser/trace/log/psw-${yy}.log log_zz=/home/pswuser/trace/log/psw-${zz}.log #depmod mkdir -p /home/pswuser/trace mount -t tmpfs -o size=500M tmpfs /home/pswuser/trace mkdir -p /home/pswuser/trace/log touch /home/pswuser/trace/run_trace sleep 20 if [ -f /home/pswuser/trace/run_trace ] ; then echo "lttng create" > ${log_xx} lttng create psw-${xx} \ -o /home/pswuser/trace/psw-${xx} >> ${log_xx} 2>&1 echo "lttng enable-event" >> ${log_xx} sleep 1 lttng enable-event -a -k -s psw-${xx} >> ${log_xx} 2>&1 sleep 1 echo "lttng start" >> ${log_xx} lttng start psw-${xx} >> ${log_xx} 2>&1 sleep 1 fi while [ 1 -gt 0 ] ; do sleep 7 yy=`/bin/date +"%s"` log_yy=/home/pswuser/trace/log/psw-${yy}.log #stop xx if [ -d /home/pswuser/trace/psw-${xx} ] ; then echo "lttng stop" >> ${log_xx} lttng stop psw-${xx} >> ${log_xx} 2>&1 sleep 1 echo "lttng destroy" >> ${log_xx} lttng destroy psw-${xx} >> ${log_xx} 2>&1 echo "lttng done" >> ${log_xx} fi # start yy after stopping xx if [ -f /home/pswuser/trace/run_trace ] ; then echo "lttng create ${yy} after closing ${xx}" > ${log_yy} lttng create psw-${yy} \ -o /home/pswuser/trace/psw-${yy} >> ${log_yy} 2>&1 sleep 1 echo "lttng enable_event" >> ${log_yy} lttng enable-event -a -k -s psw-${yy} >> ${log_yy} 2>&1 sleep 1 echo "lttng start" >> ${log_yy} lttng start psw-${yy} >> ${log_yy} 2>&1 fi # check zz # delete unless detected or detected2 is present if [ ! -f /home/pswuser/bin/delay-detected ] && [ ! -f /home/pswuser/bin/delay-detected2 ] ; then echo "lttng delete files" >> ${log_zz} rm -rf /home/pswuser/trace/psw-${zz}* >> ${log_zz} 2>&1 #if [ $? -eq 0 ] ; then rm ${log_zz} ; fi fi # delete second snapshot if [ -f /home/pswuser/bin/delay-detected2 ] ; then rm -f /home/pswuser/bin/delay-detected2 # no more tracing once event detected rm -f /home/pswuser/trace/run_trace fi # trigger second snapshot delete first snapshot if [ -f /home/pswuser/bin/delay-detected ] ; then rm -f /home/pswuser/bin/delay-detected touch /home/pswuser/bin/delay-detected2 fi # ls -l /lttng-traces/psw-* # zz (delete candidate) is old xx echo "xx ${xx} yy ${yy} zz ${zz}" zz=${xx} log_zz=$log_xx # xx is now the new one xx=${yy} log_xx=$log_yy # check disk use if [ -d /home/pswuser/trace ] ; then du -h /home/pswuser/trace fi done ---------------------------------------- Any clues are welcome. Another question. Would it be possible to do this by setting up a ring buffer that will wrap around after a certain time. I can easily timestamp the event I am looking for and then capture the buffer containing the event. Regards Phil Wilshire -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander.kampmann at gmx.de Sat Jan 5 14:47:25 2013 From: alexander.kampmann at gmx.de (Alexander Kampmann) Date: Sat, 05 Jan 2013 20:47:25 +0100 Subject: [lttng-dev] Reading cache misses in Userspace? Message-ID: <50E8834D.1010802@gmx.de> hey, I would like to find out which part of my application causes most cache misses. So I tried to add userspace events to my application. I hoped LTTng would give me some mean of determining between which tracepoints the most cache misses occur. I started a session like that: sudo lttng create session sudo lttng enable-event -a -u sudo lttng add-context -u -t perf:LLC-load-misses -t perf:LLC-store-misses -t perf:LLC-prefetch-misses I get: Error: perf:LLC-prefetch-misses: UST invalid context Error: perf:LLC-store-misses: UST invalid context Error: perf:LLC-load-misses: UST invalid context Does this mean I can not add perf:LLC-* context to my userspace events? Is there any way to figure out which part of my application causes cache misses? If I use sudo lttng add-context -k -t perf:LLC-load-misses -t perf:LLC-store-misses -t perf:LLC-prefetch-misses instead, I don't get an error, but the babeltrace output does not contain any cache miss counts as well. I would appreciate any help, Alex From David.OShea at quantum.com Sun Jan 6 23:40:03 2013 From: David.OShea at quantum.com (David OShea) Date: Mon, 7 Jan 2013 04:40:03 +0000 Subject: [lttng-dev] babletrace with python bindings In-Reply-To: <20121219183932.GA9587@Krystal> References: <20121218184045.288000@gmx.com> <20121219183932.GA9587@Krystal> Message-ID: <20998D40D9A2B7499CA5A3A2666CB1EB19F8ABF4@ZURMSG1.QUANTUM.com> > -----Original Message----- > From: Mathieu Desnoyers [mailto:mathieu.desnoyers at efficios.com] > Sent: Thursday, 20 December 2012 5:10 AM > To: ajonwa ajonwa > Cc: lttng-dev at lists.lttng.org > Subject: Re: [lttng-dev] babletrace with python bindings > > * ajonwa ajonwa (ajonwa at gmx.com) wrote: > > Hello everyone, > > > > I get the following error message while attempting to compile > babeltrace with python bindings: [...] > This branch is currently in development, and might be out of sync with > the master branch of babeltrace at the moment. We don't have immediate > plans to work on it, but bontributions are welcome. Apologies for the late reply. I just wanted to point out that if you check out commit 24a3136a383, it does build. It's an older version of babeltrace, but does work despite some bugs. The main bug I recall is that iterator.set_pos(babeltrace.IterPos(babeltrace.SEEK_BEGIN)) doesn't fail immediately, and works in some traces, but sometimes results in a subsequent assertion failure in the Python interpreter after a few events have been read, or returns a bogus event at the start of the trace. Quite possibly this is a babeltrace bug that has been fixed already. Regards, David ---------------------------------------------------------------------- The information contained in this transmission may be confidential. Any disclosure, copying, or further distribution of confidential information is not permitted unless such privilege is explicitly granted in writing by Quantum. Quantum reserves the right to have electronic communications, including email and attachments, sent across its networks filtered through anti virus and spam software programs and retain such messages in order to comply with applicable data security and retention requirements. Quantum is not responsible for the proper and complete transmission of the substance of this communication or for any delay in its receipt. From mathieu.desnoyers at efficios.com Mon Jan 7 08:44:04 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 7 Jan 2013 08:44:04 -0500 Subject: [lttng-dev] Cross-domain influence on overhead In-Reply-To: <524C960C5DFC794E82BE548D825F05CF5BC8AEAD@EU-MBX-04.mgc.mentorg.com> References: <524C960C5DFC794E82BE548D825F05CF5BC8AEAD@EU-MBX-04.mgc.mentorg.com> Message-ID: <20130107134404.GA30165@Krystal> * Oestman, Fredrik (Fredrik_Oestman at mentor.com) wrote: > Hi, > > I've noticed the following somewhat puzzling effect on both Intel and > ARM architecture computers: > > If all trace events are enabled in one domain only, either kernel or > user space, and there are lots of static tracepoints instrumented in > the other, then these inactive tracepoints start causing overhead of > about the same magnitude as if they were active, as if trace events > were enabled in this domain. > > Is there any obvious explanation to this behaviour? No, this would be really surprising. Can you provide your test script, and more details about the way you perform your benchmarks ? How is the overhead calculated ? From how many tracepoints hit ? How many processes spawned/exec() done ? How many tracepoints hit per process ? Thanks, Mathieu > > Cheers, > > Fredrik ?stman > > http://go.mentor.com/sourceryanalyzer/ > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon Jan 7 08:47:44 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 7 Jan 2013 08:47:44 -0500 Subject: [lttng-dev] Reading cache misses in Userspace? In-Reply-To: <50E8834D.1010802@gmx.de> References: <50E8834D.1010802@gmx.de> Message-ID: <20130107134744.GB30165@Krystal> * Alexander Kampmann (alexander.kampmann at gmx.de) wrote: > hey, > > I would like to find out which part of my application causes most cache > misses. So I tried to add userspace events to my application. I hoped > LTTng would give me some mean of determining between which tracepoints > the most cache misses occur. > > I started a session like that: > > sudo lttng create session > sudo lttng enable-event -a -u > sudo lttng add-context -u -t perf:LLC-load-misses -t > perf:LLC-store-misses -t perf:LLC-prefetch-misses > > I get: > > Error: perf:LLC-prefetch-misses: UST invalid context > Error: perf:LLC-store-misses: UST invalid context > Error: perf:LLC-load-misses: UST invalid context > > Does this mean I can not add perf:LLC-* context to my userspace events? > Is there any way to figure out which part of my application causes cache > misses? Currently, perf counters are only for kernel tracing (-k domain). We envision using those counters from user-space when Linux kernel support will be there. > > If I use > > sudo lttng add-context -k -t perf:LLC-load-misses -t > perf:LLC-store-misses -t perf:LLC-prefetch-misses > > instead, I don't get an error, but the babeltrace output does not > contain any cache miss counts as well. Does it contain _any_ performance counters at all ? Did you ensure that you issue add-context before you start tracing ? How many performance counters does your machine have ? Shown by dmesg, e.g.: dmesg |grep "generic reg" Thanks, Mathieu > > I would appreciate any help, > > Alex > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From Fredrik_Oestman at mentor.com Mon Jan 7 08:53:49 2013 From: Fredrik_Oestman at mentor.com (Oestman, Fredrik) Date: Mon, 7 Jan 2013 13:53:49 +0000 Subject: [lttng-dev] Cross-domain influence on overhead In-Reply-To: <20130107134404.GA30165@Krystal> References: <524C960C5DFC794E82BE548D825F05CF5BC8AEAD@EU-MBX-04.mgc.mentorg.com>, <20130107134404.GA30165@Krystal> Message-ID: <524C960C5DFC794E82BE548D825F05CF5BC8B0E2@EU-MBX-04.mgc.mentorg.com> Hi, Mathieu Desnoyers wrote: >No, this would be really surprising. Indeed. It appears to have been an artefact of the test setup which escaped our initial reviews. Very sorry for this! Cheers, Fredrik ?stman From yannick.brosseau at gmail.com Mon Jan 7 13:15:20 2013 From: yannick.brosseau at gmail.com (Yannick Brosseau) Date: Mon, 07 Jan 2013 13:15:20 -0500 Subject: [lttng-dev] Reading cache misses in Userspace? In-Reply-To: <50E8834D.1010802@gmx.de> References: <50E8834D.1010802@gmx.de> Message-ID: <50EB10B8.80703@gmail.com> On 2013-01-05 14:47, Alexander Kampmann wrote: > hey, > > I would like to find out which part of my application causes most > cache misses. So I tried to add userspace events to my application. I > hoped LTTng would give me some mean of determining between which > tracepoints the most cache misses occur. > > I started a session like that: > > sudo lttng create session > sudo lttng enable-event -a -u > sudo lttng add-context -u -t perf:LLC-load-misses -t > perf:LLC-store-misses -t perf:LLC-prefetch-misses > > I get: > > Error: perf:LLC-prefetch-misses: UST invalid context > Error: perf:LLC-store-misses: UST invalid context > Error: perf:LLC-load-misses: UST invalid context > > Does this mean I can not add perf:LLC-* context to my userspace > events? Is there any way to figure out which part of my application > causes cache misses? > > If I use > > sudo lttng add-context -k -t perf:LLC-load-misses -t > perf:LLC-store-misses -t perf:LLC-prefetch-misses > > instead, I don't get an error, but the babeltrace output does not > contain any cache miss counts as well. This context will be added to kernel events only, so you will need to active some kernel event to see them. sudo lttng enable-event -a -k would do the trick. You can also only activate some events to reduce the size of the trace. The sched* events and maybe the syscall would be interesting to place the perf counter to some specific place of the application. Yannick From matthew.khouzam at ericsson.com Mon Jan 7 14:10:42 2013 From: matthew.khouzam at ericsson.com (Matthew Khouzam) Date: Mon, 7 Jan 2013 14:10:42 -0500 Subject: [lttng-dev] Reading cache misses in Userspace? In-Reply-To: <50EB10B8.80703@gmail.com> References: <50E8834D.1010802@gmx.de> <50EB10B8.80703@gmail.com> Message-ID: <50EB1DB2.70109@ericsson.com> Hi, This may be redundant, but if you enable kernel tracing, you can still do your user space tracing and then correlate both of them to see what was done when your cache misses go through the roof. So that would be: lttng create-session mySession lttng enlable-event -a -k lttng add-context -k perf:LLC-load-misses ... lttng enable-event -a -u lttng start ./yourapp lttng stop lttng destroy Good luck, Matthew On 13-01-07 01:15 PM, Yannick Brosseau wrote: > On 2013-01-05 14:47, Alexander Kampmann wrote: >> hey, >> >> I would like to find out which part of my application causes most >> cache misses. So I tried to add userspace events to my application. I >> hoped LTTng would give me some mean of determining between which >> tracepoints the most cache misses occur. >> >> I started a session like that: >> >> sudo lttng create session >> sudo lttng enable-event -a -u >> sudo lttng add-context -u -t perf:LLC-load-misses -t >> perf:LLC-store-misses -t perf:LLC-prefetch-misses >> >> I get: >> >> Error: perf:LLC-prefetch-misses: UST invalid context >> Error: perf:LLC-store-misses: UST invalid context >> Error: perf:LLC-load-misses: UST invalid context >> >> Does this mean I can not add perf:LLC-* context to my userspace >> events? Is there any way to figure out which part of my application >> causes cache misses? >> >> If I use >> >> sudo lttng add-context -k -t perf:LLC-load-misses -t >> perf:LLC-store-misses -t perf:LLC-prefetch-misses >> >> instead, I don't get an error, but the babeltrace output does not >> contain any cache miss counts as well. > This context will be added to kernel events only, so you will need to > active some kernel event to see them. > sudo lttng enable-event -a -k would do the trick. You can also only > activate some events to reduce the size of the trace. The sched* events > and maybe the syscall would be interesting to place the perf counter to > some specific place of the application. > > Yannick > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev From mathieu.desnoyers at efficios.com Mon Jan 7 14:16:02 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 7 Jan 2013 14:16:02 -0500 Subject: [lttng-dev] System Hang In-Reply-To: References: Message-ID: <20130107191602.GA1342@Krystal> * Phil Wilshire (sysdcs at gmail.com) wrote: > Hi, > Just getting back into lttng after quite a few years > I need to set up a continuous trace on a system. > > Every 10 seconds I stop one session and start another to give me individual > files for each 10 second segment. > I originally intended to start the next session before stopping the > previous but that was causing the sessond to hang. > > Ever so often I can start the trace and the trace file is generated but > ongoing commands to lttng are ignored. The new trace file then grows until > all the disk space is used. sessiond seems to be hung > > > I have the kernel dmseg log attached and I also have the trace file if > needed > > > [ 345.223564] LTT state dump thread start > [ 345.231033] LTT state dump end > [ 353.586011] ring buffer relay-metadata: 3604 records written, 0 records > overrun > [ 353.590023] ring buffer relay-discard, cpu 0: 408474 records written, 0 > records overrun > [ 353.590237] ring buffer relay-discard, cpu 1: 390793 records written, 0 > records overrun > [ 353.590237] ring buffer relay-discard, cpu 2: 363560 records written, 0 > records overrun > [ 353.590685] ring buffer relay-discard, cpu 3: 518867 records written, 0 > records overrun > [ 355.720753] LTTng: state dump begin > [ 355.720753] LTT state dump thread start > [ 355.732034] LTT state dump end > [ 364.111388] ring buffer relay-metadata: 3604 records written, 0 records > overrun > [ 364.120334] ring buffer relay-discard, cpu 0: 409693 records written, 0 > records overrun > [ 364.120334] ring buffer relay-discard, cpu 1: 401971 records written, 0 > records overrun > [ 364.121438] ring buffer relay-discard, cpu 2: 380074 records written, 0 > records overrun > [ 364.122187] ring buffer relay-discard, cpu 3: 524538 records written, 0 > records overrun > [ 366.259690] LTTng: state dump begin > [ 366.259690] LTT state dump thread start > [ 366.266253] LTT state dump end > [ 374.633764] ring buffer relay-metadata: 3604 records written, 0 records > overrun > [ 374.640024] ring buffer relay-discard, cpu 0: 430919 records written, 0 > records overrun > [ 374.640024] ring buffer relay-discard, cpu 1: 387021 records written, 0 > records overrun > [ 374.641033] ring buffer relay-discard, cpu 2: 370007 records written, 0 > records overrun > [ 374.641033] ring buffer relay-discard, cpu 3: 528606 records written, 0 > records overrun > [ 376.795384] LTTng: state dump begin > [ 376.795384] LTT state dump thread start > [ 601.060274] INFO: task lttng-sessiond:2885 blocked for more than 120 > seconds. > [ 601.069038] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables > this message. > [ 601.077626] lttng-sessiond D ffff880074456b18 0 2885 1 > 0x10000000 > [ 601.085210] ffff88006c0679f8 0000000000000082 0000000000000001 > ffff88007b0a4140 > [ 601.094031] ffff88006c0679a8 ffff880074456840 ffff88006c067fd8 > ffff88006c067fd8 > [ 601.105026] 0000000000011c80 ffff880074456840 0000000000000000 > ffff88006c067a68 > [ 601.112170] Call Trace: > [ 601.116027] [] schedule+0x5b/0x5d Hrm, the kernel seems to be stuck in the statedump. We added new stuff there in LTTng-modules 2.1, so there is probably something fishy. This backtrace only tells us that the statedump is waiting for do_lttng_statedump to complete. I would really like to see the backtrace of all tasks in your system at that point (SysRQ t). For more info, see Documentation/sysrq.txt from your Linux kernel sources. Also the dump of sysrq-l (all active cpus) would be useful. Also sysrq-d (all locks held) might help. More below, > [ 601.121025] [] lttng_statedump_start+0x5aa/0x623 > [lttng_statedump] > [ 601.129035] [] ? abort_exclusive_wait+0x8f/0x8f > [ 601.136030] [] lttng_session_enable+0x52d/0x55b > [lttng_tracer] > [ 601.144034] [] ? abort_exclusive_wait+0x8f/0x8f > [ 601.150039] [] lttng_session_ioctl+0x15f/0x225 > [lttng_tracer] > [ 601.158042] [] ? sock_recvmsg+0xa4/0xb9 > [ 601.163185] [] ? lookup_page_cgroup+0x36/0x4d > [ 601.169453] [] ? cpumask_any_but+0x29/0x38 > [ 601.175508] [] ? trace_preempt_on+0x12/0x2f > [ 601.182031] [] ? sub_preempt_count+0x97/0xc0 > [ 601.187735] [] ? _raw_spin_unlock+0x2a/0x35 > [ 601.193922] [] ? spin_unlock+0xe/0x10 > [ 601.200027] [] ? do_wp_page+0x26f/0x563 > [ 601.206028] [] ? trace_preempt_off+0x12/0x30 > [ 601.212031] [] ? add_preempt_count+0xb4/0xcf > [ 601.218043] [] ? handle_pte_fault+0x6c6/0x76c > [ 601.223737] [] ? verify_iovec+0x52/0xa3 > [ 601.229426] [] ? handle_mm_fault+0x199/0x1a9 > [ 601.236033] [] ? do_page_fault+0x2f6/0x377 > [ 601.242034] [] ? > __event_probe__sys_mprotect+0xf5/0xf5 [lttng_tracer] > [ 601.251031] [] vfs_ioctl+0x22/0x3a > [ 601.256029] [] do_vfs_ioctl+0x3c4/0x407 > [ 601.261188] [] ? fget_light+0x91/0x9d > [ 601.267026] [] sys_ioctl+0x47/0x6a > [ 601.272050] [] tracesys+0xd9/0xde > > > cat /proc/cpuinfo > > processor : 0 > vendor_id : GenuineIntel > cpu family : 6 > model : 28 > model name : Intel(R) Atom(TM) CPU D525 @ 1.80GHz > stepping : 10 > microcode : 0x107 > cpu MHz : 1799.823 > cache size : 512 KB > physical id : 0 > siblings : 4 > core id : 0 > cpu cores : 2 > apicid : 0 > initial apicid : 0 > fpu : yes > fpu_exception : yes > cpuid level : 10 > wp : yes > flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat > pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm > constant_tsc arch_perfmon pebs bts rep_good nopl aperfmperf pni dtes64 > monitor ds_cpl tm2 ssse3 cx16 xtpr pdcm movbe lahf_lm dts > bogomips : 1775.61 > clflush size : 64 > cache_alignment : 64 > address sizes : 36 bits physical, 48 bits virtual > power management: > > (repeated for 3 other cpus ) > > uname -a > Linux 3.2.21-x510v1 #1 SMP PREEMPT Thu Dec 20 11:24:36 EST 2012 x86_64 > GNU/Linux > > Script used to run trace > ================================================= > #!/bin/sh > > xx=`/bin/date +"%s"` > yy="yy" > zz="zz" > log_xx=/home/pswuser/trace/log/psw-${xx}.log > log_yy=/home/pswuser/trace/log/psw-${yy}.log > log_zz=/home/pswuser/trace/log/psw-${zz}.log > #depmod > mkdir -p /home/pswuser/trace > mount -t tmpfs -o size=500M tmpfs /home/pswuser/trace > mkdir -p /home/pswuser/trace/log > touch /home/pswuser/trace/run_trace > sleep 20 > if [ -f /home/pswuser/trace/run_trace ] ; then > > echo "lttng create" > ${log_xx} > lttng create psw-${xx} \ > -o /home/pswuser/trace/psw-${xx} >> ${log_xx} 2>&1 > echo "lttng enable-event" >> ${log_xx} > sleep 1 > lttng enable-event -a -k -s psw-${xx} >> ${log_xx} 2>&1 > sleep 1 > echo "lttng start" >> ${log_xx} > lttng start psw-${xx} >> ${log_xx} 2>&1 > sleep 1 > > fi > > while [ 1 -gt 0 ] ; do > sleep 7 > yy=`/bin/date +"%s"` > log_yy=/home/pswuser/trace/log/psw-${yy}.log > > > #stop xx > if [ -d /home/pswuser/trace/psw-${xx} ] ; then > echo "lttng stop" >> ${log_xx} > lttng stop psw-${xx} >> ${log_xx} 2>&1 > sleep 1 > echo "lttng destroy" >> ${log_xx} > lttng destroy psw-${xx} >> ${log_xx} 2>&1 > echo "lttng done" >> ${log_xx} > fi > > # start yy after stopping xx > if [ -f /home/pswuser/trace/run_trace ] ; then > echo "lttng create ${yy} after closing ${xx}" > ${log_yy} > lttng create psw-${yy} \ > -o /home/pswuser/trace/psw-${yy} >> ${log_yy} 2>&1 > sleep 1 > echo "lttng enable_event" >> ${log_yy} > lttng enable-event -a -k -s psw-${yy} >> ${log_yy} 2>&1 > sleep 1 > echo "lttng start" >> ${log_yy} > lttng start psw-${yy} >> ${log_yy} 2>&1 > fi > # check zz > # delete unless detected or detected2 is present > if [ ! -f /home/pswuser/bin/delay-detected ] && > [ ! -f /home/pswuser/bin/delay-detected2 ] ; then > echo "lttng delete files" >> ${log_zz} > rm -rf /home/pswuser/trace/psw-${zz}* >> ${log_zz} 2>&1 > #if [ $? -eq 0 ] ; then rm ${log_zz} ; fi > fi > # delete second snapshot > if [ -f /home/pswuser/bin/delay-detected2 ] ; then > rm -f /home/pswuser/bin/delay-detected2 > > # no more tracing once event detected > rm -f /home/pswuser/trace/run_trace > fi > # trigger second snapshot delete first snapshot > if [ -f /home/pswuser/bin/delay-detected ] ; then > rm -f /home/pswuser/bin/delay-detected > touch /home/pswuser/bin/delay-detected2 > fi > > # ls -l /lttng-traces/psw-* > # zz (delete candidate) is old xx > echo "xx ${xx} yy ${yy} zz ${zz}" > zz=${xx} > log_zz=$log_xx > > # xx is now the new one > xx=${yy} > log_xx=$log_yy > > # check disk use > if [ -d /home/pswuser/trace ] ; then > du -h /home/pswuser/trace > fi > > > done > ---------------------------------------- > > Any clues are welcome. > > Another question. > > Would it be possible to do this by setting up a ring buffer that will wrap > around after a certain time. I can easily timestamp the event I am looking > for and then capture the buffer containing the event. Stay tuned for 2013 lttng releases. This will likely be implemented this year (flight recorder and snapshots). Thanks, Mathieu > > > Regards > Phil Wilshire > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Mon Jan 7 15:07:19 2013 From: dgoulet at efficios.com (David Goulet) Date: Mon, 07 Jan 2013 15:07:19 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Add kernel modules loading for new probes In-Reply-To: <20121210195057.GB17705@Krystal> References: <1355168223-6704-1-git-send-email-andrew_gabbasov@mentor.com> <20121210195057.GB17705@Krystal> Message-ID: <50EB2AF7.90108@efficios.com> Merged in master! Cheers! David Mathieu Desnoyers: > * Andrew Gabbasov (andrew_gabbasov at mentor.com) wrote: >> New probes introduced by commit b87700e318c27267890cbd6fb5e50b687279131b >> in lttng-modules. > > David, these probes are 2.2 material. So feel free to either include > this patch in 2.1 or keep it for 2.2. Since the modprobe error is > ignored, it won't make much difference. > > Thanks, > > Acked-by: Mathieu Desnoyers > >> >> Signed-off-by: Andrew Gabbasov >> --- >> src/bin/lttng-sessiond/modprobe.c | 11 +++++++++++ >> 1 file changed, 11 insertions(+) >> >> diff --git a/src/bin/lttng-sessiond/modprobe.c b/src/bin/lttng-sessiond/modprobe.c >> index 8e5cc94..1a5a1b7 100644 >> --- a/src/bin/lttng-sessiond/modprobe.c >> +++ b/src/bin/lttng-sessiond/modprobe.c >> @@ -46,7 +46,10 @@ const struct kern_modules_param kern_modules_list[] = { >> { "lttng-types", 0 }, >> { "lttng-probe-asoc", 0 }, >> { "lttng-probe-block", 0 }, >> + { "lttng-probe-btrfs", 0 }, >> + { "lttng-probe-compaction", 0 }, >> { "lttng-probe-ext3", 0 }, >> + { "lttng-probe-ext4", 0 }, >> { "lttng-probe-gpio", 0 }, >> { "lttng-probe-irq", 0 }, >> { "lttng-probe-jbd", 0 }, >> @@ -58,16 +61,24 @@ const struct kern_modules_param kern_modules_list[] = { >> { "lttng-probe-napi", 0 }, >> { "lttng-probe-net", 0 }, >> { "lttng-probe-power", 0 }, >> + { "lttng-probe-printk", 0 }, >> + { "lttng-probe-random", 0 }, >> + { "lttng-probe-rcu", 0 }, >> + { "lttng-probe-regmap", 0 }, >> { "lttng-probe-regulator", 0 }, >> + { "lttng-probe-rpm", 0 }, >> { "lttng-probe-sched", 0 }, >> { "lttng-probe-scsi", 0 }, >> { "lttng-probe-signal", 0 }, >> { "lttng-probe-skb", 0 }, >> { "lttng-probe-sock", 0 }, >> { "lttng-probe-statedump", 0 }, >> + { "lttng-probe-sunrpc", 0 }, >> { "lttng-probe-timer", 0 }, >> { "lttng-probe-udp", 0 }, >> { "lttng-probe-vmscan", 0 }, >> + { "lttng-probe-workqueue", 0 }, >> + { "lttng-probe-writeback", 0 }, >> }; >> >> /* >> -- >> 1.7.10.4 >> >> >> _______________________________________________ >> lttng-dev mailing list >> lttng-dev at lists.lttng.org >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > From dgoulet at ev0ke.net Mon Jan 7 15:07:32 2013 From: dgoulet at ev0ke.net (David Goulet) Date: Mon, 07 Jan 2013 15:07:32 -0500 Subject: [lttng-dev] [LTTng-Tools PATCH] Add pkg-config for liblttng-ctl [v2] In-Reply-To: <1356031866-24252-1-git-send-email-yannick.brosseau@gmail.com> References: <1356031866-24252-1-git-send-email-yannick.brosseau@gmail.com> Message-ID: <50EB2B04.20300@ev0ke.net> Merged! Thanks! David Yannick Brosseau: > v2: Update description > > Signed-off-by: Yannick Brosseau > --- > .gitignore | 2 +- > configure.ac | 1 + > src/lib/lttng-ctl/Makefile.am | 3 +++ > src/lib/lttng-ctl/lttng-ctl.pc.in | 13 +++++++++++++ > 4 files changed, 18 insertions(+), 1 deletion(-) > create mode 100644 src/lib/lttng-ctl/lttng-ctl.pc.in > > diff --git a/.gitignore b/.gitignore > index 383dbf9..afc97b6 100644 > --- a/.gitignore > +++ b/.gitignore > @@ -35,7 +35,7 @@ src/bin/lttng-sessiond/lttng-sessiond > src/bin/lttng/lttng > src/bin/lttng-consumerd/lttng-consumerd > src/bin/lttng-relayd/lttng-relayd > - > +src/lib/lttng-ctl/lttng-ctl.pc > src/lib/lttng-ctl/filter/filter-grammar-test > src/lib/lttng-ctl/filter/filter-lexer.c > src/lib/lttng-ctl/filter/filter-parser.c > diff --git a/configure.ac b/configure.ac > index 54aa385..be6736c 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -281,6 +281,7 @@ AC_CONFIG_FILES([ > src/lib/Makefile > src/lib/lttng-ctl/Makefile > src/lib/lttng-ctl/filter/Makefile > + src/lib/lttng-ctl/lttng-ctl.pc > src/bin/Makefile > src/bin/lttng-consumerd/Makefile > src/bin/lttng-sessiond/Makefile > diff --git a/src/lib/lttng-ctl/Makefile.am b/src/lib/lttng-ctl/Makefile.am > index 2681bdd..542f4bb 100644 > --- a/src/lib/lttng-ctl/Makefile.am > +++ b/src/lib/lttng-ctl/Makefile.am > @@ -11,3 +11,6 @@ liblttng_ctl_la_LIBADD = \ > $(top_builddir)/src/common/libcommon.la \ > $(top_builddir)/src/common/hashtable/libhashtable.la \ > $(top_builddir)/src/lib/lttng-ctl/filter/libfilter.la > + > +pkgconfigdir = $(libdir)/pkgconfig > +pkgconfig_DATA = lttng-ctl.pc > diff --git a/src/lib/lttng-ctl/lttng-ctl.pc.in b/src/lib/lttng-ctl/lttng-ctl.pc.in > new file mode 100644 > index 0000000..86382c2 > --- /dev/null > +++ b/src/lib/lttng-ctl/lttng-ctl.pc.in > @@ -0,0 +1,13 @@ > +prefix=@prefix@ > +exec_prefix=@exec_prefix@ > +libdir=@libdir@ > +includedir=@includedir@ > + > +Name: LTTng control library > +Description: The LTTng control and utility library is a library used to control the tracing sessions of a LTTng-session deamon > +Version: @PACKAGE_VERSION@ > +Requires: > +Requires.private: > +Libs: -L${libdir} -llttng-ctl > +Cflags: -I${includedir} > + From mathieu.desnoyers at efficios.com Mon Jan 7 16:18:55 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 7 Jan 2013 16:18:55 -0500 Subject: [lttng-dev] Request change name of function lookup_enum in libbabeltrace to make GDB use this lib In-Reply-To: References: <20121205120845.GA31696@Krystal> <50C0C06A.40207@redhat.com> <20121210140524.GA31945@Krystal> <20121220141643.GA22763@Krystal> Message-ID: <20130107211855.GB3678@Krystal> * Hui Zhu (teawater at gmail.com) wrote: > On Thu, Dec 20, 2012 at 10:16 PM, Mathieu Desnoyers > wrote: > > * Hui Zhu (teawater at gmail.com) wrote: > >> On Tue, Dec 11, 2012 at 11:18 PM, Hui Zhu wrote: > >> > On Mon, Dec 10, 2012 at 10:05 PM, Mathieu Desnoyers > >> > wrote: > >> >> * Hui Zhu (teawater at gmail.com) wrote: > >> >>> On Thu, Dec 6, 2012 at 11:57 PM, Pedro Alves wrote: > >> >>> > On 12/05/2012 12:08 PM, Mathieu Desnoyers wrote: > >> >>> >> * Hui Zhu (teawater at gmail.com) wrote: > >> >>> >>> Hi, > >> >>> >>> > >> >>> >>> I am working on add CTF support to GDB. You can see my patch review threads in: > >> >>> >>> http://sourceware.org/ml/gdb-patches/2012-11/msg00552.html > >> >>> >>> http://sourceware.org/ml/gdb-patches/2012-11/msg00554.html > >> >>> >>> http://sourceware.org/ml/gdb-patches/2012-11/msg00553.html > >> >>> >>> http://sourceware.org/ml/gdb-patches/2012-11/msg00555.html > >> >>> >>> http://sourceware.org/ml/gdb-patches/2012-11/msg00556.html > >> >>> >>> > >> >>> >>> To make GDB support CTF read, I use libbabeltrace with GDB. You can > >> >>> >>> see the patch in > >> >>> >>> http://sourceware.org/ml/gdb-patches/2012-11/msg00555.html. > >> >>> >>> I have a issue is libbabeltrace have a function called lookup_enum > >> >>> >>> that is same with a GDB function. > >> >>> >>> I change the function name of GDB to handle this issue in my patch. > >> >>> >>> > >> >>> >>> But Tom said let libbabeltrace to change function name is better. > >> >>> >>> So I send this mail to ask do you mind change the function name of > >> >>> >>> lookup_enum? If you can change the function name that will be really > >> >>> >>> helpful for us. Thanks a lot. > >> >>> >>> And I post a patch about change the function name in libbabeltrace. > >> >>> >> > >> >>> >> I'm CCing Julien Desfossez on this one. From what I see, > >> >>> >> include/babeltrace/types.h is not included into the system, so it should > >> >>> >> not be considered to be a public header of libbabeltrace. > >> >>> > > >> >>> > I've just built and installed babeltrace 1.0.0 (where's the mainline repository, > >> >>> > BTW?), and indeed, I'm not seeing the types.h file anywhere in the > >> >>> > installed tree: > >> >>> > > >> >>> > $ ~/src/babeltrace/install/include> find > >> >>> > . > >> >>> > ./babeltrace > >> >>> > ./babeltrace/trace-handle.h > >> >>> > ./babeltrace/list.h > >> >>> > ./babeltrace/babeltrace.h > >> >>> > ./babeltrace/context.h > >> >>> > ./babeltrace/iterator.h > >> >>> > ./babeltrace/ctf > >> >>> > ./babeltrace/ctf/callbacks.h > >> >>> > ./babeltrace/ctf/events.h > >> >>> > ./babeltrace/ctf/iterator.h > >> >>> > ./babeltrace/format.h > >> >>> > ./babeltrace/clock-types.h > >> >>> > > >> >>> > The GDB patch is including types.h explicitly: > >> >>> > > >> >>> > +#ifdef HAVE_LIBBABELTRACE > >> >>> > +#include > >> >>> > +#include > >> >>> > +#include > >> >>> > +#include > >> >>> > > >> >>> > So indeed, Hui, you'll need to make sure your patch works against an > >> >>> > installed babeltrace, making sure it does not pick up headers > >> >>> > from babeltrace's source directory. If there's really no reason to > >> >>> > include that types.h header (since it seems you don't really need any > >> >>> > function declared in that file), maybe there's actually nothing for > >> >>> > babeltrace to do. > >> >>> > >> >>> Oops, sorry for I miss something. > >> >>> I use include babeltrace/types.h because I use function > >> >>> get_int_signedness that defined inside it. > >> >> > >> >> Can you use: > >> >> > >> >> include/babeltrace/ctf/events.h: bt_ctf_get_int_signedness() instead ? > >> >> > >> >> This one is within an exported header, > >> >> > >> >> Thanks, > >> >> > >> >> Mathieu > >> > > >> > Great! My part is OK now. Thanks for your help. > >> > > >> > Best, > >> > Hui > >> > > >> > >> Hi Mathieu., > >> > >> I am so sorry that I still have issue with the function name of lookup_enum. > >> What I met is a crash when try to use libbabeltrace in GDB: > >> #0 0x00000000005d0cfc in block_static_block (block=0x7ffff6e5ee3e) at > >> ../../gdb/gdb/block.c:343 > >> #1 0x00000000005d42ae in lookup_symbol_aux_local (name=0xf70c70 > >> "\240!\224\001", block=0x7ffff6e5ee3e, > >> domain=STRUCT_DOMAIN, language=language_c) at ../../gdb/gdb/symtab.c:1429 > >> #2 0x00000000005d40b5 in lookup_symbol_aux (name=0xf70c70 > >> "\240!\224\001", block=0x7ffff6e5ee3e, domain=STRUCT_DOMAIN, > >> language=language_c, is_a_field_of_this=0x0) at ../../gdb/gdb/symtab.c:1345 > >> #3 0x00000000005d3cae in lookup_symbol_in_language (name=0xf70c70 > >> "\240!\224\001", block=0x7ffff6e5ee3e, > >> domain=STRUCT_DOMAIN, lang=language_c, is_a_field_of_this=0x0) at > >> ../../gdb/gdb/symtab.c:1231 > >> #4 0x00000000005d3cff in lookup_symbol (name=0xf70c70 > >> "\240!\224\001", block=0x7ffff6e5ee3e, domain=STRUCT_DOMAIN, > >> is_a_field_of_this=0x0) at ../../gdb/gdb/symtab.c:1246 > >> #5 0x000000000062f372 in lookup_enum (name=0xf70c70 "\240!\224\001", > >> block=0x7ffff6e5ee3e) > >> at ../../gdb/gdb/gdbtypes.c:1287 > >> #6 0x00007ffff6e479b5 in ctf_read_event (ppos=0xf6cca8, > >> stream=0xf6cc10) at ../../../babeltrace/formats/ctf/ctf.c:434 > >> #7 0x00007ffff7071204 in stream_read_event (sin=) at > >> ../../babeltrace/lib/iterator.c:65 > >> #8 0x00007ffff7071eb3 in bt_iter_init (iter=0x13ec820, ctx=0xf4b8b0, > >> begin_pos=0x7fffffffdad0, end_pos=) > >> at ../../babeltrace/lib/iterator.c:703 > >> #9 0x00007ffff6e4a6ac in bt_ctf_iter_create (ctx=0xf4b8b0, > >> begin_pos=0x7fffffffdad0, end_pos=0x0) > >> at ../../../babeltrace/formats/ctf/iterator.c:53 > >> #10 0x000000000050d4b1 in bt_ctf_open (dirname=0xd98c1b > >> "/home/teawater/gdb/ctf/kernel/") at ../../gdb/gdb/ctf.c:1289 > >> > >> You can see that when function ctf_read_event of libbabeltrace try to > >> call function lookup_enum. It call the function of GDB. Then it got > >> crash. > >> > >> So could you help me with it? > > > > Hrm, since lookup_enum() and other similar functions are internal to > > babeltrace, we should probably define them as: > > > > __attribute__((visibility("hidden"))) > > > > so they don't override other libraries' symbols. > > > > Can you try doing this modification to babeltrace and see if it helps ? > > If it does, then we'll consider doing that across our code-base. > > > > Thanks, > > > > Mathieu > > > > > > This is what I got when I add it to lookup_enum: > make[2]: Entering directory `/home/teawater/gdb/ctf/bb/converter' > CCLD babeltrace > ../formats/ctf/.libs/libbabeltrace-ctf.so: undefined reference to `lookup_enum' > collect2: ld returned 1 exit status > make[2]: *** [babeltrace] Error 1 > make[2]: Leaving directory `/home/teawater/gdb/ctf/bb/converter' > make[1]: *** [all-recursive] Error 1 > make[1]: Leaving directory `/home/teawater/gdb/ctf/bb' > make: *** [all] Error 2 OK. So those symbols are used by other .so within our own code-base, but not exported. We'll need to namespace them. Julien will prepare a patch. Thanks! Mathieu > > Thanks, > Hui > > >> > >> Thanks, > >> Hui > >> > >> >> > >> >>> > >> >>> Thanks, > >> >>> Hui > >> >>> > >> >>> > >> >>> > > >> >>> >> Julien, is there an publically exposed babeltrace API that performs > >> >>> >> something similar to the internal lookup_enum() ? > >> >>> >> > >> >>> >> Hui, are you using other functions from include/babeltrace/types.h ? > >> >>> > > >> >>> > -- > >> >>> > Pedro Alves > >> >>> > > >> >> > >> >> -- > >> >> Mathieu Desnoyers > >> >> Operating System Efficiency R&D Consultant > >> >> EfficiOS Inc. > >> >> http://www.efficios.com > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From christian.babeux at efficios.com Mon Jan 7 17:12:40 2013 From: christian.babeux at efficios.com (Christian Babeux) Date: Mon, 7 Jan 2013 17:12:40 -0500 Subject: [lttng-dev] [PATCH lttng-tools 1/3] Extras: Add the checkpatch coding style script Message-ID: <1357596762-14132-1-git-send-email-christian.babeux@efficios.com> Taken from the Linux Kernel tree in scripts/checkpatch.pl. Signed-off-by: Christian Babeux --- extras/checkpatch.pl | 3685 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 3685 insertions(+) create mode 100755 extras/checkpatch.pl diff --git a/extras/checkpatch.pl b/extras/checkpatch.pl new file mode 100755 index 0000000..4d2c7df --- /dev/null +++ b/extras/checkpatch.pl @@ -0,0 +1,3685 @@ +#!/usr/bin/perl -w +# (c) 2001, Dave Jones. (the file handling bit) +# (c) 2005, Joel Schopp (the ugly bit) +# (c) 2007,2008, Andy Whitcroft (new conditions, test suite) +# (c) 2008-2010 Andy Whitcroft +# Licensed under the terms of the GNU GPL License version 2 + +use strict; + +my $P = $0; +$P =~ s at .*/@@g; + +my $V = '0.32'; + +use Getopt::Long qw(:config no_auto_abbrev); + +my $quiet = 0; +my $tree = 1; +my $chk_signoff = 1; +my $chk_patch = 1; +my $tst_only; +my $emacs = 0; +my $terse = 0; +my $file = 0; +my $check = 0; +my $summary = 1; +my $mailback = 0; +my $summary_file = 0; +my $show_types = 0; +my $root; +my %debug; +my %ignore_type = (); +my @ignore = (); +my $help = 0; +my $configuration_file = ".checkpatch.conf"; +my $max_line_length = 80; + +sub help { + my ($exitcode) = @_; + + print << "EOM"; +Usage: $P [OPTION]... [FILE]... +Version: $V + +Options: + -q, --quiet quiet + --no-tree run without a kernel tree + --no-signoff do not check for 'Signed-off-by' line + --patch treat FILE as patchfile (default) + --emacs emacs compile window format + --terse one line per report + -f, --file treat FILE as regular source file + --subjective, --strict enable more subjective tests + --ignore TYPE(,TYPE2...) ignore various comma separated message types + --max-line-length=n set the maximum line length, if exceeded, warn + --show-types show the message "types" in the output + --root=PATH PATH to the kernel tree root + --no-summary suppress the per-file summary + --mailback only produce a report in case of warnings/errors + --summary-file include the filename in summary + --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of + 'values', 'possible', 'type', and 'attr' (default + is all off) + --test-only=WORD report only warnings/errors containing WORD + literally + -h, --help, --version display this help and exit + +When FILE is - read standard input. +EOM + + exit($exitcode); +} + +my $conf = which_conf($configuration_file); +if (-f $conf) { + my @conf_args; + open(my $conffile, '<', "$conf") + or warn "$P: Can't find a readable $configuration_file file $!\n"; + + while (<$conffile>) { + my $line = $_; + + $line =~ s/\s*\n?$//g; + $line =~ s/^\s*//g; + $line =~ s/\s+/ /g; + + next if ($line =~ m/^\s*#/); + next if ($line =~ m/^\s*$/); + + my @words = split(" ", $line); + foreach my $word (@words) { + last if ($word =~ m/^#/); + push (@conf_args, $word); + } + } + close($conffile); + unshift(@ARGV, @conf_args) if @conf_args; +} + +GetOptions( + 'q|quiet+' => \$quiet, + 'tree!' => \$tree, + 'signoff!' => \$chk_signoff, + 'patch!' => \$chk_patch, + 'emacs!' => \$emacs, + 'terse!' => \$terse, + 'f|file!' => \$file, + 'subjective!' => \$check, + 'strict!' => \$check, + 'ignore=s' => \@ignore, + 'show-types!' => \$show_types, + 'max-line-length=i' => \$max_line_length, + 'root=s' => \$root, + 'summary!' => \$summary, + 'mailback!' => \$mailback, + 'summary-file!' => \$summary_file, + + 'debug=s' => \%debug, + 'test-only=s' => \$tst_only, + 'h|help' => \$help, + 'version' => \$help +) or help(1); + +help(0) if ($help); + +my $exit = 0; + +if ($#ARGV < 0) { + print "$P: no input files\n"; + exit(1); +} + + at ignore = split(/,/, join(',', at ignore)); +foreach my $word (@ignore) { + $word =~ s/\s*\n?$//g; + $word =~ s/^\s*//g; + $word =~ s/\s+/ /g; + $word =~ tr/[a-z]/[A-Z]/; + + next if ($word =~ m/^\s*#/); + next if ($word =~ m/^\s*$/); + + $ignore_type{$word}++; +} + +my $dbg_values = 0; +my $dbg_possible = 0; +my $dbg_type = 0; +my $dbg_attr = 0; +for my $key (keys %debug) { + ## no critic + eval "\${dbg_$key} = '$debug{$key}';"; + die "$@" if ($@); +} + +my $rpt_cleaners = 0; + +if ($terse) { + $emacs = 1; + $quiet++; +} + +if ($tree) { + if (defined $root) { + if (!top_of_kernel_tree($root)) { + die "$P: $root: --root does not point at a valid tree\n"; + } + } else { + if (top_of_kernel_tree('.')) { + $root = '.'; + } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && + top_of_kernel_tree($1)) { + $root = $1; + } + } + + if (!defined $root) { + print "Must be run from the top-level dir. of a kernel tree\n"; + exit(2); + } +} + +my $emitted_corrupt = 0; + +our $Ident = qr{ + [A-Za-z_][A-Za-z\d_]* + (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* + }x; +our $Storage = qr{extern|static|asmlinkage}; +our $Sparse = qr{ + __user| + __kernel| + __force| + __iomem| + __must_check| + __init_refok| + __kprobes| + __ref| + __rcu + }x; + +# Notes to $Attribute: +# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check +our $Attribute = qr{ + const| + __percpu| + __nocast| + __safe| + __bitwise__| + __packed__| + __packed2__| + __naked| + __maybe_unused| + __always_unused| + __noreturn| + __used| + __cold| + __noclone| + __deprecated| + __read_mostly| + __kprobes| + __(?:mem|cpu|dev|)(?:initdata|initconst|init\b)| + ____cacheline_aligned| + ____cacheline_aligned_in_smp| + ____cacheline_internodealigned_in_smp| + __weak + }x; +our $Modifier; +our $Inline = qr{inline|__always_inline|noinline}; +our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; +our $Lval = qr{$Ident(?:$Member)*}; + +our $Float_hex = qr{(?i:0x[0-9a-f]+p-?[0-9]+[fl]?)}; +our $Float_dec = qr{(?i:((?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?))}; +our $Float_int = qr{(?i:[0-9]+e-?[0-9]+[fl]?)}; +our $Float = qr{$Float_hex|$Float_dec|$Float_int}; +our $Constant = qr{(?:$Float|(?i:(?:0x[0-9a-f]+|[0-9]+)[ul]*))}; +our $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)}; +our $Compare = qr{<=|>=|==|!=|<|>}; +our $Operators = qr{ + <=|>=|==|!=| + =>|->|<<|>>|<|>|!|~| + &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|% + }x; + +our $NonptrType; +our $Type; +our $Declare; + +our $NON_ASCII_UTF8 = qr{ + [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte + | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs + | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte + | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates + | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 + | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 + | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 +}x; + +our $UTF8 = qr{ + [\x09\x0A\x0D\x20-\x7E] # ASCII + | $NON_ASCII_UTF8 +}x; + +our $typeTypedefs = qr{(?x: + (?:__)?(?:u|s|be|le)(?:8|16|32|64)| + atomic_t +)}; + +our $logFunctions = qr{(?x: + printk(?:_ratelimited|_once|)| + [a-z0-9]+_(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| + WARN(?:_RATELIMIT|_ONCE|)| + panic| + MODULE_[A-Z_]+ +)}; + +our $signature_tags = qr{(?xi: + Signed-off-by:| + Acked-by:| + Tested-by:| + Reviewed-by:| + Reported-by:| + To:| + Cc: +)}; + +our @typeList = ( + qr{void}, + qr{(?:unsigned\s+)?char}, + qr{(?:unsigned\s+)?short}, + qr{(?:unsigned\s+)?int}, + qr{(?:unsigned\s+)?long}, + qr{(?:unsigned\s+)?long\s+int}, + qr{(?:unsigned\s+)?long\s+long}, + qr{(?:unsigned\s+)?long\s+long\s+int}, + qr{unsigned}, + qr{float}, + qr{double}, + qr{bool}, + qr{struct\s+$Ident}, + qr{union\s+$Ident}, + qr{enum\s+$Ident}, + qr{${Ident}_t}, + qr{${Ident}_handler}, + qr{${Ident}_handler_fn}, +); +our @modifierList = ( + qr{fastcall}, +); + +our $allowed_asm_includes = qr{(?x: + irq| + memory +)}; +# memory.h: ARM has a custom one + +sub build_types { + my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)"; + my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)"; + $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; + $NonptrType = qr{ + (?:$Modifier\s+|const\s+)* + (?: + (?:typeof|__typeof__)\s*\([^\)]*\)| + (?:$typeTypedefs\b)| + (?:${all}\b) + ) + (?:\s+$Modifier|\s+const)* + }x; + $Type = qr{ + $NonptrType + (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)? + (?:\s+$Inline|\s+$Modifier)* + }x; + $Declare = qr{(?:$Storage\s+)?$Type}; +} +build_types(); + + +our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; + +# Using $balanced_parens, $LvalOrFunc, or $FuncArg +# requires at least perl version v5.10.0 +# Any use must be runtime checked with $^V + +our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; +our $LvalOrFunc = qr{($Lval)\s*($balanced_parens{0,1})\s*}; +our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant)}; + +sub deparenthesize { + my ($string) = @_; + return "" if (!defined($string)); + $string =~ s@^\s*\(\s*@@g; + $string =~ s@\s*\)\s*$@@g; + $string =~ s@\s+@ @g; + return $string; +} + +$chk_signoff = 0 if ($file); + +my @rawlines = (); +my @lines = (); +my $vname; +for my $filename (@ARGV) { + my $FILE; + if ($file) { + open($FILE, '-|', "diff -u /dev/null $filename") || + die "$P: $filename: diff failed - $!\n"; + } elsif ($filename eq '-') { + open($FILE, '<&STDIN'); + } else { + open($FILE, '<', "$filename") || + die "$P: $filename: open failed - $!\n"; + } + if ($filename eq '-') { + $vname = 'Your patch'; + } else { + $vname = $filename; + } + while (<$FILE>) { + chomp; + push(@rawlines, $_); + } + close($FILE); + if (!process($filename)) { + $exit = 1; + } + @rawlines = (); + @lines = (); +} + +exit($exit); + +sub top_of_kernel_tree { + my ($root) = @_; + + my @tree_check = ( + "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", + "README", "Documentation", "arch", "include", "drivers", + "fs", "init", "ipc", "kernel", "lib", "scripts", + ); + + foreach my $check (@tree_check) { + if (! -e $root . '/' . $check) { + return 0; + } + } + return 1; +} + +sub parse_email { + my ($formatted_email) = @_; + + my $name = ""; + my $address = ""; + my $comment = ""; + + if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { + $name = $1; + $address = $2; + $comment = $3 if defined $3; + } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { + $address = $1; + $comment = $2 if defined $2; + } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { + $address = $1; + $comment = $2 if defined $2; + $formatted_email =~ s/$address.*$//; + $name = $formatted_email; + $name =~ s/^\s+|\s+$//g; + $name =~ s/^\"|\"$//g; + # If there's a name left after stripping spaces and + # leading quotes, and the address doesn't have both + # leading and trailing angle brackets, the address + # is invalid. ie: + # "joe smith joe at smith.com" bad + # "joe smith ]+>$/) { + $name = ""; + $address = ""; + $comment = ""; + } + } + + $name =~ s/^\s+|\s+$//g; + $name =~ s/^\"|\"$//g; + $address =~ s/^\s+|\s+$//g; + $address =~ s/^\<|\>$//g; + + if ($name =~ /[^\w \-]/i) { ##has "must quote" chars + $name =~ s/(?"; + } + + return $formatted_email; +} + +sub which_conf { + my ($conf) = @_; + + foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { + if (-e "$path/$conf") { + return "$path/$conf"; + } + } + + return ""; +} + +sub expand_tabs { + my ($str) = @_; + + my $res = ''; + my $n = 0; + for my $c (split(//, $str)) { + if ($c eq "\t") { + $res .= ' '; + $n++; + for (; ($n % 8) != 0; $n++) { + $res .= ' '; + } + next; + } + $res .= $c; + $n++; + } + + return $res; +} +sub copy_spacing { + (my $res = shift) =~ tr/\t/ /c; + return $res; +} + +sub line_stats { + my ($line) = @_; + + # Drop the diff line leader and expand tabs + $line =~ s/^.//; + $line = expand_tabs($line); + + # Pick the indent from the front of the line. + my ($white) = ($line =~ /^(\s*)/); + + return (length($line), length($white)); +} + +my $sanitise_quote = ''; + +sub sanitise_line_reset { + my ($in_comment) = @_; + + if ($in_comment) { + $sanitise_quote = '*/'; + } else { + $sanitise_quote = ''; + } +} +sub sanitise_line { + my ($line) = @_; + + my $res = ''; + my $l = ''; + + my $qlen = 0; + my $off = 0; + my $c; + + # Always copy over the diff marker. + $res = substr($line, 0, 1); + + for ($off = 1; $off < length($line); $off++) { + $c = substr($line, $off, 1); + + # Comments we are wacking completly including the begin + # and end, all to $;. + if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { + $sanitise_quote = '*/'; + + substr($res, $off, 2, "$;$;"); + $off++; + next; + } + if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { + $sanitise_quote = ''; + substr($res, $off, 2, "$;$;"); + $off++; + next; + } + if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { + $sanitise_quote = '//'; + + substr($res, $off, 2, $sanitise_quote); + $off++; + next; + } + + # A \ in a string means ignore the next character. + if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && + $c eq "\\") { + substr($res, $off, 2, 'XX'); + $off++; + next; + } + # Regular quotes. + if ($c eq "'" || $c eq '"') { + if ($sanitise_quote eq '') { + $sanitise_quote = $c; + + substr($res, $off, 1, $c); + next; + } elsif ($sanitise_quote eq $c) { + $sanitise_quote = ''; + } + } + + #print "c<$c> SQ<$sanitise_quote>\n"; + if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { + substr($res, $off, 1, $;); + } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { + substr($res, $off, 1, $;); + } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { + substr($res, $off, 1, 'X'); + } else { + substr($res, $off, 1, $c); + } + } + + if ($sanitise_quote eq '//') { + $sanitise_quote = ''; + } + + # The pathname on a #include may be surrounded by '<' and '>'. + if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { + my $clean = 'X' x length($1); + $res =~ s@\<.*\>@<$clean>@; + + # The whole of a #error is a string. + } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { + my $clean = 'X' x length($1); + $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; + } + + return $res; +} + +sub ctx_statement_block { + my ($linenr, $remain, $off) = @_; + my $line = $linenr - 1; + my $blk = ''; + my $soff = $off; + my $coff = $off - 1; + my $coff_set = 0; + + my $loff = 0; + + my $type = ''; + my $level = 0; + my @stack = (); + my $p; + my $c; + my $len = 0; + + my $remainder; + while (1) { + @stack = (['', 0]) if ($#stack == -1); + + #warn "CSB: blk<$blk> remain<$remain>\n"; + # If we are about to drop off the end, pull in more + # context. + if ($off >= $len) { + for (; $remain > 0; $line++) { + last if (!defined $lines[$line]); + next if ($lines[$line] =~ /^-/); + $remain--; + $loff = $len; + $blk .= $lines[$line] . "\n"; + $len = length($blk); + $line++; + last; + } + # Bail if there is no further context. + #warn "CSB: blk<$blk> off<$off> len<$len>\n"; + if ($off >= $len) { + last; + } + if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { + $level++; + $type = '#'; + } + } + $p = $c; + $c = substr($blk, $off, 1); + $remainder = substr($blk, $off); + + #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; + + # Handle nested #if/#else. + if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { + push(@stack, [ $type, $level ]); + } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { + ($type, $level) = @{$stack[$#stack - 1]}; + } elsif ($remainder =~ /^#\s*endif\b/) { + ($type, $level) = @{pop(@stack)}; + } + + # Statement ends at the ';' or a close '}' at the + # outermost level. + if ($level == 0 && $c eq ';') { + last; + } + + # An else is really a conditional as long as its not else if + if ($level == 0 && $coff_set == 0 && + (!defined($p) || $p =~ /(?:\s|\}|\+)/) && + $remainder =~ /^(else)(?:\s|{)/ && + $remainder !~ /^else\s+if\b/) { + $coff = $off + length($1) - 1; + $coff_set = 1; + #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; + #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; + } + + if (($type eq '' || $type eq '(') && $c eq '(') { + $level++; + $type = '('; + } + if ($type eq '(' && $c eq ')') { + $level--; + $type = ($level != 0)? '(' : ''; + + if ($level == 0 && $coff < $soff) { + $coff = $off; + $coff_set = 1; + #warn "CSB: mark coff<$coff>\n"; + } + } + if (($type eq '' || $type eq '{') && $c eq '{') { + $level++; + $type = '{'; + } + if ($type eq '{' && $c eq '}') { + $level--; + $type = ($level != 0)? '{' : ''; + + if ($level == 0) { + if (substr($blk, $off + 1, 1) eq ';') { + $off++; + } + last; + } + } + # Preprocessor commands end at the newline unless escaped. + if ($type eq '#' && $c eq "\n" && $p ne "\\") { + $level--; + $type = ''; + $off++; + last; + } + $off++; + } + # We are truly at the end, so shuffle to the next line. + if ($off == $len) { + $loff = $len + 1; + $line++; + $remain--; + } + + my $statement = substr($blk, $soff, $off - $soff + 1); + my $condition = substr($blk, $soff, $coff - $soff + 1); + + #warn "STATEMENT<$statement>\n"; + #warn "CONDITION<$condition>\n"; + + #print "coff<$coff> soff<$off> loff<$loff>\n"; + + return ($statement, $condition, + $line, $remain + 1, $off - $loff + 1, $level); +} + +sub statement_lines { + my ($stmt) = @_; + + # Strip the diff line prefixes and rip blank lines at start and end. + $stmt =~ s/(^|\n)./$1/g; + $stmt =~ s/^\s*//; + $stmt =~ s/\s*$//; + + my @stmt_lines = ($stmt =~ /\n/g); + + return $#stmt_lines + 2; +} + +sub statement_rawlines { + my ($stmt) = @_; + + my @stmt_lines = ($stmt =~ /\n/g); + + return $#stmt_lines + 2; +} + +sub statement_block_size { + my ($stmt) = @_; + + $stmt =~ s/(^|\n)./$1/g; + $stmt =~ s/^\s*{//; + $stmt =~ s/}\s*$//; + $stmt =~ s/^\s*//; + $stmt =~ s/\s*$//; + + my @stmt_lines = ($stmt =~ /\n/g); + my @stmt_statements = ($stmt =~ /;/g); + + my $stmt_lines = $#stmt_lines + 2; + my $stmt_statements = $#stmt_statements + 1; + + if ($stmt_lines > $stmt_statements) { + return $stmt_lines; + } else { + return $stmt_statements; + } +} + +sub ctx_statement_full { + my ($linenr, $remain, $off) = @_; + my ($statement, $condition, $level); + + my (@chunks); + + # Grab the first conditional/block pair. + ($statement, $condition, $linenr, $remain, $off, $level) = + ctx_statement_block($linenr, $remain, $off); + #print "F: c<$condition> s<$statement> remain<$remain>\n"; + push(@chunks, [ $condition, $statement ]); + if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { + return ($level, $linenr, @chunks); + } + + # Pull in the following conditional/block pairs and see if they + # could continue the statement. + for (;;) { + ($statement, $condition, $linenr, $remain, $off, $level) = + ctx_statement_block($linenr, $remain, $off); + #print "C: c<$condition> s<$statement> remain<$remain>\n"; + last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); + #print "C: push\n"; + push(@chunks, [ $condition, $statement ]); + } + + return ($level, $linenr, @chunks); +} + +sub ctx_block_get { + my ($linenr, $remain, $outer, $open, $close, $off) = @_; + my $line; + my $start = $linenr - 1; + my $blk = ''; + my @o; + my @c; + my @res = (); + + my $level = 0; + my @stack = ($level); + for ($line = $start; $remain > 0; $line++) { + next if ($rawlines[$line] =~ /^-/); + $remain--; + + $blk .= $rawlines[$line]; + + # Handle nested #if/#else. + if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { + push(@stack, $level); + } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { + $level = $stack[$#stack - 1]; + } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { + $level = pop(@stack); + } + + foreach my $c (split(//, $lines[$line])) { + ##print "C<$c>L<$level><$open$close>O<$off>\n"; + if ($off > 0) { + $off--; + next; + } + + if ($c eq $close && $level > 0) { + $level--; + last if ($level == 0); + } elsif ($c eq $open) { + $level++; + } + } + + if (!$outer || $level <= 1) { + push(@res, $rawlines[$line]); + } + + last if ($level == 0); + } + + return ($level, @res); +} +sub ctx_block_outer { + my ($linenr, $remain) = @_; + + my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); + return @r; +} +sub ctx_block { + my ($linenr, $remain) = @_; + + my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); + return @r; +} +sub ctx_statement { + my ($linenr, $remain, $off) = @_; + + my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); + return @r; +} +sub ctx_block_level { + my ($linenr, $remain) = @_; + + return ctx_block_get($linenr, $remain, 0, '{', '}', 0); +} +sub ctx_statement_level { + my ($linenr, $remain, $off) = @_; + + return ctx_block_get($linenr, $remain, 0, '(', ')', $off); +} + +sub ctx_locate_comment { + my ($first_line, $end_line) = @_; + + # Catch a comment on the end of the line itself. + my ($current_comment) = ($rawlines[$end_line - 1] =~ m at .*(/\*.*\*/)\s*(?:\\\s*)?$@); + return $current_comment if (defined $current_comment); + + # Look through the context and try and figure out if there is a + # comment. + my $in_comment = 0; + $current_comment = ''; + for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { + my $line = $rawlines[$linenr - 1]; + #warn " $line\n"; + if ($linenr == $first_line and $line =~ m@^.\s*\*@) { + $in_comment = 1; + } + if ($line =~ m@/\*@) { + $in_comment = 1; + } + if (!$in_comment && $current_comment ne '') { + $current_comment = ''; + } + $current_comment .= $line . "\n" if ($in_comment); + if ($line =~ m@\*/@) { + $in_comment = 0; + } + } + + chomp($current_comment); + return($current_comment); +} +sub ctx_has_comment { + my ($first_line, $end_line) = @_; + my $cmt = ctx_locate_comment($first_line, $end_line); + + ##print "LINE: $rawlines[$end_line - 1 ]\n"; + ##print "CMMT: $cmt\n"; + + return ($cmt ne ''); +} + +sub raw_line { + my ($linenr, $cnt) = @_; + + my $offset = $linenr - 1; + $cnt++; + + my $line; + while ($cnt) { + $line = $rawlines[$offset++]; + next if (defined($line) && $line =~ /^-/); + $cnt--; + } + + return $line; +} + +sub cat_vet { + my ($vet) = @_; + my ($res, $coded); + + $res = ''; + while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { + $res .= $1; + if ($2 ne '') { + $coded = sprintf("^%c", unpack('C', $2) + 64); + $res .= $coded; + } + } + $res =~ s/$/\$/; + + return $res; +} + +my $av_preprocessor = 0; +my $av_pending; +my @av_paren_type; +my $av_pend_colon; + +sub annotate_reset { + $av_preprocessor = 0; + $av_pending = '_'; + @av_paren_type = ('E'); + $av_pend_colon = 'O'; +} + +sub annotate_values { + my ($stream, $type) = @_; + + my $res; + my $var = '_' x length($stream); + my $cur = $stream; + + print "$stream\n" if ($dbg_values > 1); + + while (length($cur)) { + @av_paren_type = ('E') if ($#av_paren_type < 0); + print " <" . join('', @av_paren_type) . + "> <$type> <$av_pending>" if ($dbg_values > 1); + if ($cur =~ /^(\s+)/o) { + print "WS($1)\n" if ($dbg_values > 1); + if ($1 =~ /\n/ && $av_preprocessor) { + $type = pop(@av_paren_type); + $av_preprocessor = 0; + } + + } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { + print "CAST($1)\n" if ($dbg_values > 1); + push(@av_paren_type, $type); + $type = 'c'; + + } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { + print "DECLARE($1)\n" if ($dbg_values > 1); + $type = 'T'; + + } elsif ($cur =~ /^($Modifier)\s*/) { + print "MODIFIER($1)\n" if ($dbg_values > 1); + $type = 'T'; + + } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { + print "DEFINE($1,$2)\n" if ($dbg_values > 1); + $av_preprocessor = 1; + push(@av_paren_type, $type); + if ($2 ne '') { + $av_pending = 'N'; + } + $type = 'E'; + + } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { + print "UNDEF($1)\n" if ($dbg_values > 1); + $av_preprocessor = 1; + push(@av_paren_type, $type); + + } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { + print "PRE_START($1)\n" if ($dbg_values > 1); + $av_preprocessor = 1; + + push(@av_paren_type, $type); + push(@av_paren_type, $type); + $type = 'E'; + + } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { + print "PRE_RESTART($1)\n" if ($dbg_values > 1); + $av_preprocessor = 1; + + push(@av_paren_type, $av_paren_type[$#av_paren_type]); + + $type = 'E'; + + } elsif ($cur =~ /^(\#\s*(?:endif))/o) { + print "PRE_END($1)\n" if ($dbg_values > 1); + + $av_preprocessor = 1; + + # Assume all arms of the conditional end as this + # one does, and continue as if the #endif was not here. + pop(@av_paren_type); + push(@av_paren_type, $type); + $type = 'E'; + + } elsif ($cur =~ /^(\\\n)/o) { + print "PRECONT($1)\n" if ($dbg_values > 1); + + } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { + print "ATTR($1)\n" if ($dbg_values > 1); + $av_pending = $type; + $type = 'N'; + + } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { + print "SIZEOF($1)\n" if ($dbg_values > 1); + if (defined $2) { + $av_pending = 'V'; + } + $type = 'N'; + + } elsif ($cur =~ /^(if|while|for)\b/o) { + print "COND($1)\n" if ($dbg_values > 1); + $av_pending = 'E'; + $type = 'N'; + + } elsif ($cur =~/^(case)/o) { + print "CASE($1)\n" if ($dbg_values > 1); + $av_pend_colon = 'C'; + $type = 'N'; + + } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { + print "KEYWORD($1)\n" if ($dbg_values > 1); + $type = 'N'; + + } elsif ($cur =~ /^(\()/o) { + print "PAREN('$1')\n" if ($dbg_values > 1); + push(@av_paren_type, $av_pending); + $av_pending = '_'; + $type = 'N'; + + } elsif ($cur =~ /^(\))/o) { + my $new_type = pop(@av_paren_type); + if ($new_type ne '_') { + $type = $new_type; + print "PAREN('$1') -> $type\n" + if ($dbg_values > 1); + } else { + print "PAREN('$1')\n" if ($dbg_values > 1); + } + + } elsif ($cur =~ /^($Ident)\s*\(/o) { + print "FUNC($1)\n" if ($dbg_values > 1); + $type = 'V'; + $av_pending = 'V'; + + } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { + if (defined $2 && $type eq 'C' || $type eq 'T') { + $av_pend_colon = 'B'; + } elsif ($type eq 'E') { + $av_pend_colon = 'L'; + } + print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); + $type = 'V'; + + } elsif ($cur =~ /^($Ident|$Constant)/o) { + print "IDENT($1)\n" if ($dbg_values > 1); + $type = 'V'; + + } elsif ($cur =~ /^($Assignment)/o) { + print "ASSIGN($1)\n" if ($dbg_values > 1); + $type = 'N'; + + } elsif ($cur =~/^(;|{|})/) { + print "END($1)\n" if ($dbg_values > 1); + $type = 'E'; + $av_pend_colon = 'O'; + + } elsif ($cur =~/^(,)/) { + print "COMMA($1)\n" if ($dbg_values > 1); + $type = 'C'; + + } elsif ($cur =~ /^(\?)/o) { + print "QUESTION($1)\n" if ($dbg_values > 1); + $type = 'N'; + + } elsif ($cur =~ /^(:)/o) { + print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); + + substr($var, length($res), 1, $av_pend_colon); + if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { + $type = 'E'; + } else { + $type = 'N'; + } + $av_pend_colon = 'O'; + + } elsif ($cur =~ /^(\[)/o) { + print "CLOSE($1)\n" if ($dbg_values > 1); + $type = 'N'; + + } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { + my $variant; + + print "OPV($1)\n" if ($dbg_values > 1); + if ($type eq 'V') { + $variant = 'B'; + } else { + $variant = 'U'; + } + + substr($var, length($res), 1, $variant); + $type = 'N'; + + } elsif ($cur =~ /^($Operators)/o) { + print "OP($1)\n" if ($dbg_values > 1); + if ($1 ne '++' && $1 ne '--') { + $type = 'N'; + } + + } elsif ($cur =~ /(^.)/o) { + print "C($1)\n" if ($dbg_values > 1); + } + if (defined $1) { + $cur = substr($cur, length($1)); + $res .= $type x length($1); + } + } + + return ($res, $var); +} + +sub possible { + my ($possible, $line) = @_; + my $notPermitted = qr{(?: + ^(?: + $Modifier| + $Storage| + $Type| + DEFINE_\S+ + )$| + ^(?: + goto| + return| + case| + else| + asm|__asm__| + do| + \#| + \#\#| + )(?:\s|$)| + ^(?:typedef|struct|enum)\b + )}x; + warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); + if ($possible !~ $notPermitted) { + # Check for modifiers. + $possible =~ s/\s*$Storage\s*//g; + $possible =~ s/\s*$Sparse\s*//g; + if ($possible =~ /^\s*$/) { + + } elsif ($possible =~ /\s/) { + $possible =~ s/\s*$Type\s*//g; + for my $modifier (split(' ', $possible)) { + if ($modifier !~ $notPermitted) { + warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); + push(@modifierList, $modifier); + } + } + + } else { + warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); + push(@typeList, $possible); + } + build_types(); + } else { + warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); + } +} + +my $prefix = ''; + +sub show_type { + return !defined $ignore_type{$_[0]}; +} + +sub report { + if (!show_type($_[1]) || + (defined $tst_only && $_[2] !~ /\Q$tst_only\E/)) { + return 0; + } + my $line; + if ($show_types) { + $line = "$prefix$_[0]:$_[1]: $_[2]\n"; + } else { + $line = "$prefix$_[0]: $_[2]\n"; + } + $line = (split('\n', $line))[0] . "\n" if ($terse); + + push(our @report, $line); + + return 1; +} +sub report_dump { + our @report; +} + +sub ERROR { + if (report("ERROR", $_[0], $_[1])) { + our $clean = 0; + our $cnt_error++; + } +} +sub WARN { + if (report("WARNING", $_[0], $_[1])) { + our $clean = 0; + our $cnt_warn++; + } +} +sub CHK { + if ($check && report("CHECK", $_[0], $_[1])) { + our $clean = 0; + our $cnt_chk++; + } +} + +sub check_absolute_file { + my ($absolute, $herecurr) = @_; + my $file = $absolute; + + ##print "absolute<$absolute>\n"; + + # See if any suffix of this path is a path within the tree. + while ($file =~ s@^[^/]*/@@) { + if (-f "$root/$file") { + ##print "file<$file>\n"; + last; + } + } + if (! -f _) { + return 0; + } + + # It is, so see if the prefix is acceptable. + my $prefix = $absolute; + substr($prefix, -length($file)) = ''; + + ##print "prefix<$prefix>\n"; + if ($prefix ne ".../") { + WARN("USE_RELATIVE_PATH", + "use relative pathname instead of absolute in changelog text\n" . $herecurr); + } +} + +sub pos_last_openparen { + my ($line) = @_; + + my $pos = 0; + + my $opens = $line =~ tr/\(/\(/; + my $closes = $line =~ tr/\)/\)/; + + my $last_openparen = 0; + + if (($opens == 0) || ($closes >= $opens)) { + return -1; + } + + my $len = length($line); + + for ($pos = 0; $pos < $len; $pos++) { + my $string = substr($line, $pos); + if ($string =~ /^($FuncArg|$balanced_parens)/) { + $pos += length($1) - 1; + } elsif (substr($line, $pos, 1) eq '(') { + $last_openparen = $pos; + } elsif (index($string, '(') == -1) { + last; + } + } + + return $last_openparen + 1; +} + +sub process { + my $filename = shift; + + my $linenr=0; + my $prevline=""; + my $prevrawline=""; + my $stashline=""; + my $stashrawline=""; + + my $length; + my $indent; + my $previndent=0; + my $stashindent=0; + + our $clean = 1; + my $signoff = 0; + my $is_patch = 0; + + my $in_header_lines = 1; + my $in_commit_log = 0; #Scanning lines before patch + + my $non_utf8_charset = 0; + + our @report = (); + our $cnt_lines = 0; + our $cnt_error = 0; + our $cnt_warn = 0; + our $cnt_chk = 0; + + # Trace the real file/line as we go. + my $realfile = ''; + my $realline = 0; + my $realcnt = 0; + my $here = ''; + my $in_comment = 0; + my $comment_edge = 0; + my $first_line = 0; + my $p1_prefix = ''; + + my $prev_values = 'E'; + + # suppression flags + my %suppress_ifbraces; + my %suppress_whiletrailers; + my %suppress_export; + my $suppress_statement = 0; + + my %camelcase = (); + + # Pre-scan the patch sanitizing the lines. + # Pre-scan the patch looking for any __setup documentation. + # + my @setup_docs = (); + my $setup_docs = 0; + + sanitise_line_reset(); + my $line; + foreach my $rawline (@rawlines) { + $linenr++; + $line = $rawline; + + if ($rawline=~/^\+\+\+\s+(\S+)/) { + $setup_docs = 0; + if ($1 =~ m at Documentation/kernel-parameters.txt$@) { + $setup_docs = 1; + } + #next; + } + if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { + $realline=$1-1; + if (defined $2) { + $realcnt=$3+1; + } else { + $realcnt=1+1; + } + $in_comment = 0; + + # Guestimate if this is a continuing comment. Run + # the context looking for a comment "edge". If this + # edge is a close comment then we must be in a comment + # at context start. + my $edge; + my $cnt = $realcnt; + for (my $ln = $linenr + 1; $cnt > 0; $ln++) { + next if (defined $rawlines[$ln - 1] && + $rawlines[$ln - 1] =~ /^-/); + $cnt--; + #print "RAW<$rawlines[$ln - 1]>\n"; + last if (!defined $rawlines[$ln - 1]); + if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && + $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { + ($edge) = $1; + last; + } + } + if (defined $edge && $edge eq '*/') { + $in_comment = 1; + } + + # Guestimate if this is a continuing comment. If this + # is the start of a diff block and this line starts + # ' *' then it is very likely a comment. + if (!defined $edge && + $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) + { + $in_comment = 1; + } + + ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; + sanitise_line_reset($in_comment); + + } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { + # Standardise the strings and chars within the input to + # simplify matching -- only bother with positive lines. + $line = sanitise_line($rawline); + } + push(@lines, $line); + + if ($realcnt > 1) { + $realcnt-- if ($line =~ /^(?:\+| |$)/); + } else { + $realcnt = 0; + } + + #print "==>$rawline\n"; + #print "-->$line\n"; + + if ($setup_docs && $line =~ /^\+/) { + push(@setup_docs, $line); + } + } + + $prefix = ''; + + $realcnt = 0; + $linenr = 0; + foreach my $line (@lines) { + $linenr++; + + my $rawline = $rawlines[$linenr - 1]; + +#extract the line range in the file after the patch is applied + if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { + $is_patch = 1; + $first_line = $linenr + 1; + $realline=$1-1; + if (defined $2) { + $realcnt=$3+1; + } else { + $realcnt=1+1; + } + annotate_reset(); + $prev_values = 'E'; + + %suppress_ifbraces = (); + %suppress_whiletrailers = (); + %suppress_export = (); + $suppress_statement = 0; + next; + +# track the line number as we move through the hunk, note that +# new versions of GNU diff omit the leading space on completely +# blank context lines so we need to count that too. + } elsif ($line =~ /^( |\+|$)/) { + $realline++; + $realcnt-- if ($realcnt != 0); + + # Measure the line length and indent. + ($length, $indent) = line_stats($rawline); + + # Track the previous line. + ($prevline, $stashline) = ($stashline, $line); + ($previndent, $stashindent) = ($stashindent, $indent); + ($prevrawline, $stashrawline) = ($stashrawline, $rawline); + + #warn "line<$line>\n"; + + } elsif ($realcnt == 1) { + $realcnt--; + } + + my $hunk_line = ($realcnt != 0); + +#make up the handle for any error we report on this line + $prefix = "$filename:$realline: " if ($emacs && $file); + $prefix = "$filename:$linenr: " if ($emacs && !$file); + + $here = "#$linenr: " if (!$file); + $here = "#$realline: " if ($file); + + # extract the filename as it passes + if ($line =~ /^diff --git.*?(\S+)$/) { + $realfile = $1; + $realfile =~ s@^([^/]*)/@@; + $in_commit_log = 0; + } elsif ($line =~ /^\+\+\+\s+(\S+)/) { + $realfile = $1; + $realfile =~ s@^([^/]*)/@@; + $in_commit_log = 0; + + $p1_prefix = $1; + if (!$file && $tree && $p1_prefix ne '' && + -e "$root/$p1_prefix") { + WARN("PATCH_PREFIX", + "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); + } + + if ($realfile =~ m@^include/asm/@) { + ERROR("MODIFIED_INCLUDE_ASM", + "do not modify files in include/asm, change architecture specific files in include/asm-\n" . "$here$rawline\n"); + } + next; + } + + $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); + + my $hereline = "$here\n$rawline\n"; + my $herecurr = "$here\n$rawline\n"; + my $hereprev = "$here\n$prevrawline\n$rawline\n"; + + $cnt_lines++ if ($realcnt != 0); + +# Check for incorrect file permissions + if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { + my $permhere = $here . "FILE: $realfile\n"; + if ($realfile =~ /(Makefile|Kconfig|\.c|\.h|\.S|\.tmpl)$/) { + ERROR("EXECUTE_PERMISSIONS", + "do not set execute permissions for source files\n" . $permhere); + } + } + +# Check the patch for a signoff: + if ($line =~ /^\s*signed-off-by:/i) { + $signoff++; + $in_commit_log = 0; + } + +# Check signature styles + if (!$in_header_lines && + $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { + my $space_before = $1; + my $sign_off = $2; + my $space_after = $3; + my $email = $4; + my $ucfirst_sign_off = ucfirst(lc($sign_off)); + + if ($sign_off !~ /$signature_tags/) { + WARN("BAD_SIGN_OFF", + "Non-standard signature: $sign_off\n" . $herecurr); + } + if (defined $space_before && $space_before ne "") { + WARN("BAD_SIGN_OFF", + "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr); + } + if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { + WARN("BAD_SIGN_OFF", + "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr); + } + if (!defined $space_after || $space_after ne " ") { + WARN("BAD_SIGN_OFF", + "Use a single space after $ucfirst_sign_off\n" . $herecurr); + } + + my ($email_name, $email_address, $comment) = parse_email($email); + my $suggested_email = format_email(($email_name, $email_address)); + if ($suggested_email eq "") { + ERROR("BAD_SIGN_OFF", + "Unrecognized email address: '$email'\n" . $herecurr); + } else { + my $dequoted = $suggested_email; + $dequoted =~ s/^"//; + $dequoted =~ s/" $comment" ne $email && + "$suggested_email$comment" ne $email) { + WARN("BAD_SIGN_OFF", + "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr); + } + } + } + +# Check for wrappage within a valid hunk of the file + if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { + ERROR("CORRUPTED_PATCH", + "patch seems to be corrupt (line wrapped?)\n" . + $herecurr) if (!$emitted_corrupt++); + } + +# Check for absolute kernel paths. + if ($tree) { + while ($line =~ m{(?:^|\s)(/\S*)}g) { + my $file = $1; + + if ($file =~ m{^(.*?)(?::\d+)+:?$} && + check_absolute_file($1, $herecurr)) { + # + } else { + check_absolute_file($file, $herecurr); + } + } + } + +# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php + if (($realfile =~ /^$/ || $line =~ /^\+/) && + $rawline !~ m/^$UTF8*$/) { + my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); + + my $blank = copy_spacing($rawline); + my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; + my $hereptr = "$hereline$ptr\n"; + + CHK("INVALID_UTF8", + "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); + } + +# Check if it's the start of a commit log +# (not a header line and we haven't seen the patch filename) + if ($in_header_lines && $realfile =~ /^$/ && + $rawline !~ /^(commit\b|from\b|[\w-]+:).+$/i) { + $in_header_lines = 0; + $in_commit_log = 1; + } + +# Check if there is UTF-8 in a commit log when a mail header has explicitly +# declined it, i.e defined some charset where it is missing. + if ($in_header_lines && + $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && + $1 !~ /utf-8/i) { + $non_utf8_charset = 1; + } + + if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && + $rawline =~ /$NON_ASCII_UTF8/) { + WARN("UTF8_BEFORE_PATCH", + "8-bit UTF-8 used in possible commit log\n" . $herecurr); + } + +# ignore non-hunk lines and lines being removed + next if (!$hunk_line || $line =~ /^-/); + +#trailing whitespace + if ($line =~ /^\+.*\015/) { + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; + ERROR("DOS_LINE_ENDINGS", + "DOS line endings\n" . $herevet); + + } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; + ERROR("TRAILING_WHITESPACE", + "trailing whitespace\n" . $herevet); + $rpt_cleaners = 1; + } + +# check for Kconfig help text having a real description +# Only applies when adding the entry originally, after that we do not have +# sufficient context to determine whether it is indeed long enough. + if ($realfile =~ /Kconfig/ && + $line =~ /.\s*config\s+/) { + my $length = 0; + my $cnt = $realcnt; + my $ln = $linenr + 1; + my $f; + my $is_start = 0; + my $is_end = 0; + for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { + $f = $lines[$ln - 1]; + $cnt-- if ($lines[$ln - 1] !~ /^-/); + $is_end = $lines[$ln - 1] =~ /^\+/; + + next if ($f =~ /^-/); + + if ($lines[$ln - 1] =~ /.\s*(?:bool|tristate)\s*\"/) { + $is_start = 1; + } elsif ($lines[$ln - 1] =~ /.\s*(?:---)?help(?:---)?$/) { + $length = -1; + } + + $f =~ s/^.//; + $f =~ s/#.*//; + $f =~ s/^\s+//; + next if ($f =~ /^$/); + if ($f =~ /^\s*config\s/) { + $is_end = 1; + last; + } + $length++; + } + WARN("CONFIG_DESCRIPTION", + "please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_start && $is_end && $length < 4); + #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; + } + +# discourage the addition of CONFIG_EXPERIMENTAL in Kconfig. + if ($realfile =~ /Kconfig/ && + $line =~ /.\s*depends on\s+.*\bEXPERIMENTAL\b/) { + WARN("CONFIG_EXPERIMENTAL", + "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n"); + } + + if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && + ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { + my $flag = $1; + my $replacement = { + 'EXTRA_AFLAGS' => 'asflags-y', + 'EXTRA_CFLAGS' => 'ccflags-y', + 'EXTRA_CPPFLAGS' => 'cppflags-y', + 'EXTRA_LDFLAGS' => 'ldflags-y', + }; + + WARN("DEPRECATED_VARIABLE", + "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); + } + +# check we are in a valid source file if not then ignore this hunk + next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/); + +#line length limit + if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && + $rawline !~ /^.\s*\*\s*\@$Ident\s/ && + !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:|,|\)\s*;)\s*$/ || + $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) && + $length > $max_line_length) + { + WARN("LONG_LINE", + "line over $max_line_length characters\n" . $herecurr); + } + +# Check for user-visible strings broken across lines, which breaks the ability +# to grep for the string. Limited to strings used as parameters (those +# following an open parenthesis), which almost completely eliminates false +# positives, as well as warning only once per parameter rather than once per +# line of the string. Make an exception when the previous string ends in a +# newline (multiple lines in one string constant) or \n\t (common in inline +# assembly to indent the instruction on the following line). + if ($line =~ /^\+\s*"/ && + $prevline =~ /"\s*$/ && + $prevline =~ /\(/ && + $prevrawline !~ /\\n(?:\\t)*"\s*$/) { + WARN("SPLIT_STRING", + "quoted string split across lines\n" . $hereprev); + } + +# check for spaces before a quoted newline + if ($rawline =~ /^.*\".*\s\\n/) { + WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", + "unnecessary whitespace before a quoted newline\n" . $herecurr); + } + +# check for adding lines without a newline. + if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { + WARN("MISSING_EOF_NEWLINE", + "adding a line without newline at end of file\n" . $herecurr); + } + +# Blackfin: use hi/lo macros + if ($realfile =~ m at arch/blackfin/.*\.S$@) { + if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) { + my $herevet = "$here\n" . cat_vet($line) . "\n"; + ERROR("LO_MACRO", + "use the LO() macro, not (... & 0xFFFF)\n" . $herevet); + } + if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) { + my $herevet = "$here\n" . cat_vet($line) . "\n"; + ERROR("HI_MACRO", + "use the HI() macro, not (... >> 16)\n" . $herevet); + } + } + +# check we are in a valid source file C or perl if not then ignore this hunk + next if ($realfile !~ /\.(h|c|pl)$/); + +# at the beginning of a line any tabs must come first and anything +# more than 8 must use tabs. + if ($rawline =~ /^\+\s* \t\s*\S/ || + $rawline =~ /^\+\s* \s*/) { + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; + ERROR("CODE_INDENT", + "code indent should use tabs where possible\n" . $herevet); + $rpt_cleaners = 1; + } + +# check for space before tabs. + if ($rawline =~ /^\+/ && $rawline =~ / \t/) { + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; + WARN("SPACE_BEFORE_TAB", + "please, no space before tabs\n" . $herevet); + } + +# check for && or || at the start of a line + if ($rawline =~ /^\+\s*(&&|\|\|)/) { + CHK("LOGICAL_CONTINUATIONS", + "Logical continuations should be on the previous line\n" . $hereprev); + } + +# check multi-line statement indentation matches previous line + if ($^V && $^V ge 5.10.0 && + $prevline =~ /^\+(\t*)(if \(|$Ident\().*(\&\&|\|\||,)\s*$/) { + $prevline =~ /^\+(\t*)(.*)$/; + my $oldindent = $1; + my $rest = $2; + + my $pos = pos_last_openparen($rest); + if ($pos >= 0) { + $line =~ /^(\+| )([ \t]*)/; + my $newindent = $2; + + my $goodtabindent = $oldindent . + "\t" x ($pos / 8) . + " " x ($pos % 8); + my $goodspaceindent = $oldindent . " " x $pos; + + if ($newindent ne $goodtabindent && + $newindent ne $goodspaceindent) { + CHK("PARENTHESIS_ALIGNMENT", + "Alignment should match open parenthesis\n" . $hereprev); + } + } + } + + if ($line =~ /^\+.*\*[ \t]*\)[ \t]+/) { + CHK("SPACING", + "No space is necessary after a cast\n" . $hereprev); + } + + if ($realfile =~ m@^(drivers/net/|net/)@ && + $rawline =~ /^\+[ \t]*\/\*[ \t]*$/ && + $prevrawline =~ /^\+[ \t]*$/) { + WARN("NETWORKING_BLOCK_COMMENT_STYLE", + "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); + } + + if ($realfile =~ m@^(drivers/net/|net/)@ && + $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ + $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ + $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ + $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ + WARN("NETWORKING_BLOCK_COMMENT_STYLE", + "networking block comments put the trailing */ on a separate line\n" . $herecurr); + } + +# check for spaces at the beginning of a line. +# Exceptions: +# 1) within comments +# 2) indented preprocessor commands +# 3) hanging labels + if ($rawline =~ /^\+ / && $line !~ /\+ *(?:$;|#|$Ident:)/) { + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; + WARN("LEADING_SPACE", + "please, no spaces at the start of a line\n" . $herevet); + } + +# check we are in a valid C source file if not then ignore this hunk + next if ($realfile !~ /\.(h|c)$/); + +# discourage the addition of CONFIG_EXPERIMENTAL in #if(def). + if ($line =~ /^\+\s*\#\s*if.*\bCONFIG_EXPERIMENTAL\b/) { + WARN("CONFIG_EXPERIMENTAL", + "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n"); + } + +# check for RCS/CVS revision markers + if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { + WARN("CVS_KEYWORD", + "CVS style keyword markers, these will _not_ be updated\n". $herecurr); + } + +# Blackfin: don't use __builtin_bfin_[cs]sync + if ($line =~ /__builtin_bfin_csync/) { + my $herevet = "$here\n" . cat_vet($line) . "\n"; + ERROR("CSYNC", + "use the CSYNC() macro in asm/blackfin.h\n" . $herevet); + } + if ($line =~ /__builtin_bfin_ssync/) { + my $herevet = "$here\n" . cat_vet($line) . "\n"; + ERROR("SSYNC", + "use the SSYNC() macro in asm/blackfin.h\n" . $herevet); + } + +# Check for potential 'bare' types + my ($stat, $cond, $line_nr_next, $remain_next, $off_next, + $realline_next); +#print "LINE<$line>\n"; + if ($linenr >= $suppress_statement && + $realcnt && $line =~ /.\s*\S/) { + ($stat, $cond, $line_nr_next, $remain_next, $off_next) = + ctx_statement_block($linenr, $realcnt, 0); + $stat =~ s/\n./\n /g; + $cond =~ s/\n./\n /g; + +#print "linenr<$linenr> <$stat>\n"; + # If this statement has no statement boundaries within + # it there is no point in retrying a statement scan + # until we hit end of it. + my $frag = $stat; $frag =~ s/;+\s*$//; + if ($frag !~ /(?:{|;)/) { +#print "skip<$line_nr_next>\n"; + $suppress_statement = $line_nr_next; + } + + # Find the real next line. + $realline_next = $line_nr_next; + if (defined $realline_next && + (!defined $lines[$realline_next - 1] || + substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { + $realline_next++; + } + + my $s = $stat; + $s =~ s/{.*$//s; + + # Ignore goto labels. + if ($s =~ /$Ident:\*$/s) { + + # Ignore functions being called + } elsif ($s =~ /^.\s*$Ident\s*\(/s) { + + } elsif ($s =~ /^.\s*else\b/s) { + + # declarations always start with types + } elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?((?:\s*$Ident)+?)\b(?:\s+$Sparse)?\s*\**\s*(?:$Ident|\(\*[^\)]*\))(?:\s*$Modifier)?\s*(?:;|=|,|\()/s) { + my $type = $1; + $type =~ s/\s+/ /g; + possible($type, "A:" . $s); + + # definitions in global scope can only start with types + } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { + possible($1, "B:" . $s); + } + + # any (foo ... *) is a pointer cast, and foo is a type + while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { + possible($1, "C:" . $s); + } + + # Check for any sort of function declaration. + # int foo(something bar, other baz); + # void (*store_gdt)(x86_descr_ptr *); + if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { + my ($name_len) = length($1); + + my $ctx = $s; + substr($ctx, 0, $name_len + 1, ''); + $ctx =~ s/\)[^\)]*$//; + + for my $arg (split(/\s*,\s*/, $ctx)) { + if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { + + possible($1, "D:" . $s); + } + } + } + + } + +# +# Checks which may be anchored in the context. +# + +# Check for switch () and associated case and default +# statements should be at the same indent. + if ($line=~/\bswitch\s*\(.*\)/) { + my $err = ''; + my $sep = ''; + my @ctx = ctx_block_outer($linenr, $realcnt); + shift(@ctx); + for my $ctx (@ctx) { + my ($clen, $cindent) = line_stats($ctx); + if ($ctx =~ /^\+\s*(case\s+|default:)/ && + $indent != $cindent) { + $err .= "$sep$ctx\n"; + $sep = ''; + } else { + $sep = "[...]\n"; + } + } + if ($err ne '') { + ERROR("SWITCH_CASE_INDENT_LEVEL", + "switch and case should be at the same indent\n$hereline$err"); + } + } + +# if/while/etc brace do not go on next line, unless defining a do while loop, +# or if that brace on the next line is for something else + if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { + my $pre_ctx = "$1$2"; + + my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); + + if ($line =~ /^\+\t{6,}/) { + WARN("DEEP_INDENTATION", + "Too many leading tabs - consider code refactoring\n" . $herecurr); + } + + my $ctx_cnt = $realcnt - $#ctx - 1; + my $ctx = join("\n", @ctx); + + my $ctx_ln = $linenr; + my $ctx_skip = $realcnt; + + while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && + defined $lines[$ctx_ln - 1] && + $lines[$ctx_ln - 1] =~ /^-/)) { + ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; + $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); + $ctx_ln++; + } + + #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; + #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; + + if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { + ERROR("OPEN_BRACE", + "that open brace { should be on the previous line\n" . + "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); + } + if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && + $ctx =~ /\)\s*\;\s*$/ && + defined $lines[$ctx_ln - 1]) + { + my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); + if ($nindent > $indent) { + WARN("TRAILING_SEMICOLON", + "trailing semicolon indicates no statements, indent implies otherwise\n" . + "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); + } + } + } + +# Check relative indent for conditionals and blocks. + if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { + ($stat, $cond, $line_nr_next, $remain_next, $off_next) = + ctx_statement_block($linenr, $realcnt, 0) + if (!defined $stat); + my ($s, $c) = ($stat, $cond); + + substr($s, 0, length($c), ''); + + # Make sure we remove the line prefixes as we have + # none on the first line, and are going to readd them + # where necessary. + $s =~ s/\n./\n/gs; + + # Find out how long the conditional actually is. + my @newlines = ($c =~ /\n/gs); + my $cond_lines = 1 + $#newlines; + + # We want to check the first line inside the block + # starting at the end of the conditional, so remove: + # 1) any blank line termination + # 2) any opening brace { on end of the line + # 3) any do (...) { + my $continuation = 0; + my $check = 0; + $s =~ s/^.*\bdo\b//; + $s =~ s/^\s*{//; + if ($s =~ s/^\s*\\//) { + $continuation = 1; + } + if ($s =~ s/^\s*?\n//) { + $check = 1; + $cond_lines++; + } + + # Also ignore a loop construct at the end of a + # preprocessor statement. + if (($prevline =~ /^.\s*#\s*define\s/ || + $prevline =~ /\\\s*$/) && $continuation == 0) { + $check = 0; + } + + my $cond_ptr = -1; + $continuation = 0; + while ($cond_ptr != $cond_lines) { + $cond_ptr = $cond_lines; + + # If we see an #else/#elif then the code + # is not linear. + if ($s =~ /^\s*\#\s*(?:else|elif)/) { + $check = 0; + } + + # Ignore: + # 1) blank lines, they should be at 0, + # 2) preprocessor lines, and + # 3) labels. + if ($continuation || + $s =~ /^\s*?\n/ || + $s =~ /^\s*#\s*?/ || + $s =~ /^\s*$Ident\s*:/) { + $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; + if ($s =~ s/^.*?\n//) { + $cond_lines++; + } + } + } + + my (undef, $sindent) = line_stats("+" . $s); + my $stat_real = raw_line($linenr, $cond_lines); + + # Check if either of these lines are modified, else + # this is not this patch's fault. + if (!defined($stat_real) || + $stat !~ /^\+/ && $stat_real !~ /^\+/) { + $check = 0; + } + if (defined($stat_real) && $cond_lines > 1) { + $stat_real = "[...]\n$stat_real"; + } + + #print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n"; + + if ($check && (($sindent % 8) != 0 || + ($sindent <= $indent && $s ne ''))) { + WARN("SUSPECT_CODE_INDENT", + "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); + } + } + + # Track the 'values' across context and added lines. + my $opline = $line; $opline =~ s/^./ /; + my ($curr_values, $curr_vars) = + annotate_values($opline . "\n", $prev_values); + $curr_values = $prev_values . $curr_values; + if ($dbg_values) { + my $outline = $opline; $outline =~ s/\t/ /g; + print "$linenr > .$outline\n"; + print "$linenr > $curr_values\n"; + print "$linenr > $curr_vars\n"; + } + $prev_values = substr($curr_values, -1); + +#ignore lines not being added + if ($line=~/^[^\+]/) {next;} + +# TEST: allow direct testing of the type matcher. + if ($dbg_type) { + if ($line =~ /^.\s*$Declare\s*$/) { + ERROR("TEST_TYPE", + "TEST: is type\n" . $herecurr); + } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { + ERROR("TEST_NOT_TYPE", + "TEST: is not type ($1 is)\n". $herecurr); + } + next; + } +# TEST: allow direct testing of the attribute matcher. + if ($dbg_attr) { + if ($line =~ /^.\s*$Modifier\s*$/) { + ERROR("TEST_ATTR", + "TEST: is attr\n" . $herecurr); + } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { + ERROR("TEST_NOT_ATTR", + "TEST: is not attr ($1 is)\n". $herecurr); + } + next; + } + +# check for initialisation to aggregates open brace on the next line + if ($line =~ /^.\s*{/ && + $prevline =~ /(?:^|[^=])=\s*$/) { + ERROR("OPEN_BRACE", + "that open brace { should be on the previous line\n" . $hereprev); + } + +# +# Checks which are anchored on the added line. +# + +# check for malformed paths in #include statements (uses RAW line) + if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { + my $path = $1; + if ($path =~ m{//}) { + ERROR("MALFORMED_INCLUDE", + "malformed #include filename\n" . $herecurr); + } + if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { + ERROR("UAPI_INCLUDE", + "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); + } + } + +# no C99 // comments + if ($line =~ m{//}) { + ERROR("C99_COMMENTS", + "do not use C99 // comments\n" . $herecurr); + } + # Remove C99 comments. + $line =~ s@//.*@@; + $opline =~ s@//.*@@; + +# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider +# the whole statement. +#print "APW <$lines[$realline_next - 1]>\n"; + if (defined $realline_next && + exists $lines[$realline_next - 1] && + !defined $suppress_export{$realline_next} && + ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || + $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { + # Handle definitions which produce identifiers with + # a prefix: + # XXX(foo); + # EXPORT_SYMBOL(something_foo); + my $name = $1; + if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && + $name =~ /^${Ident}_$2/) { +#print "FOO C name<$name>\n"; + $suppress_export{$realline_next} = 1; + + } elsif ($stat !~ /(?: + \n.}\s*$| + ^.DEFINE_$Ident\(\Q$name\E\)| + ^.DECLARE_$Ident\(\Q$name\E\)| + ^.LIST_HEAD\(\Q$name\E\)| + ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| + \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() + )/x) { +#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; + $suppress_export{$realline_next} = 2; + } else { + $suppress_export{$realline_next} = 1; + } + } + if (!defined $suppress_export{$linenr} && + $prevline =~ /^.\s*$/ && + ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || + $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { +#print "FOO B <$lines[$linenr - 1]>\n"; + $suppress_export{$linenr} = 2; + } + if (defined $suppress_export{$linenr} && + $suppress_export{$linenr} == 2) { + WARN("EXPORT_SYMBOL", + "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); + } + +# check for global initialisers. + if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) { + ERROR("GLOBAL_INITIALISERS", + "do not initialise globals to 0 or NULL\n" . + $herecurr); + } +# check for static initialisers. + if ($line =~ /\bstatic\s.*=\s*(0|NULL|false)\s*;/) { + ERROR("INITIALISED_STATIC", + "do not initialise statics to 0 or NULL\n" . + $herecurr); + } + +# check for static const char * arrays. + if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { + WARN("STATIC_CONST_CHAR_ARRAY", + "static const char * array should probably be static const char * const\n" . + $herecurr); + } + +# check for static char foo[] = "bar" declarations. + if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { + WARN("STATIC_CONST_CHAR_ARRAY", + "static char array declaration should probably be static const char\n" . + $herecurr); + } + +# check for declarations of struct pci_device_id + if ($line =~ /\bstruct\s+pci_device_id\s+\w+\s*\[\s*\]\s*\=\s*\{/) { + WARN("DEFINE_PCI_DEVICE_TABLE", + "Use DEFINE_PCI_DEVICE_TABLE for struct pci_device_id\n" . $herecurr); + } + +# check for new typedefs, only function parameters and sparse annotations +# make sense. + if ($line =~ /\btypedef\s/ && + $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && + $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && + $line !~ /\b$typeTypedefs\b/ && + $line !~ /\b__bitwise(?:__|)\b/) { + WARN("NEW_TYPEDEFS", + "do not add new typedefs\n" . $herecurr); + } + +# * goes on variable not on type + # (char*[ const]) + while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { + #print "AA<$1>\n"; + my ($from, $to) = ($2, $2); + + # Should start with a space. + $to =~ s/^(\S)/ $1/; + # Should not end with a space. + $to =~ s/\s+$//; + # '*'s should not have spaces between. + while ($to =~ s/\*\s+\*/\*\*/) { + } + + #print "from<$from> to<$to>\n"; + if ($from ne $to) { + ERROR("POINTER_LOCATION", + "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr); + } + } + while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { + #print "BB<$1>\n"; + my ($from, $to, $ident) = ($2, $2, $3); + + # Should start with a space. + $to =~ s/^(\S)/ $1/; + # Should not end with a space. + $to =~ s/\s+$//; + # '*'s should not have spaces between. + while ($to =~ s/\*\s+\*/\*\*/) { + } + # Modifiers should have spaces. + $to =~ s/(\b$Modifier$)/$1 /; + + #print "from<$from> to<$to> ident<$ident>\n"; + if ($from ne $to && $ident !~ /^$Modifier$/) { + ERROR("POINTER_LOCATION", + "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr); + } + } + +# # no BUG() or BUG_ON() +# if ($line =~ /\b(BUG|BUG_ON)\b/) { +# print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n"; +# print "$herecurr"; +# $clean = 0; +# } + + if ($line =~ /\bLINUX_VERSION_CODE\b/) { + WARN("LINUX_VERSION_CODE", + "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); + } + +# check for uses of printk_ratelimit + if ($line =~ /\bprintk_ratelimit\s*\(/) { + WARN("PRINTK_RATELIMITED", +"Prefer printk_ratelimited or pr__ratelimited to printk_ratelimit\n" . $herecurr); + } + +# printk should use KERN_* levels. Note that follow on printk's on the +# same line do not need a level, so we use the current block context +# to try and find and validate the current printk. In summary the current +# printk includes all preceding printk's which have no newline on the end. +# we assume the first bad printk is the one to report. + if ($line =~ /\bprintk\((?!KERN_)\s*"/) { + my $ok = 0; + for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { + #print "CHECK<$lines[$ln - 1]\n"; + # we have a preceding printk if it ends + # with "\n" ignore it, else it is to blame + if ($lines[$ln - 1] =~ m{\bprintk\(}) { + if ($rawlines[$ln - 1] !~ m{\\n"}) { + $ok = 1; + } + last; + } + } + if ($ok == 0) { + WARN("PRINTK_WITHOUT_KERN_LEVEL", + "printk() should include KERN_ facility level\n" . $herecurr); + } + } + + if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { + my $orig = $1; + my $level = lc($orig); + $level = "warn" if ($level eq "warning"); + my $level2 = $level; + $level2 = "dbg" if ($level eq "debug"); + WARN("PREFER_PR_LEVEL", + "Prefer netdev_$level2(netdev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); + } + + if ($line =~ /\bpr_warning\s*\(/) { + WARN("PREFER_PR_LEVEL", + "Prefer pr_warn(... to pr_warning(...\n" . $herecurr); + } + +# function brace can't be on same line, except for #defines of do while, +# or if closed on same line + if (($line=~/$Type\s*$Ident\(.*\).*\s{/) and + !($line=~/\#\s*define.*do\s{/) and !($line=~/}/)) { + ERROR("OPEN_BRACE", + "open brace '{' following function declarations go on the next line\n" . $herecurr); + } + +# open braces for enum, union and struct go on the same line. + if ($line =~ /^.\s*{/ && + $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { + ERROR("OPEN_BRACE", + "open brace '{' following $1 go on the same line\n" . $hereprev); + } + +# missing space after union, struct or enum definition + if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?(?:\s+$Ident)?[=\{]/) { + WARN("SPACING", + "missing space after $1 definition\n" . $herecurr); + } + +# check for spacing round square brackets; allowed: +# 1. with a type on the left -- int [] a; +# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, +# 3. inside a curly brace -- = { [0...10] = 5 } + while ($line =~ /(.*?\s)\[/g) { + my ($where, $prefix) = ($-[1], $1); + if ($prefix !~ /$Type\s+$/ && + ($where != 0 || $prefix !~ /^.\s+$/) && + $prefix !~ /[{,]\s+$/) { + ERROR("BRACKET_SPACE", + "space prohibited before open square bracket '['\n" . $herecurr); + } + } + +# check for spaces between functions and their parentheses. + while ($line =~ /($Ident)\s+\(/g) { + my $name = $1; + my $ctx_before = substr($line, 0, $-[1]); + my $ctx = "$ctx_before$name"; + + # Ignore those directives where spaces _are_ permitted. + if ($name =~ /^(?: + if|for|while|switch|return|case| + volatile|__volatile__| + __attribute__|format|__extension__| + asm|__asm__)$/x) + { + + # cpp #define statements have non-optional spaces, ie + # if there is a space between the name and the open + # parenthesis it is simply not a parameter group. + } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { + + # cpp #elif statement condition may start with a ( + } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { + + # If this whole things ends with a type its most + # likely a typedef for a function. + } elsif ($ctx =~ /$Type$/) { + + } else { + WARN("SPACING", + "space prohibited between function name and open parenthesis '('\n" . $herecurr); + } + } + +# check for whitespace before a non-naked semicolon + if ($line =~ /^\+.*\S\s+;/) { + CHK("SPACING", + "space prohibited before semicolon\n" . $herecurr); + } + +# Check operator spacing. + if (!($line=~/\#\s*include/)) { + my $ops = qr{ + <<=|>>=|<=|>=|==|!=| + \+=|-=|\*=|\/=|%=|\^=|\|=|&=| + =>|->|<<|>>|<|>|=|!|~| + &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| + \?|: + }x; + my @elements = split(/($ops|;)/, $opline); + my $off = 0; + + my $blank = copy_spacing($opline); + + for (my $n = 0; $n < $#elements; $n += 2) { + $off += length($elements[$n]); + + # Pick up the preceding and succeeding characters. + my $ca = substr($opline, 0, $off); + my $cc = ''; + if (length($opline) >= ($off + length($elements[$n + 1]))) { + $cc = substr($opline, $off + length($elements[$n + 1])); + } + my $cb = "$ca$;$cc"; + + my $a = ''; + $a = 'V' if ($elements[$n] ne ''); + $a = 'W' if ($elements[$n] =~ /\s$/); + $a = 'C' if ($elements[$n] =~ /$;$/); + $a = 'B' if ($elements[$n] =~ /(\[|\()$/); + $a = 'O' if ($elements[$n] eq ''); + $a = 'E' if ($ca =~ /^\s*$/); + + my $op = $elements[$n + 1]; + + my $c = ''; + if (defined $elements[$n + 2]) { + $c = 'V' if ($elements[$n + 2] ne ''); + $c = 'W' if ($elements[$n + 2] =~ /^\s/); + $c = 'C' if ($elements[$n + 2] =~ /^$;/); + $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); + $c = 'O' if ($elements[$n + 2] eq ''); + $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); + } else { + $c = 'E'; + } + + my $ctx = "${a}x${c}"; + + my $at = "(ctx:$ctx)"; + + my $ptr = substr($blank, 0, $off) . "^"; + my $hereptr = "$hereline$ptr\n"; + + # Pull out the value of this operator. + my $op_type = substr($curr_values, $off + 1, 1); + + # Get the full operator variant. + my $opv = $op . substr($curr_vars, $off, 1); + + # Ignore operators passed as parameters. + if ($op_type ne 'V' && + $ca =~ /\s$/ && $cc =~ /^\s*,/) { + +# # Ignore comments +# } elsif ($op =~ /^$;+$/) { + + # ; should have either the end of line or a space or \ after it + } elsif ($op eq ';') { + if ($ctx !~ /.x[WEBC]/ && + $cc !~ /^\\/ && $cc !~ /^;/) { + ERROR("SPACING", + "space required after that '$op' $at\n" . $hereptr); + } + + # // is a comment + } elsif ($op eq '//') { + + # No spaces for: + # -> + # : when part of a bitfield + } elsif ($op eq '->' || $opv eq ':B') { + if ($ctx =~ /Wx.|.xW/) { + ERROR("SPACING", + "spaces prohibited around that '$op' $at\n" . $hereptr); + } + + # , must have a space on the right. + } elsif ($op eq ',') { + if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { + ERROR("SPACING", + "space required after that '$op' $at\n" . $hereptr); + } + + # '*' as part of a type definition -- reported already. + } elsif ($opv eq '*_') { + #warn "'*' is part of type\n"; + + # unary operators should have a space before and + # none after. May be left adjacent to another + # unary operator, or a cast + } elsif ($op eq '!' || $op eq '~' || + $opv eq '*U' || $opv eq '-U' || + $opv eq '&U' || $opv eq '&&U') { + if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { + ERROR("SPACING", + "space required before that '$op' $at\n" . $hereptr); + } + if ($op eq '*' && $cc =~/\s*$Modifier\b/) { + # A unary '*' may be const + + } elsif ($ctx =~ /.xW/) { + ERROR("SPACING", + "space prohibited after that '$op' $at\n" . $hereptr); + } + + # unary ++ and unary -- are allowed no space on one side. + } elsif ($op eq '++' or $op eq '--') { + if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { + ERROR("SPACING", + "space required one side of that '$op' $at\n" . $hereptr); + } + if ($ctx =~ /Wx[BE]/ || + ($ctx =~ /Wx./ && $cc =~ /^;/)) { + ERROR("SPACING", + "space prohibited before that '$op' $at\n" . $hereptr); + } + if ($ctx =~ /ExW/) { + ERROR("SPACING", + "space prohibited after that '$op' $at\n" . $hereptr); + } + + + # << and >> may either have or not have spaces both sides + } elsif ($op eq '<<' or $op eq '>>' or + $op eq '&' or $op eq '^' or $op eq '|' or + $op eq '+' or $op eq '-' or + $op eq '*' or $op eq '/' or + $op eq '%') + { + if ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { + ERROR("SPACING", + "need consistent spacing around '$op' $at\n" . + $hereptr); + } + + # A colon needs no spaces before when it is + # terminating a case value or a label. + } elsif ($opv eq ':C' || $opv eq ':L') { + if ($ctx =~ /Wx./) { + ERROR("SPACING", + "space prohibited before that '$op' $at\n" . $hereptr); + } + + # All the others need spaces both sides. + } elsif ($ctx !~ /[EWC]x[CWE]/) { + my $ok = 0; + + # Ignore email addresses + if (($op eq '<' && + $cc =~ /^\S+\@\S+>/) || + ($op eq '>' && + $ca =~ /<\S+\@\S+$/)) + { + $ok = 1; + } + + # Ignore ?: + if (($opv eq ':O' && $ca =~ /\?$/) || + ($op eq '?' && $cc =~ /^:/)) { + $ok = 1; + } + + if ($ok == 0) { + ERROR("SPACING", + "spaces required around that '$op' $at\n" . $hereptr); + } + } + $off += length($elements[$n + 1]); + } + } + +# check for multiple assignments + if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { + CHK("MULTIPLE_ASSIGNMENTS", + "multiple assignments should be avoided\n" . $herecurr); + } + +## # check for multiple declarations, allowing for a function declaration +## # continuation. +## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && +## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { +## +## # Remove any bracketed sections to ensure we do not +## # falsly report the parameters of functions. +## my $ln = $line; +## while ($ln =~ s/\([^\(\)]*\)//g) { +## } +## if ($ln =~ /,/) { +## WARN("MULTIPLE_DECLARATION", +## "declaring multiple variables together should be avoided\n" . $herecurr); +## } +## } + +#need space before brace following if, while, etc + if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) || + $line =~ /do{/) { + ERROR("SPACING", + "space required before the open brace '{'\n" . $herecurr); + } + +# closing brace should have a space following it when it has anything +# on the line + if ($line =~ /}(?!(?:,|;|\)))\S/) { + ERROR("SPACING", + "space required after that close brace '}'\n" . $herecurr); + } + +# check spacing on square brackets + if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { + ERROR("SPACING", + "space prohibited after that open square bracket '['\n" . $herecurr); + } + if ($line =~ /\s\]/) { + ERROR("SPACING", + "space prohibited before that close square bracket ']'\n" . $herecurr); + } + +# check spacing on parentheses + if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && + $line !~ /for\s*\(\s+;/) { + ERROR("SPACING", + "space prohibited after that open parenthesis '('\n" . $herecurr); + } + if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && + $line !~ /for\s*\(.*;\s+\)/ && + $line !~ /:\s+\)/) { + ERROR("SPACING", + "space prohibited before that close parenthesis ')'\n" . $herecurr); + } + +#goto labels aren't indented, allow a single space however + if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and + !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { + WARN("INDENTED_LABEL", + "labels should not be indented\n" . $herecurr); + } + +# Return is not a function. + if (defined($stat) && $stat =~ /^.\s*return(\s*)(\(.*);/s) { + my $spacing = $1; + my $value = $2; + + # Flatten any parentheses + $value =~ s/\(/ \(/g; + $value =~ s/\)/\) /g; + while ($value =~ s/\[[^\[\]]*\]/1/ || + $value !~ /(?:$Ident|-?$Constant)\s* + $Compare\s* + (?:$Ident|-?$Constant)/x && + $value =~ s/\([^\(\)]*\)/1/) { + } +#print "value<$value>\n"; + if ($value =~ /^\s*(?:$Ident|-?$Constant)\s*$/) { + ERROR("RETURN_PARENTHESES", + "return is not a function, parentheses are not required\n" . $herecurr); + + } elsif ($spacing !~ /\s+/) { + ERROR("SPACING", + "space required before the open parenthesis '('\n" . $herecurr); + } + } +# Return of what appears to be an errno should normally be -'ve + if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) { + my $name = $1; + if ($name ne 'EOF' && $name ne 'ERROR') { + WARN("USE_NEGATIVE_ERRNO", + "return of an errno should typically be -ve (return -$1)\n" . $herecurr); + } + } + +# Need a space before open parenthesis after if, while etc + if ($line=~/\b(if|while|for|switch)\(/) { + ERROR("SPACING", "space required before the open parenthesis '('\n" . $herecurr); + } + +# Check for illegal assignment in if conditional -- and check for trailing +# statements after the conditional. + if ($line =~ /do\s*(?!{)/) { + ($stat, $cond, $line_nr_next, $remain_next, $off_next) = + ctx_statement_block($linenr, $realcnt, 0) + if (!defined $stat); + my ($stat_next) = ctx_statement_block($line_nr_next, + $remain_next, $off_next); + $stat_next =~ s/\n./\n /g; + ##print "stat<$stat> stat_next<$stat_next>\n"; + + if ($stat_next =~ /^\s*while\b/) { + # If the statement carries leading newlines, + # then count those as offsets. + my ($whitespace) = + ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); + my $offset = + statement_rawlines($whitespace) - 1; + + $suppress_whiletrailers{$line_nr_next + + $offset} = 1; + } + } + if (!defined $suppress_whiletrailers{$linenr} && + $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { + my ($s, $c) = ($stat, $cond); + + if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { + ERROR("ASSIGN_IN_IF", + "do not use assignment in if condition\n" . $herecurr); + } + + # Find out what is on the end of the line after the + # conditional. + substr($s, 0, length($c), ''); + $s =~ s/\n.*//g; + $s =~ s/$;//g; # Remove any comments + if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && + $c !~ /}\s*while\s*/) + { + # Find out how long the conditional actually is. + my @newlines = ($c =~ /\n/gs); + my $cond_lines = 1 + $#newlines; + my $stat_real = ''; + + $stat_real = raw_line($linenr, $cond_lines) + . "\n" if ($cond_lines); + if (defined($stat_real) && $cond_lines > 1) { + $stat_real = "[...]\n$stat_real"; + } + + ERROR("TRAILING_STATEMENTS", + "trailing statements should be on next line\n" . $herecurr . $stat_real); + } + } + +# Check for bitwise tests written as boolean + if ($line =~ / + (?: + (?:\[|\(|\&\&|\|\|) + \s*0[xX][0-9]+\s* + (?:\&\&|\|\|) + | + (?:\&\&|\|\|) + \s*0[xX][0-9]+\s* + (?:\&\&|\|\||\)|\]) + )/x) + { + WARN("HEXADECIMAL_BOOLEAN_TEST", + "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); + } + +# if and else should not have general statements after it + if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { + my $s = $1; + $s =~ s/$;//g; # Remove any comments + if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { + ERROR("TRAILING_STATEMENTS", + "trailing statements should be on next line\n" . $herecurr); + } + } +# if should not continue a brace + if ($line =~ /}\s*if\b/) { + ERROR("TRAILING_STATEMENTS", + "trailing statements should be on next line\n" . + $herecurr); + } +# case and default should not have general statements after them + if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && + $line !~ /\G(?: + (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| + \s*return\s+ + )/xg) + { + ERROR("TRAILING_STATEMENTS", + "trailing statements should be on next line\n" . $herecurr); + } + + # Check for }else {, these must be at the same + # indent level to be relevant to each other. + if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and + $previndent == $indent) { + ERROR("ELSE_AFTER_BRACE", + "else should follow close brace '}'\n" . $hereprev); + } + + if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ and + $previndent == $indent) { + my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); + + # Find out what is on the end of the line after the + # conditional. + substr($s, 0, length($c), ''); + $s =~ s/\n.*//g; + + if ($s =~ /^\s*;/) { + ERROR("WHILE_AFTER_BRACE", + "while should follow close brace '}'\n" . $hereprev); + } + } + +#CamelCase + while ($line =~ m{($Constant|$Lval)}g) { + my $var = $1; + if ($var !~ /$Constant/ && + $var =~ /[A-Z]\w*[a-z]|[a-z]\w*[A-Z]/ && + !defined $camelcase{$var}) { + $camelcase{$var} = 1; + WARN("CAMELCASE", + "Avoid CamelCase: <$var>\n" . $herecurr); + } + } + +#no spaces allowed after \ in define + if ($line=~/\#\s*define.*\\\s$/) { + WARN("WHITESPACE_AFTER_LINE_CONTINUATION", + "Whitepspace after \\ makes next lines useless\n" . $herecurr); + } + +#warn if is #included and is available (uses RAW line) + if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\}) { + my $file = "$1.h"; + my $checkfile = "include/linux/$file"; + if (-f "$root/$checkfile" && + $realfile ne $checkfile && + $1 !~ /$allowed_asm_includes/) + { + if ($realfile =~ m{^arch/}) { + CHK("ARCH_INCLUDE_LINUX", + "Consider using #include instead of \n" . $herecurr); + } else { + WARN("INCLUDE_LINUX", + "Use #include instead of \n" . $herecurr); + } + } + } + +# multi-statement macros should be enclosed in a do while loop, grab the +# first statement and ensure its the whole macro if its not enclosed +# in a known good container + if ($realfile !~ m@/vmlinux.lds.h$@ && + $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { + my $ln = $linenr; + my $cnt = $realcnt; + my ($off, $dstat, $dcond, $rest); + my $ctx = ''; + ($dstat, $dcond, $ln, $cnt, $off) = + ctx_statement_block($linenr, $realcnt, 0); + $ctx = $dstat; + #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; + #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; + + $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//; + $dstat =~ s/$;//g; + $dstat =~ s/\\\n.//g; + $dstat =~ s/^\s*//s; + $dstat =~ s/\s*$//s; + + # Flatten any parentheses and braces + while ($dstat =~ s/\([^\(\)]*\)/1/ || + $dstat =~ s/\{[^\{\}]*\}/1/ || + $dstat =~ s/\[[^\[\]]*\]/1/) + { + } + + # Flatten any obvious string concatentation. + while ($dstat =~ s/("X*")\s*$Ident/$1/ || + $dstat =~ s/$Ident\s*("X*")/$1/) + { + } + + my $exceptions = qr{ + $Declare| + module_param_named| + MODULE_PARM_DESC| + DECLARE_PER_CPU| + DEFINE_PER_CPU| + __typeof__\(| + union| + struct| + \.$Ident\s*=\s*| + ^\"|\"$ + }x; + #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; + if ($dstat ne '' && + $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), + $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); + $dstat !~ /^[!~-]?(?:$Ident|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo + $dstat !~ /^'X'$/ && # character constants + $dstat !~ /$exceptions/ && + $dstat !~ /^\.$Ident\s*=/ && # .foo = + $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) + $dstat !~ /^for\s*$Constant$/ && # for (...) + $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() + $dstat !~ /^do\s*{/ && # do {... + $dstat !~ /^\({/) # ({... + { + $ctx =~ s/\n*$//; + my $herectx = $here . "\n"; + my $cnt = statement_rawlines($ctx); + + for (my $n = 0; $n < $cnt; $n++) { + $herectx .= raw_line($linenr, $n) . "\n"; + } + + if ($dstat =~ /;/) { + ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", + "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); + } else { + ERROR("COMPLEX_MACRO", + "Macros with complex values should be enclosed in parenthesis\n" . "$herectx"); + } + } + +# check for line continuations outside of #defines, preprocessor #, and asm + + } else { + if ($prevline !~ /^..*\\$/ && + $line !~ /^\+\s*\#.*\\$/ && # preprocessor + $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm + $line =~ /^\+.*\\$/) { + WARN("LINE_CONTINUATIONS", + "Avoid unnecessary line continuations\n" . $herecurr); + } + } + +# do {} while (0) macro tests: +# single-statement macros do not need to be enclosed in do while (0) loop, +# macro should not end with a semicolon + if ($^V && $^V ge 5.10.0 && + $realfile !~ m@/vmlinux.lds.h$@ && + $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { + my $ln = $linenr; + my $cnt = $realcnt; + my ($off, $dstat, $dcond, $rest); + my $ctx = ''; + ($dstat, $dcond, $ln, $cnt, $off) = + ctx_statement_block($linenr, $realcnt, 0); + $ctx = $dstat; + + $dstat =~ s/\\\n.//g; + + if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { + my $stmts = $2; + my $semis = $3; + + $ctx =~ s/\n*$//; + my $cnt = statement_rawlines($ctx); + my $herectx = $here . "\n"; + + for (my $n = 0; $n < $cnt; $n++) { + $herectx .= raw_line($linenr, $n) . "\n"; + } + + if (($stmts =~ tr/;/;/) == 1 && + $stmts !~ /^\s*(if|while|for|switch)\b/) { + WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", + "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); + } + if (defined $semis && $semis ne "") { + WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", + "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); + } + } + } + +# make sure symbols are always wrapped with VMLINUX_SYMBOL() ... +# all assignments may have only one of the following with an assignment: +# . +# ALIGN(...) +# VMLINUX_SYMBOL(...) + if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) { + WARN("MISSING_VMLINUX_SYMBOL", + "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr); + } + +# check for redundant bracing round if etc + if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { + my ($level, $endln, @chunks) = + ctx_statement_full($linenr, $realcnt, 1); + #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; + #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; + if ($#chunks > 0 && $level == 0) { + my @allowed = (); + my $allow = 0; + my $seen = 0; + my $herectx = $here . "\n"; + my $ln = $linenr - 1; + for my $chunk (@chunks) { + my ($cond, $block) = @{$chunk}; + + # If the condition carries leading newlines, then count those as offsets. + my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); + my $offset = statement_rawlines($whitespace) - 1; + + $allowed[$allow] = 0; + #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; + + # We have looked at and allowed this specific line. + $suppress_ifbraces{$ln + $offset} = 1; + + $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; + $ln += statement_rawlines($block) - 1; + + substr($block, 0, length($cond), ''); + + $seen++ if ($block =~ /^\s*{/); + + #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; + if (statement_lines($cond) > 1) { + #print "APW: ALLOWED: cond<$cond>\n"; + $allowed[$allow] = 1; + } + if ($block =~/\b(?:if|for|while)\b/) { + #print "APW: ALLOWED: block<$block>\n"; + $allowed[$allow] = 1; + } + if (statement_block_size($block) > 1) { + #print "APW: ALLOWED: lines block<$block>\n"; + $allowed[$allow] = 1; + } + $allow++; + } + if ($seen) { + my $sum_allowed = 0; + foreach (@allowed) { + $sum_allowed += $_; + } + if ($sum_allowed == 0) { + WARN("BRACES", + "braces {} are not necessary for any arm of this statement\n" . $herectx); + } elsif ($sum_allowed != $allow && + $seen != $allow) { + CHK("BRACES", + "braces {} should be used on all arms of this statement\n" . $herectx); + } + } + } + } + if (!defined $suppress_ifbraces{$linenr - 1} && + $line =~ /\b(if|while|for|else)\b/) { + my $allowed = 0; + + # Check the pre-context. + if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { + #print "APW: ALLOWED: pre<$1>\n"; + $allowed = 1; + } + + my ($level, $endln, @chunks) = + ctx_statement_full($linenr, $realcnt, $-[0]); + + # Check the condition. + my ($cond, $block) = @{$chunks[0]}; + #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; + if (defined $cond) { + substr($block, 0, length($cond), ''); + } + if (statement_lines($cond) > 1) { + #print "APW: ALLOWED: cond<$cond>\n"; + $allowed = 1; + } + if ($block =~/\b(?:if|for|while)\b/) { + #print "APW: ALLOWED: block<$block>\n"; + $allowed = 1; + } + if (statement_block_size($block) > 1) { + #print "APW: ALLOWED: lines block<$block>\n"; + $allowed = 1; + } + # Check the post-context. + if (defined $chunks[1]) { + my ($cond, $block) = @{$chunks[1]}; + if (defined $cond) { + substr($block, 0, length($cond), ''); + } + if ($block =~ /^\s*\{/) { + #print "APW: ALLOWED: chunk-1 block<$block>\n"; + $allowed = 1; + } + } + if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { + my $herectx = $here . "\n"; + my $cnt = statement_rawlines($block); + + for (my $n = 0; $n < $cnt; $n++) { + $herectx .= raw_line($linenr, $n) . "\n"; + } + + WARN("BRACES", + "braces {} are not necessary for single statement blocks\n" . $herectx); + } + } + +# check for unnecessary blank lines around braces + if (($line =~ /^..*}\s*$/ && $prevline =~ /^.\s*$/)) { + CHK("BRACES", + "Blank lines aren't necessary before a close brace '}'\n" . $hereprev); + } + if (($line =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { + CHK("BRACES", + "Blank lines aren't necessary after an open brace '{'\n" . $hereprev); + } + +# no volatiles please + my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; + if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { + WARN("VOLATILE", + "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); + } + +# warn about #if 0 + if ($line =~ /^.\s*\#\s*if\s+0\b/) { + CHK("REDUNDANT_CODE", + "if this code is redundant consider removing it\n" . + $herecurr); + } + +# check for needless "if () fn()" uses + if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { + my $expr = '\s*\(\s*' . quotemeta($1) . '\s*\)\s*;'; + if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?)$expr/) { + WARN('NEEDLESS_IF', + "$1(NULL) is safe this check is probably not required\n" . $hereprev); + } + } + +# prefer usleep_range over udelay + if ($line =~ /\budelay\s*\(\s*(\w+)\s*\)/) { + # ignore udelay's < 10, however + if (! (($1 =~ /(\d+)/) && ($1 < 10)) ) { + CHK("USLEEP_RANGE", + "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $line); + } + } + +# warn about unexpectedly long msleep's + if ($line =~ /\bmsleep\s*\((\d+)\);/) { + if ($1 < 20) { + WARN("MSLEEP", + "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $line); + } + } + +# warn about #ifdefs in C files +# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { +# print "#ifdef in C files should be avoided\n"; +# print "$herecurr"; +# $clean = 0; +# } + +# warn about spacing in #ifdefs + if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { + ERROR("SPACING", + "exactly one space required after that #$1\n" . $herecurr); + } + +# check for spinlock_t definitions without a comment. + if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || + $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { + my $which = $1; + if (!ctx_has_comment($first_line, $linenr)) { + CHK("UNCOMMENTED_DEFINITION", + "$1 definition without comment\n" . $herecurr); + } + } +# check for memory barriers without a comment. + if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) { + if (!ctx_has_comment($first_line, $linenr)) { + CHK("MEMORY_BARRIER", + "memory barrier without comment\n" . $herecurr); + } + } +# check of hardware specific defines + if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m at include/asm-@) { + CHK("ARCH_DEFINES", + "architecture specific defines should be avoided\n" . $herecurr); + } + +# Check that the storage class is at the beginning of a declaration + if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) { + WARN("STORAGE_CLASS", + "storage class should be at the beginning of the declaration\n" . $herecurr) + } + +# check the location of the inline attribute, that it is between +# storage class and type. + if ($line =~ /\b$Type\s+$Inline\b/ || + $line =~ /\b$Inline\s+$Storage\b/) { + ERROR("INLINE_LOCATION", + "inline keyword should sit between storage class and type\n" . $herecurr); + } + +# Check for __inline__ and __inline, prefer inline + if ($line =~ /\b(__inline__|__inline)\b/) { + WARN("INLINE", + "plain inline is preferred over $1\n" . $herecurr); + } + +# Check for __attribute__ packed, prefer __packed + if ($line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { + WARN("PREFER_PACKED", + "__packed is preferred over __attribute__((packed))\n" . $herecurr); + } + +# Check for __attribute__ aligned, prefer __aligned + if ($line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { + WARN("PREFER_ALIGNED", + "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); + } + +# Check for __attribute__ format(printf, prefer __printf + if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { + WARN("PREFER_PRINTF", + "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr); + } + +# Check for __attribute__ format(scanf, prefer __scanf + if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { + WARN("PREFER_SCANF", + "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr); + } + +# check for sizeof(&) + if ($line =~ /\bsizeof\s*\(\s*\&/) { + WARN("SIZEOF_ADDRESS", + "sizeof(& should be avoided\n" . $herecurr); + } + +# check for sizeof without parenthesis + if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { + WARN("SIZEOF_PARENTHESIS", + "sizeof $1 should be sizeof($1)\n" . $herecurr); + } + +# check for line continuations in quoted strings with odd counts of " + if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) { + WARN("LINE_CONTINUATIONS", + "Avoid line continuations in quoted strings\n" . $herecurr); + } + +# check for struct spinlock declarations + if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { + WARN("USE_SPINLOCK_T", + "struct spinlock should be spinlock_t\n" . $herecurr); + } + +# Check for misused memsets + if ($^V && $^V ge 5.10.0 && + defined $stat && + $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) { + + my $ms_addr = $2; + my $ms_val = $7; + my $ms_size = $12; + + if ($ms_size =~ /^(0x|)0$/i) { + ERROR("MEMSET", + "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); + } elsif ($ms_size =~ /^(0x|)1$/i) { + WARN("MEMSET", + "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); + } + } + +# typecasts on min/max could be min_t/max_t + if ($^V && $^V ge 5.10.0 && + defined $stat && + $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { + if (defined $2 || defined $7) { + my $call = $1; + my $cast1 = deparenthesize($2); + my $arg1 = $3; + my $cast2 = deparenthesize($7); + my $arg2 = $8; + my $cast; + + if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { + $cast = "$cast1 or $cast2"; + } elsif ($cast1 ne "") { + $cast = $cast1; + } else { + $cast = $cast2; + } + WARN("MINMAX", + "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); + } + } + +# check usleep_range arguments + if ($^V && $^V ge 5.10.0 && + defined $stat && + $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { + my $min = $1; + my $max = $7; + if ($min eq $max) { + WARN("USLEEP_RANGE", + "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); + } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && + $min > $max) { + WARN("USLEEP_RANGE", + "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); + } + } + +# check for new externs in .c files. + if ($realfile =~ /\.c$/ && defined $stat && + $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) + { + my $function_name = $1; + my $paren_space = $2; + + my $s = $stat; + if (defined $cond) { + substr($s, 0, length($cond), ''); + } + if ($s =~ /^\s*;/ && + $function_name ne 'uninitialized_var') + { + WARN("AVOID_EXTERNS", + "externs should be avoided in .c files\n" . $herecurr); + } + + if ($paren_space =~ /\n/) { + WARN("FUNCTION_ARGUMENTS", + "arguments for function declarations should follow identifier\n" . $herecurr); + } + + } elsif ($realfile =~ /\.c$/ && defined $stat && + $stat =~ /^.\s*extern\s+/) + { + WARN("AVOID_EXTERNS", + "externs should be avoided in .c files\n" . $herecurr); + } + +# checks for new __setup's + if ($rawline =~ /\b__setup\("([^"]*)"/) { + my $name = $1; + + if (!grep(/$name/, @setup_docs)) { + CHK("UNDOCUMENTED_SETUP", + "__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr); + } + } + +# check for pointless casting of kmalloc return + if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) { + WARN("UNNECESSARY_CASTS", + "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); + } + +# check for multiple semicolons + if ($line =~ /;\s*;\s*$/) { + WARN("ONE_SEMICOLON", + "Statements terminations use 1 semicolon\n" . $herecurr); + } + +# check for switch/default statements without a break; + if ($^V && $^V ge 5.10.0 && + defined $stat && + $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { + my $ctx = ''; + my $herectx = $here . "\n"; + my $cnt = statement_rawlines($stat); + for (my $n = 0; $n < $cnt; $n++) { + $herectx .= raw_line($linenr, $n) . "\n"; + } + WARN("DEFAULT_NO_BREAK", + "switch default: should use break\n" . $herectx); + } + +# check for gcc specific __FUNCTION__ + if ($line =~ /__FUNCTION__/) { + WARN("USE_FUNC", + "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr); + } + +# check for use of yield() + if ($line =~ /\byield\s*\(\s*\)/) { + WARN("YIELD", + "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); + } + +# check for semaphores initialized locked + if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { + WARN("CONSIDER_COMPLETION", + "consider using a completion\n" . $herecurr); + } + +# recommend kstrto* over simple_strto* and strict_strto* + if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { + WARN("CONSIDER_KSTRTO", + "$1 is obsolete, use k$3 instead\n" . $herecurr); + } + +# check for __initcall(), use device_initcall() explicitly please + if ($line =~ /^.\s*__initcall\s*\(/) { + WARN("USE_DEVICE_INITCALL", + "please use device_initcall() instead of __initcall()\n" . $herecurr); + } + +# check for various ops structs, ensure they are const. + my $struct_ops = qr{acpi_dock_ops| + address_space_operations| + backlight_ops| + block_device_operations| + dentry_operations| + dev_pm_ops| + dma_map_ops| + extent_io_ops| + file_lock_operations| + file_operations| + hv_ops| + ide_dma_ops| + intel_dvo_dev_ops| + item_operations| + iwl_ops| + kgdb_arch| + kgdb_io| + kset_uevent_ops| + lock_manager_operations| + microcode_ops| + mtrr_ops| + neigh_ops| + nlmsvc_binding| + pci_raw_ops| + pipe_buf_operations| + platform_hibernation_ops| + platform_suspend_ops| + proto_ops| + rpc_pipe_ops| + seq_operations| + snd_ac97_build_ops| + soc_pcmcia_socket_ops| + stacktrace_ops| + sysfs_ops| + tty_operations| + usb_mon_operations| + wd_ops}x; + if ($line !~ /\bconst\b/ && + $line =~ /\bstruct\s+($struct_ops)\b/) { + WARN("CONST_STRUCT", + "struct $1 should normally be const\n" . + $herecurr); + } + +# use of NR_CPUS is usually wrong +# ignore definitions of NR_CPUS and usage to define arrays as likely right + if ($line =~ /\bNR_CPUS\b/ && + $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && + $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && + $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && + $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && + $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) + { + WARN("NR_CPUS", + "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); + } + +# check for %L{u,d,i} in strings + my $string; + while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { + $string = substr($rawline, $-[1], $+[1] - $-[1]); + $string =~ s/%%/__/g; + if ($string =~ /(?mutex.\n" . $herecurr); + } + } + + if ($line =~ /debugfs_create_file.*S_IWUGO/ || + $line =~ /DEVICE_ATTR.*S_IWUGO/ ) { + WARN("EXPORTED_WORLD_WRITABLE", + "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); + } + } + + # If we have no input at all, then there is nothing to report on + # so just keep quiet. + if ($#rawlines == -1) { + exit(0); + } + + # In mailback mode only produce a report in the negative, for + # things that appear to be patches. + if ($mailback && ($clean == 1 || !$is_patch)) { + exit(0); + } + + # This is not a patch, and we are are in 'no-patch' mode so + # just keep quiet. + if (!$chk_patch && !$is_patch) { + exit(0); + } + + if (!$is_patch) { + ERROR("NOT_UNIFIED_DIFF", + "Does not appear to be a unified-diff format patch\n"); + } + if ($is_patch && $chk_signoff && $signoff == 0) { + ERROR("MISSING_SIGN_OFF", + "Missing Signed-off-by: line(s)\n"); + } + + print report_dump(); + if ($summary && !($clean == 1 && $quiet == 1)) { + print "$filename " if ($summary_file); + print "total: $cnt_error errors, $cnt_warn warnings, " . + (($check)? "$cnt_chk checks, " : "") . + "$cnt_lines lines checked\n"; + print "\n" if ($quiet == 0); + } + + if ($quiet == 0) { + + if ($^V lt 5.10.0) { + print("NOTE: perl $^V is not modern enough to detect all possible issues.\n"); + print("An upgrade to at least perl v5.10.0 is suggested.\n\n"); + } + + # If there were whitespace errors which cleanpatch can fix + # then suggest that. + if ($rpt_cleaners) { + print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n"; + print " scripts/cleanfile\n\n"; + $rpt_cleaners = 0; + } + } + + if ($quiet == 0 && keys %ignore_type) { + print "NOTE: Ignored message types:"; + foreach my $ignore (sort keys %ignore_type) { + print " $ignore"; + } + print "\n\n"; + } + + if ($clean == 1 && $quiet == 0) { + print "$vname has no obvious style problems and is ready for submission.\n" + } + if ($clean == 0 && $quiet == 0) { + print << "EOM"; +$vname has style problems, please review. + +If any of these errors are false positives, please report +them to the maintainer, see CHECKPATCH in MAINTAINERS. +EOM + } + + return $clean; +} -- 1.8.0.2 From christian.babeux at efficios.com Mon Jan 7 17:12:41 2013 From: christian.babeux at efficios.com (Christian Babeux) Date: Mon, 7 Jan 2013 17:12:41 -0500 Subject: [lttng-dev] [PATCH lttng-tools 2/3] Extras: Change TYPE of braces around single statement warning in checkpatch In-Reply-To: <1357596762-14132-1-git-send-email-christian.babeux@efficios.com> References: <1357596762-14132-1-git-send-email-christian.babeux@efficios.com> Message-ID: <1357596762-14132-2-git-send-email-christian.babeux@efficios.com> Change the TYPE of the "braces {} are not necessary for single statement blocks" warning from BRACES to BRACES_SINGLE_STMT in order to correctly ignore this particular warning and continue to warn for other BRACES warnings. Signed-off-by: Christian Babeux --- extras/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/checkpatch.pl b/extras/checkpatch.pl index 4d2c7df..7b2d29b 100755 --- a/extras/checkpatch.pl +++ b/extras/checkpatch.pl @@ -3198,7 +3198,7 @@ sub process { $herectx .= raw_line($linenr, $n) . "\n"; } - WARN("BRACES", + WARN("BRACES_SINGLE_STMT", "braces {} are not necessary for single statement blocks\n" . $herectx); } } -- 1.8.0.2 From christian.babeux at efficios.com Mon Jan 7 17:12:42 2013 From: christian.babeux at efficios.com (Christian Babeux) Date: Mon, 7 Jan 2013 17:12:42 -0500 Subject: [lttng-dev] [PATCH lttng-tools 3/3] Extras: Add a checkpatch git pre-commit hook to detect style issue In-Reply-To: <1357596762-14132-1-git-send-email-christian.babeux@efficios.com> References: <1357596762-14132-1-git-send-email-christian.babeux@efficios.com> Message-ID: <1357596762-14132-3-git-send-email-christian.babeux@efficios.com> This commit add the checkpatch-hook script that can be installed in git hooks folder in order to detect style issue before commiting any staged changes. The .checkpatch.conf file contains the appropriate options conforming to the coding style used in the lttng-tools tree. Also included in this commit is an install script to automatically install the hook in the git local repo. To override the pre-commit hook check, one can use the `git commit --no-verify` command. Signed-off-by: Christian Babeux --- .gitignore | 2 ++ extras/.checkpatch.conf | 7 +++++++ extras/checkpatch-hook | 30 ++++++++++++++++++++++++++++++ extras/install-checkpatch-hook | 42 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+) create mode 100644 extras/.checkpatch.conf create mode 100755 extras/checkpatch-hook create mode 100755 extras/install-checkpatch-hook diff --git a/.gitignore b/.gitignore index 383dbf9..e61fd07 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,8 @@ extras/bindings/swig/python/lttng.i extras/bindings/swig/python/lttng.py extras/bindings/swig/python/lttng_wrap.c +.checkpatch.conf + # Tests test_sessions test_kernel_data_trace diff --git a/extras/.checkpatch.conf b/extras/.checkpatch.conf new file mode 100644 index 0000000..936f435 --- /dev/null +++ b/extras/.checkpatch.conf @@ -0,0 +1,7 @@ +# Not a kernel tree +--no-tree + +# Ignore braces {} are not necessary for single statement blocks warning. +# We enforce usage of {} even on single statement blocks. +# See CodingStyles for more information. +--ignore BRACES_SINGLE_STMT diff --git a/extras/checkpatch-hook b/extras/checkpatch-hook new file mode 100755 index 0000000..686815b --- /dev/null +++ b/extras/checkpatch-hook @@ -0,0 +1,30 @@ +#!/bin/sh +# +# Copyright (C) - 2013 Christian Babeux +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License, version 2 only, as +# published by the Free Software Foundation. +# +# 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., 51 +# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# To enable this hook, run the "install-checkpatch-hook" script. + +CHECKPATCH="extras/checkpatch.pl" + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 +fi + +git diff --cached $against -- | $CHECKPATCH --no-signoff - diff --git a/extras/install-checkpatch-hook b/extras/install-checkpatch-hook new file mode 100755 index 0000000..9f0e985 --- /dev/null +++ b/extras/install-checkpatch-hook @@ -0,0 +1,42 @@ +#!/bin/sh +# +# Copyright (C) - 2013 Christian Babeux +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License, version 2 only, as +# published by the Free Software Foundation. +# +# 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., 51 +# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Install the checkpatch pre-commit hook. + +DIR="$( cd "$( dirname "$0" )" && pwd )" + +PRECOMMIT_HOOK="../.git/hooks/pre-commit" +PRECOMMIT_SCRIPT="checkpatch-hook" +CHECKPATCH_CONF=".checkpatch.conf" + +if [ -f $PRECOMMIT_HOOK ]; +then + echo "File $PRECOMMIT_HOOK already exists. Aborting." + exit 1 +else + ln -s $DIR/$PRECOMMIT_SCRIPT $PRECOMMIT_HOOK +fi + +if [ -f ../$CHECKPATCH_CONF ]; +then + echo "File ../$CHECKPATCH_CONF already exists. Aborting." + exit 1 +else + ln -s $DIR/$CHECKPATCH_CONF ../$CHECKPATCH_CONF +fi + +echo "Checkpatch pre-commit hook successfully installed!" -- 1.8.0.2 From mathieu.desnoyers at efficios.com Tue Jan 8 11:36:03 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 8 Jan 2013 11:36:03 -0500 Subject: [lttng-dev] System Hang In-Reply-To: <20130107191602.GA1342@Krystal> References: <20130107191602.GA1342@Krystal> Message-ID: <20130108163603.GA19358@Krystal> * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > * Phil Wilshire (sysdcs at gmail.com) wrote: > > Hi, > > Just getting back into lttng after quite a few years > > I need to set up a continuous trace on a system. > > > > Every 10 seconds I stop one session and start another to give me individual > > files for each 10 second segment. > > I originally intended to start the next session before stopping the > > previous but that was causing the sessond to hang. > > > > Ever so often I can start the trace and the trace file is generated but > > ongoing commands to lttng are ignored. The new trace file then grows until > > all the disk space is used. sessiond seems to be hung > > > > > > I have the kernel dmseg log attached and I also have the trace file if > > needed > > > > > > [ 345.223564] LTT state dump thread start > > [ 345.231033] LTT state dump end > > [ 353.586011] ring buffer relay-metadata: 3604 records written, 0 records > > overrun > > [ 353.590023] ring buffer relay-discard, cpu 0: 408474 records written, 0 > > records overrun > > [ 353.590237] ring buffer relay-discard, cpu 1: 390793 records written, 0 > > records overrun > > [ 353.590237] ring buffer relay-discard, cpu 2: 363560 records written, 0 > > records overrun > > [ 353.590685] ring buffer relay-discard, cpu 3: 518867 records written, 0 > > records overrun > > [ 355.720753] LTTng: state dump begin > > [ 355.720753] LTT state dump thread start > > [ 355.732034] LTT state dump end > > [ 364.111388] ring buffer relay-metadata: 3604 records written, 0 records > > overrun > > [ 364.120334] ring buffer relay-discard, cpu 0: 409693 records written, 0 > > records overrun > > [ 364.120334] ring buffer relay-discard, cpu 1: 401971 records written, 0 > > records overrun > > [ 364.121438] ring buffer relay-discard, cpu 2: 380074 records written, 0 > > records overrun > > [ 364.122187] ring buffer relay-discard, cpu 3: 524538 records written, 0 > > records overrun > > [ 366.259690] LTTng: state dump begin > > [ 366.259690] LTT state dump thread start > > [ 366.266253] LTT state dump end > > [ 374.633764] ring buffer relay-metadata: 3604 records written, 0 records > > overrun > > [ 374.640024] ring buffer relay-discard, cpu 0: 430919 records written, 0 > > records overrun > > [ 374.640024] ring buffer relay-discard, cpu 1: 387021 records written, 0 > > records overrun > > [ 374.641033] ring buffer relay-discard, cpu 2: 370007 records written, 0 > > records overrun > > [ 374.641033] ring buffer relay-discard, cpu 3: 528606 records written, 0 > > records overrun > > [ 376.795384] LTTng: state dump begin > > [ 376.795384] LTT state dump thread start > > [ 601.060274] INFO: task lttng-sessiond:2885 blocked for more than 120 > > seconds. > > [ 601.069038] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables > > this message. > > [ 601.077626] lttng-sessiond D ffff880074456b18 0 2885 1 > > 0x10000000 > > [ 601.085210] ffff88006c0679f8 0000000000000082 0000000000000001 > > ffff88007b0a4140 > > [ 601.094031] ffff88006c0679a8 ffff880074456840 ffff88006c067fd8 > > ffff88006c067fd8 > > [ 601.105026] 0000000000011c80 ffff880074456840 0000000000000000 > > ffff88006c067a68 > > [ 601.112170] Call Trace: > > [ 601.116027] [] schedule+0x5b/0x5d > > Hrm, the kernel seems to be stuck in the statedump. We added new stuff > there in LTTng-modules 2.1, so there is probably something fishy. > > This backtrace only tells us that the statedump is waiting for > do_lttng_statedump to complete. > > I would really like to see the backtrace of all tasks in your system at > that point (SysRQ t). For more info, see Documentation/sysrq.txt from > your Linux kernel sources. Also the dump of sysrq-l (all active cpus) > would be useful. Also sysrq-d (all locks held) might help. I've been able to reproduce the issue on my setup. More to come soon. Thanks, Mathieu > > More below, > > > [ 601.121025] [] lttng_statedump_start+0x5aa/0x623 > > [lttng_statedump] > > [ 601.129035] [] ? abort_exclusive_wait+0x8f/0x8f > > [ 601.136030] [] lttng_session_enable+0x52d/0x55b > > [lttng_tracer] > > [ 601.144034] [] ? abort_exclusive_wait+0x8f/0x8f > > [ 601.150039] [] lttng_session_ioctl+0x15f/0x225 > > [lttng_tracer] > > [ 601.158042] [] ? sock_recvmsg+0xa4/0xb9 > > [ 601.163185] [] ? lookup_page_cgroup+0x36/0x4d > > [ 601.169453] [] ? cpumask_any_but+0x29/0x38 > > [ 601.175508] [] ? trace_preempt_on+0x12/0x2f > > [ 601.182031] [] ? sub_preempt_count+0x97/0xc0 > > [ 601.187735] [] ? _raw_spin_unlock+0x2a/0x35 > > [ 601.193922] [] ? spin_unlock+0xe/0x10 > > [ 601.200027] [] ? do_wp_page+0x26f/0x563 > > [ 601.206028] [] ? trace_preempt_off+0x12/0x30 > > [ 601.212031] [] ? add_preempt_count+0xb4/0xcf > > [ 601.218043] [] ? handle_pte_fault+0x6c6/0x76c > > [ 601.223737] [] ? verify_iovec+0x52/0xa3 > > [ 601.229426] [] ? handle_mm_fault+0x199/0x1a9 > > [ 601.236033] [] ? do_page_fault+0x2f6/0x377 > > [ 601.242034] [] ? > > __event_probe__sys_mprotect+0xf5/0xf5 [lttng_tracer] > > [ 601.251031] [] vfs_ioctl+0x22/0x3a > > [ 601.256029] [] do_vfs_ioctl+0x3c4/0x407 > > [ 601.261188] [] ? fget_light+0x91/0x9d > > [ 601.267026] [] sys_ioctl+0x47/0x6a > > [ 601.272050] [] tracesys+0xd9/0xde > > > > > > cat /proc/cpuinfo > > > > processor : 0 > > vendor_id : GenuineIntel > > cpu family : 6 > > model : 28 > > model name : Intel(R) Atom(TM) CPU D525 @ 1.80GHz > > stepping : 10 > > microcode : 0x107 > > cpu MHz : 1799.823 > > cache size : 512 KB > > physical id : 0 > > siblings : 4 > > core id : 0 > > cpu cores : 2 > > apicid : 0 > > initial apicid : 0 > > fpu : yes > > fpu_exception : yes > > cpuid level : 10 > > wp : yes > > flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat > > pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm > > constant_tsc arch_perfmon pebs bts rep_good nopl aperfmperf pni dtes64 > > monitor ds_cpl tm2 ssse3 cx16 xtpr pdcm movbe lahf_lm dts > > bogomips : 1775.61 > > clflush size : 64 > > cache_alignment : 64 > > address sizes : 36 bits physical, 48 bits virtual > > power management: > > > > (repeated for 3 other cpus ) > > > > uname -a > > Linux 3.2.21-x510v1 #1 SMP PREEMPT Thu Dec 20 11:24:36 EST 2012 x86_64 > > GNU/Linux > > > > Script used to run trace > > ================================================= > > #!/bin/sh > > > > xx=`/bin/date +"%s"` > > yy="yy" > > zz="zz" > > log_xx=/home/pswuser/trace/log/psw-${xx}.log > > log_yy=/home/pswuser/trace/log/psw-${yy}.log > > log_zz=/home/pswuser/trace/log/psw-${zz}.log > > #depmod > > mkdir -p /home/pswuser/trace > > mount -t tmpfs -o size=500M tmpfs /home/pswuser/trace > > mkdir -p /home/pswuser/trace/log > > touch /home/pswuser/trace/run_trace > > sleep 20 > > if [ -f /home/pswuser/trace/run_trace ] ; then > > > > echo "lttng create" > ${log_xx} > > lttng create psw-${xx} \ > > -o /home/pswuser/trace/psw-${xx} >> ${log_xx} 2>&1 > > echo "lttng enable-event" >> ${log_xx} > > sleep 1 > > lttng enable-event -a -k -s psw-${xx} >> ${log_xx} 2>&1 > > sleep 1 > > echo "lttng start" >> ${log_xx} > > lttng start psw-${xx} >> ${log_xx} 2>&1 > > sleep 1 > > > > fi > > > > while [ 1 -gt 0 ] ; do > > sleep 7 > > yy=`/bin/date +"%s"` > > log_yy=/home/pswuser/trace/log/psw-${yy}.log > > > > > > #stop xx > > if [ -d /home/pswuser/trace/psw-${xx} ] ; then > > echo "lttng stop" >> ${log_xx} > > lttng stop psw-${xx} >> ${log_xx} 2>&1 > > sleep 1 > > echo "lttng destroy" >> ${log_xx} > > lttng destroy psw-${xx} >> ${log_xx} 2>&1 > > echo "lttng done" >> ${log_xx} > > fi > > > > # start yy after stopping xx > > if [ -f /home/pswuser/trace/run_trace ] ; then > > echo "lttng create ${yy} after closing ${xx}" > ${log_yy} > > lttng create psw-${yy} \ > > -o /home/pswuser/trace/psw-${yy} >> ${log_yy} 2>&1 > > sleep 1 > > echo "lttng enable_event" >> ${log_yy} > > lttng enable-event -a -k -s psw-${yy} >> ${log_yy} 2>&1 > > sleep 1 > > echo "lttng start" >> ${log_yy} > > lttng start psw-${yy} >> ${log_yy} 2>&1 > > fi > > # check zz > > # delete unless detected or detected2 is present > > if [ ! -f /home/pswuser/bin/delay-detected ] && > > [ ! -f /home/pswuser/bin/delay-detected2 ] ; then > > echo "lttng delete files" >> ${log_zz} > > rm -rf /home/pswuser/trace/psw-${zz}* >> ${log_zz} 2>&1 > > #if [ $? -eq 0 ] ; then rm ${log_zz} ; fi > > fi > > # delete second snapshot > > if [ -f /home/pswuser/bin/delay-detected2 ] ; then > > rm -f /home/pswuser/bin/delay-detected2 > > > > # no more tracing once event detected > > rm -f /home/pswuser/trace/run_trace > > fi > > # trigger second snapshot delete first snapshot > > if [ -f /home/pswuser/bin/delay-detected ] ; then > > rm -f /home/pswuser/bin/delay-detected > > touch /home/pswuser/bin/delay-detected2 > > fi > > > > # ls -l /lttng-traces/psw-* > > # zz (delete candidate) is old xx > > echo "xx ${xx} yy ${yy} zz ${zz}" > > zz=${xx} > > log_zz=$log_xx > > > > # xx is now the new one > > xx=${yy} > > log_xx=$log_yy > > > > # check disk use > > if [ -d /home/pswuser/trace ] ; then > > du -h /home/pswuser/trace > > fi > > > > > > done > > ---------------------------------------- > > > > Any clues are welcome. > > > > Another question. > > > > Would it be possible to do this by setting up a ring buffer that will wrap > > around after a certain time. I can easily timestamp the event I am looking > > for and then capture the buffer containing the event. > > Stay tuned for 2013 lttng releases. This will likely be implemented this > year (flight recorder and snapshots). > > Thanks, > > Mathieu > > > > > > > Regards > > Phil Wilshire > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Tue Jan 8 14:31:32 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 8 Jan 2013 14:31:32 -0500 Subject: [lttng-dev] System Hang In-Reply-To: <20130108163603.GA19358@Krystal> References: <20130107191602.GA1342@Krystal> <20130108163603.GA19358@Krystal> Message-ID: <20130108193132.GA21318@Krystal> Hi Phil, I pushed a fix into master, stable-2.1, and stable-2.0 branches of lttng-modules that fixes the issue you reported. Please confirm if it fixes things for you. The fix: commit 8240b2e21a7ce1653d5e45b01c4709c86c3fb636 Author: Mathieu Desnoyers Date: Tue Jan 8 14:27:05 2013 -0500 Fix: statedump hang due to incorrect wait/wakeup use Reported-by: Phil Wilshire Signed-off-by: Mathieu Desnoyers Thanks, Mathieu * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > > * Phil Wilshire (sysdcs at gmail.com) wrote: > > > Hi, > > > Just getting back into lttng after quite a few years > > > I need to set up a continuous trace on a system. > > > > > > Every 10 seconds I stop one session and start another to give me individual > > > files for each 10 second segment. > > > I originally intended to start the next session before stopping the > > > previous but that was causing the sessond to hang. > > > > > > Ever so often I can start the trace and the trace file is generated but > > > ongoing commands to lttng are ignored. The new trace file then grows until > > > all the disk space is used. sessiond seems to be hung > > > > > > > > > I have the kernel dmseg log attached and I also have the trace file if > > > needed > > > > > > > > > [ 345.223564] LTT state dump thread start > > > [ 345.231033] LTT state dump end > > > [ 353.586011] ring buffer relay-metadata: 3604 records written, 0 records > > > overrun > > > [ 353.590023] ring buffer relay-discard, cpu 0: 408474 records written, 0 > > > records overrun > > > [ 353.590237] ring buffer relay-discard, cpu 1: 390793 records written, 0 > > > records overrun > > > [ 353.590237] ring buffer relay-discard, cpu 2: 363560 records written, 0 > > > records overrun > > > [ 353.590685] ring buffer relay-discard, cpu 3: 518867 records written, 0 > > > records overrun > > > [ 355.720753] LTTng: state dump begin > > > [ 355.720753] LTT state dump thread start > > > [ 355.732034] LTT state dump end > > > [ 364.111388] ring buffer relay-metadata: 3604 records written, 0 records > > > overrun > > > [ 364.120334] ring buffer relay-discard, cpu 0: 409693 records written, 0 > > > records overrun > > > [ 364.120334] ring buffer relay-discard, cpu 1: 401971 records written, 0 > > > records overrun > > > [ 364.121438] ring buffer relay-discard, cpu 2: 380074 records written, 0 > > > records overrun > > > [ 364.122187] ring buffer relay-discard, cpu 3: 524538 records written, 0 > > > records overrun > > > [ 366.259690] LTTng: state dump begin > > > [ 366.259690] LTT state dump thread start > > > [ 366.266253] LTT state dump end > > > [ 374.633764] ring buffer relay-metadata: 3604 records written, 0 records > > > overrun > > > [ 374.640024] ring buffer relay-discard, cpu 0: 430919 records written, 0 > > > records overrun > > > [ 374.640024] ring buffer relay-discard, cpu 1: 387021 records written, 0 > > > records overrun > > > [ 374.641033] ring buffer relay-discard, cpu 2: 370007 records written, 0 > > > records overrun > > > [ 374.641033] ring buffer relay-discard, cpu 3: 528606 records written, 0 > > > records overrun > > > [ 376.795384] LTTng: state dump begin > > > [ 376.795384] LTT state dump thread start > > > [ 601.060274] INFO: task lttng-sessiond:2885 blocked for more than 120 > > > seconds. > > > [ 601.069038] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables > > > this message. > > > [ 601.077626] lttng-sessiond D ffff880074456b18 0 2885 1 > > > 0x10000000 > > > [ 601.085210] ffff88006c0679f8 0000000000000082 0000000000000001 > > > ffff88007b0a4140 > > > [ 601.094031] ffff88006c0679a8 ffff880074456840 ffff88006c067fd8 > > > ffff88006c067fd8 > > > [ 601.105026] 0000000000011c80 ffff880074456840 0000000000000000 > > > ffff88006c067a68 > > > [ 601.112170] Call Trace: > > > [ 601.116027] [] schedule+0x5b/0x5d > > > > Hrm, the kernel seems to be stuck in the statedump. We added new stuff > > there in LTTng-modules 2.1, so there is probably something fishy. > > > > This backtrace only tells us that the statedump is waiting for > > do_lttng_statedump to complete. > > > > I would really like to see the backtrace of all tasks in your system at > > that point (SysRQ t). For more info, see Documentation/sysrq.txt from > > your Linux kernel sources. Also the dump of sysrq-l (all active cpus) > > would be useful. Also sysrq-d (all locks held) might help. > > > I've been able to reproduce the issue on my setup. More to come soon. > > Thanks, > > Mathieu > > > > > More below, > > > > > [ 601.121025] [] lttng_statedump_start+0x5aa/0x623 > > > [lttng_statedump] > > > [ 601.129035] [] ? abort_exclusive_wait+0x8f/0x8f > > > [ 601.136030] [] lttng_session_enable+0x52d/0x55b > > > [lttng_tracer] > > > [ 601.144034] [] ? abort_exclusive_wait+0x8f/0x8f > > > [ 601.150039] [] lttng_session_ioctl+0x15f/0x225 > > > [lttng_tracer] > > > [ 601.158042] [] ? sock_recvmsg+0xa4/0xb9 > > > [ 601.163185] [] ? lookup_page_cgroup+0x36/0x4d > > > [ 601.169453] [] ? cpumask_any_but+0x29/0x38 > > > [ 601.175508] [] ? trace_preempt_on+0x12/0x2f > > > [ 601.182031] [] ? sub_preempt_count+0x97/0xc0 > > > [ 601.187735] [] ? _raw_spin_unlock+0x2a/0x35 > > > [ 601.193922] [] ? spin_unlock+0xe/0x10 > > > [ 601.200027] [] ? do_wp_page+0x26f/0x563 > > > [ 601.206028] [] ? trace_preempt_off+0x12/0x30 > > > [ 601.212031] [] ? add_preempt_count+0xb4/0xcf > > > [ 601.218043] [] ? handle_pte_fault+0x6c6/0x76c > > > [ 601.223737] [] ? verify_iovec+0x52/0xa3 > > > [ 601.229426] [] ? handle_mm_fault+0x199/0x1a9 > > > [ 601.236033] [] ? do_page_fault+0x2f6/0x377 > > > [ 601.242034] [] ? > > > __event_probe__sys_mprotect+0xf5/0xf5 [lttng_tracer] > > > [ 601.251031] [] vfs_ioctl+0x22/0x3a > > > [ 601.256029] [] do_vfs_ioctl+0x3c4/0x407 > > > [ 601.261188] [] ? fget_light+0x91/0x9d > > > [ 601.267026] [] sys_ioctl+0x47/0x6a > > > [ 601.272050] [] tracesys+0xd9/0xde > > > > > > > > > cat /proc/cpuinfo > > > > > > processor : 0 > > > vendor_id : GenuineIntel > > > cpu family : 6 > > > model : 28 > > > model name : Intel(R) Atom(TM) CPU D525 @ 1.80GHz > > > stepping : 10 > > > microcode : 0x107 > > > cpu MHz : 1799.823 > > > cache size : 512 KB > > > physical id : 0 > > > siblings : 4 > > > core id : 0 > > > cpu cores : 2 > > > apicid : 0 > > > initial apicid : 0 > > > fpu : yes > > > fpu_exception : yes > > > cpuid level : 10 > > > wp : yes > > > flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat > > > pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm > > > constant_tsc arch_perfmon pebs bts rep_good nopl aperfmperf pni dtes64 > > > monitor ds_cpl tm2 ssse3 cx16 xtpr pdcm movbe lahf_lm dts > > > bogomips : 1775.61 > > > clflush size : 64 > > > cache_alignment : 64 > > > address sizes : 36 bits physical, 48 bits virtual > > > power management: > > > > > > (repeated for 3 other cpus ) > > > > > > uname -a > > > Linux 3.2.21-x510v1 #1 SMP PREEMPT Thu Dec 20 11:24:36 EST 2012 x86_64 > > > GNU/Linux > > > > > > Script used to run trace > > > ================================================= > > > #!/bin/sh > > > > > > xx=`/bin/date +"%s"` > > > yy="yy" > > > zz="zz" > > > log_xx=/home/pswuser/trace/log/psw-${xx}.log > > > log_yy=/home/pswuser/trace/log/psw-${yy}.log > > > log_zz=/home/pswuser/trace/log/psw-${zz}.log > > > #depmod > > > mkdir -p /home/pswuser/trace > > > mount -t tmpfs -o size=500M tmpfs /home/pswuser/trace > > > mkdir -p /home/pswuser/trace/log > > > touch /home/pswuser/trace/run_trace > > > sleep 20 > > > if [ -f /home/pswuser/trace/run_trace ] ; then > > > > > > echo "lttng create" > ${log_xx} > > > lttng create psw-${xx} \ > > > -o /home/pswuser/trace/psw-${xx} >> ${log_xx} 2>&1 > > > echo "lttng enable-event" >> ${log_xx} > > > sleep 1 > > > lttng enable-event -a -k -s psw-${xx} >> ${log_xx} 2>&1 > > > sleep 1 > > > echo "lttng start" >> ${log_xx} > > > lttng start psw-${xx} >> ${log_xx} 2>&1 > > > sleep 1 > > > > > > fi > > > > > > while [ 1 -gt 0 ] ; do > > > sleep 7 > > > yy=`/bin/date +"%s"` > > > log_yy=/home/pswuser/trace/log/psw-${yy}.log > > > > > > > > > #stop xx > > > if [ -d /home/pswuser/trace/psw-${xx} ] ; then > > > echo "lttng stop" >> ${log_xx} > > > lttng stop psw-${xx} >> ${log_xx} 2>&1 > > > sleep 1 > > > echo "lttng destroy" >> ${log_xx} > > > lttng destroy psw-${xx} >> ${log_xx} 2>&1 > > > echo "lttng done" >> ${log_xx} > > > fi > > > > > > # start yy after stopping xx > > > if [ -f /home/pswuser/trace/run_trace ] ; then > > > echo "lttng create ${yy} after closing ${xx}" > ${log_yy} > > > lttng create psw-${yy} \ > > > -o /home/pswuser/trace/psw-${yy} >> ${log_yy} 2>&1 > > > sleep 1 > > > echo "lttng enable_event" >> ${log_yy} > > > lttng enable-event -a -k -s psw-${yy} >> ${log_yy} 2>&1 > > > sleep 1 > > > echo "lttng start" >> ${log_yy} > > > lttng start psw-${yy} >> ${log_yy} 2>&1 > > > fi > > > # check zz > > > # delete unless detected or detected2 is present > > > if [ ! -f /home/pswuser/bin/delay-detected ] && > > > [ ! -f /home/pswuser/bin/delay-detected2 ] ; then > > > echo "lttng delete files" >> ${log_zz} > > > rm -rf /home/pswuser/trace/psw-${zz}* >> ${log_zz} 2>&1 > > > #if [ $? -eq 0 ] ; then rm ${log_zz} ; fi > > > fi > > > # delete second snapshot > > > if [ -f /home/pswuser/bin/delay-detected2 ] ; then > > > rm -f /home/pswuser/bin/delay-detected2 > > > > > > # no more tracing once event detected > > > rm -f /home/pswuser/trace/run_trace > > > fi > > > # trigger second snapshot delete first snapshot > > > if [ -f /home/pswuser/bin/delay-detected ] ; then > > > rm -f /home/pswuser/bin/delay-detected > > > touch /home/pswuser/bin/delay-detected2 > > > fi > > > > > > # ls -l /lttng-traces/psw-* > > > # zz (delete candidate) is old xx > > > echo "xx ${xx} yy ${yy} zz ${zz}" > > > zz=${xx} > > > log_zz=$log_xx > > > > > > # xx is now the new one > > > xx=${yy} > > > log_xx=$log_yy > > > > > > # check disk use > > > if [ -d /home/pswuser/trace ] ; then > > > du -h /home/pswuser/trace > > > fi > > > > > > > > > done > > > ---------------------------------------- > > > > > > Any clues are welcome. > > > > > > Another question. > > > > > > Would it be possible to do this by setting up a ring buffer that will wrap > > > around after a certain time. I can easily timestamp the event I am looking > > > for and then capture the buffer containing the event. > > > > Stay tuned for 2013 lttng releases. This will likely be implemented this > > year (flight recorder and snapshots). > > > > Thanks, > > > > Mathieu > > > > > > > > > > > Regards > > > Phil Wilshire > > > > > _______________________________________________ > > > lttng-dev mailing list > > > lttng-dev at lists.lttng.org > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From aspear at vmware.com Tue Jan 8 17:42:00 2013 From: aspear at vmware.com (Aaron Spear) Date: Tue, 8 Jan 2013 14:42:00 -0800 (PST) Subject: [lttng-dev] Java and UST ? In-Reply-To: <268188172.2948226.1357684502836.JavaMail.root@vmware.com> Message-ID: <522299390.2953632.1357684920252.JavaMail.root@vmware.com> Hi All, In a conversation with Mathieu the other day he mentioned that there was some ongoing work to create some standard Java logging implementation that logged via UST. I was hoping to find some more detail about this and plans that are underway, and then ask how I can help. My ideal would be to have an SLF4J implementation (or java.util.logging) that I could easily build into any given java app that then uses UST to do the logging. There are many interesting questions that come up in my head with respect to what you do with mappings between Java and CTF (how "components" are treated, contexts, enable/disable, treatment of Java objects in CTF metadata, ...) cheers, Aaron Spear -------------- next part -------------- An HTML attachment was scrubbed... URL: From mathieu.desnoyers at efficios.com Wed Jan 9 12:54:44 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 9 Jan 2013 12:54:44 -0500 Subject: [lttng-dev] System Hang In-Reply-To: <20130108193132.GA21318@Krystal> References: <20130107191602.GA1342@Krystal> <20130108163603.GA19358@Krystal> <20130108193132.GA21318@Krystal> Message-ID: <20130109175443.GA10042@Krystal> Hrm, after double-check, there was an ancient bug (dating from lttng 0.x) in lttng-statedump. Can you try with the last fix pushed into stable-2.0, stable-2.1, master ? commit c3cd3de91a64e9f786e11658b1d05440e496352f Author: Mathieu Desnoyers Date: Wed Jan 9 12:40:55 2013 -0500 Fix: statedump hang/too early completion due to logic error The previous "Fix: statedump hang due to incorrect wait/wakeup use" was not actually fixing the real problem. The issue is that we should pass the expected condition to wait_event() rather than its contrary. This bug has been sitting there for a while. I suspect that a recent change in the Linux scheduler behavior for newly spawned worker threads might have contributed to trigger the hang more reliably. The effects of this bugs are: - possible hang of the lttng-sessiond (within the kernel) at tracing start, - the statedump end event is traced before all worker threads have actually completed, which can confuse LTTng viewer state systems. Reported-by: Phil Wilshire Signed-off-by: Mathieu Desnoyers Thanks, Mathieu * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > Hi Phil, > > I pushed a fix into master, stable-2.1, and stable-2.0 branches of > lttng-modules that fixes the issue you reported. Please confirm if it > fixes things for you. > > The fix: > > commit 8240b2e21a7ce1653d5e45b01c4709c86c3fb636 > Author: Mathieu Desnoyers > Date: Tue Jan 8 14:27:05 2013 -0500 > > Fix: statedump hang due to incorrect wait/wakeup use > > Reported-by: Phil Wilshire > Signed-off-by: Mathieu Desnoyers > > Thanks, > > Mathieu > > * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > > * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > > > * Phil Wilshire (sysdcs at gmail.com) wrote: > > > > Hi, > > > > Just getting back into lttng after quite a few years > > > > I need to set up a continuous trace on a system. > > > > > > > > Every 10 seconds I stop one session and start another to give me individual > > > > files for each 10 second segment. > > > > I originally intended to start the next session before stopping the > > > > previous but that was causing the sessond to hang. > > > > > > > > Ever so often I can start the trace and the trace file is generated but > > > > ongoing commands to lttng are ignored. The new trace file then grows until > > > > all the disk space is used. sessiond seems to be hung > > > > > > > > > > > > I have the kernel dmseg log attached and I also have the trace file if > > > > needed > > > > > > > > > > > > [ 345.223564] LTT state dump thread start > > > > [ 345.231033] LTT state dump end > > > > [ 353.586011] ring buffer relay-metadata: 3604 records written, 0 records > > > > overrun > > > > [ 353.590023] ring buffer relay-discard, cpu 0: 408474 records written, 0 > > > > records overrun > > > > [ 353.590237] ring buffer relay-discard, cpu 1: 390793 records written, 0 > > > > records overrun > > > > [ 353.590237] ring buffer relay-discard, cpu 2: 363560 records written, 0 > > > > records overrun > > > > [ 353.590685] ring buffer relay-discard, cpu 3: 518867 records written, 0 > > > > records overrun > > > > [ 355.720753] LTTng: state dump begin > > > > [ 355.720753] LTT state dump thread start > > > > [ 355.732034] LTT state dump end > > > > [ 364.111388] ring buffer relay-metadata: 3604 records written, 0 records > > > > overrun > > > > [ 364.120334] ring buffer relay-discard, cpu 0: 409693 records written, 0 > > > > records overrun > > > > [ 364.120334] ring buffer relay-discard, cpu 1: 401971 records written, 0 > > > > records overrun > > > > [ 364.121438] ring buffer relay-discard, cpu 2: 380074 records written, 0 > > > > records overrun > > > > [ 364.122187] ring buffer relay-discard, cpu 3: 524538 records written, 0 > > > > records overrun > > > > [ 366.259690] LTTng: state dump begin > > > > [ 366.259690] LTT state dump thread start > > > > [ 366.266253] LTT state dump end > > > > [ 374.633764] ring buffer relay-metadata: 3604 records written, 0 records > > > > overrun > > > > [ 374.640024] ring buffer relay-discard, cpu 0: 430919 records written, 0 > > > > records overrun > > > > [ 374.640024] ring buffer relay-discard, cpu 1: 387021 records written, 0 > > > > records overrun > > > > [ 374.641033] ring buffer relay-discard, cpu 2: 370007 records written, 0 > > > > records overrun > > > > [ 374.641033] ring buffer relay-discard, cpu 3: 528606 records written, 0 > > > > records overrun > > > > [ 376.795384] LTTng: state dump begin > > > > [ 376.795384] LTT state dump thread start > > > > [ 601.060274] INFO: task lttng-sessiond:2885 blocked for more than 120 > > > > seconds. > > > > [ 601.069038] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables > > > > this message. > > > > [ 601.077626] lttng-sessiond D ffff880074456b18 0 2885 1 > > > > 0x10000000 > > > > [ 601.085210] ffff88006c0679f8 0000000000000082 0000000000000001 > > > > ffff88007b0a4140 > > > > [ 601.094031] ffff88006c0679a8 ffff880074456840 ffff88006c067fd8 > > > > ffff88006c067fd8 > > > > [ 601.105026] 0000000000011c80 ffff880074456840 0000000000000000 > > > > ffff88006c067a68 > > > > [ 601.112170] Call Trace: > > > > [ 601.116027] [] schedule+0x5b/0x5d > > > > > > Hrm, the kernel seems to be stuck in the statedump. We added new stuff > > > there in LTTng-modules 2.1, so there is probably something fishy. > > > > > > This backtrace only tells us that the statedump is waiting for > > > do_lttng_statedump to complete. > > > > > > I would really like to see the backtrace of all tasks in your system at > > > that point (SysRQ t). For more info, see Documentation/sysrq.txt from > > > your Linux kernel sources. Also the dump of sysrq-l (all active cpus) > > > would be useful. Also sysrq-d (all locks held) might help. > > > > > > I've been able to reproduce the issue on my setup. More to come soon. > > > > Thanks, > > > > Mathieu > > > > > > > > More below, > > > > > > > [ 601.121025] [] lttng_statedump_start+0x5aa/0x623 > > > > [lttng_statedump] > > > > [ 601.129035] [] ? abort_exclusive_wait+0x8f/0x8f > > > > [ 601.136030] [] lttng_session_enable+0x52d/0x55b > > > > [lttng_tracer] > > > > [ 601.144034] [] ? abort_exclusive_wait+0x8f/0x8f > > > > [ 601.150039] [] lttng_session_ioctl+0x15f/0x225 > > > > [lttng_tracer] > > > > [ 601.158042] [] ? sock_recvmsg+0xa4/0xb9 > > > > [ 601.163185] [] ? lookup_page_cgroup+0x36/0x4d > > > > [ 601.169453] [] ? cpumask_any_but+0x29/0x38 > > > > [ 601.175508] [] ? trace_preempt_on+0x12/0x2f > > > > [ 601.182031] [] ? sub_preempt_count+0x97/0xc0 > > > > [ 601.187735] [] ? _raw_spin_unlock+0x2a/0x35 > > > > [ 601.193922] [] ? spin_unlock+0xe/0x10 > > > > [ 601.200027] [] ? do_wp_page+0x26f/0x563 > > > > [ 601.206028] [] ? trace_preempt_off+0x12/0x30 > > > > [ 601.212031] [] ? add_preempt_count+0xb4/0xcf > > > > [ 601.218043] [] ? handle_pte_fault+0x6c6/0x76c > > > > [ 601.223737] [] ? verify_iovec+0x52/0xa3 > > > > [ 601.229426] [] ? handle_mm_fault+0x199/0x1a9 > > > > [ 601.236033] [] ? do_page_fault+0x2f6/0x377 > > > > [ 601.242034] [] ? > > > > __event_probe__sys_mprotect+0xf5/0xf5 [lttng_tracer] > > > > [ 601.251031] [] vfs_ioctl+0x22/0x3a > > > > [ 601.256029] [] do_vfs_ioctl+0x3c4/0x407 > > > > [ 601.261188] [] ? fget_light+0x91/0x9d > > > > [ 601.267026] [] sys_ioctl+0x47/0x6a > > > > [ 601.272050] [] tracesys+0xd9/0xde > > > > > > > > > > > > cat /proc/cpuinfo > > > > > > > > processor : 0 > > > > vendor_id : GenuineIntel > > > > cpu family : 6 > > > > model : 28 > > > > model name : Intel(R) Atom(TM) CPU D525 @ 1.80GHz > > > > stepping : 10 > > > > microcode : 0x107 > > > > cpu MHz : 1799.823 > > > > cache size : 512 KB > > > > physical id : 0 > > > > siblings : 4 > > > > core id : 0 > > > > cpu cores : 2 > > > > apicid : 0 > > > > initial apicid : 0 > > > > fpu : yes > > > > fpu_exception : yes > > > > cpuid level : 10 > > > > wp : yes > > > > flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat > > > > pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm > > > > constant_tsc arch_perfmon pebs bts rep_good nopl aperfmperf pni dtes64 > > > > monitor ds_cpl tm2 ssse3 cx16 xtpr pdcm movbe lahf_lm dts > > > > bogomips : 1775.61 > > > > clflush size : 64 > > > > cache_alignment : 64 > > > > address sizes : 36 bits physical, 48 bits virtual > > > > power management: > > > > > > > > (repeated for 3 other cpus ) > > > > > > > > uname -a > > > > Linux 3.2.21-x510v1 #1 SMP PREEMPT Thu Dec 20 11:24:36 EST 2012 x86_64 > > > > GNU/Linux > > > > > > > > Script used to run trace > > > > ================================================= > > > > #!/bin/sh > > > > > > > > xx=`/bin/date +"%s"` > > > > yy="yy" > > > > zz="zz" > > > > log_xx=/home/pswuser/trace/log/psw-${xx}.log > > > > log_yy=/home/pswuser/trace/log/psw-${yy}.log > > > > log_zz=/home/pswuser/trace/log/psw-${zz}.log > > > > #depmod > > > > mkdir -p /home/pswuser/trace > > > > mount -t tmpfs -o size=500M tmpfs /home/pswuser/trace > > > > mkdir -p /home/pswuser/trace/log > > > > touch /home/pswuser/trace/run_trace > > > > sleep 20 > > > > if [ -f /home/pswuser/trace/run_trace ] ; then > > > > > > > > echo "lttng create" > ${log_xx} > > > > lttng create psw-${xx} \ > > > > -o /home/pswuser/trace/psw-${xx} >> ${log_xx} 2>&1 > > > > echo "lttng enable-event" >> ${log_xx} > > > > sleep 1 > > > > lttng enable-event -a -k -s psw-${xx} >> ${log_xx} 2>&1 > > > > sleep 1 > > > > echo "lttng start" >> ${log_xx} > > > > lttng start psw-${xx} >> ${log_xx} 2>&1 > > > > sleep 1 > > > > > > > > fi > > > > > > > > while [ 1 -gt 0 ] ; do > > > > sleep 7 > > > > yy=`/bin/date +"%s"` > > > > log_yy=/home/pswuser/trace/log/psw-${yy}.log > > > > > > > > > > > > #stop xx > > > > if [ -d /home/pswuser/trace/psw-${xx} ] ; then > > > > echo "lttng stop" >> ${log_xx} > > > > lttng stop psw-${xx} >> ${log_xx} 2>&1 > > > > sleep 1 > > > > echo "lttng destroy" >> ${log_xx} > > > > lttng destroy psw-${xx} >> ${log_xx} 2>&1 > > > > echo "lttng done" >> ${log_xx} > > > > fi > > > > > > > > # start yy after stopping xx > > > > if [ -f /home/pswuser/trace/run_trace ] ; then > > > > echo "lttng create ${yy} after closing ${xx}" > ${log_yy} > > > > lttng create psw-${yy} \ > > > > -o /home/pswuser/trace/psw-${yy} >> ${log_yy} 2>&1 > > > > sleep 1 > > > > echo "lttng enable_event" >> ${log_yy} > > > > lttng enable-event -a -k -s psw-${yy} >> ${log_yy} 2>&1 > > > > sleep 1 > > > > echo "lttng start" >> ${log_yy} > > > > lttng start psw-${yy} >> ${log_yy} 2>&1 > > > > fi > > > > # check zz > > > > # delete unless detected or detected2 is present > > > > if [ ! -f /home/pswuser/bin/delay-detected ] && > > > > [ ! -f /home/pswuser/bin/delay-detected2 ] ; then > > > > echo "lttng delete files" >> ${log_zz} > > > > rm -rf /home/pswuser/trace/psw-${zz}* >> ${log_zz} 2>&1 > > > > #if [ $? -eq 0 ] ; then rm ${log_zz} ; fi > > > > fi > > > > # delete second snapshot > > > > if [ -f /home/pswuser/bin/delay-detected2 ] ; then > > > > rm -f /home/pswuser/bin/delay-detected2 > > > > > > > > # no more tracing once event detected > > > > rm -f /home/pswuser/trace/run_trace > > > > fi > > > > # trigger second snapshot delete first snapshot > > > > if [ -f /home/pswuser/bin/delay-detected ] ; then > > > > rm -f /home/pswuser/bin/delay-detected > > > > touch /home/pswuser/bin/delay-detected2 > > > > fi > > > > > > > > # ls -l /lttng-traces/psw-* > > > > # zz (delete candidate) is old xx > > > > echo "xx ${xx} yy ${yy} zz ${zz}" > > > > zz=${xx} > > > > log_zz=$log_xx > > > > > > > > # xx is now the new one > > > > xx=${yy} > > > > log_xx=$log_yy > > > > > > > > # check disk use > > > > if [ -d /home/pswuser/trace ] ; then > > > > du -h /home/pswuser/trace > > > > fi > > > > > > > > > > > > done > > > > ---------------------------------------- > > > > > > > > Any clues are welcome. > > > > > > > > Another question. > > > > > > > > Would it be possible to do this by setting up a ring buffer that will wrap > > > > around after a certain time. I can easily timestamp the event I am looking > > > > for and then capture the buffer containing the event. > > > > > > Stay tuned for 2013 lttng releases. This will likely be implemented this > > > year (flight recorder and snapshots). > > > > > > Thanks, > > > > > > Mathieu > > > > > > > > > > > > > > > Regards > > > > Phil Wilshire > > > > > > > _______________________________________________ > > > > lttng-dev mailing list > > > > lttng-dev at lists.lttng.org > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > > > > -- > > > Mathieu Desnoyers > > > Operating System Efficiency R&D Consultant > > > EfficiOS Inc. > > > http://www.efficios.com > > > > > > _______________________________________________ > > > lttng-dev mailing list > > > lttng-dev at lists.lttng.org > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed Jan 9 13:39:11 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 9 Jan 2013 13:39:11 -0500 Subject: [lttng-dev] [RELEASE] Userspace RCU 0.6.9 Message-ID: <20130109183911.GA14358@Krystal> liburcu is a LGPLv2.1 userspace RCU (read-copy-update) library. This data synchronization library provides read-side access which scales linearly with the number of cores. It does so by allowing multiples copies of a given data structure to live at the same time, and by monitoring the data structure accesses to detect grace periods after which memory reclamation is possible. This is a bugfix release for the stable-0.6 series of the Userspace RCU library. It fixes a hang in use-case where call_rcu is used in a parent process that performs a fork(), without following exec(), and then continues to use call_rcu or synchronize_rcu. Changelog: 2013-01-09 Userspace RCU 0.6.9 * API cleanup: use "uatomic_*" in cmm_smp_mb__ API * uatomic: add memory barrier API for and/or/add/sub/inc/sub * Fix uatomic sign cast * Discourage use of pthread_atfork() for call_rcu handlers * Fix call_rcu fork handling * test: fork handling Project website: http://lttng.org/urcu Download link: http://lttng.org/files/urcu/ -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed Jan 9 13:46:17 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 9 Jan 2013 13:46:17 -0500 Subject: [lttng-dev] [RELEASE] Userspace RCU 0.7.6 Message-ID: <20130109184616.GA14968@Krystal> liburcu is a LGPLv2.1 userspace RCU (read-copy-update) library. This data synchronization library provides read-side access which scales linearly with the number of cores. It does so by allowing multiples copies of a given data structure to live at the same time, and by monitoring the data structure accesses to detect grace periods after which memory reclamation is possible. liburcu-cds provides efficient data structures based on RCU and lock-free algorithms. Those structures include hash tables, queues, stacks, and doubly-linked lists. This is a bugfix release, mainly fixing handling of processes using call_rcu, then fork() without following exec(), and then continuing use of synchronize_rcu() or call_rcu() in the child process. A hang in synchronize_rcu() in the child could occur, which is fixed by this release. Changelog: 2013-01-09 Userspace RCU 0.7.6 * Discourage use of pthread_atfork() for call_rcu handlers * Fix call_rcu fork handling * test: fork handling * Fix TLS detection: test with linker, add --disable-compiler-tls * Cleanup: cast pthread_self() return value to unsigned long * Fallback mechanism not working on platform where TLS is unsupported Project website: http://lttng.org/urcu Download link: http://lttng.org/files/urcu/ -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From jdesfossez at efficios.com Wed Jan 9 14:48:13 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Wed, 9 Jan 2013 14:48:13 -0500 Subject: [lttng-dev] [BABELTRACE PATCH] Namespace the lookup_enum function In-Reply-To: <20130107211855.GB3678@Krystal> References: <20130107211855.GB3678@Krystal> Message-ID: <1357760893-11961-1-git-send-email-jdesfossez@efficios.com> This patch namespaces the lookup_enum function because it causes problem with the integration in gdb even though it is not exported. Hui, can you try this patch and confirm it solves the current problem ? After that we will continue the internal namespacing. Thanks, Julien --- formats/ctf/ctf.c | 2 +- include/babeltrace/types.h | 2 +- types/types.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index 18a5601..a8f8408 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -431,7 +431,7 @@ int ctf_read_event(struct stream_pos *ppos, struct ctf_stream_definition *stream } else { struct definition_enum *enum_definition; - enum_definition = lookup_enum(&stream->stream_event_header->p, "id", FALSE); + enum_definition = bt_lookup_enum(&stream->stream_event_header->p, "id", FALSE); if (enum_definition) { id = enum_definition->integer->value._unsigned; } diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index b42ba03..00c928b 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -521,7 +521,7 @@ struct definition *lookup_definition(const struct definition *definition, struct definition_integer *lookup_integer(const struct definition *definition, const char *field_name, int signedness); -struct definition_enum *lookup_enum(const struct definition *definition, +struct definition_enum *bt_lookup_enum(const struct definition *definition, const char *field_name, int signedness); struct definition *lookup_variant(const struct definition *definition, diff --git a/types/types.c b/types/types.c index 5599027..139e318 100644 --- a/types/types.c +++ b/types/types.c @@ -642,7 +642,7 @@ struct definition_integer *lookup_integer(const struct definition *definition, return lookup_integer; } -struct definition_enum *lookup_enum(const struct definition *definition, +struct definition_enum *bt_lookup_enum(const struct definition *definition, const char *field_name, int signedness) { -- 1.7.10.4 From simon.marchi at polymtl.ca Wed Jan 9 15:28:14 2013 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Wed, 9 Jan 2013 15:28:14 -0500 Subject: [lttng-dev] [PATCH ust] Remove LIBFORMAT output in configure. Message-ID: <1357763294-24232-1-git-send-email-simon.marchi@polymtl.ca> Signed-off-by: Simon Marchi --- configure.ac | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/configure.ac b/configure.ac index c4377a5..a67e8f9 100644 --- a/configure.ac +++ b/configure.ac @@ -309,7 +309,6 @@ AS_ECHO("$version_description") # Report on the configuration options AS_ECHO() AS_ECHO("LTTng-UST will be built with the following options:") -AS_ECHO("Library format: $LIBFORMAT") AS_ECHO() AS_ECHO_N("Java support (JNI): ") -- 1.7.1 From mathieu.desnoyers at efficios.com Wed Jan 9 15:42:41 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 9 Jan 2013 15:42:41 -0500 Subject: [lttng-dev] [PATCH ust] Remove LIBFORMAT output in configure. In-Reply-To: <1357763294-24232-1-git-send-email-simon.marchi@polymtl.ca> References: <1357763294-24232-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <20130109204241.GA16429@Krystal> * Simon Marchi (simon.marchi at polymtl.ca) wrote: > Signed-off-by: Simon Marchi merged into ust master branch, thanks ! Mathieu > --- > configure.ac | 1 - > 1 files changed, 0 insertions(+), 1 deletions(-) > > diff --git a/configure.ac b/configure.ac > index c4377a5..a67e8f9 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -309,7 +309,6 @@ AS_ECHO("$version_description") > # Report on the configuration options > AS_ECHO() > AS_ECHO("LTTng-UST will be built with the following options:") > -AS_ECHO("Library format: $LIBFORMAT") > > AS_ECHO() > AS_ECHO_N("Java support (JNI): ") > -- > 1.7.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed Jan 9 21:00:01 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 9 Jan 2013 21:00:01 -0500 Subject: [lttng-dev] Java and UST ? In-Reply-To: <522299390.2953632.1357684920252.JavaMail.root@vmware.com> References: <268188172.2948226.1357684502836.JavaMail.root@vmware.com> <522299390.2953632.1357684920252.JavaMail.root@vmware.com> Message-ID: <20130110020001.GA19541@Krystal> Jim, could you share the design we came up with to support JUL through our various discussions ? Thanks, Mathieu * Aaron Spear (aspear at vmware.com) wrote: > Hi All, > > > In a conversation with Mathieu the other day he mentioned that there > was some ongoing work to create some standard Java logging > implementation that logged via UST. I was hoping to find some more > detail about this and plans that are underway, and then ask how I can > help. My ideal would be to have an SLF4J implementation (or > java.util.logging) that I could easily build into any given java app > that then uses UST to do the logging. There are many interesting > questions that come up in my head with respect to what you do with > mappings between Java and CTF (how "components" are treated, contexts, > enable/disable, treatment of Java objects in CTF metadata, ...) > > > > cheers, > Aaron Spear > > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From David.OShea at quantum.com Wed Jan 9 23:49:48 2013 From: David.OShea at quantum.com (David OShea) Date: Thu, 10 Jan 2013 04:49:48 +0000 Subject: [lttng-dev] Arrays printed in hex Message-ID: <20998D40D9A2B7499CA5A3A2666CB1EB19F8AEE2@ZURMSG1.QUANTUM.com> Hi all, In lttng-ust 2.0.5, tracepoint.h's comments include: """ * * Integer, printed in base 10 * * ctf_integer(int, field_a, arg0) * * * Integer, printed with 0x base 16 * * ctf_integer_hex(unsigned long, field_d, arg1) [...] * * Array sequence of signed integer values * * ctf_array(long, field_f, arg4, FIXED_LEN4) * ctf_sequence(long, field_g, arg4, size_t, arg4_len) """ Could _hex versions of ctf_array() and ctf_sequence() be easily added, where all the elements of the array/sequence would be output in hex by babeltrace? Thanks in advance, David ---------------------------------------------------------------------- The information contained in this transmission may be confidential. Any disclosure, copying, or further distribution of confidential information is not permitted unless such privilege is explicitly granted in writing by Quantum. Quantum reserves the right to have electronic communications, including email and attachments, sent across its networks filtered through anti virus and spam software programs and retain such messages in order to comply with applicable data security and retention requirements. Quantum is not responsible for the proper and complete transmission of the substance of this communication or for any delay in its receipt. From shemminger at vyatta.com Thu Jan 10 11:32:47 2013 From: shemminger at vyatta.com (Stephen Hemminger) Date: Thu, 10 Jan 2013 08:32:47 -0800 Subject: [lttng-dev] [RELEASE] Userspace RCU 0.7.6 In-Reply-To: <20130109184616.GA14968@Krystal> References: <20130109184616.GA14968@Krystal> Message-ID: <20130110083247.591ad0ba@nehalam.linuxnetplumber.net> On Wed, 9 Jan 2013 13:46:17 -0500 Mathieu Desnoyers wrote: > liburcu is a LGPLv2.1 userspace RCU (read-copy-update) library. This > data synchronization library provides read-side access which scales > linearly with the number of cores. It does so by allowing multiples > copies of a given data structure to live at the same time, and by > monitoring the data structure accesses to detect grace periods after > which memory reclamation is possible. > > liburcu-cds provides efficient data structures based on RCU and > lock-free algorithms. Those structures include hash tables, queues, > stacks, and doubly-linked lists. > > This is a bugfix release, mainly fixing handling of processes using > call_rcu, then fork() without following exec(), and then continuing use > of synchronize_rcu() or call_rcu() in the child process. A hang in > synchronize_rcu() in the child could occur, which is fixed by this > release. > > Changelog: > 2013-01-09 Userspace RCU 0.7.6 > * Discourage use of pthread_atfork() for call_rcu handlers > * Fix call_rcu fork handling > * test: fork handling > * Fix TLS detection: test with linker, add --disable-compiler-tls > * Cleanup: cast pthread_self() return value to unsigned long > * Fallback mechanism not working on platform where TLS is unsupported > > Project website: http://lttng.org/urcu > Download link: http://lttng.org/files/urcu/ > Why is the git repository still at 0.7.4 and there is no tag for 0.7.6? Am I looking at the right place? $ git remote -v origin git://git.lttng.org/userspace-rcu.git (fetch) From mathieu.desnoyers at efficios.com Thu Jan 10 11:42:41 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 10 Jan 2013 11:42:41 -0500 Subject: [lttng-dev] [RELEASE] Userspace RCU 0.7.6 In-Reply-To: <20130110083247.591ad0ba@nehalam.linuxnetplumber.net> References: <20130109184616.GA14968@Krystal> <20130110083247.591ad0ba@nehalam.linuxnetplumber.net> Message-ID: <20130110164241.GA5051@Krystal> * Stephen Hemminger (shemminger at vyatta.com) wrote: > On Wed, 9 Jan 2013 13:46:17 -0500 > Mathieu Desnoyers wrote: > > > liburcu is a LGPLv2.1 userspace RCU (read-copy-update) library. This > > data synchronization library provides read-side access which scales > > linearly with the number of cores. It does so by allowing multiples > > copies of a given data structure to live at the same time, and by > > monitoring the data structure accesses to detect grace periods after > > which memory reclamation is possible. > > > > liburcu-cds provides efficient data structures based on RCU and > > lock-free algorithms. Those structures include hash tables, queues, > > stacks, and doubly-linked lists. > > > > This is a bugfix release, mainly fixing handling of processes using > > call_rcu, then fork() without following exec(), and then continuing use > > of synchronize_rcu() or call_rcu() in the child process. A hang in > > synchronize_rcu() in the child could occur, which is fixed by this > > release. > > > > Changelog: > > 2013-01-09 Userspace RCU 0.7.6 > > * Discourage use of pthread_atfork() for call_rcu handlers > > * Fix call_rcu fork handling > > * test: fork handling > > * Fix TLS detection: test with linker, add --disable-compiler-tls > > * Cleanup: cast pthread_self() return value to unsigned long > > * Fallback mechanism not working on platform where TLS is unsupported > > > > Project website: http://lttng.org/urcu > > Download link: http://lttng.org/files/urcu/ > > > > Why is the git repository still at 0.7.4 and there is no tag for 0.7.6? > Am I looking at the right place? > $ git remote -v > origin git://git.lttng.org/userspace-rcu.git (fetch) I tried doing this to confirm: git clone git://git.lttng.org/userspace-rcu.git cd userspace-rcu git tag -l and v0.7.6 is there. Please note that this tag is in the stable-0.7 branch (not master). Please let me know if the problem persists for you after making sure you use the right branch. Thanks, Mathieu -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From shemminger at vyatta.com Thu Jan 10 11:57:54 2013 From: shemminger at vyatta.com (Stephen Hemminger) Date: Thu, 10 Jan 2013 08:57:54 -0800 Subject: [lttng-dev] [RELEASE] Userspace RCU 0.7.6 In-Reply-To: <20130110164241.GA5051@Krystal> References: <20130109184616.GA14968@Krystal> <20130110083247.591ad0ba@nehalam.linuxnetplumber.net> <20130110164241.GA5051@Krystal> Message-ID: <20130110085754.2d32b314@nehalam.linuxnetplumber.net> On Thu, 10 Jan 2013 11:42:41 -0500 Mathieu Desnoyers wrote: > * Stephen Hemminger (shemminger at vyatta.com) wrote: > > On Wed, 9 Jan 2013 13:46:17 -0500 > > Mathieu Desnoyers wrote: > > > > > liburcu is a LGPLv2.1 userspace RCU (read-copy-update) library. This > > > data synchronization library provides read-side access which scales > > > linearly with the number of cores. It does so by allowing multiples > > > copies of a given data structure to live at the same time, and by > > > monitoring the data structure accesses to detect grace periods after > > > which memory reclamation is possible. > > > > > > liburcu-cds provides efficient data structures based on RCU and > > > lock-free algorithms. Those structures include hash tables, queues, > > > stacks, and doubly-linked lists. > > > > > > This is a bugfix release, mainly fixing handling of processes using > > > call_rcu, then fork() without following exec(), and then continuing use > > > of synchronize_rcu() or call_rcu() in the child process. A hang in > > > synchronize_rcu() in the child could occur, which is fixed by this > > > release. > > > > > > Changelog: > > > 2013-01-09 Userspace RCU 0.7.6 > > > * Discourage use of pthread_atfork() for call_rcu handlers > > > * Fix call_rcu fork handling > > > * test: fork handling > > > * Fix TLS detection: test with linker, add --disable-compiler-tls > > > * Cleanup: cast pthread_self() return value to unsigned long > > > * Fallback mechanism not working on platform where TLS is unsupported > > > > > > Project website: http://lttng.org/urcu > > > Download link: http://lttng.org/files/urcu/ > > > > > > > Why is the git repository still at 0.7.4 and there is no tag for 0.7.6? > > Am I looking at the right place? > > $ git remote -v > > origin git://git.lttng.org/userspace-rcu.git (fetch) > > I tried doing this to confirm: > > git clone git://git.lttng.org/userspace-rcu.git > cd userspace-rcu > git tag -l > > and v0.7.6 is there. > > Please note that this tag is in the stable-0.7 branch (not master). > > Please let me know if the problem persists for you after making sure you > use the right branch. > > Thanks, > > Mathieu > Ok, I didn't see the stable branch. From mathieu.desnoyers at efficios.com Thu Jan 10 11:59:42 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 10 Jan 2013 11:59:42 -0500 Subject: [lttng-dev] Coding blog: lockless queues Message-ID: <20130110165942.GA5133@Krystal> Hi Rusty! I've stumbled on your blog post: http://rusty.ozlabs.org/?p=317 and I find that you looked at the RCU lock-free queue implementation in the Userspace RCU project, but not at the wait-free concurrent queue implementation we have (wait-free enqueue, blocking dequeue), which does not require RCU at all and might be a much better fit for what you are trying to achieve. A quick pointer to the implementation: git://git.lttng.org/userspace-rcu.git master branch files: urcu/wfcqueue.h (public API) urcu/static/wfcqueue.h (API implementation) (https://git.lttng.org/?p=userspace-rcu.git;a=blob;f=urcu/static/wfcqueue.h;h=4b3535aaa83207a4f4eb801dc63150bef8f28bbc;hb=HEAD) Some nice features of this wfcqueue is to allow this: - enqueue is wait-free (uses xchg() and store), - splice (a kind of dequeue_all) from queue is only needs mutual exclusion with other dequeue, but not with other splice. We call it "blocking" because it may have to busy-wait if enqueue is preempted between xchg and store, - synchronization needed when iterating on the queue (so we wait for store to complete if we reach a node being enqueued) is performed at the very last moment where it is needed: this is why we provide "first" and "next" iterators. - we also support "dequeue", to dequeue nodes one by one. The dequeue operation needs mutual exclusion against other dequeue acting on that queue (and against first/next iterators). I'd be very interested to hear feedback from you on this implementation. Thanks! Mathieu -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Thu Jan 10 12:24:53 2013 From: dgoulet at efficios.com (David Goulet) Date: Thu, 10 Jan 2013 12:24:53 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Fix: update next_net_seq_num after sending header Message-ID: <1357838693-22011-1-git-send-email-dgoulet@efficios.com> Increment the sequence number after we are sure that the relayd has received correctly the data header. If an error occurs when sending the header, the data won't be extracted from the buffers thus keeping this sequence number untouched. Furthermore, after sending the header, if the relayd dies, this value won't matter much and if there is an error on the stream when reading the trace data, the stream will be deleted thus closed on the relayd making this value useless. It's important to note that this sequence number is updated on the relayd side if the full expected data packet was received. So, incrementing the value after the transmission of the header is not changing anything in terms of value coherency. The point is to have a semantic of when read and used successfully (transmission to relayd), let's update it. In that code flow, the stream's lock is acquired so no need to read/update it atomically. I've also added a comments to better understand the purpose of this variable and how to use it. Signed-off-by: David Goulet --- src/common/consumer.c | 4 +++- src/common/consumer.h | 14 +++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/common/consumer.c b/src/common/consumer.c index 935a03d..15fc9b0 100644 --- a/src/common/consumer.c +++ b/src/common/consumer.c @@ -755,7 +755,7 @@ static int write_relayd_stream_header(struct lttng_consumer_stream *stream, * this next value, 1 should always be substracted in order to compare * the last seen sequence number on the relayd side to the last sent. */ - data_hdr.net_seq_num = htobe64(stream->next_net_seq_num++); + data_hdr.net_seq_num = htobe64(stream->next_net_seq_num); /* Other fields are zeroed previously */ ret = relayd_send_data_hdr(&relayd->data_sock, &data_hdr, @@ -764,6 +764,8 @@ static int write_relayd_stream_header(struct lttng_consumer_stream *stream, goto error; } + ++stream->next_net_seq_num; + /* Set to go on data socket */ outfd = relayd->data_sock.fd; } diff --git a/src/common/consumer.h b/src/common/consumer.h index 193533e..8305146 100644 --- a/src/common/consumer.h +++ b/src/common/consumer.h @@ -129,7 +129,19 @@ struct lttng_consumer_stream { unsigned int metadata_flag; /* Used when the stream is set for network streaming */ uint64_t relayd_stream_id; - /* Next sequence number to use for trace packet */ + /* + * When sending a stream packet to a relayd, this number is used to track + * the packet sent by the consumer and seen by the relayd. When sending the + * data header to the relayd, this number is sent and if the transmission + * was successful, it is incremented. + * + * Even if the full data is not fully transmitted it won't matter since + * only two possible error can happen after that where either the relayd + * died or a read error is detected on the stream making this value useless + * after that. + * + * This value SHOULD be read/updated atomically or with the lock acquired. + */ uint64_t next_net_seq_num; /* * Lock to use the stream FDs since they are used between threads. -- 1.7.10.4 From mathieu.desnoyers at efficios.com Thu Jan 10 12:38:30 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 10 Jan 2013 12:38:30 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Fix: update next_net_seq_num after sending header In-Reply-To: <1357838693-22011-1-git-send-email-dgoulet@efficios.com> References: <1357838693-22011-1-git-send-email-dgoulet@efficios.com> Message-ID: <20130110173830.GA5835@Krystal> * David Goulet (dgoulet at efficios.com) wrote: > Increment the sequence number after we are sure that the relayd has > received correctly the data header. If an error occurs when sending the > header, the data won't be extracted from the buffers thus keeping this > sequence number untouched. > > Furthermore, after sending the header, if the relayd dies, this value > won't matter much and if there is an error on the stream when reading > the trace data, the stream will be deleted thus closed on the relayd > making this value useless. > > It's important to note that this sequence number is updated on the > relayd side if the full expected data packet was received. So, > incrementing the value after the transmission of the header is not > changing anything in terms of value coherency. The point is to have a > semantic of when read and used successfully (transmission to relayd), > let's update it. > > In that code flow, the stream's lock is acquired so no need to > read/update it atomically. I've also added a comments to better > understand the purpose of this variable and how to use it. > > Signed-off-by: David Goulet Acked-by: Mathieu Desnoyers > --- > src/common/consumer.c | 4 +++- > src/common/consumer.h | 14 +++++++++++++- > 2 files changed, 16 insertions(+), 2 deletions(-) > > diff --git a/src/common/consumer.c b/src/common/consumer.c > index 935a03d..15fc9b0 100644 > --- a/src/common/consumer.c > +++ b/src/common/consumer.c > @@ -755,7 +755,7 @@ static int write_relayd_stream_header(struct lttng_consumer_stream *stream, > * this next value, 1 should always be substracted in order to compare > * the last seen sequence number on the relayd side to the last sent. > */ > - data_hdr.net_seq_num = htobe64(stream->next_net_seq_num++); > + data_hdr.net_seq_num = htobe64(stream->next_net_seq_num); > /* Other fields are zeroed previously */ > > ret = relayd_send_data_hdr(&relayd->data_sock, &data_hdr, > @@ -764,6 +764,8 @@ static int write_relayd_stream_header(struct lttng_consumer_stream *stream, > goto error; > } > > + ++stream->next_net_seq_num; > + > /* Set to go on data socket */ > outfd = relayd->data_sock.fd; > } > diff --git a/src/common/consumer.h b/src/common/consumer.h > index 193533e..8305146 100644 > --- a/src/common/consumer.h > +++ b/src/common/consumer.h > @@ -129,7 +129,19 @@ struct lttng_consumer_stream { > unsigned int metadata_flag; > /* Used when the stream is set for network streaming */ > uint64_t relayd_stream_id; > - /* Next sequence number to use for trace packet */ > + /* > + * When sending a stream packet to a relayd, this number is used to track > + * the packet sent by the consumer and seen by the relayd. When sending the > + * data header to the relayd, this number is sent and if the transmission > + * was successful, it is incremented. > + * > + * Even if the full data is not fully transmitted it won't matter since > + * only two possible error can happen after that where either the relayd > + * died or a read error is detected on the stream making this value useless > + * after that. > + * > + * This value SHOULD be read/updated atomically or with the lock acquired. > + */ > uint64_t next_net_seq_num; > /* > * Lock to use the stream FDs since they are used between threads. > -- > 1.7.10.4 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Thu Jan 10 12:45:48 2013 From: dgoulet at efficios.com (David Goulet) Date: Thu, 10 Jan 2013 12:45:48 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Atomically update relayd stream and session id Message-ID: <1357839948-25490-1-git-send-email-dgoulet@efficios.com> Improve protection to the variables where the uatomic_add_return() call does a volatile access and returns the value atomically incremented. Enclose that in two new functions, one for each id, which helps with the code semantic and brings a single call site for the value update making the code easier to scale and understand when adding contention to those variables. Signed-off-by: David Goulet --- src/bin/lttng-relayd/lttng-relayd.h | 19 +++++++++++++++++++ src/bin/lttng-relayd/main.c | 9 +++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/bin/lttng-relayd/lttng-relayd.h b/src/bin/lttng-relayd/lttng-relayd.h index edd32d6..b2566a1 100644 --- a/src/bin/lttng-relayd/lttng-relayd.h +++ b/src/bin/lttng-relayd/lttng-relayd.h @@ -23,6 +23,9 @@ #include #include +extern uint64_t relayd_last_stream_id; +extern uint64_t relayd_last_session_id; + /* * Queue used to enqueue relay requests */ @@ -81,4 +84,20 @@ struct relay_command { unsigned int version_check_done:1; }; +/* + * Atomically increment the id and return the next stream id. + */ +static inline uint64_t relayd_get_next_stream_id(void) +{ + return (uint64_t) uatomic_add_return(&relayd_last_stream_id, 1); +} + +/* + * Atomically increment the id and return the next session id. + */ +static inline uint64_t relayd_get_next_session_id(void) +{ + return (uint64_t) uatomic_add_return(&relayd_last_session_id, 1); +} + #endif /* LTTNG_RELAYD_H */ diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c index 6627310..a042ce6 100644 --- a/src/bin/lttng-relayd/main.c +++ b/src/bin/lttng-relayd/main.c @@ -82,8 +82,9 @@ static pthread_t listener_thread; static pthread_t dispatcher_thread; static pthread_t worker_thread; -static uint64_t last_relay_stream_id; -static uint64_t last_relay_session_id; +/* Declared extern in lttng-relayd.h */ +uint64_t relayd_last_stream_id; +uint64_t relayd_last_session_id; /* * Relay command queue. @@ -968,7 +969,7 @@ int relay_create_session(struct lttcomm_relayd_hdr *recv_hdr, goto error; } - session->id = ++last_relay_session_id; + session->id = relayd_get_next_session_id(); session->sock = cmd->sock; cmd->session = session; @@ -1032,7 +1033,7 @@ int relay_add_stream(struct lttcomm_relayd_hdr *recv_hdr, } rcu_read_lock(); - stream->stream_handle = ++last_relay_stream_id; + stream->stream_handle = relayd_get_next_stream_id(); stream->prev_seq = -1ULL; stream->session = session; -- 1.7.10.4 From dgoulet at efficios.com Thu Jan 10 12:54:33 2013 From: dgoulet at efficios.com (David Goulet) Date: Thu, 10 Jan 2013 12:54:33 -0500 Subject: [lttng-dev] [PATCH lttng-tools 1/3] Extras: Add the checkpatch coding style script In-Reply-To: <1357596762-14132-1-git-send-email-christian.babeux@efficios.com> References: <1357596762-14132-1-git-send-email-christian.babeux@efficios.com> Message-ID: <50EF0059.50205@efficios.com> Merged! Thanks David Christian Babeux: > Taken from the Linux Kernel tree in scripts/checkpatch.pl. > > Signed-off-by: Christian Babeux > --- > extras/checkpatch.pl | 3685 ++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 3685 insertions(+) > create mode 100755 extras/checkpatch.pl > > diff --git a/extras/checkpatch.pl b/extras/checkpatch.pl > new file mode 100755 > index 0000000..4d2c7df > --- /dev/null > +++ b/extras/checkpatch.pl > @@ -0,0 +1,3685 @@ > +#!/usr/bin/perl -w > +# (c) 2001, Dave Jones. (the file handling bit) > +# (c) 2005, Joel Schopp (the ugly bit) > +# (c) 2007,2008, Andy Whitcroft (new conditions, test suite) > +# (c) 2008-2010 Andy Whitcroft > +# Licensed under the terms of the GNU GPL License version 2 > + > +use strict; > + > +my $P = $0; > +$P =~ s at .*/@@g; > + > +my $V = '0.32'; > + > +use Getopt::Long qw(:config no_auto_abbrev); > + > +my $quiet = 0; > +my $tree = 1; > +my $chk_signoff = 1; > +my $chk_patch = 1; > +my $tst_only; > +my $emacs = 0; > +my $terse = 0; > +my $file = 0; > +my $check = 0; > +my $summary = 1; > +my $mailback = 0; > +my $summary_file = 0; > +my $show_types = 0; > +my $root; > +my %debug; > +my %ignore_type = (); > +my @ignore = (); > +my $help = 0; > +my $configuration_file = ".checkpatch.conf"; > +my $max_line_length = 80; > + > +sub help { > + my ($exitcode) = @_; > + > + print << "EOM"; > +Usage: $P [OPTION]... [FILE]... > +Version: $V > + > +Options: > + -q, --quiet quiet > + --no-tree run without a kernel tree > + --no-signoff do not check for 'Signed-off-by' line > + --patch treat FILE as patchfile (default) > + --emacs emacs compile window format > + --terse one line per report > + -f, --file treat FILE as regular source file > + --subjective, --strict enable more subjective tests > + --ignore TYPE(,TYPE2...) ignore various comma separated message types > + --max-line-length=n set the maximum line length, if exceeded, warn > + --show-types show the message "types" in the output > + --root=PATH PATH to the kernel tree root > + --no-summary suppress the per-file summary > + --mailback only produce a report in case of warnings/errors > + --summary-file include the filename in summary > + --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of > + 'values', 'possible', 'type', and 'attr' (default > + is all off) > + --test-only=WORD report only warnings/errors containing WORD > + literally > + -h, --help, --version display this help and exit > + > +When FILE is - read standard input. > +EOM > + > + exit($exitcode); > +} > + > +my $conf = which_conf($configuration_file); > +if (-f $conf) { > + my @conf_args; > + open(my $conffile, '<', "$conf") > + or warn "$P: Can't find a readable $configuration_file file $!\n"; > + > + while (<$conffile>) { > + my $line = $_; > + > + $line =~ s/\s*\n?$//g; > + $line =~ s/^\s*//g; > + $line =~ s/\s+/ /g; > + > + next if ($line =~ m/^\s*#/); > + next if ($line =~ m/^\s*$/); > + > + my @words = split(" ", $line); > + foreach my $word (@words) { > + last if ($word =~ m/^#/); > + push (@conf_args, $word); > + } > + } > + close($conffile); > + unshift(@ARGV, @conf_args) if @conf_args; > +} > + > +GetOptions( > + 'q|quiet+' => \$quiet, > + 'tree!' => \$tree, > + 'signoff!' => \$chk_signoff, > + 'patch!' => \$chk_patch, > + 'emacs!' => \$emacs, > + 'terse!' => \$terse, > + 'f|file!' => \$file, > + 'subjective!' => \$check, > + 'strict!' => \$check, > + 'ignore=s' => \@ignore, > + 'show-types!' => \$show_types, > + 'max-line-length=i' => \$max_line_length, > + 'root=s' => \$root, > + 'summary!' => \$summary, > + 'mailback!' => \$mailback, > + 'summary-file!' => \$summary_file, > + > + 'debug=s' => \%debug, > + 'test-only=s' => \$tst_only, > + 'h|help' => \$help, > + 'version' => \$help > +) or help(1); > + > +help(0) if ($help); > + > +my $exit = 0; > + > +if ($#ARGV < 0) { > + print "$P: no input files\n"; > + exit(1); > +} > + > + at ignore = split(/,/, join(',', at ignore)); > +foreach my $word (@ignore) { > + $word =~ s/\s*\n?$//g; > + $word =~ s/^\s*//g; > + $word =~ s/\s+/ /g; > + $word =~ tr/[a-z]/[A-Z]/; > + > + next if ($word =~ m/^\s*#/); > + next if ($word =~ m/^\s*$/); > + > + $ignore_type{$word}++; > +} > + > +my $dbg_values = 0; > +my $dbg_possible = 0; > +my $dbg_type = 0; > +my $dbg_attr = 0; > +for my $key (keys %debug) { > + ## no critic > + eval "\${dbg_$key} = '$debug{$key}';"; > + die "$@" if ($@); > +} > + > +my $rpt_cleaners = 0; > + > +if ($terse) { > + $emacs = 1; > + $quiet++; > +} > + > +if ($tree) { > + if (defined $root) { > + if (!top_of_kernel_tree($root)) { > + die "$P: $root: --root does not point at a valid tree\n"; > + } > + } else { > + if (top_of_kernel_tree('.')) { > + $root = '.'; > + } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && > + top_of_kernel_tree($1)) { > + $root = $1; > + } > + } > + > + if (!defined $root) { > + print "Must be run from the top-level dir. of a kernel tree\n"; > + exit(2); > + } > +} > + > +my $emitted_corrupt = 0; > + > +our $Ident = qr{ > + [A-Za-z_][A-Za-z\d_]* > + (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* > + }x; > +our $Storage = qr{extern|static|asmlinkage}; > +our $Sparse = qr{ > + __user| > + __kernel| > + __force| > + __iomem| > + __must_check| > + __init_refok| > + __kprobes| > + __ref| > + __rcu > + }x; > + > +# Notes to $Attribute: > +# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check > +our $Attribute = qr{ > + const| > + __percpu| > + __nocast| > + __safe| > + __bitwise__| > + __packed__| > + __packed2__| > + __naked| > + __maybe_unused| > + __always_unused| > + __noreturn| > + __used| > + __cold| > + __noclone| > + __deprecated| > + __read_mostly| > + __kprobes| > + __(?:mem|cpu|dev|)(?:initdata|initconst|init\b)| > + ____cacheline_aligned| > + ____cacheline_aligned_in_smp| > + ____cacheline_internodealigned_in_smp| > + __weak > + }x; > +our $Modifier; > +our $Inline = qr{inline|__always_inline|noinline}; > +our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; > +our $Lval = qr{$Ident(?:$Member)*}; > + > +our $Float_hex = qr{(?i:0x[0-9a-f]+p-?[0-9]+[fl]?)}; > +our $Float_dec = qr{(?i:((?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?))}; > +our $Float_int = qr{(?i:[0-9]+e-?[0-9]+[fl]?)}; > +our $Float = qr{$Float_hex|$Float_dec|$Float_int}; > +our $Constant = qr{(?:$Float|(?i:(?:0x[0-9a-f]+|[0-9]+)[ul]*))}; > +our $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)}; > +our $Compare = qr{<=|>=|==|!=|<|>}; > +our $Operators = qr{ > + <=|>=|==|!=| > + =>|->|<<|>>|<|>|!|~| > + &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|% > + }x; > + > +our $NonptrType; > +our $Type; > +our $Declare; > + > +our $NON_ASCII_UTF8 = qr{ > + [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte > + | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs > + | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte > + | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates > + | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 > + | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 > + | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 > +}x; > + > +our $UTF8 = qr{ > + [\x09\x0A\x0D\x20-\x7E] # ASCII > + | $NON_ASCII_UTF8 > +}x; > + > +our $typeTypedefs = qr{(?x: > + (?:__)?(?:u|s|be|le)(?:8|16|32|64)| > + atomic_t > +)}; > + > +our $logFunctions = qr{(?x: > + printk(?:_ratelimited|_once|)| > + [a-z0-9]+_(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| > + WARN(?:_RATELIMIT|_ONCE|)| > + panic| > + MODULE_[A-Z_]+ > +)}; > + > +our $signature_tags = qr{(?xi: > + Signed-off-by:| > + Acked-by:| > + Tested-by:| > + Reviewed-by:| > + Reported-by:| > + To:| > + Cc: > +)}; > + > +our @typeList = ( > + qr{void}, > + qr{(?:unsigned\s+)?char}, > + qr{(?:unsigned\s+)?short}, > + qr{(?:unsigned\s+)?int}, > + qr{(?:unsigned\s+)?long}, > + qr{(?:unsigned\s+)?long\s+int}, > + qr{(?:unsigned\s+)?long\s+long}, > + qr{(?:unsigned\s+)?long\s+long\s+int}, > + qr{unsigned}, > + qr{float}, > + qr{double}, > + qr{bool}, > + qr{struct\s+$Ident}, > + qr{union\s+$Ident}, > + qr{enum\s+$Ident}, > + qr{${Ident}_t}, > + qr{${Ident}_handler}, > + qr{${Ident}_handler_fn}, > +); > +our @modifierList = ( > + qr{fastcall}, > +); > + > +our $allowed_asm_includes = qr{(?x: > + irq| > + memory > +)}; > +# memory.h: ARM has a custom one > + > +sub build_types { > + my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)"; > + my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)"; > + $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; > + $NonptrType = qr{ > + (?:$Modifier\s+|const\s+)* > + (?: > + (?:typeof|__typeof__)\s*\([^\)]*\)| > + (?:$typeTypedefs\b)| > + (?:${all}\b) > + ) > + (?:\s+$Modifier|\s+const)* > + }x; > + $Type = qr{ > + $NonptrType > + (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)? > + (?:\s+$Inline|\s+$Modifier)* > + }x; > + $Declare = qr{(?:$Storage\s+)?$Type}; > +} > +build_types(); > + > + > +our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; > + > +# Using $balanced_parens, $LvalOrFunc, or $FuncArg > +# requires at least perl version v5.10.0 > +# Any use must be runtime checked with $^V > + > +our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; > +our $LvalOrFunc = qr{($Lval)\s*($balanced_parens{0,1})\s*}; > +our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant)}; > + > +sub deparenthesize { > + my ($string) = @_; > + return "" if (!defined($string)); > + $string =~ s@^\s*\(\s*@@g; > + $string =~ s@\s*\)\s*$@@g; > + $string =~ s@\s+@ @g; > + return $string; > +} > + > +$chk_signoff = 0 if ($file); > + > +my @rawlines = (); > +my @lines = (); > +my $vname; > +for my $filename (@ARGV) { > + my $FILE; > + if ($file) { > + open($FILE, '-|', "diff -u /dev/null $filename") || > + die "$P: $filename: diff failed - $!\n"; > + } elsif ($filename eq '-') { > + open($FILE, '<&STDIN'); > + } else { > + open($FILE, '<', "$filename") || > + die "$P: $filename: open failed - $!\n"; > + } > + if ($filename eq '-') { > + $vname = 'Your patch'; > + } else { > + $vname = $filename; > + } > + while (<$FILE>) { > + chomp; > + push(@rawlines, $_); > + } > + close($FILE); > + if (!process($filename)) { > + $exit = 1; > + } > + @rawlines = (); > + @lines = (); > +} > + > +exit($exit); > + > +sub top_of_kernel_tree { > + my ($root) = @_; > + > + my @tree_check = ( > + "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", > + "README", "Documentation", "arch", "include", "drivers", > + "fs", "init", "ipc", "kernel", "lib", "scripts", > + ); > + > + foreach my $check (@tree_check) { > + if (! -e $root . '/' . $check) { > + return 0; > + } > + } > + return 1; > +} > + > +sub parse_email { > + my ($formatted_email) = @_; > + > + my $name = ""; > + my $address = ""; > + my $comment = ""; > + > + if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { > + $name = $1; > + $address = $2; > + $comment = $3 if defined $3; > + } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { > + $address = $1; > + $comment = $2 if defined $2; > + } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { > + $address = $1; > + $comment = $2 if defined $2; > + $formatted_email =~ s/$address.*$//; > + $name = $formatted_email; > + $name =~ s/^\s+|\s+$//g; > + $name =~ s/^\"|\"$//g; > + # If there's a name left after stripping spaces and > + # leading quotes, and the address doesn't have both > + # leading and trailing angle brackets, the address > + # is invalid. ie: > + # "joe smith joe at smith.com" bad > + # "joe smith + if ($name ne "" && $address !~ /^<[^>]+>$/) { > + $name = ""; > + $address = ""; > + $comment = ""; > + } > + } > + > + $name =~ s/^\s+|\s+$//g; > + $name =~ s/^\"|\"$//g; > + $address =~ s/^\s+|\s+$//g; > + $address =~ s/^\<|\>$//g; > + > + if ($name =~ /[^\w \-]/i) { ##has "must quote" chars > + $name =~ s/(? + $name = "\"$name\""; > + } > + > + return ($name, $address, $comment); > +} > + > +sub format_email { > + my ($name, $address) = @_; > + > + my $formatted_email; > + > + $name =~ s/^\s+|\s+$//g; > + $name =~ s/^\"|\"$//g; > + $address =~ s/^\s+|\s+$//g; > + > + if ($name =~ /[^\w \-]/i) { ##has "must quote" chars > + $name =~ s/(? + $name = "\"$name\""; > + } > + > + if ("$name" eq "") { > + $formatted_email = "$address"; > + } else { > + $formatted_email = "$name <$address>"; > + } > + > + return $formatted_email; > +} > + > +sub which_conf { > + my ($conf) = @_; > + > + foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { > + if (-e "$path/$conf") { > + return "$path/$conf"; > + } > + } > + > + return ""; > +} > + > +sub expand_tabs { > + my ($str) = @_; > + > + my $res = ''; > + my $n = 0; > + for my $c (split(//, $str)) { > + if ($c eq "\t") { > + $res .= ' '; > + $n++; > + for (; ($n % 8) != 0; $n++) { > + $res .= ' '; > + } > + next; > + } > + $res .= $c; > + $n++; > + } > + > + return $res; > +} > +sub copy_spacing { > + (my $res = shift) =~ tr/\t/ /c; > + return $res; > +} > + > +sub line_stats { > + my ($line) = @_; > + > + # Drop the diff line leader and expand tabs > + $line =~ s/^.//; > + $line = expand_tabs($line); > + > + # Pick the indent from the front of the line. > + my ($white) = ($line =~ /^(\s*)/); > + > + return (length($line), length($white)); > +} > + > +my $sanitise_quote = ''; > + > +sub sanitise_line_reset { > + my ($in_comment) = @_; > + > + if ($in_comment) { > + $sanitise_quote = '*/'; > + } else { > + $sanitise_quote = ''; > + } > +} > +sub sanitise_line { > + my ($line) = @_; > + > + my $res = ''; > + my $l = ''; > + > + my $qlen = 0; > + my $off = 0; > + my $c; > + > + # Always copy over the diff marker. > + $res = substr($line, 0, 1); > + > + for ($off = 1; $off < length($line); $off++) { > + $c = substr($line, $off, 1); > + > + # Comments we are wacking completly including the begin > + # and end, all to $;. > + if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { > + $sanitise_quote = '*/'; > + > + substr($res, $off, 2, "$;$;"); > + $off++; > + next; > + } > + if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { > + $sanitise_quote = ''; > + substr($res, $off, 2, "$;$;"); > + $off++; > + next; > + } > + if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { > + $sanitise_quote = '//'; > + > + substr($res, $off, 2, $sanitise_quote); > + $off++; > + next; > + } > + > + # A \ in a string means ignore the next character. > + if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && > + $c eq "\\") { > + substr($res, $off, 2, 'XX'); > + $off++; > + next; > + } > + # Regular quotes. > + if ($c eq "'" || $c eq '"') { > + if ($sanitise_quote eq '') { > + $sanitise_quote = $c; > + > + substr($res, $off, 1, $c); > + next; > + } elsif ($sanitise_quote eq $c) { > + $sanitise_quote = ''; > + } > + } > + > + #print "c<$c> SQ<$sanitise_quote>\n"; > + if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { > + substr($res, $off, 1, $;); > + } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { > + substr($res, $off, 1, $;); > + } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { > + substr($res, $off, 1, 'X'); > + } else { > + substr($res, $off, 1, $c); > + } > + } > + > + if ($sanitise_quote eq '//') { > + $sanitise_quote = ''; > + } > + > + # The pathname on a #include may be surrounded by '<' and '>'. > + if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { > + my $clean = 'X' x length($1); > + $res =~ s@\<.*\>@<$clean>@; > + > + # The whole of a #error is a string. > + } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { > + my $clean = 'X' x length($1); > + $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; > + } > + > + return $res; > +} > + > +sub ctx_statement_block { > + my ($linenr, $remain, $off) = @_; > + my $line = $linenr - 1; > + my $blk = ''; > + my $soff = $off; > + my $coff = $off - 1; > + my $coff_set = 0; > + > + my $loff = 0; > + > + my $type = ''; > + my $level = 0; > + my @stack = (); > + my $p; > + my $c; > + my $len = 0; > + > + my $remainder; > + while (1) { > + @stack = (['', 0]) if ($#stack == -1); > + > + #warn "CSB: blk<$blk> remain<$remain>\n"; > + # If we are about to drop off the end, pull in more > + # context. > + if ($off >= $len) { > + for (; $remain > 0; $line++) { > + last if (!defined $lines[$line]); > + next if ($lines[$line] =~ /^-/); > + $remain--; > + $loff = $len; > + $blk .= $lines[$line] . "\n"; > + $len = length($blk); > + $line++; > + last; > + } > + # Bail if there is no further context. > + #warn "CSB: blk<$blk> off<$off> len<$len>\n"; > + if ($off >= $len) { > + last; > + } > + if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { > + $level++; > + $type = '#'; > + } > + } > + $p = $c; > + $c = substr($blk, $off, 1); > + $remainder = substr($blk, $off); > + > + #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; > + > + # Handle nested #if/#else. > + if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { > + push(@stack, [ $type, $level ]); > + } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { > + ($type, $level) = @{$stack[$#stack - 1]}; > + } elsif ($remainder =~ /^#\s*endif\b/) { > + ($type, $level) = @{pop(@stack)}; > + } > + > + # Statement ends at the ';' or a close '}' at the > + # outermost level. > + if ($level == 0 && $c eq ';') { > + last; > + } > + > + # An else is really a conditional as long as its not else if > + if ($level == 0 && $coff_set == 0 && > + (!defined($p) || $p =~ /(?:\s|\}|\+)/) && > + $remainder =~ /^(else)(?:\s|{)/ && > + $remainder !~ /^else\s+if\b/) { > + $coff = $off + length($1) - 1; > + $coff_set = 1; > + #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; > + #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; > + } > + > + if (($type eq '' || $type eq '(') && $c eq '(') { > + $level++; > + $type = '('; > + } > + if ($type eq '(' && $c eq ')') { > + $level--; > + $type = ($level != 0)? '(' : ''; > + > + if ($level == 0 && $coff < $soff) { > + $coff = $off; > + $coff_set = 1; > + #warn "CSB: mark coff<$coff>\n"; > + } > + } > + if (($type eq '' || $type eq '{') && $c eq '{') { > + $level++; > + $type = '{'; > + } > + if ($type eq '{' && $c eq '}') { > + $level--; > + $type = ($level != 0)? '{' : ''; > + > + if ($level == 0) { > + if (substr($blk, $off + 1, 1) eq ';') { > + $off++; > + } > + last; > + } > + } > + # Preprocessor commands end at the newline unless escaped. > + if ($type eq '#' && $c eq "\n" && $p ne "\\") { > + $level--; > + $type = ''; > + $off++; > + last; > + } > + $off++; > + } > + # We are truly at the end, so shuffle to the next line. > + if ($off == $len) { > + $loff = $len + 1; > + $line++; > + $remain--; > + } > + > + my $statement = substr($blk, $soff, $off - $soff + 1); > + my $condition = substr($blk, $soff, $coff - $soff + 1); > + > + #warn "STATEMENT<$statement>\n"; > + #warn "CONDITION<$condition>\n"; > + > + #print "coff<$coff> soff<$off> loff<$loff>\n"; > + > + return ($statement, $condition, > + $line, $remain + 1, $off - $loff + 1, $level); > +} > + > +sub statement_lines { > + my ($stmt) = @_; > + > + # Strip the diff line prefixes and rip blank lines at start and end. > + $stmt =~ s/(^|\n)./$1/g; > + $stmt =~ s/^\s*//; > + $stmt =~ s/\s*$//; > + > + my @stmt_lines = ($stmt =~ /\n/g); > + > + return $#stmt_lines + 2; > +} > + > +sub statement_rawlines { > + my ($stmt) = @_; > + > + my @stmt_lines = ($stmt =~ /\n/g); > + > + return $#stmt_lines + 2; > +} > + > +sub statement_block_size { > + my ($stmt) = @_; > + > + $stmt =~ s/(^|\n)./$1/g; > + $stmt =~ s/^\s*{//; > + $stmt =~ s/}\s*$//; > + $stmt =~ s/^\s*//; > + $stmt =~ s/\s*$//; > + > + my @stmt_lines = ($stmt =~ /\n/g); > + my @stmt_statements = ($stmt =~ /;/g); > + > + my $stmt_lines = $#stmt_lines + 2; > + my $stmt_statements = $#stmt_statements + 1; > + > + if ($stmt_lines > $stmt_statements) { > + return $stmt_lines; > + } else { > + return $stmt_statements; > + } > +} > + > +sub ctx_statement_full { > + my ($linenr, $remain, $off) = @_; > + my ($statement, $condition, $level); > + > + my (@chunks); > + > + # Grab the first conditional/block pair. > + ($statement, $condition, $linenr, $remain, $off, $level) = > + ctx_statement_block($linenr, $remain, $off); > + #print "F: c<$condition> s<$statement> remain<$remain>\n"; > + push(@chunks, [ $condition, $statement ]); > + if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { > + return ($level, $linenr, @chunks); > + } > + > + # Pull in the following conditional/block pairs and see if they > + # could continue the statement. > + for (;;) { > + ($statement, $condition, $linenr, $remain, $off, $level) = > + ctx_statement_block($linenr, $remain, $off); > + #print "C: c<$condition> s<$statement> remain<$remain>\n"; > + last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); > + #print "C: push\n"; > + push(@chunks, [ $condition, $statement ]); > + } > + > + return ($level, $linenr, @chunks); > +} > + > +sub ctx_block_get { > + my ($linenr, $remain, $outer, $open, $close, $off) = @_; > + my $line; > + my $start = $linenr - 1; > + my $blk = ''; > + my @o; > + my @c; > + my @res = (); > + > + my $level = 0; > + my @stack = ($level); > + for ($line = $start; $remain > 0; $line++) { > + next if ($rawlines[$line] =~ /^-/); > + $remain--; > + > + $blk .= $rawlines[$line]; > + > + # Handle nested #if/#else. > + if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { > + push(@stack, $level); > + } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { > + $level = $stack[$#stack - 1]; > + } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { > + $level = pop(@stack); > + } > + > + foreach my $c (split(//, $lines[$line])) { > + ##print "C<$c>L<$level><$open$close>O<$off>\n"; > + if ($off > 0) { > + $off--; > + next; > + } > + > + if ($c eq $close && $level > 0) { > + $level--; > + last if ($level == 0); > + } elsif ($c eq $open) { > + $level++; > + } > + } > + > + if (!$outer || $level <= 1) { > + push(@res, $rawlines[$line]); > + } > + > + last if ($level == 0); > + } > + > + return ($level, @res); > +} > +sub ctx_block_outer { > + my ($linenr, $remain) = @_; > + > + my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); > + return @r; > +} > +sub ctx_block { > + my ($linenr, $remain) = @_; > + > + my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); > + return @r; > +} > +sub ctx_statement { > + my ($linenr, $remain, $off) = @_; > + > + my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); > + return @r; > +} > +sub ctx_block_level { > + my ($linenr, $remain) = @_; > + > + return ctx_block_get($linenr, $remain, 0, '{', '}', 0); > +} > +sub ctx_statement_level { > + my ($linenr, $remain, $off) = @_; > + > + return ctx_block_get($linenr, $remain, 0, '(', ')', $off); > +} > + > +sub ctx_locate_comment { > + my ($first_line, $end_line) = @_; > + > + # Catch a comment on the end of the line itself. > + my ($current_comment) = ($rawlines[$end_line - 1] =~ m at .*(/\*.*\*/)\s*(?:\\\s*)?$@); > + return $current_comment if (defined $current_comment); > + > + # Look through the context and try and figure out if there is a > + # comment. > + my $in_comment = 0; > + $current_comment = ''; > + for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { > + my $line = $rawlines[$linenr - 1]; > + #warn " $line\n"; > + if ($linenr == $first_line and $line =~ m@^.\s*\*@) { > + $in_comment = 1; > + } > + if ($line =~ m@/\*@) { > + $in_comment = 1; > + } > + if (!$in_comment && $current_comment ne '') { > + $current_comment = ''; > + } > + $current_comment .= $line . "\n" if ($in_comment); > + if ($line =~ m@\*/@) { > + $in_comment = 0; > + } > + } > + > + chomp($current_comment); > + return($current_comment); > +} > +sub ctx_has_comment { > + my ($first_line, $end_line) = @_; > + my $cmt = ctx_locate_comment($first_line, $end_line); > + > + ##print "LINE: $rawlines[$end_line - 1 ]\n"; > + ##print "CMMT: $cmt\n"; > + > + return ($cmt ne ''); > +} > + > +sub raw_line { > + my ($linenr, $cnt) = @_; > + > + my $offset = $linenr - 1; > + $cnt++; > + > + my $line; > + while ($cnt) { > + $line = $rawlines[$offset++]; > + next if (defined($line) && $line =~ /^-/); > + $cnt--; > + } > + > + return $line; > +} > + > +sub cat_vet { > + my ($vet) = @_; > + my ($res, $coded); > + > + $res = ''; > + while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { > + $res .= $1; > + if ($2 ne '') { > + $coded = sprintf("^%c", unpack('C', $2) + 64); > + $res .= $coded; > + } > + } > + $res =~ s/$/\$/; > + > + return $res; > +} > + > +my $av_preprocessor = 0; > +my $av_pending; > +my @av_paren_type; > +my $av_pend_colon; > + > +sub annotate_reset { > + $av_preprocessor = 0; > + $av_pending = '_'; > + @av_paren_type = ('E'); > + $av_pend_colon = 'O'; > +} > + > +sub annotate_values { > + my ($stream, $type) = @_; > + > + my $res; > + my $var = '_' x length($stream); > + my $cur = $stream; > + > + print "$stream\n" if ($dbg_values > 1); > + > + while (length($cur)) { > + @av_paren_type = ('E') if ($#av_paren_type < 0); > + print " <" . join('', @av_paren_type) . > + "> <$type> <$av_pending>" if ($dbg_values > 1); > + if ($cur =~ /^(\s+)/o) { > + print "WS($1)\n" if ($dbg_values > 1); > + if ($1 =~ /\n/ && $av_preprocessor) { > + $type = pop(@av_paren_type); > + $av_preprocessor = 0; > + } > + > + } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { > + print "CAST($1)\n" if ($dbg_values > 1); > + push(@av_paren_type, $type); > + $type = 'c'; > + > + } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { > + print "DECLARE($1)\n" if ($dbg_values > 1); > + $type = 'T'; > + > + } elsif ($cur =~ /^($Modifier)\s*/) { > + print "MODIFIER($1)\n" if ($dbg_values > 1); > + $type = 'T'; > + > + } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { > + print "DEFINE($1,$2)\n" if ($dbg_values > 1); > + $av_preprocessor = 1; > + push(@av_paren_type, $type); > + if ($2 ne '') { > + $av_pending = 'N'; > + } > + $type = 'E'; > + > + } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { > + print "UNDEF($1)\n" if ($dbg_values > 1); > + $av_preprocessor = 1; > + push(@av_paren_type, $type); > + > + } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { > + print "PRE_START($1)\n" if ($dbg_values > 1); > + $av_preprocessor = 1; > + > + push(@av_paren_type, $type); > + push(@av_paren_type, $type); > + $type = 'E'; > + > + } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { > + print "PRE_RESTART($1)\n" if ($dbg_values > 1); > + $av_preprocessor = 1; > + > + push(@av_paren_type, $av_paren_type[$#av_paren_type]); > + > + $type = 'E'; > + > + } elsif ($cur =~ /^(\#\s*(?:endif))/o) { > + print "PRE_END($1)\n" if ($dbg_values > 1); > + > + $av_preprocessor = 1; > + > + # Assume all arms of the conditional end as this > + # one does, and continue as if the #endif was not here. > + pop(@av_paren_type); > + push(@av_paren_type, $type); > + $type = 'E'; > + > + } elsif ($cur =~ /^(\\\n)/o) { > + print "PRECONT($1)\n" if ($dbg_values > 1); > + > + } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { > + print "ATTR($1)\n" if ($dbg_values > 1); > + $av_pending = $type; > + $type = 'N'; > + > + } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { > + print "SIZEOF($1)\n" if ($dbg_values > 1); > + if (defined $2) { > + $av_pending = 'V'; > + } > + $type = 'N'; > + > + } elsif ($cur =~ /^(if|while|for)\b/o) { > + print "COND($1)\n" if ($dbg_values > 1); > + $av_pending = 'E'; > + $type = 'N'; > + > + } elsif ($cur =~/^(case)/o) { > + print "CASE($1)\n" if ($dbg_values > 1); > + $av_pend_colon = 'C'; > + $type = 'N'; > + > + } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { > + print "KEYWORD($1)\n" if ($dbg_values > 1); > + $type = 'N'; > + > + } elsif ($cur =~ /^(\()/o) { > + print "PAREN('$1')\n" if ($dbg_values > 1); > + push(@av_paren_type, $av_pending); > + $av_pending = '_'; > + $type = 'N'; > + > + } elsif ($cur =~ /^(\))/o) { > + my $new_type = pop(@av_paren_type); > + if ($new_type ne '_') { > + $type = $new_type; > + print "PAREN('$1') -> $type\n" > + if ($dbg_values > 1); > + } else { > + print "PAREN('$1')\n" if ($dbg_values > 1); > + } > + > + } elsif ($cur =~ /^($Ident)\s*\(/o) { > + print "FUNC($1)\n" if ($dbg_values > 1); > + $type = 'V'; > + $av_pending = 'V'; > + > + } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { > + if (defined $2 && $type eq 'C' || $type eq 'T') { > + $av_pend_colon = 'B'; > + } elsif ($type eq 'E') { > + $av_pend_colon = 'L'; > + } > + print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); > + $type = 'V'; > + > + } elsif ($cur =~ /^($Ident|$Constant)/o) { > + print "IDENT($1)\n" if ($dbg_values > 1); > + $type = 'V'; > + > + } elsif ($cur =~ /^($Assignment)/o) { > + print "ASSIGN($1)\n" if ($dbg_values > 1); > + $type = 'N'; > + > + } elsif ($cur =~/^(;|{|})/) { > + print "END($1)\n" if ($dbg_values > 1); > + $type = 'E'; > + $av_pend_colon = 'O'; > + > + } elsif ($cur =~/^(,)/) { > + print "COMMA($1)\n" if ($dbg_values > 1); > + $type = 'C'; > + > + } elsif ($cur =~ /^(\?)/o) { > + print "QUESTION($1)\n" if ($dbg_values > 1); > + $type = 'N'; > + > + } elsif ($cur =~ /^(:)/o) { > + print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); > + > + substr($var, length($res), 1, $av_pend_colon); > + if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { > + $type = 'E'; > + } else { > + $type = 'N'; > + } > + $av_pend_colon = 'O'; > + > + } elsif ($cur =~ /^(\[)/o) { > + print "CLOSE($1)\n" if ($dbg_values > 1); > + $type = 'N'; > + > + } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { > + my $variant; > + > + print "OPV($1)\n" if ($dbg_values > 1); > + if ($type eq 'V') { > + $variant = 'B'; > + } else { > + $variant = 'U'; > + } > + > + substr($var, length($res), 1, $variant); > + $type = 'N'; > + > + } elsif ($cur =~ /^($Operators)/o) { > + print "OP($1)\n" if ($dbg_values > 1); > + if ($1 ne '++' && $1 ne '--') { > + $type = 'N'; > + } > + > + } elsif ($cur =~ /(^.)/o) { > + print "C($1)\n" if ($dbg_values > 1); > + } > + if (defined $1) { > + $cur = substr($cur, length($1)); > + $res .= $type x length($1); > + } > + } > + > + return ($res, $var); > +} > + > +sub possible { > + my ($possible, $line) = @_; > + my $notPermitted = qr{(?: > + ^(?: > + $Modifier| > + $Storage| > + $Type| > + DEFINE_\S+ > + )$| > + ^(?: > + goto| > + return| > + case| > + else| > + asm|__asm__| > + do| > + \#| > + \#\#| > + )(?:\s|$)| > + ^(?:typedef|struct|enum)\b > + )}x; > + warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); > + if ($possible !~ $notPermitted) { > + # Check for modifiers. > + $possible =~ s/\s*$Storage\s*//g; > + $possible =~ s/\s*$Sparse\s*//g; > + if ($possible =~ /^\s*$/) { > + > + } elsif ($possible =~ /\s/) { > + $possible =~ s/\s*$Type\s*//g; > + for my $modifier (split(' ', $possible)) { > + if ($modifier !~ $notPermitted) { > + warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); > + push(@modifierList, $modifier); > + } > + } > + > + } else { > + warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); > + push(@typeList, $possible); > + } > + build_types(); > + } else { > + warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); > + } > +} > + > +my $prefix = ''; > + > +sub show_type { > + return !defined $ignore_type{$_[0]}; > +} > + > +sub report { > + if (!show_type($_[1]) || > + (defined $tst_only && $_[2] !~ /\Q$tst_only\E/)) { > + return 0; > + } > + my $line; > + if ($show_types) { > + $line = "$prefix$_[0]:$_[1]: $_[2]\n"; > + } else { > + $line = "$prefix$_[0]: $_[2]\n"; > + } > + $line = (split('\n', $line))[0] . "\n" if ($terse); > + > + push(our @report, $line); > + > + return 1; > +} > +sub report_dump { > + our @report; > +} > + > +sub ERROR { > + if (report("ERROR", $_[0], $_[1])) { > + our $clean = 0; > + our $cnt_error++; > + } > +} > +sub WARN { > + if (report("WARNING", $_[0], $_[1])) { > + our $clean = 0; > + our $cnt_warn++; > + } > +} > +sub CHK { > + if ($check && report("CHECK", $_[0], $_[1])) { > + our $clean = 0; > + our $cnt_chk++; > + } > +} > + > +sub check_absolute_file { > + my ($absolute, $herecurr) = @_; > + my $file = $absolute; > + > + ##print "absolute<$absolute>\n"; > + > + # See if any suffix of this path is a path within the tree. > + while ($file =~ s@^[^/]*/@@) { > + if (-f "$root/$file") { > + ##print "file<$file>\n"; > + last; > + } > + } > + if (! -f _) { > + return 0; > + } > + > + # It is, so see if the prefix is acceptable. > + my $prefix = $absolute; > + substr($prefix, -length($file)) = ''; > + > + ##print "prefix<$prefix>\n"; > + if ($prefix ne ".../") { > + WARN("USE_RELATIVE_PATH", > + "use relative pathname instead of absolute in changelog text\n" . $herecurr); > + } > +} > + > +sub pos_last_openparen { > + my ($line) = @_; > + > + my $pos = 0; > + > + my $opens = $line =~ tr/\(/\(/; > + my $closes = $line =~ tr/\)/\)/; > + > + my $last_openparen = 0; > + > + if (($opens == 0) || ($closes >= $opens)) { > + return -1; > + } > + > + my $len = length($line); > + > + for ($pos = 0; $pos < $len; $pos++) { > + my $string = substr($line, $pos); > + if ($string =~ /^($FuncArg|$balanced_parens)/) { > + $pos += length($1) - 1; > + } elsif (substr($line, $pos, 1) eq '(') { > + $last_openparen = $pos; > + } elsif (index($string, '(') == -1) { > + last; > + } > + } > + > + return $last_openparen + 1; > +} > + > +sub process { > + my $filename = shift; > + > + my $linenr=0; > + my $prevline=""; > + my $prevrawline=""; > + my $stashline=""; > + my $stashrawline=""; > + > + my $length; > + my $indent; > + my $previndent=0; > + my $stashindent=0; > + > + our $clean = 1; > + my $signoff = 0; > + my $is_patch = 0; > + > + my $in_header_lines = 1; > + my $in_commit_log = 0; #Scanning lines before patch > + > + my $non_utf8_charset = 0; > + > + our @report = (); > + our $cnt_lines = 0; > + our $cnt_error = 0; > + our $cnt_warn = 0; > + our $cnt_chk = 0; > + > + # Trace the real file/line as we go. > + my $realfile = ''; > + my $realline = 0; > + my $realcnt = 0; > + my $here = ''; > + my $in_comment = 0; > + my $comment_edge = 0; > + my $first_line = 0; > + my $p1_prefix = ''; > + > + my $prev_values = 'E'; > + > + # suppression flags > + my %suppress_ifbraces; > + my %suppress_whiletrailers; > + my %suppress_export; > + my $suppress_statement = 0; > + > + my %camelcase = (); > + > + # Pre-scan the patch sanitizing the lines. > + # Pre-scan the patch looking for any __setup documentation. > + # > + my @setup_docs = (); > + my $setup_docs = 0; > + > + sanitise_line_reset(); > + my $line; > + foreach my $rawline (@rawlines) { > + $linenr++; > + $line = $rawline; > + > + if ($rawline=~/^\+\+\+\s+(\S+)/) { > + $setup_docs = 0; > + if ($1 =~ m at Documentation/kernel-parameters.txt$@) { > + $setup_docs = 1; > + } > + #next; > + } > + if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { > + $realline=$1-1; > + if (defined $2) { > + $realcnt=$3+1; > + } else { > + $realcnt=1+1; > + } > + $in_comment = 0; > + > + # Guestimate if this is a continuing comment. Run > + # the context looking for a comment "edge". If this > + # edge is a close comment then we must be in a comment > + # at context start. > + my $edge; > + my $cnt = $realcnt; > + for (my $ln = $linenr + 1; $cnt > 0; $ln++) { > + next if (defined $rawlines[$ln - 1] && > + $rawlines[$ln - 1] =~ /^-/); > + $cnt--; > + #print "RAW<$rawlines[$ln - 1]>\n"; > + last if (!defined $rawlines[$ln - 1]); > + if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && > + $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { > + ($edge) = $1; > + last; > + } > + } > + if (defined $edge && $edge eq '*/') { > + $in_comment = 1; > + } > + > + # Guestimate if this is a continuing comment. If this > + # is the start of a diff block and this line starts > + # ' *' then it is very likely a comment. > + if (!defined $edge && > + $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) > + { > + $in_comment = 1; > + } > + > + ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; > + sanitise_line_reset($in_comment); > + > + } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { > + # Standardise the strings and chars within the input to > + # simplify matching -- only bother with positive lines. > + $line = sanitise_line($rawline); > + } > + push(@lines, $line); > + > + if ($realcnt > 1) { > + $realcnt-- if ($line =~ /^(?:\+| |$)/); > + } else { > + $realcnt = 0; > + } > + > + #print "==>$rawline\n"; > + #print "-->$line\n"; > + > + if ($setup_docs && $line =~ /^\+/) { > + push(@setup_docs, $line); > + } > + } > + > + $prefix = ''; > + > + $realcnt = 0; > + $linenr = 0; > + foreach my $line (@lines) { > + $linenr++; > + > + my $rawline = $rawlines[$linenr - 1]; > + > +#extract the line range in the file after the patch is applied > + if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { > + $is_patch = 1; > + $first_line = $linenr + 1; > + $realline=$1-1; > + if (defined $2) { > + $realcnt=$3+1; > + } else { > + $realcnt=1+1; > + } > + annotate_reset(); > + $prev_values = 'E'; > + > + %suppress_ifbraces = (); > + %suppress_whiletrailers = (); > + %suppress_export = (); > + $suppress_statement = 0; > + next; > + > +# track the line number as we move through the hunk, note that > +# new versions of GNU diff omit the leading space on completely > +# blank context lines so we need to count that too. > + } elsif ($line =~ /^( |\+|$)/) { > + $realline++; > + $realcnt-- if ($realcnt != 0); > + > + # Measure the line length and indent. > + ($length, $indent) = line_stats($rawline); > + > + # Track the previous line. > + ($prevline, $stashline) = ($stashline, $line); > + ($previndent, $stashindent) = ($stashindent, $indent); > + ($prevrawline, $stashrawline) = ($stashrawline, $rawline); > + > + #warn "line<$line>\n"; > + > + } elsif ($realcnt == 1) { > + $realcnt--; > + } > + > + my $hunk_line = ($realcnt != 0); > + > +#make up the handle for any error we report on this line > + $prefix = "$filename:$realline: " if ($emacs && $file); > + $prefix = "$filename:$linenr: " if ($emacs && !$file); > + > + $here = "#$linenr: " if (!$file); > + $here = "#$realline: " if ($file); > + > + # extract the filename as it passes > + if ($line =~ /^diff --git.*?(\S+)$/) { > + $realfile = $1; > + $realfile =~ s@^([^/]*)/@@; > + $in_commit_log = 0; > + } elsif ($line =~ /^\+\+\+\s+(\S+)/) { > + $realfile = $1; > + $realfile =~ s@^([^/]*)/@@; > + $in_commit_log = 0; > + > + $p1_prefix = $1; > + if (!$file && $tree && $p1_prefix ne '' && > + -e "$root/$p1_prefix") { > + WARN("PATCH_PREFIX", > + "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); > + } > + > + if ($realfile =~ m@^include/asm/@) { > + ERROR("MODIFIED_INCLUDE_ASM", > + "do not modify files in include/asm, change architecture specific files in include/asm-\n" . "$here$rawline\n"); > + } > + next; > + } > + > + $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); > + > + my $hereline = "$here\n$rawline\n"; > + my $herecurr = "$here\n$rawline\n"; > + my $hereprev = "$here\n$prevrawline\n$rawline\n"; > + > + $cnt_lines++ if ($realcnt != 0); > + > +# Check for incorrect file permissions > + if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { > + my $permhere = $here . "FILE: $realfile\n"; > + if ($realfile =~ /(Makefile|Kconfig|\.c|\.h|\.S|\.tmpl)$/) { > + ERROR("EXECUTE_PERMISSIONS", > + "do not set execute permissions for source files\n" . $permhere); > + } > + } > + > +# Check the patch for a signoff: > + if ($line =~ /^\s*signed-off-by:/i) { > + $signoff++; > + $in_commit_log = 0; > + } > + > +# Check signature styles > + if (!$in_header_lines && > + $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { > + my $space_before = $1; > + my $sign_off = $2; > + my $space_after = $3; > + my $email = $4; > + my $ucfirst_sign_off = ucfirst(lc($sign_off)); > + > + if ($sign_off !~ /$signature_tags/) { > + WARN("BAD_SIGN_OFF", > + "Non-standard signature: $sign_off\n" . $herecurr); > + } > + if (defined $space_before && $space_before ne "") { > + WARN("BAD_SIGN_OFF", > + "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr); > + } > + if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { > + WARN("BAD_SIGN_OFF", > + "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr); > + } > + if (!defined $space_after || $space_after ne " ") { > + WARN("BAD_SIGN_OFF", > + "Use a single space after $ucfirst_sign_off\n" . $herecurr); > + } > + > + my ($email_name, $email_address, $comment) = parse_email($email); > + my $suggested_email = format_email(($email_name, $email_address)); > + if ($suggested_email eq "") { > + ERROR("BAD_SIGN_OFF", > + "Unrecognized email address: '$email'\n" . $herecurr); > + } else { > + my $dequoted = $suggested_email; > + $dequoted =~ s/^"//; > + $dequoted =~ s/" + # Don't force email to have quotes > + # Allow just an angle bracketed address > + if ("$dequoted$comment" ne $email && > + "<$email_address>$comment" ne $email && > + "$suggested_email$comment" ne $email) { > + WARN("BAD_SIGN_OFF", > + "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr); > + } > + } > + } > + > +# Check for wrappage within a valid hunk of the file > + if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { > + ERROR("CORRUPTED_PATCH", > + "patch seems to be corrupt (line wrapped?)\n" . > + $herecurr) if (!$emitted_corrupt++); > + } > + > +# Check for absolute kernel paths. > + if ($tree) { > + while ($line =~ m{(?:^|\s)(/\S*)}g) { > + my $file = $1; > + > + if ($file =~ m{^(.*?)(?::\d+)+:?$} && > + check_absolute_file($1, $herecurr)) { > + # > + } else { > + check_absolute_file($file, $herecurr); > + } > + } > + } > + > +# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php > + if (($realfile =~ /^$/ || $line =~ /^\+/) && > + $rawline !~ m/^$UTF8*$/) { > + my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); > + > + my $blank = copy_spacing($rawline); > + my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; > + my $hereptr = "$hereline$ptr\n"; > + > + CHK("INVALID_UTF8", > + "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); > + } > + > +# Check if it's the start of a commit log > +# (not a header line and we haven't seen the patch filename) > + if ($in_header_lines && $realfile =~ /^$/ && > + $rawline !~ /^(commit\b|from\b|[\w-]+:).+$/i) { > + $in_header_lines = 0; > + $in_commit_log = 1; > + } > + > +# Check if there is UTF-8 in a commit log when a mail header has explicitly > +# declined it, i.e defined some charset where it is missing. > + if ($in_header_lines && > + $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && > + $1 !~ /utf-8/i) { > + $non_utf8_charset = 1; > + } > + > + if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && > + $rawline =~ /$NON_ASCII_UTF8/) { > + WARN("UTF8_BEFORE_PATCH", > + "8-bit UTF-8 used in possible commit log\n" . $herecurr); > + } > + > +# ignore non-hunk lines and lines being removed > + next if (!$hunk_line || $line =~ /^-/); > + > +#trailing whitespace > + if ($line =~ /^\+.*\015/) { > + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; > + ERROR("DOS_LINE_ENDINGS", > + "DOS line endings\n" . $herevet); > + > + } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { > + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; > + ERROR("TRAILING_WHITESPACE", > + "trailing whitespace\n" . $herevet); > + $rpt_cleaners = 1; > + } > + > +# check for Kconfig help text having a real description > +# Only applies when adding the entry originally, after that we do not have > +# sufficient context to determine whether it is indeed long enough. > + if ($realfile =~ /Kconfig/ && > + $line =~ /.\s*config\s+/) { > + my $length = 0; > + my $cnt = $realcnt; > + my $ln = $linenr + 1; > + my $f; > + my $is_start = 0; > + my $is_end = 0; > + for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { > + $f = $lines[$ln - 1]; > + $cnt-- if ($lines[$ln - 1] !~ /^-/); > + $is_end = $lines[$ln - 1] =~ /^\+/; > + > + next if ($f =~ /^-/); > + > + if ($lines[$ln - 1] =~ /.\s*(?:bool|tristate)\s*\"/) { > + $is_start = 1; > + } elsif ($lines[$ln - 1] =~ /.\s*(?:---)?help(?:---)?$/) { > + $length = -1; > + } > + > + $f =~ s/^.//; > + $f =~ s/#.*//; > + $f =~ s/^\s+//; > + next if ($f =~ /^$/); > + if ($f =~ /^\s*config\s/) { > + $is_end = 1; > + last; > + } > + $length++; > + } > + WARN("CONFIG_DESCRIPTION", > + "please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_start && $is_end && $length < 4); > + #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; > + } > + > +# discourage the addition of CONFIG_EXPERIMENTAL in Kconfig. > + if ($realfile =~ /Kconfig/ && > + $line =~ /.\s*depends on\s+.*\bEXPERIMENTAL\b/) { > + WARN("CONFIG_EXPERIMENTAL", > + "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n"); > + } > + > + if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && > + ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { > + my $flag = $1; > + my $replacement = { > + 'EXTRA_AFLAGS' => 'asflags-y', > + 'EXTRA_CFLAGS' => 'ccflags-y', > + 'EXTRA_CPPFLAGS' => 'cppflags-y', > + 'EXTRA_LDFLAGS' => 'ldflags-y', > + }; > + > + WARN("DEPRECATED_VARIABLE", > + "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); > + } > + > +# check we are in a valid source file if not then ignore this hunk > + next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/); > + > +#line length limit > + if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && > + $rawline !~ /^.\s*\*\s*\@$Ident\s/ && > + !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:|,|\)\s*;)\s*$/ || > + $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) && > + $length > $max_line_length) > + { > + WARN("LONG_LINE", > + "line over $max_line_length characters\n" . $herecurr); > + } > + > +# Check for user-visible strings broken across lines, which breaks the ability > +# to grep for the string. Limited to strings used as parameters (those > +# following an open parenthesis), which almost completely eliminates false > +# positives, as well as warning only once per parameter rather than once per > +# line of the string. Make an exception when the previous string ends in a > +# newline (multiple lines in one string constant) or \n\t (common in inline > +# assembly to indent the instruction on the following line). > + if ($line =~ /^\+\s*"/ && > + $prevline =~ /"\s*$/ && > + $prevline =~ /\(/ && > + $prevrawline !~ /\\n(?:\\t)*"\s*$/) { > + WARN("SPLIT_STRING", > + "quoted string split across lines\n" . $hereprev); > + } > + > +# check for spaces before a quoted newline > + if ($rawline =~ /^.*\".*\s\\n/) { > + WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", > + "unnecessary whitespace before a quoted newline\n" . $herecurr); > + } > + > +# check for adding lines without a newline. > + if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { > + WARN("MISSING_EOF_NEWLINE", > + "adding a line without newline at end of file\n" . $herecurr); > + } > + > +# Blackfin: use hi/lo macros > + if ($realfile =~ m at arch/blackfin/.*\.S$@) { > + if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) { > + my $herevet = "$here\n" . cat_vet($line) . "\n"; > + ERROR("LO_MACRO", > + "use the LO() macro, not (... & 0xFFFF)\n" . $herevet); > + } > + if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) { > + my $herevet = "$here\n" . cat_vet($line) . "\n"; > + ERROR("HI_MACRO", > + "use the HI() macro, not (... >> 16)\n" . $herevet); > + } > + } > + > +# check we are in a valid source file C or perl if not then ignore this hunk > + next if ($realfile !~ /\.(h|c|pl)$/); > + > +# at the beginning of a line any tabs must come first and anything > +# more than 8 must use tabs. > + if ($rawline =~ /^\+\s* \t\s*\S/ || > + $rawline =~ /^\+\s* \s*/) { > + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; > + ERROR("CODE_INDENT", > + "code indent should use tabs where possible\n" . $herevet); > + $rpt_cleaners = 1; > + } > + > +# check for space before tabs. > + if ($rawline =~ /^\+/ && $rawline =~ / \t/) { > + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; > + WARN("SPACE_BEFORE_TAB", > + "please, no space before tabs\n" . $herevet); > + } > + > +# check for && or || at the start of a line > + if ($rawline =~ /^\+\s*(&&|\|\|)/) { > + CHK("LOGICAL_CONTINUATIONS", > + "Logical continuations should be on the previous line\n" . $hereprev); > + } > + > +# check multi-line statement indentation matches previous line > + if ($^V && $^V ge 5.10.0 && > + $prevline =~ /^\+(\t*)(if \(|$Ident\().*(\&\&|\|\||,)\s*$/) { > + $prevline =~ /^\+(\t*)(.*)$/; > + my $oldindent = $1; > + my $rest = $2; > + > + my $pos = pos_last_openparen($rest); > + if ($pos >= 0) { > + $line =~ /^(\+| )([ \t]*)/; > + my $newindent = $2; > + > + my $goodtabindent = $oldindent . > + "\t" x ($pos / 8) . > + " " x ($pos % 8); > + my $goodspaceindent = $oldindent . " " x $pos; > + > + if ($newindent ne $goodtabindent && > + $newindent ne $goodspaceindent) { > + CHK("PARENTHESIS_ALIGNMENT", > + "Alignment should match open parenthesis\n" . $hereprev); > + } > + } > + } > + > + if ($line =~ /^\+.*\*[ \t]*\)[ \t]+/) { > + CHK("SPACING", > + "No space is necessary after a cast\n" . $hereprev); > + } > + > + if ($realfile =~ m@^(drivers/net/|net/)@ && > + $rawline =~ /^\+[ \t]*\/\*[ \t]*$/ && > + $prevrawline =~ /^\+[ \t]*$/) { > + WARN("NETWORKING_BLOCK_COMMENT_STYLE", > + "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); > + } > + > + if ($realfile =~ m@^(drivers/net/|net/)@ && > + $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ > + $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ > + $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ > + $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ > + WARN("NETWORKING_BLOCK_COMMENT_STYLE", > + "networking block comments put the trailing */ on a separate line\n" . $herecurr); > + } > + > +# check for spaces at the beginning of a line. > +# Exceptions: > +# 1) within comments > +# 2) indented preprocessor commands > +# 3) hanging labels > + if ($rawline =~ /^\+ / && $line !~ /\+ *(?:$;|#|$Ident:)/) { > + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; > + WARN("LEADING_SPACE", > + "please, no spaces at the start of a line\n" . $herevet); > + } > + > +# check we are in a valid C source file if not then ignore this hunk > + next if ($realfile !~ /\.(h|c)$/); > + > +# discourage the addition of CONFIG_EXPERIMENTAL in #if(def). > + if ($line =~ /^\+\s*\#\s*if.*\bCONFIG_EXPERIMENTAL\b/) { > + WARN("CONFIG_EXPERIMENTAL", > + "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n"); > + } > + > +# check for RCS/CVS revision markers > + if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { > + WARN("CVS_KEYWORD", > + "CVS style keyword markers, these will _not_ be updated\n". $herecurr); > + } > + > +# Blackfin: don't use __builtin_bfin_[cs]sync > + if ($line =~ /__builtin_bfin_csync/) { > + my $herevet = "$here\n" . cat_vet($line) . "\n"; > + ERROR("CSYNC", > + "use the CSYNC() macro in asm/blackfin.h\n" . $herevet); > + } > + if ($line =~ /__builtin_bfin_ssync/) { > + my $herevet = "$here\n" . cat_vet($line) . "\n"; > + ERROR("SSYNC", > + "use the SSYNC() macro in asm/blackfin.h\n" . $herevet); > + } > + > +# Check for potential 'bare' types > + my ($stat, $cond, $line_nr_next, $remain_next, $off_next, > + $realline_next); > +#print "LINE<$line>\n"; > + if ($linenr >= $suppress_statement && > + $realcnt && $line =~ /.\s*\S/) { > + ($stat, $cond, $line_nr_next, $remain_next, $off_next) = > + ctx_statement_block($linenr, $realcnt, 0); > + $stat =~ s/\n./\n /g; > + $cond =~ s/\n./\n /g; > + > +#print "linenr<$linenr> <$stat>\n"; > + # If this statement has no statement boundaries within > + # it there is no point in retrying a statement scan > + # until we hit end of it. > + my $frag = $stat; $frag =~ s/;+\s*$//; > + if ($frag !~ /(?:{|;)/) { > +#print "skip<$line_nr_next>\n"; > + $suppress_statement = $line_nr_next; > + } > + > + # Find the real next line. > + $realline_next = $line_nr_next; > + if (defined $realline_next && > + (!defined $lines[$realline_next - 1] || > + substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { > + $realline_next++; > + } > + > + my $s = $stat; > + $s =~ s/{.*$//s; > + > + # Ignore goto labels. > + if ($s =~ /$Ident:\*$/s) { > + > + # Ignore functions being called > + } elsif ($s =~ /^.\s*$Ident\s*\(/s) { > + > + } elsif ($s =~ /^.\s*else\b/s) { > + > + # declarations always start with types > + } elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?((?:\s*$Ident)+?)\b(?:\s+$Sparse)?\s*\**\s*(?:$Ident|\(\*[^\)]*\))(?:\s*$Modifier)?\s*(?:;|=|,|\()/s) { > + my $type = $1; > + $type =~ s/\s+/ /g; > + possible($type, "A:" . $s); > + > + # definitions in global scope can only start with types > + } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { > + possible($1, "B:" . $s); > + } > + > + # any (foo ... *) is a pointer cast, and foo is a type > + while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { > + possible($1, "C:" . $s); > + } > + > + # Check for any sort of function declaration. > + # int foo(something bar, other baz); > + # void (*store_gdt)(x86_descr_ptr *); > + if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { > + my ($name_len) = length($1); > + > + my $ctx = $s; > + substr($ctx, 0, $name_len + 1, ''); > + $ctx =~ s/\)[^\)]*$//; > + > + for my $arg (split(/\s*,\s*/, $ctx)) { > + if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { > + > + possible($1, "D:" . $s); > + } > + } > + } > + > + } > + > +# > +# Checks which may be anchored in the context. > +# > + > +# Check for switch () and associated case and default > +# statements should be at the same indent. > + if ($line=~/\bswitch\s*\(.*\)/) { > + my $err = ''; > + my $sep = ''; > + my @ctx = ctx_block_outer($linenr, $realcnt); > + shift(@ctx); > + for my $ctx (@ctx) { > + my ($clen, $cindent) = line_stats($ctx); > + if ($ctx =~ /^\+\s*(case\s+|default:)/ && > + $indent != $cindent) { > + $err .= "$sep$ctx\n"; > + $sep = ''; > + } else { > + $sep = "[...]\n"; > + } > + } > + if ($err ne '') { > + ERROR("SWITCH_CASE_INDENT_LEVEL", > + "switch and case should be at the same indent\n$hereline$err"); > + } > + } > + > +# if/while/etc brace do not go on next line, unless defining a do while loop, > +# or if that brace on the next line is for something else > + if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { > + my $pre_ctx = "$1$2"; > + > + my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); > + > + if ($line =~ /^\+\t{6,}/) { > + WARN("DEEP_INDENTATION", > + "Too many leading tabs - consider code refactoring\n" . $herecurr); > + } > + > + my $ctx_cnt = $realcnt - $#ctx - 1; > + my $ctx = join("\n", @ctx); > + > + my $ctx_ln = $linenr; > + my $ctx_skip = $realcnt; > + > + while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && > + defined $lines[$ctx_ln - 1] && > + $lines[$ctx_ln - 1] =~ /^-/)) { > + ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; > + $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); > + $ctx_ln++; > + } > + > + #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; > + #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; > + > + if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { > + ERROR("OPEN_BRACE", > + "that open brace { should be on the previous line\n" . > + "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); > + } > + if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && > + $ctx =~ /\)\s*\;\s*$/ && > + defined $lines[$ctx_ln - 1]) > + { > + my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); > + if ($nindent > $indent) { > + WARN("TRAILING_SEMICOLON", > + "trailing semicolon indicates no statements, indent implies otherwise\n" . > + "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); > + } > + } > + } > + > +# Check relative indent for conditionals and blocks. > + if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { > + ($stat, $cond, $line_nr_next, $remain_next, $off_next) = > + ctx_statement_block($linenr, $realcnt, 0) > + if (!defined $stat); > + my ($s, $c) = ($stat, $cond); > + > + substr($s, 0, length($c), ''); > + > + # Make sure we remove the line prefixes as we have > + # none on the first line, and are going to readd them > + # where necessary. > + $s =~ s/\n./\n/gs; > + > + # Find out how long the conditional actually is. > + my @newlines = ($c =~ /\n/gs); > + my $cond_lines = 1 + $#newlines; > + > + # We want to check the first line inside the block > + # starting at the end of the conditional, so remove: > + # 1) any blank line termination > + # 2) any opening brace { on end of the line > + # 3) any do (...) { > + my $continuation = 0; > + my $check = 0; > + $s =~ s/^.*\bdo\b//; > + $s =~ s/^\s*{//; > + if ($s =~ s/^\s*\\//) { > + $continuation = 1; > + } > + if ($s =~ s/^\s*?\n//) { > + $check = 1; > + $cond_lines++; > + } > + > + # Also ignore a loop construct at the end of a > + # preprocessor statement. > + if (($prevline =~ /^.\s*#\s*define\s/ || > + $prevline =~ /\\\s*$/) && $continuation == 0) { > + $check = 0; > + } > + > + my $cond_ptr = -1; > + $continuation = 0; > + while ($cond_ptr != $cond_lines) { > + $cond_ptr = $cond_lines; > + > + # If we see an #else/#elif then the code > + # is not linear. > + if ($s =~ /^\s*\#\s*(?:else|elif)/) { > + $check = 0; > + } > + > + # Ignore: > + # 1) blank lines, they should be at 0, > + # 2) preprocessor lines, and > + # 3) labels. > + if ($continuation || > + $s =~ /^\s*?\n/ || > + $s =~ /^\s*#\s*?/ || > + $s =~ /^\s*$Ident\s*:/) { > + $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; > + if ($s =~ s/^.*?\n//) { > + $cond_lines++; > + } > + } > + } > + > + my (undef, $sindent) = line_stats("+" . $s); > + my $stat_real = raw_line($linenr, $cond_lines); > + > + # Check if either of these lines are modified, else > + # this is not this patch's fault. > + if (!defined($stat_real) || > + $stat !~ /^\+/ && $stat_real !~ /^\+/) { > + $check = 0; > + } > + if (defined($stat_real) && $cond_lines > 1) { > + $stat_real = "[...]\n$stat_real"; > + } > + > + #print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n"; > + > + if ($check && (($sindent % 8) != 0 || > + ($sindent <= $indent && $s ne ''))) { > + WARN("SUSPECT_CODE_INDENT", > + "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); > + } > + } > + > + # Track the 'values' across context and added lines. > + my $opline = $line; $opline =~ s/^./ /; > + my ($curr_values, $curr_vars) = > + annotate_values($opline . "\n", $prev_values); > + $curr_values = $prev_values . $curr_values; > + if ($dbg_values) { > + my $outline = $opline; $outline =~ s/\t/ /g; > + print "$linenr > .$outline\n"; > + print "$linenr > $curr_values\n"; > + print "$linenr > $curr_vars\n"; > + } > + $prev_values = substr($curr_values, -1); > + > +#ignore lines not being added > + if ($line=~/^[^\+]/) {next;} > + > +# TEST: allow direct testing of the type matcher. > + if ($dbg_type) { > + if ($line =~ /^.\s*$Declare\s*$/) { > + ERROR("TEST_TYPE", > + "TEST: is type\n" . $herecurr); > + } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { > + ERROR("TEST_NOT_TYPE", > + "TEST: is not type ($1 is)\n". $herecurr); > + } > + next; > + } > +# TEST: allow direct testing of the attribute matcher. > + if ($dbg_attr) { > + if ($line =~ /^.\s*$Modifier\s*$/) { > + ERROR("TEST_ATTR", > + "TEST: is attr\n" . $herecurr); > + } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { > + ERROR("TEST_NOT_ATTR", > + "TEST: is not attr ($1 is)\n". $herecurr); > + } > + next; > + } > + > +# check for initialisation to aggregates open brace on the next line > + if ($line =~ /^.\s*{/ && > + $prevline =~ /(?:^|[^=])=\s*$/) { > + ERROR("OPEN_BRACE", > + "that open brace { should be on the previous line\n" . $hereprev); > + } > + > +# > +# Checks which are anchored on the added line. > +# > + > +# check for malformed paths in #include statements (uses RAW line) > + if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { > + my $path = $1; > + if ($path =~ m{//}) { > + ERROR("MALFORMED_INCLUDE", > + "malformed #include filename\n" . $herecurr); > + } > + if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { > + ERROR("UAPI_INCLUDE", > + "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); > + } > + } > + > +# no C99 // comments > + if ($line =~ m{//}) { > + ERROR("C99_COMMENTS", > + "do not use C99 // comments\n" . $herecurr); > + } > + # Remove C99 comments. > + $line =~ s@//.*@@; > + $opline =~ s@//.*@@; > + > +# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider > +# the whole statement. > +#print "APW <$lines[$realline_next - 1]>\n"; > + if (defined $realline_next && > + exists $lines[$realline_next - 1] && > + !defined $suppress_export{$realline_next} && > + ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || > + $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { > + # Handle definitions which produce identifiers with > + # a prefix: > + # XXX(foo); > + # EXPORT_SYMBOL(something_foo); > + my $name = $1; > + if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && > + $name =~ /^${Ident}_$2/) { > +#print "FOO C name<$name>\n"; > + $suppress_export{$realline_next} = 1; > + > + } elsif ($stat !~ /(?: > + \n.}\s*$| > + ^.DEFINE_$Ident\(\Q$name\E\)| > + ^.DECLARE_$Ident\(\Q$name\E\)| > + ^.LIST_HEAD\(\Q$name\E\)| > + ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| > + \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() > + )/x) { > +#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; > + $suppress_export{$realline_next} = 2; > + } else { > + $suppress_export{$realline_next} = 1; > + } > + } > + if (!defined $suppress_export{$linenr} && > + $prevline =~ /^.\s*$/ && > + ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || > + $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { > +#print "FOO B <$lines[$linenr - 1]>\n"; > + $suppress_export{$linenr} = 2; > + } > + if (defined $suppress_export{$linenr} && > + $suppress_export{$linenr} == 2) { > + WARN("EXPORT_SYMBOL", > + "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); > + } > + > +# check for global initialisers. > + if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) { > + ERROR("GLOBAL_INITIALISERS", > + "do not initialise globals to 0 or NULL\n" . > + $herecurr); > + } > +# check for static initialisers. > + if ($line =~ /\bstatic\s.*=\s*(0|NULL|false)\s*;/) { > + ERROR("INITIALISED_STATIC", > + "do not initialise statics to 0 or NULL\n" . > + $herecurr); > + } > + > +# check for static const char * arrays. > + if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { > + WARN("STATIC_CONST_CHAR_ARRAY", > + "static const char * array should probably be static const char * const\n" . > + $herecurr); > + } > + > +# check for static char foo[] = "bar" declarations. > + if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { > + WARN("STATIC_CONST_CHAR_ARRAY", > + "static char array declaration should probably be static const char\n" . > + $herecurr); > + } > + > +# check for declarations of struct pci_device_id > + if ($line =~ /\bstruct\s+pci_device_id\s+\w+\s*\[\s*\]\s*\=\s*\{/) { > + WARN("DEFINE_PCI_DEVICE_TABLE", > + "Use DEFINE_PCI_DEVICE_TABLE for struct pci_device_id\n" . $herecurr); > + } > + > +# check for new typedefs, only function parameters and sparse annotations > +# make sense. > + if ($line =~ /\btypedef\s/ && > + $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && > + $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && > + $line !~ /\b$typeTypedefs\b/ && > + $line !~ /\b__bitwise(?:__|)\b/) { > + WARN("NEW_TYPEDEFS", > + "do not add new typedefs\n" . $herecurr); > + } > + > +# * goes on variable not on type > + # (char*[ const]) > + while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { > + #print "AA<$1>\n"; > + my ($from, $to) = ($2, $2); > + > + # Should start with a space. > + $to =~ s/^(\S)/ $1/; > + # Should not end with a space. > + $to =~ s/\s+$//; > + # '*'s should not have spaces between. > + while ($to =~ s/\*\s+\*/\*\*/) { > + } > + > + #print "from<$from> to<$to>\n"; > + if ($from ne $to) { > + ERROR("POINTER_LOCATION", > + "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr); > + } > + } > + while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { > + #print "BB<$1>\n"; > + my ($from, $to, $ident) = ($2, $2, $3); > + > + # Should start with a space. > + $to =~ s/^(\S)/ $1/; > + # Should not end with a space. > + $to =~ s/\s+$//; > + # '*'s should not have spaces between. > + while ($to =~ s/\*\s+\*/\*\*/) { > + } > + # Modifiers should have spaces. > + $to =~ s/(\b$Modifier$)/$1 /; > + > + #print "from<$from> to<$to> ident<$ident>\n"; > + if ($from ne $to && $ident !~ /^$Modifier$/) { > + ERROR("POINTER_LOCATION", > + "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr); > + } > + } > + > +# # no BUG() or BUG_ON() > +# if ($line =~ /\b(BUG|BUG_ON)\b/) { > +# print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n"; > +# print "$herecurr"; > +# $clean = 0; > +# } > + > + if ($line =~ /\bLINUX_VERSION_CODE\b/) { > + WARN("LINUX_VERSION_CODE", > + "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); > + } > + > +# check for uses of printk_ratelimit > + if ($line =~ /\bprintk_ratelimit\s*\(/) { > + WARN("PRINTK_RATELIMITED", > +"Prefer printk_ratelimited or pr__ratelimited to printk_ratelimit\n" . $herecurr); > + } > + > +# printk should use KERN_* levels. Note that follow on printk's on the > +# same line do not need a level, so we use the current block context > +# to try and find and validate the current printk. In summary the current > +# printk includes all preceding printk's which have no newline on the end. > +# we assume the first bad printk is the one to report. > + if ($line =~ /\bprintk\((?!KERN_)\s*"/) { > + my $ok = 0; > + for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { > + #print "CHECK<$lines[$ln - 1]\n"; > + # we have a preceding printk if it ends > + # with "\n" ignore it, else it is to blame > + if ($lines[$ln - 1] =~ m{\bprintk\(}) { > + if ($rawlines[$ln - 1] !~ m{\\n"}) { > + $ok = 1; > + } > + last; > + } > + } > + if ($ok == 0) { > + WARN("PRINTK_WITHOUT_KERN_LEVEL", > + "printk() should include KERN_ facility level\n" . $herecurr); > + } > + } > + > + if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { > + my $orig = $1; > + my $level = lc($orig); > + $level = "warn" if ($level eq "warning"); > + my $level2 = $level; > + $level2 = "dbg" if ($level eq "debug"); > + WARN("PREFER_PR_LEVEL", > + "Prefer netdev_$level2(netdev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); > + } > + > + if ($line =~ /\bpr_warning\s*\(/) { > + WARN("PREFER_PR_LEVEL", > + "Prefer pr_warn(... to pr_warning(...\n" . $herecurr); > + } > + > +# function brace can't be on same line, except for #defines of do while, > +# or if closed on same line > + if (($line=~/$Type\s*$Ident\(.*\).*\s{/) and > + !($line=~/\#\s*define.*do\s{/) and !($line=~/}/)) { > + ERROR("OPEN_BRACE", > + "open brace '{' following function declarations go on the next line\n" . $herecurr); > + } > + > +# open braces for enum, union and struct go on the same line. > + if ($line =~ /^.\s*{/ && > + $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { > + ERROR("OPEN_BRACE", > + "open brace '{' following $1 go on the same line\n" . $hereprev); > + } > + > +# missing space after union, struct or enum definition > + if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?(?:\s+$Ident)?[=\{]/) { > + WARN("SPACING", > + "missing space after $1 definition\n" . $herecurr); > + } > + > +# check for spacing round square brackets; allowed: > +# 1. with a type on the left -- int [] a; > +# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, > +# 3. inside a curly brace -- = { [0...10] = 5 } > + while ($line =~ /(.*?\s)\[/g) { > + my ($where, $prefix) = ($-[1], $1); > + if ($prefix !~ /$Type\s+$/ && > + ($where != 0 || $prefix !~ /^.\s+$/) && > + $prefix !~ /[{,]\s+$/) { > + ERROR("BRACKET_SPACE", > + "space prohibited before open square bracket '['\n" . $herecurr); > + } > + } > + > +# check for spaces between functions and their parentheses. > + while ($line =~ /($Ident)\s+\(/g) { > + my $name = $1; > + my $ctx_before = substr($line, 0, $-[1]); > + my $ctx = "$ctx_before$name"; > + > + # Ignore those directives where spaces _are_ permitted. > + if ($name =~ /^(?: > + if|for|while|switch|return|case| > + volatile|__volatile__| > + __attribute__|format|__extension__| > + asm|__asm__)$/x) > + { > + > + # cpp #define statements have non-optional spaces, ie > + # if there is a space between the name and the open > + # parenthesis it is simply not a parameter group. > + } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { > + > + # cpp #elif statement condition may start with a ( > + } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { > + > + # If this whole things ends with a type its most > + # likely a typedef for a function. > + } elsif ($ctx =~ /$Type$/) { > + > + } else { > + WARN("SPACING", > + "space prohibited between function name and open parenthesis '('\n" . $herecurr); > + } > + } > + > +# check for whitespace before a non-naked semicolon > + if ($line =~ /^\+.*\S\s+;/) { > + CHK("SPACING", > + "space prohibited before semicolon\n" . $herecurr); > + } > + > +# Check operator spacing. > + if (!($line=~/\#\s*include/)) { > + my $ops = qr{ > + <<=|>>=|<=|>=|==|!=| > + \+=|-=|\*=|\/=|%=|\^=|\|=|&=| > + =>|->|<<|>>|<|>|=|!|~| > + &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| > + \?|: > + }x; > + my @elements = split(/($ops|;)/, $opline); > + my $off = 0; > + > + my $blank = copy_spacing($opline); > + > + for (my $n = 0; $n < $#elements; $n += 2) { > + $off += length($elements[$n]); > + > + # Pick up the preceding and succeeding characters. > + my $ca = substr($opline, 0, $off); > + my $cc = ''; > + if (length($opline) >= ($off + length($elements[$n + 1]))) { > + $cc = substr($opline, $off + length($elements[$n + 1])); > + } > + my $cb = "$ca$;$cc"; > + > + my $a = ''; > + $a = 'V' if ($elements[$n] ne ''); > + $a = 'W' if ($elements[$n] =~ /\s$/); > + $a = 'C' if ($elements[$n] =~ /$;$/); > + $a = 'B' if ($elements[$n] =~ /(\[|\()$/); > + $a = 'O' if ($elements[$n] eq ''); > + $a = 'E' if ($ca =~ /^\s*$/); > + > + my $op = $elements[$n + 1]; > + > + my $c = ''; > + if (defined $elements[$n + 2]) { > + $c = 'V' if ($elements[$n + 2] ne ''); > + $c = 'W' if ($elements[$n + 2] =~ /^\s/); > + $c = 'C' if ($elements[$n + 2] =~ /^$;/); > + $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); > + $c = 'O' if ($elements[$n + 2] eq ''); > + $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); > + } else { > + $c = 'E'; > + } > + > + my $ctx = "${a}x${c}"; > + > + my $at = "(ctx:$ctx)"; > + > + my $ptr = substr($blank, 0, $off) . "^"; > + my $hereptr = "$hereline$ptr\n"; > + > + # Pull out the value of this operator. > + my $op_type = substr($curr_values, $off + 1, 1); > + > + # Get the full operator variant. > + my $opv = $op . substr($curr_vars, $off, 1); > + > + # Ignore operators passed as parameters. > + if ($op_type ne 'V' && > + $ca =~ /\s$/ && $cc =~ /^\s*,/) { > + > +# # Ignore comments > +# } elsif ($op =~ /^$;+$/) { > + > + # ; should have either the end of line or a space or \ after it > + } elsif ($op eq ';') { > + if ($ctx !~ /.x[WEBC]/ && > + $cc !~ /^\\/ && $cc !~ /^;/) { > + ERROR("SPACING", > + "space required after that '$op' $at\n" . $hereptr); > + } > + > + # // is a comment > + } elsif ($op eq '//') { > + > + # No spaces for: > + # -> > + # : when part of a bitfield > + } elsif ($op eq '->' || $opv eq ':B') { > + if ($ctx =~ /Wx.|.xW/) { > + ERROR("SPACING", > + "spaces prohibited around that '$op' $at\n" . $hereptr); > + } > + > + # , must have a space on the right. > + } elsif ($op eq ',') { > + if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { > + ERROR("SPACING", > + "space required after that '$op' $at\n" . $hereptr); > + } > + > + # '*' as part of a type definition -- reported already. > + } elsif ($opv eq '*_') { > + #warn "'*' is part of type\n"; > + > + # unary operators should have a space before and > + # none after. May be left adjacent to another > + # unary operator, or a cast > + } elsif ($op eq '!' || $op eq '~' || > + $opv eq '*U' || $opv eq '-U' || > + $opv eq '&U' || $opv eq '&&U') { > + if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { > + ERROR("SPACING", > + "space required before that '$op' $at\n" . $hereptr); > + } > + if ($op eq '*' && $cc =~/\s*$Modifier\b/) { > + # A unary '*' may be const > + > + } elsif ($ctx =~ /.xW/) { > + ERROR("SPACING", > + "space prohibited after that '$op' $at\n" . $hereptr); > + } > + > + # unary ++ and unary -- are allowed no space on one side. > + } elsif ($op eq '++' or $op eq '--') { > + if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { > + ERROR("SPACING", > + "space required one side of that '$op' $at\n" . $hereptr); > + } > + if ($ctx =~ /Wx[BE]/ || > + ($ctx =~ /Wx./ && $cc =~ /^;/)) { > + ERROR("SPACING", > + "space prohibited before that '$op' $at\n" . $hereptr); > + } > + if ($ctx =~ /ExW/) { > + ERROR("SPACING", > + "space prohibited after that '$op' $at\n" . $hereptr); > + } > + > + > + # << and >> may either have or not have spaces both sides > + } elsif ($op eq '<<' or $op eq '>>' or > + $op eq '&' or $op eq '^' or $op eq '|' or > + $op eq '+' or $op eq '-' or > + $op eq '*' or $op eq '/' or > + $op eq '%') > + { > + if ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { > + ERROR("SPACING", > + "need consistent spacing around '$op' $at\n" . > + $hereptr); > + } > + > + # A colon needs no spaces before when it is > + # terminating a case value or a label. > + } elsif ($opv eq ':C' || $opv eq ':L') { > + if ($ctx =~ /Wx./) { > + ERROR("SPACING", > + "space prohibited before that '$op' $at\n" . $hereptr); > + } > + > + # All the others need spaces both sides. > + } elsif ($ctx !~ /[EWC]x[CWE]/) { > + my $ok = 0; > + > + # Ignore email addresses > + if (($op eq '<' && > + $cc =~ /^\S+\@\S+>/) || > + ($op eq '>' && > + $ca =~ /<\S+\@\S+$/)) > + { > + $ok = 1; > + } > + > + # Ignore ?: > + if (($opv eq ':O' && $ca =~ /\?$/) || > + ($op eq '?' && $cc =~ /^:/)) { > + $ok = 1; > + } > + > + if ($ok == 0) { > + ERROR("SPACING", > + "spaces required around that '$op' $at\n" . $hereptr); > + } > + } > + $off += length($elements[$n + 1]); > + } > + } > + > +# check for multiple assignments > + if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { > + CHK("MULTIPLE_ASSIGNMENTS", > + "multiple assignments should be avoided\n" . $herecurr); > + } > + > +## # check for multiple declarations, allowing for a function declaration > +## # continuation. > +## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && > +## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { > +## > +## # Remove any bracketed sections to ensure we do not > +## # falsly report the parameters of functions. > +## my $ln = $line; > +## while ($ln =~ s/\([^\(\)]*\)//g) { > +## } > +## if ($ln =~ /,/) { > +## WARN("MULTIPLE_DECLARATION", > +## "declaring multiple variables together should be avoided\n" . $herecurr); > +## } > +## } > + > +#need space before brace following if, while, etc > + if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) || > + $line =~ /do{/) { > + ERROR("SPACING", > + "space required before the open brace '{'\n" . $herecurr); > + } > + > +# closing brace should have a space following it when it has anything > +# on the line > + if ($line =~ /}(?!(?:,|;|\)))\S/) { > + ERROR("SPACING", > + "space required after that close brace '}'\n" . $herecurr); > + } > + > +# check spacing on square brackets > + if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { > + ERROR("SPACING", > + "space prohibited after that open square bracket '['\n" . $herecurr); > + } > + if ($line =~ /\s\]/) { > + ERROR("SPACING", > + "space prohibited before that close square bracket ']'\n" . $herecurr); > + } > + > +# check spacing on parentheses > + if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && > + $line !~ /for\s*\(\s+;/) { > + ERROR("SPACING", > + "space prohibited after that open parenthesis '('\n" . $herecurr); > + } > + if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && > + $line !~ /for\s*\(.*;\s+\)/ && > + $line !~ /:\s+\)/) { > + ERROR("SPACING", > + "space prohibited before that close parenthesis ')'\n" . $herecurr); > + } > + > +#goto labels aren't indented, allow a single space however > + if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and > + !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { > + WARN("INDENTED_LABEL", > + "labels should not be indented\n" . $herecurr); > + } > + > +# Return is not a function. > + if (defined($stat) && $stat =~ /^.\s*return(\s*)(\(.*);/s) { > + my $spacing = $1; > + my $value = $2; > + > + # Flatten any parentheses > + $value =~ s/\(/ \(/g; > + $value =~ s/\)/\) /g; > + while ($value =~ s/\[[^\[\]]*\]/1/ || > + $value !~ /(?:$Ident|-?$Constant)\s* > + $Compare\s* > + (?:$Ident|-?$Constant)/x && > + $value =~ s/\([^\(\)]*\)/1/) { > + } > +#print "value<$value>\n"; > + if ($value =~ /^\s*(?:$Ident|-?$Constant)\s*$/) { > + ERROR("RETURN_PARENTHESES", > + "return is not a function, parentheses are not required\n" . $herecurr); > + > + } elsif ($spacing !~ /\s+/) { > + ERROR("SPACING", > + "space required before the open parenthesis '('\n" . $herecurr); > + } > + } > +# Return of what appears to be an errno should normally be -'ve > + if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) { > + my $name = $1; > + if ($name ne 'EOF' && $name ne 'ERROR') { > + WARN("USE_NEGATIVE_ERRNO", > + "return of an errno should typically be -ve (return -$1)\n" . $herecurr); > + } > + } > + > +# Need a space before open parenthesis after if, while etc > + if ($line=~/\b(if|while|for|switch)\(/) { > + ERROR("SPACING", "space required before the open parenthesis '('\n" . $herecurr); > + } > + > +# Check for illegal assignment in if conditional -- and check for trailing > +# statements after the conditional. > + if ($line =~ /do\s*(?!{)/) { > + ($stat, $cond, $line_nr_next, $remain_next, $off_next) = > + ctx_statement_block($linenr, $realcnt, 0) > + if (!defined $stat); > + my ($stat_next) = ctx_statement_block($line_nr_next, > + $remain_next, $off_next); > + $stat_next =~ s/\n./\n /g; > + ##print "stat<$stat> stat_next<$stat_next>\n"; > + > + if ($stat_next =~ /^\s*while\b/) { > + # If the statement carries leading newlines, > + # then count those as offsets. > + my ($whitespace) = > + ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); > + my $offset = > + statement_rawlines($whitespace) - 1; > + > + $suppress_whiletrailers{$line_nr_next + > + $offset} = 1; > + } > + } > + if (!defined $suppress_whiletrailers{$linenr} && > + $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { > + my ($s, $c) = ($stat, $cond); > + > + if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { > + ERROR("ASSIGN_IN_IF", > + "do not use assignment in if condition\n" . $herecurr); > + } > + > + # Find out what is on the end of the line after the > + # conditional. > + substr($s, 0, length($c), ''); > + $s =~ s/\n.*//g; > + $s =~ s/$;//g; # Remove any comments > + if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && > + $c !~ /}\s*while\s*/) > + { > + # Find out how long the conditional actually is. > + my @newlines = ($c =~ /\n/gs); > + my $cond_lines = 1 + $#newlines; > + my $stat_real = ''; > + > + $stat_real = raw_line($linenr, $cond_lines) > + . "\n" if ($cond_lines); > + if (defined($stat_real) && $cond_lines > 1) { > + $stat_real = "[...]\n$stat_real"; > + } > + > + ERROR("TRAILING_STATEMENTS", > + "trailing statements should be on next line\n" . $herecurr . $stat_real); > + } > + } > + > +# Check for bitwise tests written as boolean > + if ($line =~ / > + (?: > + (?:\[|\(|\&\&|\|\|) > + \s*0[xX][0-9]+\s* > + (?:\&\&|\|\|) > + | > + (?:\&\&|\|\|) > + \s*0[xX][0-9]+\s* > + (?:\&\&|\|\||\)|\]) > + )/x) > + { > + WARN("HEXADECIMAL_BOOLEAN_TEST", > + "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); > + } > + > +# if and else should not have general statements after it > + if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { > + my $s = $1; > + $s =~ s/$;//g; # Remove any comments > + if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { > + ERROR("TRAILING_STATEMENTS", > + "trailing statements should be on next line\n" . $herecurr); > + } > + } > +# if should not continue a brace > + if ($line =~ /}\s*if\b/) { > + ERROR("TRAILING_STATEMENTS", > + "trailing statements should be on next line\n" . > + $herecurr); > + } > +# case and default should not have general statements after them > + if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && > + $line !~ /\G(?: > + (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| > + \s*return\s+ > + )/xg) > + { > + ERROR("TRAILING_STATEMENTS", > + "trailing statements should be on next line\n" . $herecurr); > + } > + > + # Check for }else {, these must be at the same > + # indent level to be relevant to each other. > + if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and > + $previndent == $indent) { > + ERROR("ELSE_AFTER_BRACE", > + "else should follow close brace '}'\n" . $hereprev); > + } > + > + if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ and > + $previndent == $indent) { > + my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); > + > + # Find out what is on the end of the line after the > + # conditional. > + substr($s, 0, length($c), ''); > + $s =~ s/\n.*//g; > + > + if ($s =~ /^\s*;/) { > + ERROR("WHILE_AFTER_BRACE", > + "while should follow close brace '}'\n" . $hereprev); > + } > + } > + > +#CamelCase > + while ($line =~ m{($Constant|$Lval)}g) { > + my $var = $1; > + if ($var !~ /$Constant/ && > + $var =~ /[A-Z]\w*[a-z]|[a-z]\w*[A-Z]/ && > + !defined $camelcase{$var}) { > + $camelcase{$var} = 1; > + WARN("CAMELCASE", > + "Avoid CamelCase: <$var>\n" . $herecurr); > + } > + } > + > +#no spaces allowed after \ in define > + if ($line=~/\#\s*define.*\\\s$/) { > + WARN("WHITESPACE_AFTER_LINE_CONTINUATION", > + "Whitepspace after \\ makes next lines useless\n" . $herecurr); > + } > + > +#warn if is #included and is available (uses RAW line) > + if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\}) { > + my $file = "$1.h"; > + my $checkfile = "include/linux/$file"; > + if (-f "$root/$checkfile" && > + $realfile ne $checkfile && > + $1 !~ /$allowed_asm_includes/) > + { > + if ($realfile =~ m{^arch/}) { > + CHK("ARCH_INCLUDE_LINUX", > + "Consider using #include instead of \n" . $herecurr); > + } else { > + WARN("INCLUDE_LINUX", > + "Use #include instead of \n" . $herecurr); > + } > + } > + } > + > +# multi-statement macros should be enclosed in a do while loop, grab the > +# first statement and ensure its the whole macro if its not enclosed > +# in a known good container > + if ($realfile !~ m@/vmlinux.lds.h$@ && > + $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { > + my $ln = $linenr; > + my $cnt = $realcnt; > + my ($off, $dstat, $dcond, $rest); > + my $ctx = ''; > + ($dstat, $dcond, $ln, $cnt, $off) = > + ctx_statement_block($linenr, $realcnt, 0); > + $ctx = $dstat; > + #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; > + #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; > + > + $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//; > + $dstat =~ s/$;//g; > + $dstat =~ s/\\\n.//g; > + $dstat =~ s/^\s*//s; > + $dstat =~ s/\s*$//s; > + > + # Flatten any parentheses and braces > + while ($dstat =~ s/\([^\(\)]*\)/1/ || > + $dstat =~ s/\{[^\{\}]*\}/1/ || > + $dstat =~ s/\[[^\[\]]*\]/1/) > + { > + } > + > + # Flatten any obvious string concatentation. > + while ($dstat =~ s/("X*")\s*$Ident/$1/ || > + $dstat =~ s/$Ident\s*("X*")/$1/) > + { > + } > + > + my $exceptions = qr{ > + $Declare| > + module_param_named| > + MODULE_PARM_DESC| > + DECLARE_PER_CPU| > + DEFINE_PER_CPU| > + __typeof__\(| > + union| > + struct| > + \.$Ident\s*=\s*| > + ^\"|\"$ > + }x; > + #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; > + if ($dstat ne '' && > + $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), > + $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); > + $dstat !~ /^[!~-]?(?:$Ident|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo > + $dstat !~ /^'X'$/ && # character constants > + $dstat !~ /$exceptions/ && > + $dstat !~ /^\.$Ident\s*=/ && # .foo = > + $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) > + $dstat !~ /^for\s*$Constant$/ && # for (...) > + $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() > + $dstat !~ /^do\s*{/ && # do {... > + $dstat !~ /^\({/) # ({... > + { > + $ctx =~ s/\n*$//; > + my $herectx = $here . "\n"; > + my $cnt = statement_rawlines($ctx); > + > + for (my $n = 0; $n < $cnt; $n++) { > + $herectx .= raw_line($linenr, $n) . "\n"; > + } > + > + if ($dstat =~ /;/) { > + ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", > + "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); > + } else { > + ERROR("COMPLEX_MACRO", > + "Macros with complex values should be enclosed in parenthesis\n" . "$herectx"); > + } > + } > + > +# check for line continuations outside of #defines, preprocessor #, and asm > + > + } else { > + if ($prevline !~ /^..*\\$/ && > + $line !~ /^\+\s*\#.*\\$/ && # preprocessor > + $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm > + $line =~ /^\+.*\\$/) { > + WARN("LINE_CONTINUATIONS", > + "Avoid unnecessary line continuations\n" . $herecurr); > + } > + } > + > +# do {} while (0) macro tests: > +# single-statement macros do not need to be enclosed in do while (0) loop, > +# macro should not end with a semicolon > + if ($^V && $^V ge 5.10.0 && > + $realfile !~ m@/vmlinux.lds.h$@ && > + $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { > + my $ln = $linenr; > + my $cnt = $realcnt; > + my ($off, $dstat, $dcond, $rest); > + my $ctx = ''; > + ($dstat, $dcond, $ln, $cnt, $off) = > + ctx_statement_block($linenr, $realcnt, 0); > + $ctx = $dstat; > + > + $dstat =~ s/\\\n.//g; > + > + if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { > + my $stmts = $2; > + my $semis = $3; > + > + $ctx =~ s/\n*$//; > + my $cnt = statement_rawlines($ctx); > + my $herectx = $here . "\n"; > + > + for (my $n = 0; $n < $cnt; $n++) { > + $herectx .= raw_line($linenr, $n) . "\n"; > + } > + > + if (($stmts =~ tr/;/;/) == 1 && > + $stmts !~ /^\s*(if|while|for|switch)\b/) { > + WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", > + "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); > + } > + if (defined $semis && $semis ne "") { > + WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", > + "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); > + } > + } > + } > + > +# make sure symbols are always wrapped with VMLINUX_SYMBOL() ... > +# all assignments may have only one of the following with an assignment: > +# . > +# ALIGN(...) > +# VMLINUX_SYMBOL(...) > + if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) { > + WARN("MISSING_VMLINUX_SYMBOL", > + "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr); > + } > + > +# check for redundant bracing round if etc > + if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { > + my ($level, $endln, @chunks) = > + ctx_statement_full($linenr, $realcnt, 1); > + #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; > + #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; > + if ($#chunks > 0 && $level == 0) { > + my @allowed = (); > + my $allow = 0; > + my $seen = 0; > + my $herectx = $here . "\n"; > + my $ln = $linenr - 1; > + for my $chunk (@chunks) { > + my ($cond, $block) = @{$chunk}; > + > + # If the condition carries leading newlines, then count those as offsets. > + my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); > + my $offset = statement_rawlines($whitespace) - 1; > + > + $allowed[$allow] = 0; > + #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; > + > + # We have looked at and allowed this specific line. > + $suppress_ifbraces{$ln + $offset} = 1; > + > + $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; > + $ln += statement_rawlines($block) - 1; > + > + substr($block, 0, length($cond), ''); > + > + $seen++ if ($block =~ /^\s*{/); > + > + #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; > + if (statement_lines($cond) > 1) { > + #print "APW: ALLOWED: cond<$cond>\n"; > + $allowed[$allow] = 1; > + } > + if ($block =~/\b(?:if|for|while)\b/) { > + #print "APW: ALLOWED: block<$block>\n"; > + $allowed[$allow] = 1; > + } > + if (statement_block_size($block) > 1) { > + #print "APW: ALLOWED: lines block<$block>\n"; > + $allowed[$allow] = 1; > + } > + $allow++; > + } > + if ($seen) { > + my $sum_allowed = 0; > + foreach (@allowed) { > + $sum_allowed += $_; > + } > + if ($sum_allowed == 0) { > + WARN("BRACES", > + "braces {} are not necessary for any arm of this statement\n" . $herectx); > + } elsif ($sum_allowed != $allow && > + $seen != $allow) { > + CHK("BRACES", > + "braces {} should be used on all arms of this statement\n" . $herectx); > + } > + } > + } > + } > + if (!defined $suppress_ifbraces{$linenr - 1} && > + $line =~ /\b(if|while|for|else)\b/) { > + my $allowed = 0; > + > + # Check the pre-context. > + if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { > + #print "APW: ALLOWED: pre<$1>\n"; > + $allowed = 1; > + } > + > + my ($level, $endln, @chunks) = > + ctx_statement_full($linenr, $realcnt, $-[0]); > + > + # Check the condition. > + my ($cond, $block) = @{$chunks[0]}; > + #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; > + if (defined $cond) { > + substr($block, 0, length($cond), ''); > + } > + if (statement_lines($cond) > 1) { > + #print "APW: ALLOWED: cond<$cond>\n"; > + $allowed = 1; > + } > + if ($block =~/\b(?:if|for|while)\b/) { > + #print "APW: ALLOWED: block<$block>\n"; > + $allowed = 1; > + } > + if (statement_block_size($block) > 1) { > + #print "APW: ALLOWED: lines block<$block>\n"; > + $allowed = 1; > + } > + # Check the post-context. > + if (defined $chunks[1]) { > + my ($cond, $block) = @{$chunks[1]}; > + if (defined $cond) { > + substr($block, 0, length($cond), ''); > + } > + if ($block =~ /^\s*\{/) { > + #print "APW: ALLOWED: chunk-1 block<$block>\n"; > + $allowed = 1; > + } > + } > + if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { > + my $herectx = $here . "\n"; > + my $cnt = statement_rawlines($block); > + > + for (my $n = 0; $n < $cnt; $n++) { > + $herectx .= raw_line($linenr, $n) . "\n"; > + } > + > + WARN("BRACES", > + "braces {} are not necessary for single statement blocks\n" . $herectx); > + } > + } > + > +# check for unnecessary blank lines around braces > + if (($line =~ /^..*}\s*$/ && $prevline =~ /^.\s*$/)) { > + CHK("BRACES", > + "Blank lines aren't necessary before a close brace '}'\n" . $hereprev); > + } > + if (($line =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { > + CHK("BRACES", > + "Blank lines aren't necessary after an open brace '{'\n" . $hereprev); > + } > + > +# no volatiles please > + my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; > + if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { > + WARN("VOLATILE", > + "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); > + } > + > +# warn about #if 0 > + if ($line =~ /^.\s*\#\s*if\s+0\b/) { > + CHK("REDUNDANT_CODE", > + "if this code is redundant consider removing it\n" . > + $herecurr); > + } > + > +# check for needless "if () fn()" uses > + if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { > + my $expr = '\s*\(\s*' . quotemeta($1) . '\s*\)\s*;'; > + if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?)$expr/) { > + WARN('NEEDLESS_IF', > + "$1(NULL) is safe this check is probably not required\n" . $hereprev); > + } > + } > + > +# prefer usleep_range over udelay > + if ($line =~ /\budelay\s*\(\s*(\w+)\s*\)/) { > + # ignore udelay's < 10, however > + if (! (($1 =~ /(\d+)/) && ($1 < 10)) ) { > + CHK("USLEEP_RANGE", > + "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $line); > + } > + } > + > +# warn about unexpectedly long msleep's > + if ($line =~ /\bmsleep\s*\((\d+)\);/) { > + if ($1 < 20) { > + WARN("MSLEEP", > + "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $line); > + } > + } > + > +# warn about #ifdefs in C files > +# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { > +# print "#ifdef in C files should be avoided\n"; > +# print "$herecurr"; > +# $clean = 0; > +# } > + > +# warn about spacing in #ifdefs > + if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { > + ERROR("SPACING", > + "exactly one space required after that #$1\n" . $herecurr); > + } > + > +# check for spinlock_t definitions without a comment. > + if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || > + $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { > + my $which = $1; > + if (!ctx_has_comment($first_line, $linenr)) { > + CHK("UNCOMMENTED_DEFINITION", > + "$1 definition without comment\n" . $herecurr); > + } > + } > +# check for memory barriers without a comment. > + if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) { > + if (!ctx_has_comment($first_line, $linenr)) { > + CHK("MEMORY_BARRIER", > + "memory barrier without comment\n" . $herecurr); > + } > + } > +# check of hardware specific defines > + if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m at include/asm-@) { > + CHK("ARCH_DEFINES", > + "architecture specific defines should be avoided\n" . $herecurr); > + } > + > +# Check that the storage class is at the beginning of a declaration > + if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) { > + WARN("STORAGE_CLASS", > + "storage class should be at the beginning of the declaration\n" . $herecurr) > + } > + > +# check the location of the inline attribute, that it is between > +# storage class and type. > + if ($line =~ /\b$Type\s+$Inline\b/ || > + $line =~ /\b$Inline\s+$Storage\b/) { > + ERROR("INLINE_LOCATION", > + "inline keyword should sit between storage class and type\n" . $herecurr); > + } > + > +# Check for __inline__ and __inline, prefer inline > + if ($line =~ /\b(__inline__|__inline)\b/) { > + WARN("INLINE", > + "plain inline is preferred over $1\n" . $herecurr); > + } > + > +# Check for __attribute__ packed, prefer __packed > + if ($line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { > + WARN("PREFER_PACKED", > + "__packed is preferred over __attribute__((packed))\n" . $herecurr); > + } > + > +# Check for __attribute__ aligned, prefer __aligned > + if ($line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { > + WARN("PREFER_ALIGNED", > + "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); > + } > + > +# Check for __attribute__ format(printf, prefer __printf > + if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { > + WARN("PREFER_PRINTF", > + "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr); > + } > + > +# Check for __attribute__ format(scanf, prefer __scanf > + if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { > + WARN("PREFER_SCANF", > + "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr); > + } > + > +# check for sizeof(&) > + if ($line =~ /\bsizeof\s*\(\s*\&/) { > + WARN("SIZEOF_ADDRESS", > + "sizeof(& should be avoided\n" . $herecurr); > + } > + > +# check for sizeof without parenthesis > + if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { > + WARN("SIZEOF_PARENTHESIS", > + "sizeof $1 should be sizeof($1)\n" . $herecurr); > + } > + > +# check for line continuations in quoted strings with odd counts of " > + if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) { > + WARN("LINE_CONTINUATIONS", > + "Avoid line continuations in quoted strings\n" . $herecurr); > + } > + > +# check for struct spinlock declarations > + if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { > + WARN("USE_SPINLOCK_T", > + "struct spinlock should be spinlock_t\n" . $herecurr); > + } > + > +# Check for misused memsets > + if ($^V && $^V ge 5.10.0 && > + defined $stat && > + $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) { > + > + my $ms_addr = $2; > + my $ms_val = $7; > + my $ms_size = $12; > + > + if ($ms_size =~ /^(0x|)0$/i) { > + ERROR("MEMSET", > + "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); > + } elsif ($ms_size =~ /^(0x|)1$/i) { > + WARN("MEMSET", > + "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); > + } > + } > + > +# typecasts on min/max could be min_t/max_t > + if ($^V && $^V ge 5.10.0 && > + defined $stat && > + $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { > + if (defined $2 || defined $7) { > + my $call = $1; > + my $cast1 = deparenthesize($2); > + my $arg1 = $3; > + my $cast2 = deparenthesize($7); > + my $arg2 = $8; > + my $cast; > + > + if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { > + $cast = "$cast1 or $cast2"; > + } elsif ($cast1 ne "") { > + $cast = $cast1; > + } else { > + $cast = $cast2; > + } > + WARN("MINMAX", > + "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); > + } > + } > + > +# check usleep_range arguments > + if ($^V && $^V ge 5.10.0 && > + defined $stat && > + $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { > + my $min = $1; > + my $max = $7; > + if ($min eq $max) { > + WARN("USLEEP_RANGE", > + "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); > + } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && > + $min > $max) { > + WARN("USLEEP_RANGE", > + "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); > + } > + } > + > +# check for new externs in .c files. > + if ($realfile =~ /\.c$/ && defined $stat && > + $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) > + { > + my $function_name = $1; > + my $paren_space = $2; > + > + my $s = $stat; > + if (defined $cond) { > + substr($s, 0, length($cond), ''); > + } > + if ($s =~ /^\s*;/ && > + $function_name ne 'uninitialized_var') > + { > + WARN("AVOID_EXTERNS", > + "externs should be avoided in .c files\n" . $herecurr); > + } > + > + if ($paren_space =~ /\n/) { > + WARN("FUNCTION_ARGUMENTS", > + "arguments for function declarations should follow identifier\n" . $herecurr); > + } > + > + } elsif ($realfile =~ /\.c$/ && defined $stat && > + $stat =~ /^.\s*extern\s+/) > + { > + WARN("AVOID_EXTERNS", > + "externs should be avoided in .c files\n" . $herecurr); > + } > + > +# checks for new __setup's > + if ($rawline =~ /\b__setup\("([^"]*)"/) { > + my $name = $1; > + > + if (!grep(/$name/, @setup_docs)) { > + CHK("UNDOCUMENTED_SETUP", > + "__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr); > + } > + } > + > +# check for pointless casting of kmalloc return > + if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) { > + WARN("UNNECESSARY_CASTS", > + "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); > + } > + > +# check for multiple semicolons > + if ($line =~ /;\s*;\s*$/) { > + WARN("ONE_SEMICOLON", > + "Statements terminations use 1 semicolon\n" . $herecurr); > + } > + > +# check for switch/default statements without a break; > + if ($^V && $^V ge 5.10.0 && > + defined $stat && > + $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { > + my $ctx = ''; > + my $herectx = $here . "\n"; > + my $cnt = statement_rawlines($stat); > + for (my $n = 0; $n < $cnt; $n++) { > + $herectx .= raw_line($linenr, $n) . "\n"; > + } > + WARN("DEFAULT_NO_BREAK", > + "switch default: should use break\n" . $herectx); > + } > + > +# check for gcc specific __FUNCTION__ > + if ($line =~ /__FUNCTION__/) { > + WARN("USE_FUNC", > + "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr); > + } > + > +# check for use of yield() > + if ($line =~ /\byield\s*\(\s*\)/) { > + WARN("YIELD", > + "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); > + } > + > +# check for semaphores initialized locked > + if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { > + WARN("CONSIDER_COMPLETION", > + "consider using a completion\n" . $herecurr); > + } > + > +# recommend kstrto* over simple_strto* and strict_strto* > + if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { > + WARN("CONSIDER_KSTRTO", > + "$1 is obsolete, use k$3 instead\n" . $herecurr); > + } > + > +# check for __initcall(), use device_initcall() explicitly please > + if ($line =~ /^.\s*__initcall\s*\(/) { > + WARN("USE_DEVICE_INITCALL", > + "please use device_initcall() instead of __initcall()\n" . $herecurr); > + } > + > +# check for various ops structs, ensure they are const. > + my $struct_ops = qr{acpi_dock_ops| > + address_space_operations| > + backlight_ops| > + block_device_operations| > + dentry_operations| > + dev_pm_ops| > + dma_map_ops| > + extent_io_ops| > + file_lock_operations| > + file_operations| > + hv_ops| > + ide_dma_ops| > + intel_dvo_dev_ops| > + item_operations| > + iwl_ops| > + kgdb_arch| > + kgdb_io| > + kset_uevent_ops| > + lock_manager_operations| > + microcode_ops| > + mtrr_ops| > + neigh_ops| > + nlmsvc_binding| > + pci_raw_ops| > + pipe_buf_operations| > + platform_hibernation_ops| > + platform_suspend_ops| > + proto_ops| > + rpc_pipe_ops| > + seq_operations| > + snd_ac97_build_ops| > + soc_pcmcia_socket_ops| > + stacktrace_ops| > + sysfs_ops| > + tty_operations| > + usb_mon_operations| > + wd_ops}x; > + if ($line !~ /\bconst\b/ && > + $line =~ /\bstruct\s+($struct_ops)\b/) { > + WARN("CONST_STRUCT", > + "struct $1 should normally be const\n" . > + $herecurr); > + } > + > +# use of NR_CPUS is usually wrong > +# ignore definitions of NR_CPUS and usage to define arrays as likely right > + if ($line =~ /\bNR_CPUS\b/ && > + $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && > + $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && > + $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && > + $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && > + $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) > + { > + WARN("NR_CPUS", > + "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); > + } > + > +# check for %L{u,d,i} in strings > + my $string; > + while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { > + $string = substr($rawline, $-[1], $+[1] - $-[1]); > + $string =~ s/%%/__/g; > + if ($string =~ /(? + WARN("PRINTF_L", > + "\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr); > + last; > + } > + } > + > +# whine mightly about in_atomic > + if ($line =~ /\bin_atomic\s*\(/) { > + if ($realfile =~ m@^drivers/@) { > + ERROR("IN_ATOMIC", > + "do not use in_atomic in drivers\n" . $herecurr); > + } elsif ($realfile !~ m@^kernel/@) { > + WARN("IN_ATOMIC", > + "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); > + } > + } > + > +# check for lockdep_set_novalidate_class > + if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || > + $line =~ /__lockdep_no_validate__\s*\)/ ) { > + if ($realfile !~ m@^kernel/lockdep@ && > + $realfile !~ m@^include/linux/lockdep@ && > + $realfile !~ m@^drivers/base/core@) { > + ERROR("LOCKDEP", > + "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); > + } > + } > + > + if ($line =~ /debugfs_create_file.*S_IWUGO/ || > + $line =~ /DEVICE_ATTR.*S_IWUGO/ ) { > + WARN("EXPORTED_WORLD_WRITABLE", > + "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); > + } > + } > + > + # If we have no input at all, then there is nothing to report on > + # so just keep quiet. > + if ($#rawlines == -1) { > + exit(0); > + } > + > + # In mailback mode only produce a report in the negative, for > + # things that appear to be patches. > + if ($mailback && ($clean == 1 || !$is_patch)) { > + exit(0); > + } > + > + # This is not a patch, and we are are in 'no-patch' mode so > + # just keep quiet. > + if (!$chk_patch && !$is_patch) { > + exit(0); > + } > + > + if (!$is_patch) { > + ERROR("NOT_UNIFIED_DIFF", > + "Does not appear to be a unified-diff format patch\n"); > + } > + if ($is_patch && $chk_signoff && $signoff == 0) { > + ERROR("MISSING_SIGN_OFF", > + "Missing Signed-off-by: line(s)\n"); > + } > + > + print report_dump(); > + if ($summary && !($clean == 1 && $quiet == 1)) { > + print "$filename " if ($summary_file); > + print "total: $cnt_error errors, $cnt_warn warnings, " . > + (($check)? "$cnt_chk checks, " : "") . > + "$cnt_lines lines checked\n"; > + print "\n" if ($quiet == 0); > + } > + > + if ($quiet == 0) { > + > + if ($^V lt 5.10.0) { > + print("NOTE: perl $^V is not modern enough to detect all possible issues.\n"); > + print("An upgrade to at least perl v5.10.0 is suggested.\n\n"); > + } > + > + # If there were whitespace errors which cleanpatch can fix > + # then suggest that. > + if ($rpt_cleaners) { > + print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n"; > + print " scripts/cleanfile\n\n"; > + $rpt_cleaners = 0; > + } > + } > + > + if ($quiet == 0 && keys %ignore_type) { > + print "NOTE: Ignored message types:"; > + foreach my $ignore (sort keys %ignore_type) { > + print " $ignore"; > + } > + print "\n\n"; > + } > + > + if ($clean == 1 && $quiet == 0) { > + print "$vname has no obvious style problems and is ready for submission.\n" > + } > + if ($clean == 0 && $quiet == 0) { > + print << "EOM"; > +$vname has style problems, please review. > + > +If any of these errors are false positives, please report > +them to the maintainer, see CHECKPATCH in MAINTAINERS. > +EOM > + } > + > + return $clean; > +} From mathieu.desnoyers at efficios.com Thu Jan 10 13:12:33 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 10 Jan 2013 13:12:33 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Atomically update relayd stream and session id In-Reply-To: <1357839948-25490-1-git-send-email-dgoulet@efficios.com> References: <1357839948-25490-1-git-send-email-dgoulet@efficios.com> Message-ID: <20130110181233.GA10684@Krystal> * David Goulet (dgoulet at efficios.com) wrote: > Improve protection to the variables where the uatomic_add_return() call > does a volatile access and returns the value atomically incremented. > > Enclose that in two new functions, one for each id, which helps with the > code semantic and brings a single call site for the value update making > the code easier to scale and understand when adding contention to those > variables. > > Signed-off-by: David Goulet This won't build on 32-bit architectures, due to lack of 64-bit atomic ops. Thanks, Mathieu > --- > src/bin/lttng-relayd/lttng-relayd.h | 19 +++++++++++++++++++ > src/bin/lttng-relayd/main.c | 9 +++++---- > 2 files changed, 24 insertions(+), 4 deletions(-) > > diff --git a/src/bin/lttng-relayd/lttng-relayd.h b/src/bin/lttng-relayd/lttng-relayd.h > index edd32d6..b2566a1 100644 > --- a/src/bin/lttng-relayd/lttng-relayd.h > +++ b/src/bin/lttng-relayd/lttng-relayd.h > @@ -23,6 +23,9 @@ > #include > #include > > +extern uint64_t relayd_last_stream_id; > +extern uint64_t relayd_last_session_id; > + > /* > * Queue used to enqueue relay requests > */ > @@ -81,4 +84,20 @@ struct relay_command { > unsigned int version_check_done:1; > }; > > +/* > + * Atomically increment the id and return the next stream id. > + */ > +static inline uint64_t relayd_get_next_stream_id(void) > +{ > + return (uint64_t) uatomic_add_return(&relayd_last_stream_id, 1); > +} > + > +/* > + * Atomically increment the id and return the next session id. > + */ > +static inline uint64_t relayd_get_next_session_id(void) > +{ > + return (uint64_t) uatomic_add_return(&relayd_last_session_id, 1); > +} > + > #endif /* LTTNG_RELAYD_H */ > diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c > index 6627310..a042ce6 100644 > --- a/src/bin/lttng-relayd/main.c > +++ b/src/bin/lttng-relayd/main.c > @@ -82,8 +82,9 @@ static pthread_t listener_thread; > static pthread_t dispatcher_thread; > static pthread_t worker_thread; > > -static uint64_t last_relay_stream_id; > -static uint64_t last_relay_session_id; > +/* Declared extern in lttng-relayd.h */ > +uint64_t relayd_last_stream_id; > +uint64_t relayd_last_session_id; > > /* > * Relay command queue. > @@ -968,7 +969,7 @@ int relay_create_session(struct lttcomm_relayd_hdr *recv_hdr, > goto error; > } > > - session->id = ++last_relay_session_id; > + session->id = relayd_get_next_session_id(); > session->sock = cmd->sock; > cmd->session = session; > > @@ -1032,7 +1033,7 @@ int relay_add_stream(struct lttcomm_relayd_hdr *recv_hdr, > } > > rcu_read_lock(); > - stream->stream_handle = ++last_relay_stream_id; > + stream->stream_handle = relayd_get_next_stream_id(); > stream->prev_seq = -1ULL; > stream->session = session; > > -- > 1.7.10.4 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Thu Jan 10 13:17:58 2013 From: dgoulet at efficios.com (David Goulet) Date: Thu, 10 Jan 2013 13:17:58 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Atomically update relayd stream and session id In-Reply-To: <20130110181233.GA10684@Krystal> References: <1357839948-25490-1-git-send-email-dgoulet@efficios.com> <20130110181233.GA10684@Krystal> Message-ID: <50EF05D6.6050903@efficios.com> Wait wut? Like every uatomic_inc/read() used else were in the code won't build or just this specific add_return call? Thanks! David Mathieu Desnoyers: > * David Goulet (dgoulet at efficios.com) wrote: >> Improve protection to the variables where the uatomic_add_return() call >> does a volatile access and returns the value atomically incremented. >> >> Enclose that in two new functions, one for each id, which helps with the >> code semantic and brings a single call site for the value update making >> the code easier to scale and understand when adding contention to those >> variables. >> >> Signed-off-by: David Goulet > > This won't build on 32-bit architectures, due to lack of 64-bit atomic > ops. > > Thanks, > > Mathieu > >> --- >> src/bin/lttng-relayd/lttng-relayd.h | 19 +++++++++++++++++++ >> src/bin/lttng-relayd/main.c | 9 +++++---- >> 2 files changed, 24 insertions(+), 4 deletions(-) >> >> diff --git a/src/bin/lttng-relayd/lttng-relayd.h b/src/bin/lttng-relayd/lttng-relayd.h >> index edd32d6..b2566a1 100644 >> --- a/src/bin/lttng-relayd/lttng-relayd.h >> +++ b/src/bin/lttng-relayd/lttng-relayd.h >> @@ -23,6 +23,9 @@ >> #include >> #include >> >> +extern uint64_t relayd_last_stream_id; >> +extern uint64_t relayd_last_session_id; >> + >> /* >> * Queue used to enqueue relay requests >> */ >> @@ -81,4 +84,20 @@ struct relay_command { >> unsigned int version_check_done:1; >> }; >> >> +/* >> + * Atomically increment the id and return the next stream id. >> + */ >> +static inline uint64_t relayd_get_next_stream_id(void) >> +{ >> + return (uint64_t) uatomic_add_return(&relayd_last_stream_id, 1); >> +} >> + >> +/* >> + * Atomically increment the id and return the next session id. >> + */ >> +static inline uint64_t relayd_get_next_session_id(void) >> +{ >> + return (uint64_t) uatomic_add_return(&relayd_last_session_id, 1); >> +} >> + >> #endif /* LTTNG_RELAYD_H */ >> diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c >> index 6627310..a042ce6 100644 >> --- a/src/bin/lttng-relayd/main.c >> +++ b/src/bin/lttng-relayd/main.c >> @@ -82,8 +82,9 @@ static pthread_t listener_thread; >> static pthread_t dispatcher_thread; >> static pthread_t worker_thread; >> >> -static uint64_t last_relay_stream_id; >> -static uint64_t last_relay_session_id; >> +/* Declared extern in lttng-relayd.h */ >> +uint64_t relayd_last_stream_id; >> +uint64_t relayd_last_session_id; >> >> /* >> * Relay command queue. >> @@ -968,7 +969,7 @@ int relay_create_session(struct lttcomm_relayd_hdr *recv_hdr, >> goto error; >> } >> >> - session->id = ++last_relay_session_id; >> + session->id = relayd_get_next_session_id(); >> session->sock = cmd->sock; >> cmd->session = session; >> >> @@ -1032,7 +1033,7 @@ int relay_add_stream(struct lttcomm_relayd_hdr *recv_hdr, >> } >> >> rcu_read_lock(); >> - stream->stream_handle = ++last_relay_stream_id; >> + stream->stream_handle = relayd_get_next_stream_id(); >> stream->prev_seq = -1ULL; >> stream->session = session; >> >> -- >> 1.7.10.4 >> >> >> _______________________________________________ >> lttng-dev mailing list >> lttng-dev at lists.lttng.org >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > From christian.babeux at efficios.com Thu Jan 10 14:20:01 2013 From: christian.babeux at efficios.com (Christian Babeux) Date: Thu, 10 Jan 2013 14:20:01 -0500 Subject: [lttng-dev] Follow us on Twitter Message-ID: Hi all, You can now follow LTTng on Twitter: https://twitter.com/lttng_project Thanks, Christian From mathieu.desnoyers at efficios.com Thu Jan 10 15:25:28 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 10 Jan 2013 15:25:28 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Atomically update relayd stream and session id In-Reply-To: <50EF05D6.6050903@efficios.com> References: <1357839948-25490-1-git-send-email-dgoulet@efficios.com> <20130110181233.GA10684@Krystal> <50EF05D6.6050903@efficios.com> Message-ID: <20130110202528.GA16015@Krystal> * David Goulet (dgoulet at efficios.com) wrote: > Wait wut? > > Like every uatomic_inc/read() used else were in the code won't build or > just this specific add_return call? You cannot use uatomic_*() on uint64_t variables on 32-bit systems. Other uatomic_* are probably on uint32_t, integers, or longs, which are all OK. Thanks, Mathieu > > Thanks! > David > > Mathieu Desnoyers: > > * David Goulet (dgoulet at efficios.com) wrote: > >> Improve protection to the variables where the uatomic_add_return() call > >> does a volatile access and returns the value atomically incremented. > >> > >> Enclose that in two new functions, one for each id, which helps with the > >> code semantic and brings a single call site for the value update making > >> the code easier to scale and understand when adding contention to those > >> variables. > >> > >> Signed-off-by: David Goulet > > > > This won't build on 32-bit architectures, due to lack of 64-bit atomic > > ops. > > > > Thanks, > > > > Mathieu > > > >> --- > >> src/bin/lttng-relayd/lttng-relayd.h | 19 +++++++++++++++++++ > >> src/bin/lttng-relayd/main.c | 9 +++++---- > >> 2 files changed, 24 insertions(+), 4 deletions(-) > >> > >> diff --git a/src/bin/lttng-relayd/lttng-relayd.h b/src/bin/lttng-relayd/lttng-relayd.h > >> index edd32d6..b2566a1 100644 > >> --- a/src/bin/lttng-relayd/lttng-relayd.h > >> +++ b/src/bin/lttng-relayd/lttng-relayd.h > >> @@ -23,6 +23,9 @@ > >> #include > >> #include > >> > >> +extern uint64_t relayd_last_stream_id; > >> +extern uint64_t relayd_last_session_id; > >> + > >> /* > >> * Queue used to enqueue relay requests > >> */ > >> @@ -81,4 +84,20 @@ struct relay_command { > >> unsigned int version_check_done:1; > >> }; > >> > >> +/* > >> + * Atomically increment the id and return the next stream id. > >> + */ > >> +static inline uint64_t relayd_get_next_stream_id(void) > >> +{ > >> + return (uint64_t) uatomic_add_return(&relayd_last_stream_id, 1); > >> +} > >> + > >> +/* > >> + * Atomically increment the id and return the next session id. > >> + */ > >> +static inline uint64_t relayd_get_next_session_id(void) > >> +{ > >> + return (uint64_t) uatomic_add_return(&relayd_last_session_id, 1); > >> +} > >> + > >> #endif /* LTTNG_RELAYD_H */ > >> diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c > >> index 6627310..a042ce6 100644 > >> --- a/src/bin/lttng-relayd/main.c > >> +++ b/src/bin/lttng-relayd/main.c > >> @@ -82,8 +82,9 @@ static pthread_t listener_thread; > >> static pthread_t dispatcher_thread; > >> static pthread_t worker_thread; > >> > >> -static uint64_t last_relay_stream_id; > >> -static uint64_t last_relay_session_id; > >> +/* Declared extern in lttng-relayd.h */ > >> +uint64_t relayd_last_stream_id; > >> +uint64_t relayd_last_session_id; > >> > >> /* > >> * Relay command queue. > >> @@ -968,7 +969,7 @@ int relay_create_session(struct lttcomm_relayd_hdr *recv_hdr, > >> goto error; > >> } > >> > >> - session->id = ++last_relay_session_id; > >> + session->id = relayd_get_next_session_id(); > >> session->sock = cmd->sock; > >> cmd->session = session; > >> > >> @@ -1032,7 +1033,7 @@ int relay_add_stream(struct lttcomm_relayd_hdr *recv_hdr, > >> } > >> > >> rcu_read_lock(); > >> - stream->stream_handle = ++last_relay_stream_id; > >> + stream->stream_handle = relayd_get_next_stream_id(); > >> stream->prev_seq = -1ULL; > >> stream->session = session; > >> > >> -- > >> 1.7.10.4 > >> > >> > >> _______________________________________________ > >> lttng-dev mailing list > >> lttng-dev at lists.lttng.org > >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From simon.marchi at polymtl.ca Thu Jan 10 17:24:08 2013 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Thu, 10 Jan 2013 17:24:08 -0500 Subject: [lttng-dev] [PATCH lttng-modules] Fix compilation of ext4 and btrfs tracepoints on 2.6.40 kernels Message-ID: <1357856648-32362-1-git-send-email-simon.marchi@polymtl.ca> See f95480cf62e9acb42b74fce162544694b76c9704. The new btrfs and ext4 tracepoints used 3.0.0 in the compilation logic. Signed-off-by: Simon Marchi --- instrumentation/events/lttng-module/btrfs.h | 4 ++-- instrumentation/events/lttng-module/ext4.h | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/instrumentation/events/lttng-module/btrfs.h b/instrumentation/events/lttng-module/btrfs.h index b0ff3c6..c01a6e0 100644 --- a/instrumentation/events/lttng-module/btrfs.h +++ b/instrumentation/events/lttng-module/btrfs.h @@ -39,7 +39,7 @@ struct extent_state; { BTRFS_SHARED_BLOCK_REF_KEY, "SHARED_BLOCK_REF" }, \ { BTRFS_SHARED_DATA_REF_KEY, "SHARED_DATA_REF" }) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) #define __show_root_type(obj) \ __print_symbolic_u64(obj, \ { BTRFS_ROOT_TREE_OBJECTID, "ROOT_TREE" }, \ @@ -166,7 +166,7 @@ DEFINE_EVENT(btrfs__inode, btrfs_inode_evict, TP_ARGS(inode) ) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) #define __show_map_type(type) \ __print_symbolic_u64(type, \ { EXTENT_MAP_LAST_BYTE, "LAST_BYTE" }, \ diff --git a/instrumentation/events/lttng-module/ext4.h b/instrumentation/events/lttng-module/ext4.h index 661a5a9..4bc4285 100644 --- a/instrumentation/events/lttng-module/ext4.h +++ b/instrumentation/events/lttng-module/ext4.h @@ -305,7 +305,7 @@ DEFINE_EVENT(ext4__write_end, ext4_da_write_end, TP_ARGS(inode, pos, len, copied) ) -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,40)) TRACE_EVENT(ext4_writepage, TP_PROTO(struct inode *inode, struct page *page), @@ -581,7 +581,7 @@ DECLARE_EVENT_CLASS(ext4__page_op, (unsigned long) __entry->index) ) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) DEFINE_EVENT(ext4__page_op, ext4_writepage, TP_PROTO(struct page *page), @@ -702,7 +702,7 @@ DEFINE_EVENT(ext4__mb_new_pa, ext4_mb_new_group_pa, TRACE_EVENT(ext4_mb_release_inode_pa, TP_PROTO( -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,40)) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) struct super_block *sb, struct inode *inode, @@ -716,7 +716,7 @@ TRACE_EVENT(ext4_mb_release_inode_pa, struct ext4_prealloc_space *pa, unsigned long long block, unsigned int count), -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) TP_ARGS(pa, block, count), #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) TP_ARGS(sb, inode, pa, block, count), @@ -735,7 +735,7 @@ TRACE_EVENT(ext4_mb_release_inode_pa, ), TP_fast_assign( -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) tp_assign(dev, pa->pa_inode->i_sb->s_dev) tp_assign(ino, pa->pa_inode->i_ino) #else @@ -762,7 +762,7 @@ TRACE_EVENT(ext4_mb_release_inode_pa, TRACE_EVENT(ext4_mb_release_group_pa, -#if (LTTNG_KERNEL_RANGE(3,0,0, 3,3,0)) +#if (LTTNG_KERNEL_RANGE(2,6,40, 3,3,0)) TP_PROTO(struct ext4_prealloc_space *pa), TP_ARGS(pa), @@ -794,7 +794,7 @@ TRACE_EVENT(ext4_mb_release_group_pa, ), TP_fast_assign( -#if (LTTNG_KERNEL_RANGE(3,0,0, 3,3,0)) +#if (LTTNG_KERNEL_RANGE(2,6,40, 3,3,0)) tp_assign(dev, pa->pa_inode->i_sb->s_dev) #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) tp_assign(dev, sb->s_dev) -- 1.7.1 From Erik.Ostermueller at fisglobal.com Thu Jan 10 17:52:26 2013 From: Erik.Ostermueller at fisglobal.com (Ostermueller, Erik) Date: Thu, 10 Jan 2013 22:52:26 +0000 Subject: [lttng-dev] tracing of non-JNI java in IBM jvm Message-ID: Hi all, Would like to use LTTng to trace some pure, non-JNI java method calls. Seems like I need to * install 2.1.0-rc2 * install the TMF/Eclipse LTTng plugin * how do I indicate which classes/methods to be traced? I started with the "User-space" tracing section this doc: https://bugs.lttng.org/projects/lttng-tools/wiki ...but then I stop understanding things when I read "So, after instrumenting you applications with LTTng-ust 2.0". That was followed by a link to http://lttng.org/lttng2.0, but that didn't help. Would love to be an alpha/beta tester if this isn't ready yet. Thanks a lot, --Erik ### some info about my environment: #################################### =>uname -a Linux vlxesngperf01.atldev.com 2.6.18-238.5.1.el5 #1 SMP Mon Feb 21 05:52:39 EST 2011 x86_64 x86_64 x86_64 GNU/Linux =>cat /etc/issue Red Hat Enterprise Linux Server release 5.6 (Tikanga) Kernel \r on an \m tp at vlxesngperf01 /usr/tp/app/tp/nmon/bin$=>java -version java version "1.6.0" Java(TM) SE Runtime Environment (build pxa6460sr9fp2ifix-20111111_05(SR9 FP2+IV03622+IV02378+IZ99243+IZ97310+IV00707)) IBM J9 VM (build 2.4, JRE 1.6.0 IBM J9 2.4 Linux amd64-64 jvmxa6460sr9-20111111_94827 (JIT enabled, AOT enabled) J9VM - 20111111_094827 JIT - r9_20101028_17488ifx45 GC - 20101027_AA) JCL - 20110727_04 ________________________________ Erik Ostermueller Xpress Architecture T: 501.220.7753 C:501.213.8309 erik.ostermueller at fisglobal.com [Description: Description: Description: Description: cid:image001.png at 01CD8AB3.84921E40] [Description: Description: Description: Description: cid:image003.png at 01CD8AB3.84921E40] _____________ The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image001.png Type: image/png Size: 2842 bytes Desc: image001.png URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image002.png Type: image/png Size: 5509 bytes Desc: image002.png URL: From mathieu.desnoyers at efficios.com Thu Jan 10 18:13:22 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 10 Jan 2013 18:13:22 -0500 Subject: [lttng-dev] [PATCH lttng-modules] Fix compilation of ext4 and btrfs tracepoints on 2.6.40 kernels In-Reply-To: <1357856648-32362-1-git-send-email-simon.marchi@polymtl.ca> References: <1357856648-32362-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <20130110231322.GA22647@Krystal> * Simon Marchi (simon.marchi at polymtl.ca) wrote: > See f95480cf62e9acb42b74fce162544694b76c9704. > > The new btrfs and ext4 tracepoints used 3.0.0 in the compilation logic. merged, thanks! Mathieu > > Signed-off-by: Simon Marchi > --- > instrumentation/events/lttng-module/btrfs.h | 4 ++-- > instrumentation/events/lttng-module/ext4.h | 14 +++++++------- > 2 files changed, 9 insertions(+), 9 deletions(-) > > diff --git a/instrumentation/events/lttng-module/btrfs.h b/instrumentation/events/lttng-module/btrfs.h > index b0ff3c6..c01a6e0 100644 > --- a/instrumentation/events/lttng-module/btrfs.h > +++ b/instrumentation/events/lttng-module/btrfs.h > @@ -39,7 +39,7 @@ struct extent_state; > { BTRFS_SHARED_BLOCK_REF_KEY, "SHARED_BLOCK_REF" }, \ > { BTRFS_SHARED_DATA_REF_KEY, "SHARED_DATA_REF" }) > > -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) > #define __show_root_type(obj) \ > __print_symbolic_u64(obj, \ > { BTRFS_ROOT_TREE_OBJECTID, "ROOT_TREE" }, \ > @@ -166,7 +166,7 @@ DEFINE_EVENT(btrfs__inode, btrfs_inode_evict, > TP_ARGS(inode) > ) > > -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) > #define __show_map_type(type) \ > __print_symbolic_u64(type, \ > { EXTENT_MAP_LAST_BYTE, "LAST_BYTE" }, \ > diff --git a/instrumentation/events/lttng-module/ext4.h b/instrumentation/events/lttng-module/ext4.h > index 661a5a9..4bc4285 100644 > --- a/instrumentation/events/lttng-module/ext4.h > +++ b/instrumentation/events/lttng-module/ext4.h > @@ -305,7 +305,7 @@ DEFINE_EVENT(ext4__write_end, ext4_da_write_end, > TP_ARGS(inode, pos, len, copied) > ) > > -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)) > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,40)) > TRACE_EVENT(ext4_writepage, > TP_PROTO(struct inode *inode, struct page *page), > > @@ -581,7 +581,7 @@ DECLARE_EVENT_CLASS(ext4__page_op, > (unsigned long) __entry->index) > ) > > -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) > DEFINE_EVENT(ext4__page_op, ext4_writepage, > > TP_PROTO(struct page *page), > @@ -702,7 +702,7 @@ DEFINE_EVENT(ext4__mb_new_pa, ext4_mb_new_group_pa, > > TRACE_EVENT(ext4_mb_release_inode_pa, > TP_PROTO( > -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)) > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,40)) > #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) > struct super_block *sb, > struct inode *inode, > @@ -716,7 +716,7 @@ TRACE_EVENT(ext4_mb_release_inode_pa, > struct ext4_prealloc_space *pa, > unsigned long long block, unsigned int count), > > -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) > TP_ARGS(pa, block, count), > #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) > TP_ARGS(sb, inode, pa, block, count), > @@ -735,7 +735,7 @@ TRACE_EVENT(ext4_mb_release_inode_pa, > ), > > TP_fast_assign( > -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) > tp_assign(dev, pa->pa_inode->i_sb->s_dev) > tp_assign(ino, pa->pa_inode->i_ino) > #else > @@ -762,7 +762,7 @@ TRACE_EVENT(ext4_mb_release_inode_pa, > > TRACE_EVENT(ext4_mb_release_group_pa, > > -#if (LTTNG_KERNEL_RANGE(3,0,0, 3,3,0)) > +#if (LTTNG_KERNEL_RANGE(2,6,40, 3,3,0)) > TP_PROTO(struct ext4_prealloc_space *pa), > > TP_ARGS(pa), > @@ -794,7 +794,7 @@ TRACE_EVENT(ext4_mb_release_group_pa, > ), > > TP_fast_assign( > -#if (LTTNG_KERNEL_RANGE(3,0,0, 3,3,0)) > +#if (LTTNG_KERNEL_RANGE(2,6,40, 3,3,0)) > tp_assign(dev, pa->pa_inode->i_sb->s_dev) > #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) > tp_assign(dev, sb->s_dev) > -- > 1.7.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Fri Jan 11 09:51:10 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 11 Jan 2013 09:51:10 -0500 Subject: [lttng-dev] [RELEASE] Babeltrace 1.0.2 Message-ID: <20130111145110.GA15036@Krystal> The Babeltrace project provides trace read and write libraries, as well as a trace converter. Plugins can be created for any trace format to allow its conversion to/from another trace format. The main format expected to be converted to/from is the Common Trace Format (CTF). The default input format of the "babeltrace" command is CTF, and its default output format is a human-readable text log. The "babeltrace-log" command converts from a text log to a CTF trace. Please note that the 1.0.1 tarball does not build, this is why we skip from 1.0.0 to 1.0.2 directly. Changelog: 2012-01-11 Babeltrace 1.0.2 * Fix: add tests/lib missing files to Makefile.am 2012-01-11 Babeltrace 1.0.1 * Provides a basic pkg-config file for libbabeltrace * Fix erroneous warning/error messages * Fix comment in context.h * Cleanup: Remove whitespace at EOL from mit-license.txt * Add missing permission notice in each source file * Adding a test which do a sequence of seek BEGIN, LAST, BEGIN, LAST * Run seek tests on a second trace file * Add #define _GNU_SOURCE to remove warning about asprintf * Include a test for SEEK_BEGIN and SEEK_LAST * Fix: Report success even if we find at least one valid stream in find_max_timestamp_ctf_stream_class * Fix SEEK_BEGIN for streams that do not contain any event Project website: http://www.efficios.com/babeltrace Download link: http://www.efficios.com/files/babeltrace/ CTF specification: http://www.efficios.com/ctf -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From alexmonthy at voxpopuli.im Fri Jan 11 10:51:46 2013 From: alexmonthy at voxpopuli.im (Alexandre Montplaisir) Date: Fri, 11 Jan 2013 10:51:46 -0500 Subject: [lttng-dev] tracing of non-JNI java in IBM jvm In-Reply-To: References: Message-ID: <50F03512.4080100@voxpopuli.im> Hi Erik, I'm not sure what you mean by "non-JNI java calls". LTTng-UST is a tracer implemented in C. There are Java bindings available (if you configure UST with --with-jni-interface), but if you want to use it to trace Java applications, it will have to go through JNI. If this is what you want to do, I have an example at http://git.dorsal.polymtl.ca/~alexmont?p=ust-jni-tests.git;a=summary . It's a small Java application instrumented with UST JNI tracepoints. Finally, there is an ongoing project about hooking UST into a JUL (java.util.logging) handler, and moving more logic like session control to the Java side of things. It's still at the design stage afaik, but you might want to monitor this thread: http://lists.lttng.org/pipermail/lttng-dev/2013-January/019371.html One more comment below, On 13-01-10 05:52 PM, Ostermueller, Erik wrote: > Hi all, > > Would like to use LTTng to trace some pure, non-JNI java method calls. > Seems like I need to > > * install 2.1.0-rc2 > > * install the TMF/Eclipse LTTng plugin The Eclipse plugin does no tracing by itself. It's mainly only a viewer for LTTng/UST traces. It also has a control feature that allows controlling a LTTng session daemon from within Eclipse, but it still requires the lttng tools to be installed on the traced machine. Cheers, Alex > > * how do I indicate which classes/methods to be traced? > > I started with the "User-space" tracing section this doc: https://bugs.lttng.org/projects/lttng-tools/wiki > ...but then I stop understanding things when I read "So, after instrumenting you applications with LTTng-ust 2.0". > That was followed by a link to http://lttng.org/lttng2.0, but that didn't help. > > Would love to be an alpha/beta tester if this isn't ready yet. > > Thanks a lot, > --Erik > > ### some info about my environment: #################################### > > > =>uname -a > Linux vlxesngperf01.atldev.com 2.6.18-238.5.1.el5 #1 SMP Mon Feb 21 05:52:39 EST 2011 x86_64 x86_64 x86_64 GNU/Linux > > =>cat /etc/issue > Red Hat Enterprise Linux Server release 5.6 (Tikanga) > Kernel \r on an \m > > > tp at vlxesngperf01 /usr/tp/app/tp/nmon/bin$=>java -version > java version "1.6.0" > Java(TM) SE Runtime Environment (build pxa6460sr9fp2ifix-20111111_05(SR9 FP2+IV03622+IV02378+IZ99243+IZ97310+IV00707)) > IBM J9 VM (build 2.4, JRE 1.6.0 IBM J9 2.4 Linux amd64-64 jvmxa6460sr9-20111111_94827 (JIT enabled, AOT enabled) > J9VM - 20111111_094827 > JIT - r9_20101028_17488ifx45 > GC - 20101027_AA) > JCL - 20110727_04 > > > ________________________________ > Erik Ostermueller > Xpress Architecture > > T: 501.220.7753 > C:501.213.8309 > erik.ostermueller at fisglobal.com > [Description: Description: Description: Description: cid:image001.png at 01CD8AB3.84921E40] > [Description: Description: Description: Description: cid:image003.png at 01CD8AB3.84921E40] > > _____________ > The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you. > > > From dgoulet at efficios.com Fri Jan 11 10:59:51 2013 From: dgoulet at efficios.com (David Goulet) Date: Fri, 11 Jan 2013 10:59:51 -0500 Subject: [lttng-dev] [RELEASE] LTTng-tools 2.1.1 Message-ID: <50F036F7.5010305@efficios.com> Greetings everyone (including LTTng elves), The lttng-tools project provides a session daemon (lttng-sessiond) that acts as a tracing registry, the "lttng" command line for tracing control, a lttng-ctl library for tracing control and a lttng-relayd for network streaming. Some important fixes went in for network streaming. 2013-01-11 lttng-tools 2.1.1 * Fix: update next_net_seq_num after sending header * Fix: wrong loop continuation in metadata thread * Fix: lttng create session memleaks * Fix: remove unused session id map * Fix: wrong session id used on relayd lookup * Fix: add missing UST abi header for make dist * Fix: add missing rcu read side lock/unlock Don't hesitate to report bugs on https://bugs.lttng.org or email us for any comments and questions. Project website: http://lttng.org/lttng2.0 Download link: http://lttng.org/files/lttng-tools/lttng-tools-2.1.1.tar.bz2 (for the PGP signature, same file with .asc appended) Cheers! David From Erik.Ostermueller at fisglobal.com Fri Jan 11 11:26:51 2013 From: Erik.Ostermueller at fisglobal.com (Ostermueller, Erik) Date: Fri, 11 Jan 2013 16:26:51 +0000 Subject: [lttng-dev] tracing of non-JNI java in IBM jvm In-Reply-To: <50F03512.4080100@voxpopuli.im> References: <50F03512.4080100@voxpopuli.im> Message-ID: Thanks Alex for the quick reply....now I get it. I'll jump in on that other thread you mentioned. There is a tool called InTrace that does some of this work. Perhaps some design ideas or even code could be stolen from here: http://mchr3k.github.com/org.intrace/ This project: * implements the java.lang.instrumentation api, which can be used to plug a tracing tool into an already-running JVM. * allows you to instrument/de-instrument various classes without restarting the JVM. * Uses http://asm.ow2.org/ to inject byte code for entry/exit tracing methods. * stores thread id (good) but does nothing to sort/organize activity by thread id into a session(bad) * no graphing/aggregating of performance metrics...just displays entry/exit times, method parameters, etc... --Erik -----Original Message----- From: Alexandre Montplaisir [mailto:alexmonthy at voxpopuli.im] Sent: Friday, January 11, 2013 9:52 AM To: Ostermueller, Erik Cc: lttng-dev at lists.lttng.org Subject: Re: [lttng-dev] tracing of non-JNI java in IBM jvm Hi Erik, I'm not sure what you mean by "non-JNI java calls". LTTng-UST is a tracer implemented in C. There are Java bindings available (if you configure UST with --with-jni-interface), but if you want to use it to trace Java applications, it will have to go through JNI. If this is what you want to do, I have an example at http://git.dorsal.polymtl.ca/~alexmont?p=ust-jni-tests.git;a=summary . It's a small Java application instrumented with UST JNI tracepoints. Finally, there is an ongoing project about hooking UST into a JUL (java.util.logging) handler, and moving more logic like session control to the Java side of things. It's still at the design stage afaik, but you might want to monitor this thread: http://lists.lttng.org/pipermail/lttng-dev/2013-January/019371.html One more comment below, On 13-01-10 05:52 PM, Ostermueller, Erik wrote: > Hi all, > > Would like to use LTTng to trace some pure, non-JNI java method calls. > Seems like I need to > > * install 2.1.0-rc2 > > * install the TMF/Eclipse LTTng plugin The Eclipse plugin does no tracing by itself. It's mainly only a viewer for LTTng/UST traces. It also has a control feature that allows controlling a LTTng session daemon from within Eclipse, but it still requires the lttng tools to be installed on the traced machine. Cheers, Alex > > * how do I indicate which classes/methods to be traced? > > I started with the "User-space" tracing section this doc: > https://bugs.lttng.org/projects/lttng-tools/wiki > ...but then I stop understanding things when I read "So, after instrumenting you applications with LTTng-ust 2.0". > That was followed by a link to http://lttng.org/lttng2.0, but that didn't help. > > Would love to be an alpha/beta tester if this isn't ready yet. > > Thanks a lot, > --Erik > > ### some info about my environment: #################################### > > > =>uname -a > Linux vlxesngperf01.atldev.com 2.6.18-238.5.1.el5 #1 SMP Mon Feb 21 > 05:52:39 EST 2011 x86_64 x86_64 x86_64 GNU/Linux > > =>cat /etc/issue > Red Hat Enterprise Linux Server release 5.6 (Tikanga) Kernel \r on an > \m > > > tp at vlxesngperf01 /usr/tp/app/tp/nmon/bin$=>java -version java version > "1.6.0" > Java(TM) SE Runtime Environment (build > pxa6460sr9fp2ifix-20111111_05(SR9 > FP2+IV03622+IV02378+IZ99243+IZ97310+IV00707)) > IBM J9 VM (build 2.4, JRE 1.6.0 IBM J9 2.4 Linux amd64-64 > jvmxa6460sr9-20111111_94827 (JIT enabled, AOT enabled) J9VM - > 20111111_094827 JIT - r9_20101028_17488ifx45 > GC - 20101027_AA) > JCL - 20110727_04 > > > ________________________________ > Erik Ostermueller > Xpress Architecture > > T: 501.220.7753 > C:501.213.8309 > erik.ostermueller at fisglobal.com > > [Description: Description: Description: Description: > cid:image001.png at 01CD8AB3.84921E40] > [Description: Description: Description: Description: > cid:image003.png at 01CD8AB3.84921E40] > > _____________ > The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you. > > > _____________ The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you. From aspear at vmware.com Fri Jan 11 11:40:03 2013 From: aspear at vmware.com (Aaron Spear) Date: Fri, 11 Jan 2013 08:40:03 -0800 (PST) Subject: [lttng-dev] Issues running ust 2.1.0 as non root user In-Reply-To: <943560396.6116090.1357921852170.JavaMail.root@vmware.com> Message-ID: <968286530.6126265.1357922403542.JavaMail.root@vmware.com> Hi all, I have LTTng 2.1.0 that I built/installed from source, and it all works fine when I run as root. So as root I can take kernel traces and also ust traces. However, when I attempt to run UST as a normal user it seems that there is some issue with the session daemon that I am not quite understanding. It looks like the permissions are correct on the executables in /usr/local/bin and such. Here is the error that I see with the verbose flag on (not sure if this helps...) aspear at aspear-deb64 ~ $ lttng --verbose create mytest DEBUG3: URI string: file:///home/aspear/lttng-traces/mytest-20130111-093135 [in uri_parse() at uri.c:253] DEBUG3: URI file destination: /home/aspear/lttng-traces/mytest-20130111-093135 [in uri_parse() at uri.c:290] DEBUG3: URI dtype: 3, proto: 0, host: , subdir: , ctrl: 0, data: 0 [in uri_parse() at uri.c:467] DEBUG1: LSM cmd type : 8 [in send_session_msg() at lttng-ctl.c:259] Session mytest created. Traces will be written in /home/aspear/lttng-traces/mytest-20130111-093135 DEBUG1: Init config session in /home/aspear [in config_init() at conf.c:294] aspear at aspear-deb64 ~ $ lttng --verbose enable-event -a -u DEBUG1: Session name found: mytest [in get_session_name() at utils.c:51] DEBUG1: LSM cmd type : 6 [in send_session_msg() at lttng-ctl.c:259] Error: Events: Fatal error of the session daemon (channel channel0, session mytest) DEBUG1: Clean exit [in clean_exit() at lttng.c:169] Is there perhaps some other setup step required when you do the install from source that the install does for a normal user? thanks, Aaron Spear From dgoulet at efficios.com Fri Jan 11 11:45:06 2013 From: dgoulet at efficios.com (David Goulet) Date: Fri, 11 Jan 2013 11:45:06 -0500 Subject: [lttng-dev] Issues running ust 2.1.0 as non root user In-Reply-To: <968286530.6126265.1357922403542.JavaMail.root@vmware.com> References: <968286530.6126265.1357922403542.JavaMail.root@vmware.com> Message-ID: <50F04192.3080707@efficios.com> Hi Aaron, You will have to provide the verbose logs of the session daemon. So, quite simple, start in an other console the session daemon with your user like so: $ lttng-sessiond -vvv --verbose-consumer > /tmp/sessiond.log And do the "lttng" commands again. It's going to be quite easier to identify the problem. A Fatal error of the session daemon, I suspect something is not right with the installation or you are missing memory which I doubt :). Thanks! David Aaron Spear: > Hi all, > > I have LTTng 2.1.0 that I built/installed from source, and it all works fine when I run as root. So as root I can take kernel traces and also ust traces. However, when I attempt to run UST as a normal user it seems that there is some issue with the session daemon that I am not quite understanding. It looks like the permissions are correct on the executables in /usr/local/bin and such. Here is the error that I see with the verbose flag on (not sure if this helps...) > > aspear at aspear-deb64 ~ > $ lttng --verbose create mytest > DEBUG3: URI string: file:///home/aspear/lttng-traces/mytest-20130111-093135 [in uri_parse() at uri.c:253] > DEBUG3: URI file destination: /home/aspear/lttng-traces/mytest-20130111-093135 [in uri_parse() at uri.c:290] > DEBUG3: URI dtype: 3, proto: 0, host: , subdir: , ctrl: 0, data: 0 [in uri_parse() at uri.c:467] > DEBUG1: LSM cmd type : 8 [in send_session_msg() at lttng-ctl.c:259] > Session mytest created. > Traces will be written in /home/aspear/lttng-traces/mytest-20130111-093135 > DEBUG1: Init config session in /home/aspear [in config_init() at conf.c:294] > > aspear at aspear-deb64 ~ > $ lttng --verbose enable-event -a -u > DEBUG1: Session name found: mytest [in get_session_name() at utils.c:51] > DEBUG1: LSM cmd type : 6 [in send_session_msg() at lttng-ctl.c:259] > Error: Events: Fatal error of the session daemon (channel channel0, session mytest) > DEBUG1: Clean exit [in clean_exit() at lttng.c:169] > > Is there perhaps some other setup step required when you do the install from source that the install does for a normal user? > > thanks, > Aaron Spear > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev From aspear at vmware.com Fri Jan 11 12:22:05 2013 From: aspear at vmware.com (Aaron Spear) Date: Fri, 11 Jan 2013 09:22:05 -0800 (PST) Subject: [lttng-dev] Issues running ust 2.1.0 as non root user In-Reply-To: <50F04192.3080707@efficios.com> Message-ID: <662246047.6161088.1357924924963.JavaMail.root@vmware.com> Hi David, ----- Original Message ----- > From: "David Goulet" > Hi Aaron, > > You will have to provide the verbose logs of the session daemon. So, > quite simple, start in an other console the session daemon with your > user like so: > > $ lttng-sessiond -vvv --verbose-consumer > /tmp/sessiond.log > > And do the "lttng" commands again. It's going to be quite easier to > identify the problem. > > A Fatal error of the session daemon, I suspect something is not right > with the installation or you are missing memory which I doubt :). > > Thanks! > David Thanks very much for the tip, it led me to the solution and it works now. It would appear that the issue was that there was already some daemon running on the port perhaps in some zombie state or something. I guess maybe they were left there from some earlier failed attempt or something. I killed these processes and started it up all over and it worked. I guess the moral of the story is that if this happens at all with some frequency perhaps a little better error message from lttng enable-event would be nice... here is the error message that I saw when I manually tried to start the sessiond like you instructed: $ lttng-sessiond -vvv --verbose-consumer > /tmp/sessiond.log DEBUG3: Creating LTTng run directory: /home/aspear/.lttng [in create_lttng_rundir() at main.c:3692] DEBUG1: Client socket path /home/aspear/.lttng/client-lttng-sessiond [in main() at main.c:3995] DEBUG1: Application socket path /home/aspear/.lttng/apps-lttng-sessiond [in main() at main.c:3996] DEBUG1: LTTng run directory path: /home/aspear/.lttng [in main() at main.c:3997] DEBUG2: UST consumer 32 bits err path: /home/aspear/.lttng/ustconsumerd32/error [in main() at main.c:4006] DEBUG2: UST consumer 32 bits cmd path: /home/aspear/.lttng/ustconsumerd32/command [in main() at main.c:4008] DEBUG2: UST consumer 64 bits err path: /home/aspear/.lttng/ustconsumerd64/error [in main() at main.c:4017] DEBUG2: UST consumer 64 bits cmd path: /home/aspear/.lttng/ustconsumerd64/command [in main() at main.c:4019] Error: Already running daemon. and then this is what I saw when I tried to figure out what daemon was already running: root at aspear-deb64 ~/lttng-traces # ps -A | grep ltt 5024 pts/1 00:00:00 lttng-sessiond 5110 pts/1 00:00:07 lttng-consumerd 20660 pts/1 00:00:00 lttng-consumerd 25600 ? 00:00:32 lttng-sessiond 25611 ? 00:00:00 lttng-consumerd thanks again, Aaron From aspear at vmware.com Fri Jan 11 13:55:37 2013 From: aspear at vmware.com (Aaron Spear) Date: Fri, 11 Jan 2013 10:55:37 -0800 (PST) Subject: [lttng-dev] tracing of non-JNI java in IBM jvm In-Reply-To: Message-ID: <439402897.6438391.1357930537656.JavaMail.root@vmware.com> ----- Original Message ----- > From: "Erik Ostermueller" > To: "Alexandre Montplaisir" > Cc: lttng-dev at lists.lttng.org > Sent: Friday, January 11, 2013 9:26:51 AM > Subject: Re: [lttng-dev] tracing of non-JNI java in IBM jvm > > Thanks Alex for the quick reply....now I get it. > I'll jump in on that other thread you mentioned. > > There is a tool called InTrace that does some of this work. > Perhaps some design ideas or even code could be stolen from here: > http://mchr3k.github.com/org.intrace/ > This project: > * implements the java.lang.instrumentation api, which can be used to > plug a tracing tool into an already-running JVM. > * allows you to instrument/de-instrument various classes without > restarting the JVM. > * Uses http://asm.ow2.org/ to inject byte code for entry/exit tracing > methods. > * stores thread id (good) but does nothing to sort/organize activity > by thread id into a session(bad) > * no graphing/aggregating of performance metrics...just displays > entry/exit times, method parameters, etc... Hi Erik, I think that what you are mentioning is certainly one thing that is needed. To me I see a couple of different components here: 1) implementation of java.util.logging interfaces as well as SLF4J interfaces, as well as a dedicated LTTng java API for registering custom event typess. This would be used for static, compile time instrumentation of java apps. 2) an implementation that uses the tooling you mention above for dynamic instrumentation of any running java app. You basically would define trace and install trace points on the fly. This would be really, really powerful. The implementations of the above would have to be quite different from the way that things are done currently with UST. Currently UST uses macros in C files to define the various tracepoints statically. We would need to have API's that could be called dynamically to define tracepoints, so that the java code could do this. I have not actually looked under the hood with the current UST implementation to see what the implications are for this. It seems to me that we would want to have a Java API usage similar to what you can do with SLF4J: class MyClass { private static final Tracer tracer = LTTngFactory.getTracer("MyComponentName"); private static final String MY_TRACEPOINT = "MyTracepointWithIntegerStringAndLong"; static { // register a tracepoint. this goes through JNI and creates a tracepoint // in UST that has the given name and the specified objects tracer.registerTracepoint(MY_TRACEPOINT, new Object[]{Integer.class,String.class,Long.class}); } public void someMethod() { Integer someInteger = 123456; String someString = "this is the string"; Long someLong = 56789; tracer.trace(MY_TRACEPOINT,someInteger,someString,someLong); } } Then over the top of this you have implementations of SLF4J, java.util.logging, whatever. The infrastructure required in the JNI side for this would be the same implementation needed by the binding to the InTrace technology to dynamically create tracepoints. I need all of this right now, and am willing to spend time in the next few months to implement it. cheers, Aaron Spear, Staff Engineer, VMware Inc From Daniel.Thibault at drdc-rddc.gc.ca Fri Jan 11 17:12:49 2013 From: Daniel.Thibault at drdc-rddc.gc.ca (Thibault, Daniel) Date: Fri, 11 Jan 2013 17:12:49 -0500 Subject: [lttng-dev] lttng-ust quick start? Message-ID: <3CA1A65C03C1A34C81BBC6272782E696987596@valcartierex01.valcartier.drdc-rddc.gc.ca> I have this Ubuntu 12.04 machine with the lttng-tools suite installed, and I now want to quickstart userspace tracing. Starting at http://lttng.org/quickstart, we're told succinctly that we need to instrument the target application (details in the lttng-ust(3) manpage) and then do the actual tracing (Userspace Tracing section of the lttng-tools wiki page). Fair enough. But the lttng-ust(3) manpage is off to a rocky start. The first thing we're told is " to use the lttng-gen-tp(1) tool. See the lttng-gen-tp(1) manpage for explanation." The catch here is that lttng-gen-tp is NOT part of the basic lttng-tools installation. The manpage should explain (briefly) that lttng-gen-tp is obtained by installing liblttng-ust-dev. Might as well install liblttng-ctl-dev at the same time, so we have a complete LTTng installation. The next step in the lttng-ust(3) manpage is to create a tracepoint provider: "To create a tracepoint provider, within a build tree similar to examples/easy-ust installed with lttng-ust documentation, a sample_component_provider.h for the general layout." The sentence makes no sense (is it missing parts?), but even if one glosses over this, the main problem is that there is no easy-ust anywhere to be found within the LTTng installation. Turning to the Internet, I find https://github.com/giraldeau/lttng-ust/tree/master/doc/examples/easy-ust and grab the handful of files found there. I then open a console within that directory and invoke make: gcc -I. -c -o sample.o sample.c gcc -I. -c -o tp.o tp.c In file included from /usr/local/include/lttng/ust-tracepoint-event.h:496:0, from /usr/local/include/lttng/tracepoint-event.h:40, from sample_component_provider.h:135, from tp.c:25: ././sample_component_provider.h:128:1: erreur: '__tp_loglevel_entry__sample_component___TRACE_WARNING' undeclared here (not in a function) make: *** [tp.o] Erreur 1 I think it's telling me it does not recognise the TRACE_WARNING tracepoint loglevel being defined in sample_component_provider.h (the "TRACEPOINT_LOGLEVEL(sample_component, message, TRACE_WARNING)" call), but the name seems legitimate and ust-tracepoint-event.h looks like it should handle the TRACEPOINT_LOGLEVEL* definitions. How do I fix this? Daniel U. Thibault R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) 2459 route de la Bravoure Qu?bec, QC? G3J 1X5 CANADA Vox?: (418) 844-4000 x4245 Fax?: (418) 844-4538 Gouvernement du Canada?/ Government of Canada From christian.babeux at efficios.com Fri Jan 11 17:45:26 2013 From: christian.babeux at efficios.com (Christian Babeux) Date: Fri, 11 Jan 2013 17:45:26 -0500 Subject: [lttng-dev] lttng-ust quick start? In-Reply-To: <3CA1A65C03C1A34C81BBC6272782E696987596@valcartierex01.valcartier.drdc-rddc.gc.ca> References: <3CA1A65C03C1A34C81BBC6272782E696987596@valcartierex01.valcartier.drdc-rddc.gc.ca> Message-ID: > Turning to the Internet, I find https://github.com/giraldeau/lttng-ust/tree/master/doc/examples/easy-ust and grab the handful of files found there. > I then open a console within that directory and invoke make: Please use an official git repository such as: git://git.lttng.org/lttng-ust.git Or you can use a source distribution: http://lttng.org/files/lttng-ust/lttng-ust-2.1.0.tar.bz2 Normally this example should be installed in /usr/share/doc/lttng-ust/examples/easy-ust or /usr/local/share/doc/lttng-ust/examples/easy-ust in your case. Christian From s.martin49 at gmail.com Sat Jan 12 03:24:48 2013 From: s.martin49 at gmail.com (Samuel Martin) Date: Sat, 12 Jan 2013 09:24:48 +0100 Subject: [lttng-dev] [PATCH] don't build C++ example if a C++ compiler isn't available Message-ID: <1357979088-28687-1-git-send-email-s.martin49@gmail.com> By default lttng-ust builds a hello.cxx C++ example that demonstrates the usage of the userspace tracing library in a C++ program. Unfortunately, when no C++ support is available, the build of lttng-ust fails just because of this example code. So we make the compilation of this code conditional on whether a working C++ compiler was found. Signed-off-by: Thomas Petazzoni Signed-off-by: Samuel Martin --- configure.ac | 12 ++++++++++++ tests/Makefile.am | 6 +++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index c4377a5..d33be32 100644 --- a/configure.ac +++ b/configure.ac @@ -77,6 +77,18 @@ AC_PROG_CXX AC_PROG_MAKE_SET LT_INIT +# rw_PROG_CXX_WORKS +# Check whether the C++ compiler works. +AC_CACHE_CHECK([whether the C++ compiler works], + [rw_cv_prog_cxx_works], + [AC_LANG_PUSH([C++]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], + [rw_cv_prog_cxx_works=yes], + [rw_cv_prog_cxx_works=no]) + AC_LANG_POP([C++])]) + +AM_CONDITIONAL([CXX_WORKS], [test "x$rw_cv_prog_cxx_works" = "xyes"]) + ## Checks for libraries. AC_CHECK_LIB([dl], [dlopen], [ diff --git a/tests/Makefile.am b/tests/Makefile.am index 2b12422..7365ce4 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,7 +1,11 @@ SUBDIRS = . hello hello-static-lib fork ust-basic-tracing ust-multi-test \ - demo hello.cxx daemon + demo daemon #SUBDIRS = . hello2 basic basic_long simple_include snprintf test-nevents test-libustinstr-malloc dlopen same_line_marker trace_event register_test tracepoint libustctl_function_tests exit-fast +if CXX_WORKS +SUBDIRS += hello.cxx +endif + dist_noinst_SCRIPTS = test_loop runtests trace_matches noinst_LIBRARIES = libtap.a -- 1.8.1 From s.martin49 at gmail.com Sat Jan 12 03:23:57 2013 From: s.martin49 at gmail.com (Samuel Martin) Date: Sat, 12 Jan 2013 09:23:57 +0100 Subject: [lttng-dev] [PATCH] Make sync_file_range() usage optional Message-ID: <1357979037-28550-1-git-send-email-s.martin49@gmail.com> Under uClibc, sync_file_range() is not available under all architectures, so we fall back to fdatasync() in this case. Signed-off-by: Thomas Petazzoni Signed-off-by: Samuel Martin --- configure.ac | 2 +- src/common/compat/compat-fcntl.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 425941b..80940c0 100644 --- a/configure.ac +++ b/configure.ac @@ -150,7 +150,7 @@ AS_IF([test "x$lttng_ust_support" = "xyes"], [ ) ]) AM_CONDITIONAL([HAVE_LIBLTTNG_UST_CTL], [test "x$lttng_ust_ctl_found" = xyes]) -AC_CHECK_FUNCS([sched_getcpu sysconf]) +AC_CHECK_FUNCS([sched_getcpu sysconf sync_file_range]) # check for dlopen AC_CHECK_LIB([dl], [dlopen], diff --git a/src/common/compat/compat-fcntl.c b/src/common/compat/compat-fcntl.c index 5a1c757..7ff63a3 100644 --- a/src/common/compat/compat-fcntl.c +++ b/src/common/compat/compat-fcntl.c @@ -23,7 +23,11 @@ int compat_sync_file_range(int fd, off64_t offset, off64_t nbytes, unsigned int flags) { +#ifdef HAVE_SYNC_FILE_RANGE return sync_file_range(fd, offset, nbytes, flags); +#else + return fdatasync(fd); +#endif } #endif /* __linux__ */ -- 1.8.1 From mathieu.desnoyers at efficios.com Sun Jan 13 11:44:55 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 13 Jan 2013 11:44:55 -0500 Subject: [lttng-dev] [PATCH] don't build C++ example if a C++ compiler isn't available In-Reply-To: <1357979088-28687-1-git-send-email-s.martin49@gmail.com> References: <1357979088-28687-1-git-send-email-s.martin49@gmail.com> Message-ID: <20130113164455.GA31623@Krystal> * Samuel Martin (s.martin49 at gmail.com) wrote: > By default lttng-ust builds a hello.cxx C++ example that demonstrates > the usage of the userspace tracing library in a C++ program. > Unfortunately, when no C++ support is available, the build of lttng-ust > fails just because of this example code. So we make the compilation of > this code conditional on whether a working C++ compiler was found. merged into master, stable-2.1, stable-2.0 branches, Thanks! Mathieu > > Signed-off-by: Thomas Petazzoni > Signed-off-by: Samuel Martin > --- > configure.ac | 12 ++++++++++++ > tests/Makefile.am | 6 +++++- > 2 files changed, 17 insertions(+), 1 deletion(-) > > diff --git a/configure.ac b/configure.ac > index c4377a5..d33be32 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -77,6 +77,18 @@ AC_PROG_CXX > AC_PROG_MAKE_SET > LT_INIT > > +# rw_PROG_CXX_WORKS > +# Check whether the C++ compiler works. > +AC_CACHE_CHECK([whether the C++ compiler works], > + [rw_cv_prog_cxx_works], > + [AC_LANG_PUSH([C++]) > + AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], > + [rw_cv_prog_cxx_works=yes], > + [rw_cv_prog_cxx_works=no]) > + AC_LANG_POP([C++])]) > + > +AM_CONDITIONAL([CXX_WORKS], [test "x$rw_cv_prog_cxx_works" = "xyes"]) > + > ## Checks for libraries. > AC_CHECK_LIB([dl], [dlopen], > [ > diff --git a/tests/Makefile.am b/tests/Makefile.am > index 2b12422..7365ce4 100644 > --- a/tests/Makefile.am > +++ b/tests/Makefile.am > @@ -1,7 +1,11 @@ > SUBDIRS = . hello hello-static-lib fork ust-basic-tracing ust-multi-test \ > - demo hello.cxx daemon > + demo daemon > #SUBDIRS = . hello2 basic basic_long simple_include snprintf test-nevents test-libustinstr-malloc dlopen same_line_marker trace_event register_test tracepoint libustctl_function_tests exit-fast > > +if CXX_WORKS > +SUBDIRS += hello.cxx > +endif > + > dist_noinst_SCRIPTS = test_loop runtests trace_matches > > noinst_LIBRARIES = libtap.a > -- > 1.8.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Sun Jan 13 11:48:46 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 13 Jan 2013 11:48:46 -0500 Subject: [lttng-dev] [PATCH] Make sync_file_range() usage optional In-Reply-To: <1357979037-28550-1-git-send-email-s.martin49@gmail.com> References: <1357979037-28550-1-git-send-email-s.martin49@gmail.com> Message-ID: <20130113164846.GB31623@Krystal> * Samuel Martin (s.martin49 at gmail.com) wrote: > Under uClibc, sync_file_range() is not available under all > architectures, so we fall back to fdatasync() in this case. Hi Samuel, For future, please specify either of: [PATCH urcu] [PATCH lttng-tools] [PATCH lttng-ust] [PATCH lttng-modules] in the subject. This patch belongs to lttng-tools, so I CC David who maintains it. Acked-by: Mathieu Desnoyers Thanks! Mathieu > > Signed-off-by: Thomas Petazzoni > Signed-off-by: Samuel Martin > --- > configure.ac | 2 +- > src/common/compat/compat-fcntl.c | 4 ++++ > 2 files changed, 5 insertions(+), 1 deletion(-) > > diff --git a/configure.ac b/configure.ac > index 425941b..80940c0 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -150,7 +150,7 @@ AS_IF([test "x$lttng_ust_support" = "xyes"], [ > ) > ]) > AM_CONDITIONAL([HAVE_LIBLTTNG_UST_CTL], [test "x$lttng_ust_ctl_found" = xyes]) > -AC_CHECK_FUNCS([sched_getcpu sysconf]) > +AC_CHECK_FUNCS([sched_getcpu sysconf sync_file_range]) > > # check for dlopen > AC_CHECK_LIB([dl], [dlopen], > diff --git a/src/common/compat/compat-fcntl.c b/src/common/compat/compat-fcntl.c > index 5a1c757..7ff63a3 100644 > --- a/src/common/compat/compat-fcntl.c > +++ b/src/common/compat/compat-fcntl.c > @@ -23,7 +23,11 @@ > int compat_sync_file_range(int fd, off64_t offset, off64_t nbytes, > unsigned int flags) > { > +#ifdef HAVE_SYNC_FILE_RANGE > return sync_file_range(fd, offset, nbytes, flags); > +#else > + return fdatasync(fd); > +#endif > } > > #endif /* __linux__ */ > -- > 1.8.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Sun Jan 13 12:54:30 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 13 Jan 2013 12:54:30 -0500 Subject: [lttng-dev] babletrace with python bindings In-Reply-To: <20998D40D9A2B7499CA5A3A2666CB1EB19F8ABF4@ZURMSG1.QUANTUM.com> References: <20121218184045.288000@gmx.com> <20121219183932.GA9587@Krystal> <20998D40D9A2B7499CA5A3A2666CB1EB19F8ABF4@ZURMSG1.QUANTUM.com> Message-ID: <20130113175430.GA3702@Krystal> * David OShea (David.OShea at quantum.com) wrote: > > -----Original Message----- > > From: Mathieu Desnoyers [mailto:mathieu.desnoyers at efficios.com] > > Sent: Thursday, 20 December 2012 5:10 AM > > To: ajonwa ajonwa > > Cc: lttng-dev at lists.lttng.org > > Subject: Re: [lttng-dev] babletrace with python bindings > > > > * ajonwa ajonwa (ajonwa at gmx.com) wrote: > > > Hello everyone, > > > > > > I get the following error message while attempting to compile > > babeltrace with python bindings: > [...] > > This branch is currently in development, and might be out of sync with > > the master branch of babeltrace at the moment. We don't have immediate > > plans to work on it, but bontributions are welcome. > > Apologies for the late reply. I just wanted to point out that if you > check out commit 24a3136a383, it does build. It's an older version of > babeltrace, but does work despite some bugs. > > The main bug I recall is that > iterator.set_pos(babeltrace.IterPos(babeltrace.SEEK_BEGIN)) doesn't > fail immediately, and works in some traces, but sometimes results in a > subsequent assertion failure in the Python interpreter after a few > events have been read, or returns a bogus event at the start of the > trace. Quite possibly this is a babeltrace bug that has been fixed > already. Probably by this commit: commit 08ac0e0801251211279f9deb07f9cbbbd712d9c5 Author: Mathieu Desnoyers Date: Fri Nov 9 13:02:59 2012 -0500 Fix SEEK_BEGIN for streams that do not contain any event Reported-by: Yannick Brosseau Signed-off-by: Mathieu Desnoyers Thanks, Mathieu > > Regards, > David > > ---------------------------------------------------------------------- > The information contained in this transmission may be confidential. Any disclosure, copying, or further distribution of confidential information is not permitted unless such privilege is explicitly granted in writing by Quantum. Quantum reserves the right to have electronic communications, including email and attachments, sent across its networks filtered through anti virus and spam software programs and retain such messages in order to comply with applicable data security and retention requirements. Quantum is not responsible for the proper and complete transmission of the substance of this communication or for any delay in its receipt. -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Sun Jan 13 12:57:54 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 13 Jan 2013 12:57:54 -0500 Subject: [lttng-dev] [BABELTRACE PATCH] Namespace the lookup_enum function In-Reply-To: <1357760893-11961-1-git-send-email-jdesfossez@efficios.com> References: <20130107211855.GB3678@Krystal> <1357760893-11961-1-git-send-email-jdesfossez@efficios.com> Message-ID: <20130113175754.GA3917@Krystal> * Julien Desfossez (jdesfossez at efficios.com) wrote: > This patch namespaces the lookup_enum function because it causes problem > with the integration in gdb even though it is not exported. > Hui, can you try this patch and confirm it solves the current problem ? > After that we will continue the internal namespacing. Hi Julien, Since we know these changes are needed, can you provide patches with proper changelogs, and I'll pull them. Thanks, Mathieu > > Thanks, > > Julien > --- > formats/ctf/ctf.c | 2 +- > include/babeltrace/types.h | 2 +- > types/types.c | 2 +- > 3 files changed, 3 insertions(+), 3 deletions(-) > > diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c > index 18a5601..a8f8408 100644 > --- a/formats/ctf/ctf.c > +++ b/formats/ctf/ctf.c > @@ -431,7 +431,7 @@ int ctf_read_event(struct stream_pos *ppos, struct ctf_stream_definition *stream > } else { > struct definition_enum *enum_definition; > > - enum_definition = lookup_enum(&stream->stream_event_header->p, "id", FALSE); > + enum_definition = bt_lookup_enum(&stream->stream_event_header->p, "id", FALSE); > if (enum_definition) { > id = enum_definition->integer->value._unsigned; > } > diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h > index b42ba03..00c928b 100644 > --- a/include/babeltrace/types.h > +++ b/include/babeltrace/types.h > @@ -521,7 +521,7 @@ struct definition *lookup_definition(const struct definition *definition, > struct definition_integer *lookup_integer(const struct definition *definition, > const char *field_name, > int signedness); > -struct definition_enum *lookup_enum(const struct definition *definition, > +struct definition_enum *bt_lookup_enum(const struct definition *definition, > const char *field_name, > int signedness); > struct definition *lookup_variant(const struct definition *definition, > diff --git a/types/types.c b/types/types.c > index 5599027..139e318 100644 > --- a/types/types.c > +++ b/types/types.c > @@ -642,7 +642,7 @@ struct definition_integer *lookup_integer(const struct definition *definition, > return lookup_integer; > } > > -struct definition_enum *lookup_enum(const struct definition *definition, > +struct definition_enum *bt_lookup_enum(const struct definition *definition, > const char *field_name, > int signedness) > { > -- > 1.7.10.4 > -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Sun Jan 13 12:58:39 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 13 Jan 2013 12:58:39 -0500 Subject: [lttng-dev] Arrays printed in hex In-Reply-To: <20998D40D9A2B7499CA5A3A2666CB1EB19F8AEE2@ZURMSG1.QUANTUM.com> References: <20998D40D9A2B7499CA5A3A2666CB1EB19F8AEE2@ZURMSG1.QUANTUM.com> Message-ID: <20130113175839.GB3917@Krystal> * David OShea (David.OShea at quantum.com) wrote: > Hi all, > > In lttng-ust 2.0.5, tracepoint.h's comments include: > > """ > * * Integer, printed in base 10 * > * ctf_integer(int, field_a, arg0) > * > * * Integer, printed with 0x base 16 * > * ctf_integer_hex(unsigned long, field_d, arg1) > [...] > * * Array sequence of signed integer values * > * ctf_array(long, field_f, arg4, FIXED_LEN4) > * ctf_sequence(long, field_g, arg4, size_t, arg4_len) > """ > > Could _hex versions of ctf_array() and ctf_sequence() be easily added, > where all the elements of the array/sequence would be output in hex by > babeltrace? Yes, this would just need to be added to lttng/ust-tracepoint-event*.h file. Patches are welcome. Thanks, Mathieu > > Thanks in advance, > David > > ---------------------------------------------------------------------- > The information contained in this transmission may be confidential. Any disclosure, copying, or further distribution of confidential information is not permitted unless such privilege is explicitly granted in writing by Quantum. Quantum reserves the right to have electronic communications, including email and attachments, sent across its networks filtered through anti virus and spam software programs and retain such messages in order to comply with applicable data security and retention requirements. Quantum is not responsible for the proper and complete transmission of the substance of this communication or for any delay in its receipt. > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Sun Jan 13 12:59:18 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 13 Jan 2013 12:59:18 -0500 Subject: [lttng-dev] Arrays printed in hex In-Reply-To: <20130113175839.GB3917@Krystal> References: <20998D40D9A2B7499CA5A3A2666CB1EB19F8AEE2@ZURMSG1.QUANTUM.com> <20130113175839.GB3917@Krystal> Message-ID: <20130113175918.GC3917@Krystal> * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > * David OShea (David.OShea at quantum.com) wrote: > > Hi all, > > > > In lttng-ust 2.0.5, tracepoint.h's comments include: > > > > """ > > * * Integer, printed in base 10 * > > * ctf_integer(int, field_a, arg0) > > * > > * * Integer, printed with 0x base 16 * > > * ctf_integer_hex(unsigned long, field_d, arg1) > > [...] > > * * Array sequence of signed integer values * > > * ctf_array(long, field_f, arg4, FIXED_LEN4) > > * ctf_sequence(long, field_g, arg4, size_t, arg4_len) > > """ > > > > Could _hex versions of ctf_array() and ctf_sequence() be easily added, > > where all the elements of the array/sequence would be output in hex by > > babeltrace? > > Yes, this would just need to be added to lttng/ust-tracepoint-event*.h > file. Patches are welcome. If you cannot write a patch, please open a feature request against lttng-ust on bugs.lttng.org Thanks, Mathieu > > Thanks, > > Mathieu > > > > > Thanks in advance, > > David > > > > ---------------------------------------------------------------------- > > The information contained in this transmission may be confidential. Any disclosure, copying, or further distribution of confidential information is not permitted unless such privilege is explicitly granted in writing by Quantum. Quantum reserves the right to have electronic communications, including email and attachments, sent across its networks filtered through anti virus and spam software programs and retain such messages in order to comply with applicable data security and retention requirements. Quantum is not responsible for the proper and complete transmission of the substance of this communication or for any delay in its receipt. > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From yannick.brosseau at gmail.com Sun Jan 13 21:40:30 2013 From: yannick.brosseau at gmail.com (Yannick Brosseau) Date: Sun, 13 Jan 2013 21:40:30 -0500 Subject: [lttng-dev] [lttng-modules PATCH] Add uprobes support Message-ID: <1358131230-3446-1-git-send-email-yannick.brosseau@gmail.com> The added support is basic. It create an event with no data associated to the file path + offset specified. As per the structures currently used we cannot pass a file path bigger than 256 chars. Signed-off-by: Yannick Brosseau --- README | 5 +- lttng-abi.c | 3 + lttng-abi.h | 7 +++ lttng-events.c | 18 ++++++ lttng-events.h | 38 ++++++++++++ probes/Makefile | 5 ++ probes/lttng-uprobes.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 probes/lttng-uprobes.c diff --git a/README b/README index 1bcd5b2..7afdaa3 100644 --- a/README +++ b/README @@ -9,7 +9,7 @@ need for additional patches. Other features: - Produces CTF (Common Trace Format) natively, (http://www.efficios.com/ctf) - Tracepoints, Function tracer, CPU Performance Monitoring Unit (PMU) - counters, kprobes, and kretprobes support, + counters, kprobes, kretprobes and uprobes support, - Integrated interface for both kernel and userspace tracing, - Have the ability to attach "context" information to events in the trace (e.g. any PMU counter, pid, ppid, tid, comm name, etc). @@ -86,6 +86,9 @@ CONFIG_KPROBES: CONFIG_KRETPROBES: Dynamic function entry/return probe. lttng enable-event -k --function ... +CONFIG_UPROBES: + Dynamic userspace probe. + lttng enable-event -k --uprobe ... * Note about Perf PMU counters support diff --git a/lttng-abi.c b/lttng-abi.c index 25a350a..fe428b2 100644 --- a/lttng-abi.c +++ b/lttng-abi.c @@ -610,6 +610,9 @@ int lttng_abi_create_event(struct file *channel_file, case LTTNG_KERNEL_FUNCTION: event_param->u.ftrace.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; break; + case LTTNG_KERNEL_UPROBE: + event_param->u.uprobe.path[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; + break; default: break; } diff --git a/lttng-abi.h b/lttng-abi.h index 8d3ecdd..5abdb39 100644 --- a/lttng-abi.h +++ b/lttng-abi.h @@ -34,6 +34,7 @@ enum lttng_kernel_instrumentation { LTTNG_KERNEL_KRETPROBE = 3, LTTNG_KERNEL_NOOP = 4, /* not hooked */ LTTNG_KERNEL_SYSCALL = 5, + LTTNG_KERNEL_UPROBE = 6, }; /* @@ -79,6 +80,11 @@ struct lttng_kernel_function_tracer { char symbol_name[LTTNG_KERNEL_SYM_NAME_LEN]; }__attribute__((packed)); +struct lttng_kernel_uprobe { + char path[LTTNG_KERNEL_SYM_NAME_LEN]; + uint64_t offset; +}__attribute__((packed)); + /* * For syscall tracing, name = '\0' means "enable all". */ @@ -94,6 +100,7 @@ struct lttng_kernel_event { struct lttng_kernel_kretprobe kretprobe; struct lttng_kernel_kprobe kprobe; struct lttng_kernel_function_tracer ftrace; + struct lttng_kernel_uprobe uprobe; char padding[LTTNG_KERNEL_EVENT_PADDING2]; } u; }__attribute__((packed)); diff --git a/lttng-events.c b/lttng-events.c index 4f30904..38c901f 100644 --- a/lttng-events.c +++ b/lttng-events.c @@ -392,6 +392,16 @@ struct lttng_event *lttng_event_create(struct lttng_channel *chan, if (!event->desc) goto register_error; break; + case LTTNG_KERNEL_UPROBE: + ret = lttng_uprobes_register(event_param->name, + event_param->u.uprobe.path, + event_param->u.uprobe.offset, + event); + if (ret) + goto register_error; + ret = try_module_get(event->desc->owner); + WARN_ON_ONCE(!ret); + break; default: WARN_ON_ONCE(1); } @@ -443,6 +453,10 @@ int _lttng_event_unregister(struct lttng_event *event) case LTTNG_KERNEL_NOOP: ret = 0; break; + case LTTNG_KERNEL_UPROBE: + lttng_uprobes_unregister(event); + ret = 0; + break; default: WARN_ON_ONCE(1); } @@ -473,6 +487,10 @@ void _lttng_event_destroy(struct lttng_event *event) break; case LTTNG_KERNEL_NOOP: break; + case LTTNG_KERNEL_UPROBE: + module_put(event->desc->owner); + lttng_uprobes_destroy_private(event); + break; default: WARN_ON_ONCE(1); } diff --git a/lttng-events.h b/lttng-events.h index 09d5618..e630db0 100644 --- a/lttng-events.h +++ b/lttng-events.h @@ -26,6 +26,9 @@ #include #include #include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) +#include +#endif #include "wrapper/uuid.h" #include "lttng-abi.h" #include "lttng-abi-old.h" @@ -203,6 +206,13 @@ struct lttng_event { struct { char *symbol_name; } ftrace; + struct { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) + struct uprobe_consumer up_consumer; +#endif + struct inode *inode; + loff_t offset; + } uprobe; } u; struct list_head list; /* Event list */ unsigned int metadata_dumped:1; @@ -406,6 +416,34 @@ void lttng_kprobes_destroy_private(struct lttng_event *event) } #endif +#ifdef CONFIG_UPROBES +int lttng_uprobes_register(const char *name, + const char *path, + uint64_t offset, + struct lttng_event *event); +void lttng_uprobes_unregister(struct lttng_event *event); +void lttng_uprobes_destroy_private(struct lttng_event *event); +#else +static inline +int lttng_uprobes_register(const char *name, + const char *path, + uint64_t offset, + struct lttng_event *event) +{ + return -ENOSYS; +} + +static inline +void lttng_uprobes_unregister(struct lttng_event *event) +{ +} + +static inline +void lttng_uprobes_destroy_private(struct lttng_event *event) +{ +} +#endif + #ifdef CONFIG_KRETPROBES int lttng_kretprobes_register(const char *name, const char *symbol_name, diff --git a/probes/Makefile b/probes/Makefile index 088cd5f..de0f1a7 100644 --- a/probes/Makefile +++ b/probes/Makefile @@ -208,6 +208,11 @@ ifneq ($(CONFIG_DYNAMIC_FTRACE),) obj-m += lttng-ftrace.o endif +ifneq ($(CONFIG_UPROBES),) +obj-m += lttng-uprobes.o +endif + + endif else diff --git a/probes/lttng-uprobes.c b/probes/lttng-uprobes.c new file mode 100644 index 0000000..1d68273 --- /dev/null +++ b/probes/lttng-uprobes.c @@ -0,0 +1,156 @@ +/* + * probes/lttng-uprobes.c + * + * LTTng uprobes integration module. + * + * Copyright (C) 2013 Yannick Brosseau + * Copyright (C) 2009-2012 Mathieu Desnoyers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include "../lttng-events.h" +#include "../wrapper/ringbuffer/frontend_types.h" +#include "../wrapper/vmalloc.h" +#include "../lttng-tracer.h" + +static +int lttng_uprobes_handler_pre(struct uprobe_consumer *uc, struct pt_regs *regs) +{ + struct lttng_event *event = + container_of(uc, struct lttng_event, u.uprobe.up_consumer); + struct lttng_channel *chan = event->chan; + struct lib_ring_buffer_ctx ctx; + int ret; + + if (unlikely(!ACCESS_ONCE(chan->session->active))) + return 0; + if (unlikely(!ACCESS_ONCE(chan->enabled))) + return 0; + if (unlikely(!ACCESS_ONCE(event->enabled))) + return 0; + + lib_ring_buffer_ctx_init(&ctx, chan->chan, event, 0, + 0, -1); + ret = chan->ops->event_reserve(&ctx, event->id); + if (ret < 0) + return 0; + lib_ring_buffer_align_ctx(&ctx, 0); + chan->ops->event_write(&ctx, 0, 0); + chan->ops->event_commit(&ctx); + return 0; +} + +/* + * Create event description + */ +static +int lttng_create_uprobe_event(const char *name, struct lttng_event *event) +{ + struct lttng_event_desc *desc; + int ret; + + desc = kzalloc(sizeof(*event->desc), GFP_KERNEL); + if (!desc) + return -ENOMEM; + desc->name = kstrdup(name, GFP_KERNEL); + if (!desc->name) { + ret = -ENOMEM; + goto error_str; + } + desc->owner = THIS_MODULE; + event->desc = desc; + + return 0; + +error_str: + kfree(desc); + return ret; +} + +int lttng_uprobes_register(const char *name, + const char *path_name, + uint64_t offset, + struct lttng_event *event) +{ + int ret; + + if (path_name[0] == '\0') + path_name = NULL; + + ret = lttng_create_uprobe_event(name, event); + if (ret) + goto error; + memset(&event->u.uprobe.up_consumer, 0, + sizeof(event->u.uprobe.up_consumer)); + event->u.uprobe.up_consumer.handler = lttng_uprobes_handler_pre; + if (path_name) { + struct path path; + ret = kern_path(path_name, LOOKUP_FOLLOW, &path); + if (ret) + goto path_error; + + event->u.uprobe.inode = igrab(path.dentry->d_inode); + } + event->u.uprobe.offset = offset; + + /* TODO Is this also true for uprobes? + * Ensure the memory we just allocated don't trigger page faults. + * Well.. kprobes itself puts the page fault handler on the blacklist, + * but we can never be too careful. + */ + wrapper_vmalloc_sync_all(); + + ret = uprobe_register(event->u.uprobe.inode, + event->u.uprobe.offset, + &event->u.uprobe.up_consumer); + if (ret) + goto register_error; + return 0; + +register_error: + iput(event->u.uprobe.inode); +path_error: + kfree(event->desc->name); + kfree(event->desc); +error: + return ret; +} +EXPORT_SYMBOL_GPL(lttng_uprobes_register); + +void lttng_uprobes_unregister(struct lttng_event *event) +{ + uprobe_unregister(event->u.uprobe.inode, + event->u.uprobe.offset, + &event->u.uprobe.up_consumer); +} +EXPORT_SYMBOL_GPL(lttng_uprobes_unregister); + +void lttng_uprobes_destroy_private(struct lttng_event *event) +{ + iput(event->u.uprobe.inode); + kfree(event->desc->name); + kfree(event->desc); +} +EXPORT_SYMBOL_GPL(lttng_uprobes_destroy_private); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Yannick Brosseau"); +MODULE_DESCRIPTION("Linux Trace Toolkit Uprobes Support"); -- 1.7.10.4 From yannick.brosseau at gmail.com Sun Jan 13 22:03:37 2013 From: yannick.brosseau at gmail.com (Yannick Brosseau) Date: Sun, 13 Jan 2013 22:03:37 -0500 Subject: [lttng-dev] [lttng-tools PATCH] Add support for kernel uprobes Message-ID: <1358132617-18443-1-git-send-email-yannick.brosseau@gmail.com> Inspired by the k*probe support. It add a new option to enable-event --uprobe which require a path name and an offset in the specified file. (The file Documentation/trace/uprobetracer.txt in the kernel source provides and example on how to extract the offset for a symbol in a program) Signed-off-by: Yannick Brosseau --- include/lttng/lttng.h | 15 +++++++++ src/bin/lttng-sessiond/cmd.c | 5 +++ src/bin/lttng-sessiond/modprobe.c | 1 + src/bin/lttng-sessiond/trace-kernel.c | 7 ++++ src/bin/lttng/commands/enable_events.c | 55 ++++++++++++++++++++++++++++++++ src/bin/lttng/commands/list.c | 8 +++++ src/common/lttng-kernel.h | 7 ++++ 7 files changed, 98 insertions(+) diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h index e21b479..c790e7b 100644 --- a/include/lttng/lttng.h +++ b/include/lttng/lttng.h @@ -72,6 +72,7 @@ enum lttng_event_type { LTTNG_EVENT_FUNCTION_ENTRY = 3, LTTNG_EVENT_NOOP = 4, LTTNG_EVENT_SYSCALL = 5, + LTTNG_EVENT_UPROBE = 6, }; /* @@ -219,6 +220,19 @@ struct lttng_event_function_attr { }; /* + * Event uprobe. + * + * The structures should be initialized to zero before use. + */ +#define LTTNG_EVENT_UPROBE_PADDING1 24 +struct lttng_event_uprobe_attr { + char path[LTTNG_SYMBOL_NAME_LEN]; + uint64_t offset; + + char padding[LTTNG_EVENT_UPROBE_PADDING1]; +}; + +/* * Generic lttng event * * The structures should be initialized to zero before use. @@ -242,6 +256,7 @@ struct lttng_event { union { struct lttng_event_probe_attr probe; struct lttng_event_function_attr ftrace; + struct lttng_event_uprobe_attr uprobe; char padding[LTTNG_EVENT_PADDING2]; } attr; diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 491acde..d7fee70 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -315,6 +315,11 @@ static int list_lttng_kernel_events(char *channel_name, memcpy(&((*events)[i].attr.ftrace), &event->event->u.ftrace, sizeof(struct lttng_kernel_function)); break; + case LTTNG_KERNEL_UPROBE: + (*events)[i].type = LTTNG_EVENT_UPROBE; + memcpy(&(*events)[i].attr.uprobe, &event->event->u.uprobe, + sizeof(struct lttng_kernel_uprobe)); + break; case LTTNG_KERNEL_NOOP: (*events)[i].type = LTTNG_EVENT_NOOP; break; diff --git a/src/bin/lttng-sessiond/modprobe.c b/src/bin/lttng-sessiond/modprobe.c index 1a5a1b7..805e127 100644 --- a/src/bin/lttng-sessiond/modprobe.c +++ b/src/bin/lttng-sessiond/modprobe.c @@ -35,6 +35,7 @@ const struct kern_modules_param kern_modules_list[] = { { "lttng-ftrace", 0 }, { "lttng-kprobes", 0 }, { "lttng-kretprobes", 0 }, + { "lttng-uprobes", 0 }, { "lttng-lib-ring-buffer", 1 }, { "lttng-ring-buffer-client-discard", 1 }, { "lttng-ring-buffer-client-overwrite", 1 }, diff --git a/src/bin/lttng-sessiond/trace-kernel.c b/src/bin/lttng-sessiond/trace-kernel.c index f38cf3d..24f33f9 100644 --- a/src/bin/lttng-sessiond/trace-kernel.c +++ b/src/bin/lttng-sessiond/trace-kernel.c @@ -207,6 +207,13 @@ struct ltt_kernel_event *trace_kernel_create_event(struct lttng_event *ev) ev->attr.probe.symbol_name, LTTNG_KERNEL_SYM_NAME_LEN); attr->u.kprobe.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; break; + case LTTNG_EVENT_UPROBE: + attr->instrumentation = LTTNG_KERNEL_UPROBE; + attr->u.uprobe.offset = ev->attr.uprobe.offset; + strncpy(attr->u.uprobe.path, + ev->attr.uprobe.path, LTTNG_KERNEL_SYM_NAME_LEN); + attr->u.uprobe.path[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; + break; case LTTNG_EVENT_FUNCTION: attr->instrumentation = LTTNG_KERNEL_KRETPROBE; attr->u.kretprobe.addr = ev->attr.probe.addr; diff --git a/src/bin/lttng/commands/enable_events.c b/src/bin/lttng/commands/enable_events.c index b6c18e1..61cb15b 100644 --- a/src/bin/lttng/commands/enable_events.c +++ b/src/bin/lttng/commands/enable_events.c @@ -38,6 +38,7 @@ static char *opt_session_name; static int opt_userspace; static int opt_enable_all; static char *opt_probe; +static char *opt_uprobe; static char *opt_function; static char *opt_function_entry_symbol; static char *opt_channel_name; @@ -52,6 +53,7 @@ enum { OPT_HELP = 1, OPT_TRACEPOINT, OPT_PROBE, + OPT_UPROBE, OPT_FUNCTION, OPT_FUNCTION_ENTRY, OPT_SYSCALL, @@ -74,6 +76,7 @@ static struct poptOption long_options[] = { {"userspace", 'u', POPT_ARG_NONE, 0, OPT_USERSPACE, 0, 0}, {"tracepoint", 0, POPT_ARG_NONE, 0, OPT_TRACEPOINT, 0, 0}, {"probe", 0, POPT_ARG_STRING, &opt_probe, OPT_PROBE, 0, 0}, + {"uprobe", 0, POPT_ARG_STRING, &opt_uprobe, OPT_UPROBE, 0, 0}, {"function", 0, POPT_ARG_STRING, &opt_function, OPT_FUNCTION, 0, 0}, #if 0 /* @@ -117,6 +120,10 @@ static void usage(FILE *ofp) fprintf(ofp, " Dynamic probe.\n"); fprintf(ofp, " Addr and offset can be octal (0NNN...),\n"); fprintf(ofp, " decimal (NNN...) or hexadecimal (0xNNN...)\n"); + fprintf(ofp, " --uprobe [path+offset]\n"); + fprintf(ofp, " Dynamic uprobe.\n"); + fprintf(ofp, " offset can be octal (0NNN...),\n"); + fprintf(ofp, " decimal (NNN...) or hexadecimal (0xNNN...)\n"); fprintf(ofp, " --function [addr | symbol | symbol+offset]\n"); fprintf(ofp, " Dynamic function entry/return probe.\n"); fprintf(ofp, " Addr and offset can be octal (0NNN...),\n"); @@ -245,6 +252,42 @@ static int parse_probe_opts(struct lttng_event *ev, char *opt) end: return ret; } +/* + * Parse uprobe options. + */ +static int parse_uprobe_opts(struct lttng_event *ev, char *opt) +{ + int ret; + char s_hex[19]; + char name[LTTNG_SYMBOL_NAME_LEN]; + + if (opt == NULL) { + ret = -1; + goto end; + } + + /* Check for path+offset */ + ret = sscanf(opt, "%[^'+']+%s", name, s_hex); + if (ret == 2) { + strncpy(ev->attr.uprobe.path, name, LTTNG_SYMBOL_NAME_LEN); + ev->attr.uprobe.path[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; + DBG("probe path %s", ev->attr.uprobe.path); + if (strlen(s_hex) == 0) { + ERR("Invalid uprobe offset %s", s_hex); + ret = -1; + goto end; + } + ev->attr.uprobe.offset = strtoul(s_hex, NULL, 0); + DBG("uprobe offset %" PRIu64, ev->attr.uprobe.offset); + goto end; + } + + /* No match */ + ret = -1; + +end: + return ret; +} /* * Maps loglevel from string to value @@ -471,6 +514,14 @@ static int enable_events(char *session_name) goto error; } break; + case LTTNG_EVENT_UPROBE: + ret = parse_uprobe_opts(&ev, opt_uprobe); + if (ret < 0) { + ERR("Unable to parse uprobe options"); + ret = 0; + goto error; + } + break; case LTTNG_EVENT_FUNCTION: ret = parse_probe_opts(&ev, opt_function); if (ret < 0) { @@ -522,6 +573,7 @@ static int enable_events(char *session_name) ev.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; break; case LTTNG_EVENT_PROBE: + case LTTNG_EVENT_UPROBE: case LTTNG_EVENT_FUNCTION: case LTTNG_EVENT_FUNCTION_ENTRY: case LTTNG_EVENT_SYSCALL: @@ -636,6 +688,9 @@ int cmd_enable_events(int argc, const char **argv) case OPT_PROBE: opt_event_type = LTTNG_EVENT_PROBE; break; + case OPT_UPROBE: + opt_event_type = LTTNG_EVENT_UPROBE; + break; case OPT_FUNCTION: opt_event_type = LTTNG_EVENT_FUNCTION; break; diff --git a/src/bin/lttng/commands/list.c b/src/bin/lttng/commands/list.c index a6ea6b8..ffae239 100644 --- a/src/bin/lttng/commands/list.c +++ b/src/bin/lttng/commands/list.c @@ -231,6 +231,14 @@ static void print_events(struct lttng_event *event) MSG("%ssymbol: %s", indent8, event->attr.probe.symbol_name); } break; + case LTTNG_EVENT_UPROBE: + MSG("%s%s (type: uprobe)%s%s", indent6, + event->name, enabled_string(event->enabled), + filter_string(event->filter)); + + MSG("%spath: %s", indent8, event->attr.uprobe.path); + MSG("%soffset: 0x%" PRIx64, indent8, event->attr.uprobe.offset); + break; case LTTNG_EVENT_FUNCTION: case LTTNG_EVENT_FUNCTION_ENTRY: MSG("%s%s (type: function)%s%s", indent6, diff --git a/src/common/lttng-kernel.h b/src/common/lttng-kernel.h index fa8ba61..a43b956 100644 --- a/src/common/lttng-kernel.h +++ b/src/common/lttng-kernel.h @@ -38,6 +38,7 @@ enum lttng_kernel_instrumentation { LTTNG_KERNEL_KRETPROBE = 3, LTTNG_KERNEL_NOOP = 4, /* not hooked */ LTTNG_KERNEL_SYSCALL = 5, + LTTNG_KERNEL_UPROBE = 6, }; enum lttng_kernel_context_type { @@ -96,6 +97,11 @@ struct lttng_kernel_function { char symbol_name[LTTNG_KERNEL_SYM_NAME_LEN]; }__attribute__((packed)); +struct lttng_kernel_uprobe { + char path[LTTNG_KERNEL_SYM_NAME_LEN]; + uint64_t offset; +}__attribute__((packed)); + #define LTTNG_KERNEL_EVENT_PADDING1 16 #define LTTNG_KERNEL_EVENT_PADDING2 LTTNG_KERNEL_SYM_NAME_LEN + 32 struct lttng_kernel_event { @@ -108,6 +114,7 @@ struct lttng_kernel_event { struct lttng_kernel_kretprobe kretprobe; struct lttng_kernel_kprobe kprobe; struct lttng_kernel_function ftrace; + struct lttng_kernel_uprobe uprobe; char padding[LTTNG_KERNEL_EVENT_PADDING2]; } u; }__attribute__((packed)); -- 1.7.10.4 From Daniel.Thibault at drdc-rddc.gc.ca Mon Jan 14 12:30:37 2013 From: Daniel.Thibault at drdc-rddc.gc.ca (Thibault, Daniel) Date: Mon, 14 Jan 2013 12:30:37 -0500 Subject: [lttng-dev] lttng-ust quick start? In-Reply-To: References: <3CA1A65C03C1A34C81BBC6272782E696987596@valcartierex01.valcartier.drdc-rddc.gc.ca> Message-ID: <3CA1A65C03C1A34C81BBC6272782E6969875D2@valcartierex01.valcartier.drdc-rddc.gc.ca> -----Message d'origine----- Envoy??: 11 janvier 2013 17:45 > > Turning to the Internet, I find https://github.com/giraldeau/lttng-ust/tree/master/doc/examples/easy-ust and grab the handful of files found there. > > I then open a console within that directory and invoke make: > > Please use an official git repository such as: git://git.lttng.org/lttng-ust.git Or you can use a source distribution: > http://lttng.org/files/lttng-ust/lttng-ust-2.1.0.tar.bz2 > > Normally this example should be installed in /usr/share/doc/lttng-ust/examples/easy-ust or /usr/local/share/doc/lttng-ust/examples/easy-ust in your case. > > Christian -----Fin du message d'origine----- Part of my point is that the Ubuntu distribution is broken because it does not install the easy-ust files. I have neither /usr/share/doc/lttng-ust/ nor /usr/local/share/doc/ directories on my machines. Note that Googling for "easy-ust" finds no git repositories except for the one I quoted. The Ubuntu distribution (liblttng-ust0) is 2.0.2, but it is nevertheless not self-consistent because the man pages it installs for lttng-ust(3) mention easy-ust. Could it be an lttng-ust distribution was (is) planned for Ubuntu but hasn't made it "out there" yet, and the lttng-ust man pages were included in liblttng-ust0 by accident? There is a nearly complete mismatch between the Ubuntu lttng packages and the lttng.org git repository, which is not conducive to one adding the contents of the latter to what's installed by the former: Ubuntu lttng.org git liblttng-ctl-dev liblttng-ctl0 liblttng-ust-dev liblttng-ust0 liburcu-dev liburcu1 lttng-modules-dkms lttng-modules.git lttng-tools lttng-tools.git lttng-ust.git lttngtop lttngtop.git (2.0?) I tried lttng-ust 2.0.2 (a367ee6) 2013-Apr-18 from http://git.lttng.org/. Although lttng-ust itself compiles correctly (I only omitted the last step, 'sudo make install', in order to use the existing liblttng-ust 2.0.2 installation), easy-ust's make yields precisely the same error: gcc -I. -c -o sample.o sample.c gcc -I. -c -o tp.o tp.c In file included from /usr/local/include/lttng/ust-tracepoint-event.h:496:0, from /usr/local/include/lttng/tracepoint-event.h:40, from sample_component_provider.h:135, from tp.c:25: ././sample_component_provider.h:128:1: error: ?__tp_loglevel_entry__sample_component___TRACE_WARNING? undeclared here (not in a function) make: *** [tp.o] Error 1 Daniel U. Thibault R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) 2459 route de la Bravoure Qu?bec, QC G3J 1X5 CANADA Vox : (418) 844-4000 x4245 Fax : (418) 844-4538 [Valcartier]\\vsi-wdut-o980, [Secteur-SI]\\edge NAC : 918V QSDJ Gouvernement du Canada / Government of Canada LinkedIn: Research Gate: From jistone at redhat.com Mon Jan 14 13:05:10 2013 From: jistone at redhat.com (Josh Stone) Date: Mon, 14 Jan 2013 10:05:10 -0800 Subject: [lttng-dev] [lttng-modules PATCH] Add uprobes support In-Reply-To: <1358131230-3446-1-git-send-email-yannick.brosseau@gmail.com> References: <1358131230-3446-1-git-send-email-yannick.brosseau@gmail.com> Message-ID: <50F448D6.7050600@redhat.com> On 01/13/2013 06:40 PM, Yannick Brosseau wrote: > + ret = uprobe_register(event->u.uprobe.inode, > + event->u.uprobe.offset, > + &event->u.uprobe.up_consumer); > + uprobe_unregister(event->u.uprobe.inode, > + event->u.uprobe.offset, > + &event->u.uprobe.up_consumer); I'm guessing that you're using a Fedora kernel? :) These functions are not yet exported upstream, but coincidentally I just posted a patch for that a few days ago: https://patchwork.kernel.org/patch/1962891/ https://lkml.org/lkml/2013/1/13/118 If there's any more complaint about this, maybe you can chime in to advocate for lttng's needs too. Thanks, Josh From yannick.brosseau at gmail.com Mon Jan 14 13:18:35 2013 From: yannick.brosseau at gmail.com (Yannick Brosseau) Date: Mon, 14 Jan 2013 13:18:35 -0500 Subject: [lttng-dev] [lttng-modules PATCH] Add uprobes support In-Reply-To: <50F448D6.7050600@redhat.com> References: <1358131230-3446-1-git-send-email-yannick.brosseau@gmail.com> <50F448D6.7050600@redhat.com> Message-ID: <50F44BFB.3070206@gmail.com> On 2013-01-14 13:05, Josh Stone wrote: > On 01/13/2013 06:40 PM, Yannick Brosseau wrote: >> + ret = uprobe_register(event->u.uprobe.inode, >> + event->u.uprobe.offset, >> + &event->u.uprobe.up_consumer); >> + uprobe_unregister(event->u.uprobe.inode, >> + event->u.uprobe.offset, >> + &event->u.uprobe.up_consumer); > I'm guessing that you're using a Fedora kernel? :) Oh, you're right... I did not realize that the vanilla kernel did not contains those export. > > These functions are not yet exported upstream, but coincidentally I just > posted a patch for that a few days ago: > > https://patchwork.kernel.org/patch/1962891/ > https://lkml.org/lkml/2013/1/13/118 > > If there's any more complaint about this, maybe you can chime in to > advocate for lttng's needs too. > Ok, I'll weight in if necessary. Yannick From Daniel.Thibault at drdc-rddc.gc.ca Mon Jan 14 14:27:24 2013 From: Daniel.Thibault at drdc-rddc.gc.ca (Thibault, Daniel) Date: Mon, 14 Jan 2013 14:27:24 -0500 Subject: [lttng-dev] lttng-ust quick start? References: <3CA1A65C03C1A34C81BBC6272782E696987596@valcartierex01.valcartier.drdc-rddc.gc.ca> Message-ID: <3CA1A65C03C1A34C81BBC6272782E6969875EA@valcartierex01.valcartier.drdc-rddc.gc.ca> Interestingly, if I do install lttng-ust 2.0.2 (a367ee6) 2013-Apr-18, easy-ust's make compiles correctly. One key difference is that /usr[/local]/include/lttng/tracepoint.h now includes an enum setting the TRACE_WARNING value. The conclusion is inescapable: the Ubuntu liblttng-ust-dev package is broken. How many more headers in this Ubuntu package are the wrong ones? And are any of the other .h-containing packages (liblttng-ctl-dev, liburcu-dev and lttng-modules-dkms) similarly compromised? Daniel U. Thibault R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) 2459 route de la Bravoure Qu?bec, QC G3J 1X5 CANADA Vox : (418) 844-4000 x4245 Fax : (418) 844-4538 [Valcartier]\\vsi-wdut-o980, [Secteur-SI]\\edge NAC : 918V QSDJ Gouvernement du Canada / Government of Canada LinkedIn: Research Gate: From mathieu.desnoyers at efficios.com Mon Jan 14 14:51:04 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 14 Jan 2013 14:51:04 -0500 Subject: [lttng-dev] [lttng-modules PATCH] Add uprobes support In-Reply-To: <50F44BFB.3070206@gmail.com> References: <1358131230-3446-1-git-send-email-yannick.brosseau@gmail.com> <50F448D6.7050600@redhat.com> <50F44BFB.3070206@gmail.com> Message-ID: <20130114195104.GA11211@Krystal> * Yannick Brosseau (yannick.brosseau at gmail.com) wrote: > On 2013-01-14 13:05, Josh Stone wrote: > > On 01/13/2013 06:40 PM, Yannick Brosseau wrote: > >> + ret = uprobe_register(event->u.uprobe.inode, > >> + event->u.uprobe.offset, > >> + &event->u.uprobe.up_consumer); > >> + uprobe_unregister(event->u.uprobe.inode, > >> + event->u.uprobe.offset, > >> + &event->u.uprobe.up_consumer); > > I'm guessing that you're using a Fedora kernel? :) > Oh, you're right... I did not realize that the vanilla kernel did not > contains those export. > > > > These functions are not yet exported upstream, but coincidentally I just > > posted a patch for that a few days ago: > > > > https://patchwork.kernel.org/patch/1962891/ > > https://lkml.org/lkml/2013/1/13/118 > > > > If there's any more complaint about this, maybe you can chime in to > > advocate for lttng's needs too. > > > Ok, I'll weight in if necessary. Yes, we should be able to help out if needed. Meanwhile, we could use kallsyms to lookup these symbols and use them, as we already do in a couple of header under wrappers/ in lttng-modules. Thanks, Mathieu -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Mon Jan 14 14:54:11 2013 From: dgoulet at efficios.com (David Goulet) Date: Mon, 14 Jan 2013 14:54:11 -0500 Subject: [lttng-dev] [lttng-modules PATCH] Add uprobes support In-Reply-To: <20130114195104.GA11211@Krystal> References: <1358131230-3446-1-git-send-email-yannick.brosseau@gmail.com> <50F448D6.7050600@redhat.com> <50F44BFB.3070206@gmail.com> <20130114195104.GA11211@Krystal> Message-ID: <50F46263.9000807@efficios.com> +1 Especially because Uprobe is in mainline since 3.5, would be nice to support it before it gets in 3.8+ ... Cheers! David Mathieu Desnoyers: > * Yannick Brosseau (yannick.brosseau at gmail.com) wrote: >> On 2013-01-14 13:05, Josh Stone wrote: >>> On 01/13/2013 06:40 PM, Yannick Brosseau wrote: >>>> + ret = uprobe_register(event->u.uprobe.inode, >>>> + event->u.uprobe.offset, >>>> + &event->u.uprobe.up_consumer); >>>> + uprobe_unregister(event->u.uprobe.inode, >>>> + event->u.uprobe.offset, >>>> + &event->u.uprobe.up_consumer); >>> I'm guessing that you're using a Fedora kernel? :) >> Oh, you're right... I did not realize that the vanilla kernel did not >> contains those export. >>> >>> These functions are not yet exported upstream, but coincidentally I just >>> posted a patch for that a few days ago: >>> >>> https://patchwork.kernel.org/patch/1962891/ >>> https://lkml.org/lkml/2013/1/13/118 >>> >>> If there's any more complaint about this, maybe you can chime in to >>> advocate for lttng's needs too. >>> >> Ok, I'll weight in if necessary. > > Yes, we should be able to help out if needed. > > Meanwhile, we could use kallsyms to lookup these symbols and use them, > as we already do in a couple of header under wrappers/ in lttng-modules. > > Thanks, > > Mathieu > From jeremie.galarneau at efficios.com Mon Jan 14 11:45:46 2013 From: jeremie.galarneau at efficios.com (=?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=) Date: Mon, 14 Jan 2013 16:45:46 +0000 Subject: [lttng-dev] [PATCH lttng-tools 1/4] Extras: Added lttng.pyc to the clean section of the Python binding makefile. Message-ID: <1358181949-23456-1-git-send-email-jeremie.galarneau@efficios.com> Signed-off-by: J?r?mie Galarneau --- extras/bindings/swig/python/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/bindings/swig/python/Makefile.am b/extras/bindings/swig/python/Makefile.am index a3557b8..d592ded 100644 --- a/extras/bindings/swig/python/Makefile.am +++ b/extras/bindings/swig/python/Makefile.am @@ -24,4 +24,4 @@ lttng_wrap.c: lttng.i sed -i "s/md = d/d/g" lttng_wrap.c sed -i "s/(void)public_symbol;/(void)public_symbol;\n md = d;/g" lttng_wrap.c -CLEANFILES = lttng.i lttng.py lttng_wrap.c +CLEANFILES = lttng.i lttng.py lttng_wrap.c lttng.pyc -- 1.8.1 From jeremie.galarneau at efficios.com Mon Jan 14 11:45:47 2013 From: jeremie.galarneau at efficios.com (=?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=) Date: Mon, 14 Jan 2013 16:45:47 +0000 Subject: [lttng-dev] [PATCH lttng-tools 2/4] Extras: Fix the undefined reference to md build error. In-Reply-To: <1358181949-23456-1-git-send-email-jeremie.galarneau@efficios.com> References: <1358181949-23456-1-git-send-email-jeremie.galarneau@efficios.com> Message-ID: <1358181949-23456-2-git-send-email-jeremie.galarneau@efficios.com> Removed scripted modifications to lttng_wrap.c during Python binding generation. Signed-off-by: J?r?mie Galarneau --- extras/bindings/swig/python/Makefile.am | 4 ---- 1 file changed, 4 deletions(-) diff --git a/extras/bindings/swig/python/Makefile.am b/extras/bindings/swig/python/Makefile.am index d592ded..c6a6901 100644 --- a/extras/bindings/swig/python/Makefile.am +++ b/extras/bindings/swig/python/Makefile.am @@ -17,11 +17,7 @@ _lttng_la_LDFLAGS = -module _lttng_la_LIBADD = $(top_srcdir)/src/lib/lttng-ctl/liblttng-ctl.la \ $(top_srcdir)/src/common/sessiond-comm/libsessiond-comm.la -# SWIG 'warning md variable unused' fixed after SWIG build: lttng_wrap.c: lttng.i $(SWIG) -python -I. -I$(top_srcdir)/src/common/sessiond-comm lttng.i - sed -i "s/PyObject \*m, \*d, \*md;/PyObject \*m, \*d;\n#if defined(SWIGPYTHON_BUILTIN)\nPyObject *md;\n#endif/g" lttng_wrap.c - sed -i "s/md = d/d/g" lttng_wrap.c - sed -i "s/(void)public_symbol;/(void)public_symbol;\n md = d;/g" lttng_wrap.c CLEANFILES = lttng.i lttng.py lttng_wrap.c lttng.pyc -- 1.8.1 From jeremie.galarneau at efficios.com Mon Jan 14 11:45:48 2013 From: jeremie.galarneau at efficios.com (=?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=) Date: Mon, 14 Jan 2013 16:45:48 +0000 Subject: [lttng-dev] [PATCH lttng-tools 3/4] Extras: Redefined PyInt_AsSsize_T to PyLong_AsSsize_t. In-Reply-To: <1358181949-23456-1-git-send-email-jeremie.galarneau@efficios.com> References: <1358181949-23456-1-git-send-email-jeremie.galarneau@efficios.com> Message-ID: <1358181949-23456-3-git-send-email-jeremie.galarneau@efficios.com> Python 3 merges PyInt and PyLong types. This fixes the undefined symbol error encountered when using the bindings with Python 3. Signed-off-by: J?r?mie Galarneau --- extras/bindings/swig/python/lttng.i.in | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/extras/bindings/swig/python/lttng.i.in b/extras/bindings/swig/python/lttng.i.in index 0d6d1e9..244bc22 100644 --- a/extras/bindings/swig/python/lttng.i.in +++ b/extras/bindings/swig/python/lttng.i.in @@ -15,6 +15,14 @@ multiple concurrent processes and threads. Tracing across multiple systems is al #include %} +%{ +#if PY_MAJOR_VERSION >= 3 +// The PyInt and PyLong types were unified as of Python 3 +// This makes the typemap code useable with both Python 2 and 3. +#define PyInt_AsSsize_t PyLong_AsSsize_t +#endif +%} + typedef unsigned int uint32_t; typedef int int32_t; typedef unsigned long long uint64_t; -- 1.8.1 From jeremie.galarneau at efficios.com Mon Jan 14 11:45:49 2013 From: jeremie.galarneau at efficios.com (=?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=) Date: Mon, 14 Jan 2013 16:45:49 +0000 Subject: [lttng-dev] [PATCH lttng-tools 4/4] Extras: Fixed inconsistent use of space and tabs in lttng.i.in. In-Reply-To: <1358181949-23456-1-git-send-email-jeremie.galarneau@efficios.com> References: <1358181949-23456-1-git-send-email-jeremie.galarneau@efficios.com> Message-ID: <1358181949-23456-4-git-send-email-jeremie.galarneau@efficios.com> Python 3 does not allow mixing spaces and tabs. This eliminates the error encountered when importing the lttng module in a Python 3 interpreter. Signed-off-by: J?r?mie Galarneau --- extras/bindings/swig/python/lttng.i.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/bindings/swig/python/lttng.i.in b/extras/bindings/swig/python/lttng.i.in index 244bc22..c947ce3 100644 --- a/extras/bindings/swig/python/lttng.i.in +++ b/extras/bindings/swig/python/lttng.i.in @@ -715,7 +715,7 @@ def calibrate(handle, calibrate): %pythoncode %{ class Handle: - """ + """ Manages a handle. Takes two arguments: (str session_name, Domain domain) """ -- 1.8.1 From paul.chavent at fnac.net Tue Jan 15 07:36:16 2013 From: paul.chavent at fnac.net (paul.chavent at fnac.net) Date: Tue, 15 Jan 2013 13:36:16 +0100 (CET) Subject: [lttng-dev] Compile out of src tree Message-ID: <8549183.73181358253376696.JavaMail.www@wsfrf1114> Hi. Just a little patch in order to succeed building out of src tree. Regards. Paul. diff --git a/tests/tools/health/Makefile.am b/tests/tools/health/Makefile.am index 26d2461..1424f63 100644 --- a/tests/tools/health/Makefile.am +++ b/tests/tools/health/Makefile.am @@ -1,4 +1,4 @@ -AM_CFLAGS = -I. -O2 -g -I../../../include +AM_CFLAGS = -I$(srcdir) -O2 -g -I$(top_srcdir)/include ?AM_LDFLAGS = ? ?if LTTNG_TOOLS_BUILD_WITH_LIBDL From mathieu.desnoyers at efficios.com Tue Jan 15 08:48:50 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 15 Jan 2013 08:48:50 -0500 Subject: [lttng-dev] Compile out of src tree In-Reply-To: <8549183.73181358253376696.JavaMail.www@wsfrf1114> References: <8549183.73181358253376696.JavaMail.www@wsfrf1114> Message-ID: <20130115134850.GA25260@Krystal> * paul.chavent at fnac.net (paul.chavent at fnac.net) wrote: > Hi. > > Just a little patch in order to succeed building out of src tree. Good point! Acked-by: Mathieu Desnoyers > > Regards. > > Paul. > > diff --git a/tests/tools/health/Makefile.am b/tests/tools/health/Makefile.am > index 26d2461..1424f63 100644 > --- a/tests/tools/health/Makefile.am > +++ b/tests/tools/health/Makefile.am > @@ -1,4 +1,4 @@ > -AM_CFLAGS = -I. -O2 -g -I../../../include > +AM_CFLAGS = -I$(srcdir) -O2 -g -I$(top_srcdir)/include > ?AM_LDFLAGS = > ? > ?if LTTNG_TOOLS_BUILD_WITH_LIBDL > > > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Tue Jan 15 11:19:59 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 15 Jan 2013 11:19:59 -0500 Subject: [lttng-dev] [lttng-modules PATCH] Add uprobes support In-Reply-To: <1358131230-3446-1-git-send-email-yannick.brosseau@gmail.com> References: <1358131230-3446-1-git-send-email-yannick.brosseau@gmail.com> Message-ID: <20130115161959.GA26383@Krystal> * Yannick Brosseau (yannick.brosseau at gmail.com) wrote: > The added support is basic. It create an event with no data associated > to the file path + offset specified. > As per the structures currently used we cannot pass a file path bigger > than 256 chars. Using a pointer to a user-space string will allow you to overcome this limitation. e.g. passing through the kernel ABI: char name[LTTNG_KERNEL_SYM_NAME_LEN] char __user *path; uint64_t offset; > > Signed-off-by: Yannick Brosseau > --- > README | 5 +- > lttng-abi.c | 3 + > lttng-abi.h | 7 +++ > lttng-events.c | 18 ++++++ > lttng-events.h | 38 ++++++++++++ > probes/Makefile | 5 ++ > probes/lttng-uprobes.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++++ > 7 files changed, 231 insertions(+), 1 deletion(-) > create mode 100644 probes/lttng-uprobes.c > > diff --git a/README b/README > index 1bcd5b2..7afdaa3 100644 > --- a/README > +++ b/README > @@ -9,7 +9,7 @@ need for additional patches. Other features: > - Produces CTF (Common Trace Format) natively, > (http://www.efficios.com/ctf) > - Tracepoints, Function tracer, CPU Performance Monitoring Unit (PMU) > - counters, kprobes, and kretprobes support, > + counters, kprobes, kretprobes and uprobes support, > - Integrated interface for both kernel and userspace tracing, > - Have the ability to attach "context" information to events in the > trace (e.g. any PMU counter, pid, ppid, tid, comm name, etc). > @@ -86,6 +86,9 @@ CONFIG_KPROBES: > CONFIG_KRETPROBES: > Dynamic function entry/return probe. > lttng enable-event -k --function ... > +CONFIG_UPROBES: > + Dynamic userspace probe. > + lttng enable-event -k --uprobe ... It would be great to implement this feature with integrated lookup of file/line number (using dwarf). I think perf already has some code that does it. Adding Masami in the loop would be very relevant. In terms of usability it will make all different in the world. Of course, this won't change the ABI nor lttng-modules implementation, only the lttng-tools side. > > > * Note about Perf PMU counters support > diff --git a/lttng-abi.c b/lttng-abi.c > index 25a350a..fe428b2 100644 > --- a/lttng-abi.c > +++ b/lttng-abi.c > @@ -610,6 +610,9 @@ int lttng_abi_create_event(struct file *channel_file, > case LTTNG_KERNEL_FUNCTION: > event_param->u.ftrace.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; > break; > + case LTTNG_KERNEL_UPROBE: > + event_param->u.uprobe.path[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; > + break; > default: > break; > } > diff --git a/lttng-abi.h b/lttng-abi.h > index 8d3ecdd..5abdb39 100644 > --- a/lttng-abi.h > +++ b/lttng-abi.h > @@ -34,6 +34,7 @@ enum lttng_kernel_instrumentation { > LTTNG_KERNEL_KRETPROBE = 3, > LTTNG_KERNEL_NOOP = 4, /* not hooked */ > LTTNG_KERNEL_SYSCALL = 5, > + LTTNG_KERNEL_UPROBE = 6, > }; > > /* > @@ -79,6 +80,11 @@ struct lttng_kernel_function_tracer { > char symbol_name[LTTNG_KERNEL_SYM_NAME_LEN]; > }__attribute__((packed)); > > +struct lttng_kernel_uprobe { > + char path[LTTNG_KERNEL_SYM_NAME_LEN]; > + uint64_t offset; > +}__attribute__((packed)); > + > /* > * For syscall tracing, name = '\0' means "enable all". > */ > @@ -94,6 +100,7 @@ struct lttng_kernel_event { > struct lttng_kernel_kretprobe kretprobe; > struct lttng_kernel_kprobe kprobe; > struct lttng_kernel_function_tracer ftrace; > + struct lttng_kernel_uprobe uprobe; > char padding[LTTNG_KERNEL_EVENT_PADDING2]; > } u; > }__attribute__((packed)); > diff --git a/lttng-events.c b/lttng-events.c > index 4f30904..38c901f 100644 > --- a/lttng-events.c > +++ b/lttng-events.c > @@ -392,6 +392,16 @@ struct lttng_event *lttng_event_create(struct lttng_channel *chan, > if (!event->desc) > goto register_error; > break; > + case LTTNG_KERNEL_UPROBE: > + ret = lttng_uprobes_register(event_param->name, > + event_param->u.uprobe.path, > + event_param->u.uprobe.offset, > + event); > + if (ret) > + goto register_error; > + ret = try_module_get(event->desc->owner); > + WARN_ON_ONCE(!ret); > + break; > default: > WARN_ON_ONCE(1); > } > @@ -443,6 +453,10 @@ int _lttng_event_unregister(struct lttng_event *event) > case LTTNG_KERNEL_NOOP: > ret = 0; > break; > + case LTTNG_KERNEL_UPROBE: > + lttng_uprobes_unregister(event); > + ret = 0; > + break; > default: > WARN_ON_ONCE(1); > } > @@ -473,6 +487,10 @@ void _lttng_event_destroy(struct lttng_event *event) > break; > case LTTNG_KERNEL_NOOP: > break; > + case LTTNG_KERNEL_UPROBE: > + module_put(event->desc->owner); > + lttng_uprobes_destroy_private(event); > + break; > default: > WARN_ON_ONCE(1); > } > diff --git a/lttng-events.h b/lttng-events.h > index 09d5618..e630db0 100644 > --- a/lttng-events.h > +++ b/lttng-events.h > @@ -26,6 +26,9 @@ > #include > #include > #include > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) > +#include > +#endif please just include a wrapper/uprobes.h , so we move the ifdef to wrapper/. > #include "wrapper/uuid.h" > #include "lttng-abi.h" > #include "lttng-abi-old.h" > @@ -203,6 +206,13 @@ struct lttng_event { > struct { > char *symbol_name; > } ftrace; > + struct { > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) > + struct uprobe_consumer up_consumer; > +#endif an ifdef in a wrapper that defines struct uprobe_consumer locally if necessary would be better. We need to shove all this compatibility code under wrappers/ whenever possible. > + struct inode *inode; > + loff_t offset; > + } uprobe; > } u; > struct list_head list; /* Event list */ > unsigned int metadata_dumped:1; > @@ -406,6 +416,34 @@ void lttng_kprobes_destroy_private(struct lttng_event *event) > } > #endif > > +#ifdef CONFIG_UPROBES > +int lttng_uprobes_register(const char *name, > + const char *path, > + uint64_t offset, > + struct lttng_event *event); > +void lttng_uprobes_unregister(struct lttng_event *event); > +void lttng_uprobes_destroy_private(struct lttng_event *event); > +#else > +static inline > +int lttng_uprobes_register(const char *name, > + const char *path, > + uint64_t offset, > + struct lttng_event *event) > +{ > + return -ENOSYS; > +} > + > +static inline > +void lttng_uprobes_unregister(struct lttng_event *event) > +{ > +} > + > +static inline > +void lttng_uprobes_destroy_private(struct lttng_event *event) > +{ > +} > +#endif > + > #ifdef CONFIG_KRETPROBES > int lttng_kretprobes_register(const char *name, > const char *symbol_name, > diff --git a/probes/Makefile b/probes/Makefile > index 088cd5f..de0f1a7 100644 > --- a/probes/Makefile > +++ b/probes/Makefile > @@ -208,6 +208,11 @@ ifneq ($(CONFIG_DYNAMIC_FTRACE),) > obj-m += lttng-ftrace.o > endif > > +ifneq ($(CONFIG_UPROBES),) > +obj-m += lttng-uprobes.o > +endif > + > + Extra whiteline to remove. > endif > > else > diff --git a/probes/lttng-uprobes.c b/probes/lttng-uprobes.c > new file mode 100644 > index 0000000..1d68273 > --- /dev/null > +++ b/probes/lttng-uprobes.c > @@ -0,0 +1,156 @@ > +/* > + * probes/lttng-uprobes.c > + * > + * LTTng uprobes integration module. > + * > + * Copyright (C) 2013 Yannick Brosseau > + * Copyright (C) 2009-2012 Mathieu Desnoyers > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library 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 > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include "../lttng-events.h" > +#include "../wrapper/ringbuffer/frontend_types.h" > +#include "../wrapper/vmalloc.h" > +#include "../lttng-tracer.h" > + > +static > +int lttng_uprobes_handler_pre(struct uprobe_consumer *uc, struct pt_regs *regs) > +{ > + struct lttng_event *event = > + container_of(uc, struct lttng_event, u.uprobe.up_consumer); > + struct lttng_channel *chan = event->chan; > + struct lib_ring_buffer_ctx ctx; > + int ret; > + > + if (unlikely(!ACCESS_ONCE(chan->session->active))) > + return 0; > + if (unlikely(!ACCESS_ONCE(chan->enabled))) > + return 0; > + if (unlikely(!ACCESS_ONCE(event->enabled))) > + return 0; > + > + lib_ring_buffer_ctx_init(&ctx, chan->chan, event, 0, > + 0, -1); > + ret = chan->ops->event_reserve(&ctx, event->id); > + if (ret < 0) > + return 0; > + lib_ring_buffer_align_ctx(&ctx, 0); > + chan->ops->event_write(&ctx, 0, 0); > + chan->ops->event_commit(&ctx); > + return 0; > +} > + > +/* > + * Create event description > + */ > +static > +int lttng_create_uprobe_event(const char *name, struct lttng_event *event) > +{ > + struct lttng_event_desc *desc; > + int ret; > + > + desc = kzalloc(sizeof(*event->desc), GFP_KERNEL); > + if (!desc) > + return -ENOMEM; > + desc->name = kstrdup(name, GFP_KERNEL); > + if (!desc->name) { > + ret = -ENOMEM; > + goto error_str; > + } > + desc->owner = THIS_MODULE; > + event->desc = desc; > + > + return 0; > + > +error_str: > + kfree(desc); > + return ret; > +} > + > +int lttng_uprobes_register(const char *name, > + const char *path_name, > + uint64_t offset, > + struct lttng_event *event) > +{ > + int ret; > + > + if (path_name[0] == '\0') > + path_name = NULL; > + > + ret = lttng_create_uprobe_event(name, event); > + if (ret) > + goto error; > + memset(&event->u.uprobe.up_consumer, 0, > + sizeof(event->u.uprobe.up_consumer)); > + event->u.uprobe.up_consumer.handler = lttng_uprobes_handler_pre; > + if (path_name) { > + struct path path; > + ret = kern_path(path_name, LOOKUP_FOLLOW, &path); > + if (ret) > + goto path_error; > + > + event->u.uprobe.inode = igrab(path.dentry->d_inode); > + } > + event->u.uprobe.offset = offset; > + > + /* TODO Is this also true for uprobes? The memory we just zmalloc'd could theoretically trigger a minor page fault (if the memory segment is ever very very large and the kernel needs to fall back on vmalloc). > + * Ensure the memory we just allocated don't trigger page faults. > + * Well.. kprobes itself puts the page fault handler on the blacklist, > + * but we can never be too careful. > + */ > + wrapper_vmalloc_sync_all(); > + > + ret = uprobe_register(event->u.uprobe.inode, > + event->u.uprobe.offset, > + &event->u.uprobe.up_consumer); > + if (ret) > + goto register_error; > + return 0; > + > +register_error: > + iput(event->u.uprobe.inode); > +path_error: > + kfree(event->desc->name); > + kfree(event->desc); not sure why kfree these, which are not allocated within this function ? Should be cleaned up. > +error: > + return ret; > +} > +EXPORT_SYMBOL_GPL(lttng_uprobes_register); > + > +void lttng_uprobes_unregister(struct lttng_event *event) > +{ > + uprobe_unregister(event->u.uprobe.inode, > + event->u.uprobe.offset, > + &event->u.uprobe.up_consumer); Hrm, we should probably report to uprobes developers that uprobe_unregister() should return errors instead of silently returning. Thanks ! Mathieu > +} > +EXPORT_SYMBOL_GPL(lttng_uprobes_unregister); > + > +void lttng_uprobes_destroy_private(struct lttng_event *event) > +{ > + iput(event->u.uprobe.inode); > + kfree(event->desc->name); > + kfree(event->desc); > +} > +EXPORT_SYMBOL_GPL(lttng_uprobes_destroy_private); > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Yannick Brosseau"); > +MODULE_DESCRIPTION("Linux Trace Toolkit Uprobes Support"); > -- > 1.7.10.4 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From paulmck at linux.vnet.ibm.com Tue Jan 15 13:19:36 2013 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Tue, 15 Jan 2013 10:19:36 -0800 Subject: [lttng-dev] [PATCH] Add ACCESS_ONCE() to avoid compiler splitting assignments Message-ID: <20130115181936.GA30319@linux.vnet.ibm.com> As noted by Konstantin Khlebnikov, gcc can split assignment of constants to long variables (https://lkml.org/lkml/2013/1/15/141), though assignment of NULL (0) is OK. Assuming that a gcc bug is fixed (http://gcc.gnu.org/bugzilla/attachment.cgi?id=29169&action=diff has a patch), making the store be volatile keeps gcc from splitting. This commit therefore applies ACCESS_ONCE() to CMM_STORE_SHARED(), which is the underlying primitive used by rcu_assign_pointer(). Signed-off-by: Paul E. McKenney diff --git a/urcu/system.h b/urcu/system.h index 2a45f22..7a1887e 100644 --- a/urcu/system.h +++ b/urcu/system.h @@ -49,7 +49,7 @@ */ #define CMM_STORE_SHARED(x, v) \ ({ \ - __typeof__(x) _v = _CMM_STORE_SHARED(x, v); \ + __typeof__(x) CMM_ACCESS_ONCE(_v) = _CMM_STORE_SHARED(x, v); \ cmm_smp_wmc(); \ _v; \ }) From paulmck at linux.vnet.ibm.com Tue Jan 15 13:38:25 2013 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Tue, 15 Jan 2013 10:38:25 -0800 Subject: [lttng-dev] [rp] [RFC PATCH urcu] Add "last" output parameter to pop/dequeue In-Reply-To: <20121217144008.GA5086@Krystal> References: <20121213114456.GA9780@Krystal> <20121214163609.GD2542@linux.vnet.ibm.com> <20121217144008.GA5086@Krystal> Message-ID: <20130115183825.GR3384@linux.vnet.ibm.com> [Sorry for the delay, finally getting back to this.] On Mon, Dec 17, 2012 at 09:40:09AM -0500, Mathieu Desnoyers wrote: > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > On Thu, Dec 13, 2012 at 06:44:56AM -0500, Mathieu Desnoyers wrote: > > > I noticed that in addition to having: > > > > > > - push/enqueue returning whether the stack/queue was empty prior to the > > > operation, > > > - pop_all/splice, by nature, emptying the stack/queue, > > > > > > it can be interesting to make pop/dequeue operations return whether they > > > are returning the last element of the stack/queue (therefore emptying > > > it). This allow extending the test-cases covering the number of empty > > > stack/queue encountered by both push/enqueuer and pop/dequeuer threads > > > not only to push/enqueue paired with pop_all/splice, but also to > > > pop/dequeue. > > > > > > In the case of wfstack, this unfortunately requires to modify an already > > > exposed API. As a RFC, one question we should answer is how we want to > > > handle the way forward: should we add new functions to the wfstack API > > > and leave the existing ones alone ? > > > > > > Thoughts ? > > > > Hmmm... What is the use case, given that a push might happen immediately > > after the pop said that the stack/queue was empty? Of course, if we > > somehow know that there are no concurrent pushes, we could instead > > check for empty. > > > > So what am I missing here? > > The setup for those use-cases is the following (I'm using the stack as > example, but the same applies to queue): > > - we have N threads doing push and using the push return value that > states whether it pushed into an empty stack. > - we have M threads doing "pop", using the return value to know if it > pops a stack into an empty-stack-state. Following the locking > requirements, we protect those M threads'pop by a mutex, but they > don't need to be protected against push. > > Just to help understanding where the idea comes from, let's start with > another use-case that is similar (push/pop_all). Knowing whether we > pushed into an empty stack along with pop_all become very useful when > you want to combine the stack with a higher level batching semantic > linked to the elements present within the stack. > > In the case of grace period batching, for instance, I used > "push"/"pop_all" to provide this kind of semantic: if we push into an > empty stack, we know we will have to go through the grace period. If we > are pushed into a non-empty stack, we just wait to be awakened by the > first thread which was pushed into the stack. This requires that we use > "pop_all" before going though the grace period. > > Now more specifically about "pop", one use-case I have in mind is > energy-efficient handling of empty stacks. With M threads executing > "pop", let's suppose we want them to be blocked on a futex when there is > nothing to do. Now the tricky part is: how can we do this without adding > overhead (extra load/stores) to the stack ? > > If we have the ability to know whether we are popping the last element > of a stack, we can use this information to go into a futex wait state > after having handled the last element. Since the threads doing "push" > would monitor whether they push into an empty stack, they would wake us > whenever needed. > > If instead we choose to simply wait until one of the M threads discovers > that the stack is actually empty, we are issuing extra "pop" (which > fails) each time the stack is empty. In the worse-case, if a queue > always flip between 0 and 1 elements, we double the number of "pop" > needed to handle the same amount of nodes. > > Otherwise, if we choose to add an explicit check to see whether the > stack is empty, we are adding an extra load of the head node for every > pop. > > Another use-case I see is low-overhead monitoring of stack usage > efficiency. For this kind of use-case, we might want to know, both > within push and pop threads, if we are underutilizing our system > resources. Having the ability to know that we are reaching empty state > without any extra overhead to stack memory traffic gives us this > ability. > > I must admit that the use-cases for returning whether pop takes the last > element is not as strong as the batching case with push/pop_all, mainly > because AFAIU, we can achieve the same result by doing an extra check of > stack emptiness state (either by an explicit empty() check, or by > issuing an extra pop that will see an empty stack). What we are saving > here is the extra overhead on stack cache-lines cause by this extra > check. > > Another use-case, although maybe less compelling, is for validation. > With concurrent threads doing push/pop/pop_all operations on the stack, > we can perform the following check: If we empty the stack at the end of > test execution, the > > number of push-to-empty-stack > > must be equal to the > > number of pop_all-from-non-empty-stack > + number of pop-last-element-from-non-empty-stack > > We should note that this validation could not be performed if "pop" is > not returning whether it popped the last stack element (checked > atomically with the pop operation). This is a use-case where adding an > extra check on the pop-side would not work (it needs to be performed > atomically with pop). > > And maybe there are other use-cases that are currently beyond my > imagination too. > > Thoughts ? Sounds like a job for a separate API member that can be added when needed. I do admit that you have legitimate use cases, but I do not believe that they will be the common case. Maybe due to failure of imagination on my part, but... ;-) Thanx, Paul > Thanks, > > Mathieu > > > > > > Thanx, Paul > > > > > Thanks, > > > > > > Mathieu > > > > > > --- > > > diff --git a/tests/test_urcu_wfcq.c b/tests/test_urcu_wfcq.c > > > index 91285a5..de9566d 100644 > > > --- a/tests/test_urcu_wfcq.c > > > +++ b/tests/test_urcu_wfcq.c > > > @@ -168,6 +168,7 @@ static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); > > > static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); > > > static DEFINE_URCU_TLS(unsigned long long, nr_empty_dest_enqueues); > > > static DEFINE_URCU_TLS(unsigned long long, nr_splice); > > > +static DEFINE_URCU_TLS(unsigned long long, nr_dequeue_last); > > > > > > static unsigned int nr_enqueuers; > > > static unsigned int nr_dequeuers; > > > @@ -228,11 +229,15 @@ fail: > > > static void do_test_dequeue(enum test_sync sync) > > > { > > > struct cds_wfcq_node *node; > > > + bool last; > > > > > > if (sync == TEST_SYNC_MUTEX) > > > - node = cds_wfcq_dequeue_blocking(&head, &tail); > > > + node = cds_wfcq_dequeue_blocking(&head, &tail, &last); > > > else > > > - node = __cds_wfcq_dequeue_blocking(&head, &tail); > > > + node = __cds_wfcq_dequeue_blocking(&head, &tail, &last); > > > + > > > + if (last) > > > + URCU_TLS(nr_dequeue_last)++; > > > > > > if (node) { > > > free(node); > > > @@ -263,6 +268,7 @@ static void do_test_splice(enum test_sync sync) > > > break; > > > case CDS_WFCQ_RET_DEST_EMPTY: > > > URCU_TLS(nr_splice)++; > > > + URCU_TLS(nr_dequeue_last)++; > > > /* ok */ > > > break; > > > case CDS_WFCQ_RET_DEST_NON_EMPTY: > > > @@ -325,16 +331,21 @@ static void *thr_dequeuer(void *_count) > > > count[0] = URCU_TLS(nr_dequeues); > > > count[1] = URCU_TLS(nr_successful_dequeues); > > > count[2] = URCU_TLS(nr_splice); > > > + count[3] = URCU_TLS(nr_dequeue_last); > > > return ((void*)2); > > > } > > > > > > -static void test_end(unsigned long long *nr_dequeues) > > > +static void test_end(unsigned long long *nr_dequeues, > > > + unsigned long long *nr_dequeue_last) > > > { > > > struct cds_wfcq_node *node; > > > + bool last; > > > > > > do { > > > - node = cds_wfcq_dequeue_blocking(&head, &tail); > > > + node = cds_wfcq_dequeue_blocking(&head, &tail, &last); > > > if (node) { > > > + if (last) > > > + (*nr_dequeue_last)++; > > > free(node); > > > (*nr_dequeues)++; > > > } > > > @@ -367,7 +378,7 @@ int main(int argc, char **argv) > > > unsigned long long tot_successful_enqueues = 0, > > > tot_successful_dequeues = 0, > > > tot_empty_dest_enqueues = 0, > > > - tot_splice = 0; > > > + tot_splice = 0, tot_dequeue_last = 0; > > > unsigned long long end_dequeues = 0; > > > int i, a, retval = 0; > > > > > > @@ -480,7 +491,7 @@ int main(int argc, char **argv) > > > tid_enqueuer = malloc(sizeof(*tid_enqueuer) * nr_enqueuers); > > > tid_dequeuer = malloc(sizeof(*tid_dequeuer) * nr_dequeuers); > > > count_enqueuer = malloc(3 * sizeof(*count_enqueuer) * nr_enqueuers); > > > - count_dequeuer = malloc(3 * sizeof(*count_dequeuer) * nr_dequeuers); > > > + count_dequeuer = malloc(4 * sizeof(*count_dequeuer) * nr_dequeuers); > > > cds_wfcq_init(&head, &tail); > > > > > > next_aff = 0; > > > @@ -493,7 +504,7 @@ int main(int argc, char **argv) > > > } > > > for (i = 0; i < nr_dequeuers; i++) { > > > err = pthread_create(&tid_dequeuer[i], NULL, thr_dequeuer, > > > - &count_dequeuer[3 * i]); > > > + &count_dequeuer[4 * i]); > > > if (err != 0) > > > exit(1); > > > } > > > @@ -533,34 +544,37 @@ int main(int argc, char **argv) > > > err = pthread_join(tid_dequeuer[i], &tret); > > > if (err != 0) > > > exit(1); > > > - tot_dequeues += count_dequeuer[3 * i]; > > > - tot_successful_dequeues += count_dequeuer[3 * i + 1]; > > > - tot_splice += count_dequeuer[3 * i + 2]; > > > + tot_dequeues += count_dequeuer[4 * i]; > > > + tot_successful_dequeues += count_dequeuer[4 * i + 1]; > > > + tot_splice += count_dequeuer[4 * i + 2]; > > > + tot_dequeue_last += count_dequeuer[4 * i + 3]; > > > } > > > > > > - test_end(&end_dequeues); > > > + test_end(&end_dequeues, &tot_dequeue_last); > > > > > > printf_verbose("total number of enqueues : %llu, dequeues %llu\n", > > > tot_enqueues, tot_dequeues); > > > printf_verbose("total number of successful enqueues : %llu, " > > > "enqueues to empty dest : %llu, " > > > "successful dequeues %llu, " > > > - "splice : %llu\n", > > > + "splice : %llu, dequeue_last : %llu\n", > > > tot_successful_enqueues, > > > tot_empty_dest_enqueues, > > > tot_successful_dequeues, > > > - tot_splice); > > > + tot_splice, tot_dequeue_last); > > > printf("SUMMARY %-25s testdur %4lu nr_enqueuers %3u wdelay %6lu " > > > "nr_dequeuers %3u " > > > "rdur %6lu nr_enqueues %12llu nr_dequeues %12llu " > > > "successful enqueues %12llu enqueues to empty dest %12llu " > > > "successful dequeues %12llu splice %12llu " > > > + "dequeue_last %llu " > > > "end_dequeues %llu nr_ops %12llu\n", > > > argv[0], duration, nr_enqueuers, wdelay, > > > nr_dequeuers, rduration, tot_enqueues, tot_dequeues, > > > tot_successful_enqueues, > > > tot_empty_dest_enqueues, > > > - tot_successful_dequeues, tot_splice, end_dequeues, > > > + tot_successful_dequeues, tot_splice, tot_dequeue_last, > > > + end_dequeues, > > > tot_enqueues + tot_dequeues); > > > > > > if (tot_successful_enqueues != tot_successful_dequeues + end_dequeues) { > > > @@ -576,12 +590,11 @@ int main(int argc, char **argv) > > > * exactly as many empty queues than the number of non-empty > > > * src splice. > > > */ > > > - if (test_wait_empty && test_splice && !test_dequeue > > > - && tot_empty_dest_enqueues != tot_splice) { > > > + if (tot_empty_dest_enqueues != tot_dequeue_last) { > > > printf("WARNING! Discrepancy between empty enqueue (%llu) and " > > > - "number of non-empty splice (%llu)\n", > > > + "number of dequeue of last element (%llu)\n", > > > tot_empty_dest_enqueues, > > > - tot_splice); > > > + tot_dequeue_last); > > > retval = 1; > > > } > > > free(count_enqueuer); > > > diff --git a/tests/test_urcu_wfs.c b/tests/test_urcu_wfs.c > > > index 259ca24..6c54153 100644 > > > --- a/tests/test_urcu_wfs.c > > > +++ b/tests/test_urcu_wfs.c > > > @@ -171,6 +171,7 @@ static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); > > > static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); > > > static DEFINE_URCU_TLS(unsigned long long, nr_empty_dest_enqueues); > > > static DEFINE_URCU_TLS(unsigned long long, nr_pop_all); > > > +static DEFINE_URCU_TLS(unsigned long long, nr_pop_last); > > > > > > static unsigned int nr_enqueuers; > > > static unsigned int nr_dequeuers; > > > @@ -230,14 +231,17 @@ fail: > > > static void do_test_pop(enum test_sync sync) > > > { > > > struct cds_wfs_node *node; > > > + bool last; > > > > > > if (sync == TEST_SYNC_MUTEX) > > > cds_wfs_pop_lock(&s); > > > - node = __cds_wfs_pop_blocking(&s); > > > + node = __cds_wfs_pop_blocking(&s, &last); > > > if (sync == TEST_SYNC_MUTEX) > > > cds_wfs_pop_unlock(&s); > > > > > > if (node) { > > > + if (last) > > > + URCU_TLS(nr_pop_last)++; > > > free(node); > > > URCU_TLS(nr_successful_dequeues)++; > > > } > > > @@ -260,6 +264,7 @@ static void do_test_pop_all(enum test_sync sync) > > > return; > > > > > > URCU_TLS(nr_pop_all)++; > > > + URCU_TLS(nr_pop_last)++; > > > > > > cds_wfs_for_each_blocking_safe(head, node, n) { > > > free(node); > > > @@ -308,24 +313,30 @@ static void *thr_dequeuer(void *_count) > > > > > > printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " > > > "dequeues %llu, successful_dequeues %llu " > > > - "pop_all %llu\n", > > > + "pop_all %llu pop_last %llu\n", > > > pthread_self(), > > > (unsigned long) gettid(), > > > URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues), > > > - URCU_TLS(nr_pop_all)); > > > + URCU_TLS(nr_pop_all), > > > + URCU_TLS(nr_pop_last)); > > > count[0] = URCU_TLS(nr_dequeues); > > > count[1] = URCU_TLS(nr_successful_dequeues); > > > count[2] = URCU_TLS(nr_pop_all); > > > + count[3] = URCU_TLS(nr_pop_last); > > > return ((void*)2); > > > } > > > > > > -static void test_end(struct cds_wfs_stack *s, unsigned long long *nr_dequeues) > > > +static void test_end(struct cds_wfs_stack *s, unsigned long long *nr_dequeues, > > > + unsigned long long *nr_pop_last) > > > { > > > struct cds_wfs_node *node; > > > + bool last; > > > > > > do { > > > - node = cds_wfs_pop_blocking(s); > > > + node = cds_wfs_pop_blocking(s, &last); > > > if (node) { > > > + if (last) > > > + (*nr_pop_last)++; > > > free(node); > > > (*nr_dequeues)++; > > > } > > > @@ -358,7 +369,7 @@ int main(int argc, char **argv) > > > unsigned long long tot_successful_enqueues = 0, > > > tot_successful_dequeues = 0, > > > tot_empty_dest_enqueues = 0, > > > - tot_pop_all = 0; > > > + tot_pop_all = 0, tot_pop_last = 0; > > > unsigned long long end_dequeues = 0; > > > int i, a, retval = 0; > > > > > > @@ -471,7 +482,7 @@ int main(int argc, char **argv) > > > tid_enqueuer = malloc(sizeof(*tid_enqueuer) * nr_enqueuers); > > > tid_dequeuer = malloc(sizeof(*tid_dequeuer) * nr_dequeuers); > > > count_enqueuer = malloc(3 * sizeof(*count_enqueuer) * nr_enqueuers); > > > - count_dequeuer = malloc(3 * sizeof(*count_dequeuer) * nr_dequeuers); > > > + count_dequeuer = malloc(4 * sizeof(*count_dequeuer) * nr_dequeuers); > > > cds_wfs_init(&s); > > > > > > next_aff = 0; > > > @@ -484,7 +495,7 @@ int main(int argc, char **argv) > > > } > > > for (i = 0; i < nr_dequeuers; i++) { > > > err = pthread_create(&tid_dequeuer[i], NULL, thr_dequeuer, > > > - &count_dequeuer[3 * i]); > > > + &count_dequeuer[4 * i]); > > > if (err != 0) > > > exit(1); > > > } > > > @@ -524,34 +535,36 @@ int main(int argc, char **argv) > > > err = pthread_join(tid_dequeuer[i], &tret); > > > if (err != 0) > > > exit(1); > > > - tot_dequeues += count_dequeuer[3 * i]; > > > - tot_successful_dequeues += count_dequeuer[3 * i + 1]; > > > - tot_pop_all += count_dequeuer[3 * i + 2]; > > > + tot_dequeues += count_dequeuer[4 * i]; > > > + tot_successful_dequeues += count_dequeuer[4 * i + 1]; > > > + tot_pop_all += count_dequeuer[4 * i + 2]; > > > + tot_pop_last += count_dequeuer[4 * i + 3]; > > > } > > > > > > - test_end(&s, &end_dequeues); > > > + test_end(&s, &end_dequeues, &tot_pop_last); > > > > > > printf_verbose("total number of enqueues : %llu, dequeues %llu\n", > > > tot_enqueues, tot_dequeues); > > > printf_verbose("total number of successful enqueues : %llu, " > > > "enqueues to empty dest : %llu, " > > > "successful dequeues %llu, " > > > - "pop_all : %llu\n", > > > + "pop_all : %llu, pop_last : %llu\n", > > > tot_successful_enqueues, > > > tot_empty_dest_enqueues, > > > tot_successful_dequeues, > > > - tot_pop_all); > > > + tot_pop_all, tot_pop_last); > > > printf("SUMMARY %-25s testdur %4lu nr_enqueuers %3u wdelay %6lu " > > > "nr_dequeuers %3u " > > > "rdur %6lu nr_enqueues %12llu nr_dequeues %12llu " > > > "successful enqueues %12llu enqueues to empty dest %12llu " > > > "successful dequeues %12llu pop_all %12llu " > > > - "end_dequeues %llu nr_ops %12llu\n", > > > + "pop_last %llu end_dequeues %llu nr_ops %12llu\n", > > > argv[0], duration, nr_enqueuers, wdelay, > > > nr_dequeuers, rduration, tot_enqueues, tot_dequeues, > > > tot_successful_enqueues, > > > tot_empty_dest_enqueues, > > > - tot_successful_dequeues, tot_pop_all, end_dequeues, > > > + tot_successful_dequeues, tot_pop_all, tot_pop_last, > > > + end_dequeues, > > > tot_enqueues + tot_dequeues); > > > if (tot_successful_enqueues != tot_successful_dequeues + end_dequeues) { > > > printf("WARNING! Discrepancy between nr succ. enqueues %llu vs " > > > @@ -561,16 +574,14 @@ int main(int argc, char **argv) > > > retval = 1; > > > } > > > /* > > > - * If only using pop_all to dequeue, the enqueuer should see > > > - * exactly as many empty queues than the number of non-empty > > > - * stacks dequeued. > > > + * The enqueuer should see exactly as many empty queues than the > > > + * number of non-empty stacks dequeued. > > > */ > > > - if (test_wait_empty && test_pop_all && !test_pop > > > - && tot_empty_dest_enqueues != tot_pop_all) { > > > + if (tot_empty_dest_enqueues != tot_pop_last) { > > > printf("WARNING! Discrepancy between empty enqueue (%llu) and " > > > - "number of non-empty pop_all (%llu)\n", > > > + "number of pop last (%llu)\n", > > > tot_empty_dest_enqueues, > > > - tot_pop_all); > > > + tot_pop_last); > > > retval = 1; > > > } > > > free(count_enqueuer); > > > diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h > > > index 4b3535a..33c99ed 100644 > > > --- a/urcu/static/wfcqueue.h > > > +++ b/urcu/static/wfcqueue.h > > > @@ -352,16 +352,23 @@ ___cds_wfcq_next_nonblocking(struct cds_wfcq_head *head, > > > static inline struct cds_wfcq_node * > > > ___cds_wfcq_dequeue(struct cds_wfcq_head *head, > > > struct cds_wfcq_tail *tail, > > > + bool *last, > > > int blocking) > > > { > > > struct cds_wfcq_node *node, *next; > > > > > > - if (_cds_wfcq_empty(head, tail)) > > > + if (_cds_wfcq_empty(head, tail)) { > > > + if (last) > > > + *last = 0; > > > return NULL; > > > + } > > > > > > node = ___cds_wfcq_node_sync_next(&head->node, blocking); > > > - if (!blocking && node == CDS_WFCQ_WOULDBLOCK) > > > + if (!blocking && node == CDS_WFCQ_WOULDBLOCK) { > > > + if (last) > > > + *last = 0; > > > return CDS_WFCQ_WOULDBLOCK; > > > + } > > > > > > if ((next = CMM_LOAD_SHARED(node->next)) == NULL) { > > > /* > > > @@ -379,8 +386,11 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, > > > * content. > > > */ > > > _cds_wfcq_node_init(&head->node); > > > - if (uatomic_cmpxchg(&tail->p, node, &head->node) == node) > > > + if (uatomic_cmpxchg(&tail->p, node, &head->node) == node) { > > > + if (last) > > > + *last = 1; > > > return node; > > > + } > > > next = ___cds_wfcq_node_sync_next(node, blocking); > > > /* > > > * In nonblocking mode, if we would need to block to > > > @@ -389,6 +399,8 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, > > > */ > > > if (!blocking && next == CDS_WFCQ_WOULDBLOCK) { > > > head->node.next = node; > > > + if (last) > > > + *last = 0; > > > return CDS_WFCQ_WOULDBLOCK; > > > } > > > } > > > @@ -400,6 +412,8 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, > > > > > > /* Load q->head.next before loading node's content */ > > > cmm_smp_read_barrier_depends(); > > > + if (last) > > > + *last = 0; > > > return node; > > > } > > > > > > @@ -414,9 +428,9 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, > > > */ > > > static inline struct cds_wfcq_node * > > > ___cds_wfcq_dequeue_blocking(struct cds_wfcq_head *head, > > > - struct cds_wfcq_tail *tail) > > > + struct cds_wfcq_tail *tail, bool *last) > > > { > > > - return ___cds_wfcq_dequeue(head, tail, 1); > > > + return ___cds_wfcq_dequeue(head, tail, last, 1); > > > } > > > > > > /* > > > @@ -427,9 +441,9 @@ ___cds_wfcq_dequeue_blocking(struct cds_wfcq_head *head, > > > */ > > > static inline struct cds_wfcq_node * > > > ___cds_wfcq_dequeue_nonblocking(struct cds_wfcq_head *head, > > > - struct cds_wfcq_tail *tail) > > > + struct cds_wfcq_tail *tail, bool *last) > > > { > > > - return ___cds_wfcq_dequeue(head, tail, 0); > > > + return ___cds_wfcq_dequeue(head, tail, last, 0); > > > } > > > > > > /* > > > @@ -542,12 +556,12 @@ ___cds_wfcq_splice_nonblocking( > > > */ > > > static inline struct cds_wfcq_node * > > > _cds_wfcq_dequeue_blocking(struct cds_wfcq_head *head, > > > - struct cds_wfcq_tail *tail) > > > + struct cds_wfcq_tail *tail, bool *last) > > > { > > > struct cds_wfcq_node *retval; > > > > > > _cds_wfcq_dequeue_lock(head, tail); > > > - retval = ___cds_wfcq_dequeue_blocking(head, tail); > > > + retval = ___cds_wfcq_dequeue_blocking(head, tail, last); > > > _cds_wfcq_dequeue_unlock(head, tail); > > > return retval; > > > } > > > diff --git a/urcu/static/wfstack.h b/urcu/static/wfstack.h > > > index 9bc9519..2ebda27 100644 > > > --- a/urcu/static/wfstack.h > > > +++ b/urcu/static/wfstack.h > > > @@ -161,23 +161,35 @@ ___cds_wfs_node_sync_next(struct cds_wfs_node *node, int blocking) > > > > > > static inline > > > struct cds_wfs_node * > > > -___cds_wfs_pop(struct cds_wfs_stack *s, int blocking) > > > +___cds_wfs_pop(struct cds_wfs_stack *s, bool *last, int blocking) > > > { > > > struct cds_wfs_head *head, *new_head; > > > struct cds_wfs_node *next; > > > > > > for (;;) { > > > head = CMM_LOAD_SHARED(s->head); > > > - if (___cds_wfs_end(head)) > > > + if (___cds_wfs_end(head)) { > > > + if (last) > > > + *last = 0; > > > return NULL; > > > + } > > > next = ___cds_wfs_node_sync_next(&head->node, blocking); > > > - if (!blocking && next == CDS_WFS_WOULDBLOCK) > > > + if (!blocking && next == CDS_WFS_WOULDBLOCK) { > > > + if (last) > > > + *last = 0; > > > return CDS_WFS_WOULDBLOCK; > > > + } > > > new_head = caa_container_of(next, struct cds_wfs_head, node); > > > - if (uatomic_cmpxchg(&s->head, head, new_head) == head) > > > + if (uatomic_cmpxchg(&s->head, head, new_head) == head) { > > > + if (last) > > > + *last = ___cds_wfs_end(new_head); > > > return &head->node; > > > - if (!blocking) > > > + } > > > + if (!blocking) { > > > + if (last) > > > + *last = 0; > > > return CDS_WFS_WOULDBLOCK; > > > + } > > > /* busy-loop if head changed under us */ > > > } > > > } > > > @@ -200,9 +212,9 @@ ___cds_wfs_pop(struct cds_wfs_stack *s, int blocking) > > > */ > > > static inline > > > struct cds_wfs_node * > > > -___cds_wfs_pop_blocking(struct cds_wfs_stack *s) > > > +___cds_wfs_pop_blocking(struct cds_wfs_stack *s, bool *last) > > > { > > > - return ___cds_wfs_pop(s, 1); > > > + return ___cds_wfs_pop(s, last, 1); > > > } > > > > > > /* > > > @@ -213,9 +225,9 @@ ___cds_wfs_pop_blocking(struct cds_wfs_stack *s) > > > */ > > > static inline > > > struct cds_wfs_node * > > > -___cds_wfs_pop_nonblocking(struct cds_wfs_stack *s) > > > +___cds_wfs_pop_nonblocking(struct cds_wfs_stack *s, bool *last) > > > { > > > - return ___cds_wfs_pop(s, 0); > > > + return ___cds_wfs_pop(s, last, 0); > > > } > > > > > > /* > > > @@ -284,12 +296,12 @@ static inline void _cds_wfs_pop_unlock(struct cds_wfs_stack *s) > > > */ > > > static inline > > > struct cds_wfs_node * > > > -_cds_wfs_pop_blocking(struct cds_wfs_stack *s) > > > +_cds_wfs_pop_blocking(struct cds_wfs_stack *s, bool *last) > > > { > > > struct cds_wfs_node *retnode; > > > > > > _cds_wfs_pop_lock(s); > > > - retnode = ___cds_wfs_pop_blocking(s); > > > + retnode = ___cds_wfs_pop_blocking(s, last); > > > _cds_wfs_pop_unlock(s); > > > return retnode; > > > } > > > diff --git a/urcu/wfcqueue.h b/urcu/wfcqueue.h > > > index b6be9f3..4b9e73b 100644 > > > --- a/urcu/wfcqueue.h > > > +++ b/urcu/wfcqueue.h > > > @@ -197,7 +197,8 @@ extern bool cds_wfcq_enqueue(struct cds_wfcq_head *head, > > > */ > > > extern struct cds_wfcq_node *cds_wfcq_dequeue_blocking( > > > struct cds_wfcq_head *head, > > > - struct cds_wfcq_tail *tail); > > > + struct cds_wfcq_tail *tail, > > > + bool *last); > > > > > > /* > > > * cds_wfcq_splice_blocking: enqueue all src_q nodes at the end of dest_q. > > > @@ -229,7 +230,8 @@ extern enum cds_wfcq_ret cds_wfcq_splice_blocking( > > > */ > > > extern struct cds_wfcq_node *__cds_wfcq_dequeue_blocking( > > > struct cds_wfcq_head *head, > > > - struct cds_wfcq_tail *tail); > > > + struct cds_wfcq_tail *tail, > > > + bool *last); > > > > > > /* > > > * __cds_wfcq_dequeue_nonblocking: dequeue a node from a wait-free queue. > > > @@ -239,7 +241,8 @@ extern struct cds_wfcq_node *__cds_wfcq_dequeue_blocking( > > > */ > > > extern struct cds_wfcq_node *__cds_wfcq_dequeue_nonblocking( > > > struct cds_wfcq_head *head, > > > - struct cds_wfcq_tail *tail); > > > + struct cds_wfcq_tail *tail, > > > + bool *last); > > > > > > /* > > > * __cds_wfcq_splice_blocking: enqueue all src_q nodes at the end of dest_q. > > > diff --git a/urcu/wfstack.h b/urcu/wfstack.h > > > index 03fee8f..1e4b848 100644 > > > --- a/urcu/wfstack.h > > > +++ b/urcu/wfstack.h > > > @@ -147,7 +147,8 @@ extern int cds_wfs_push(struct cds_wfs_stack *s, struct cds_wfs_node *node); > > > * > > > * Calls __cds_wfs_pop_blocking with an internal pop mutex held. > > > */ > > > -extern struct cds_wfs_node *cds_wfs_pop_blocking(struct cds_wfs_stack *s); > > > +extern struct cds_wfs_node *cds_wfs_pop_blocking(struct cds_wfs_stack *s, > > > + bool *last); > > > > > > /* > > > * cds_wfs_pop_all_blocking: pop all nodes from a stack. > > > @@ -219,7 +220,8 @@ extern void cds_wfs_pop_unlock(struct cds_wfs_stack *s); > > > * 3) Ensuring that only ONE thread can call __cds_wfs_pop_blocking() > > > * and __cds_wfs_pop_all(). (multi-provider/single-consumer scheme). > > > */ > > > -extern struct cds_wfs_node *__cds_wfs_pop_blocking(struct cds_wfs_stack *s); > > > +extern struct cds_wfs_node *__cds_wfs_pop_blocking(struct cds_wfs_stack *s, > > > + bool *last); > > > > > > /* > > > * __cds_wfs_pop_nonblocking: pop a node from the stack. > > > @@ -227,7 +229,8 @@ extern struct cds_wfs_node *__cds_wfs_pop_blocking(struct cds_wfs_stack *s); > > > * Same as __cds_wfs_pop_blocking, but returns CDS_WFS_WOULDBLOCK if > > > * it needs to block. > > > */ > > > -extern struct cds_wfs_node *__cds_wfs_pop_nonblocking(struct cds_wfs_stack *s); > > > +extern struct cds_wfs_node *__cds_wfs_pop_nonblocking(struct cds_wfs_stack *s, > > > + bool *last); > > > > > > /* > > > * __cds_wfs_pop_all: pop all nodes from a stack. > > > diff --git a/wfcqueue.c b/wfcqueue.c > > > index ab0eb93..7baefdf 100644 > > > --- a/wfcqueue.c > > > +++ b/wfcqueue.c > > > @@ -68,9 +68,10 @@ void cds_wfcq_dequeue_unlock(struct cds_wfcq_head *head, > > > > > > struct cds_wfcq_node *cds_wfcq_dequeue_blocking( > > > struct cds_wfcq_head *head, > > > - struct cds_wfcq_tail *tail) > > > + struct cds_wfcq_tail *tail, > > > + bool *last) > > > { > > > - return _cds_wfcq_dequeue_blocking(head, tail); > > > + return _cds_wfcq_dequeue_blocking(head, tail, last); > > > } > > > > > > enum cds_wfcq_ret cds_wfcq_splice_blocking( > > > @@ -85,16 +86,18 @@ enum cds_wfcq_ret cds_wfcq_splice_blocking( > > > > > > struct cds_wfcq_node *__cds_wfcq_dequeue_blocking( > > > struct cds_wfcq_head *head, > > > - struct cds_wfcq_tail *tail) > > > + struct cds_wfcq_tail *tail, > > > + bool *last) > > > { > > > - return ___cds_wfcq_dequeue_blocking(head, tail); > > > + return ___cds_wfcq_dequeue_blocking(head, tail, last); > > > } > > > > > > struct cds_wfcq_node *__cds_wfcq_dequeue_nonblocking( > > > struct cds_wfcq_head *head, > > > - struct cds_wfcq_tail *tail) > > > + struct cds_wfcq_tail *tail, > > > + bool *last) > > > { > > > - return ___cds_wfcq_dequeue_nonblocking(head, tail); > > > + return ___cds_wfcq_dequeue_nonblocking(head, tail, last); > > > } > > > > > > enum cds_wfcq_ret __cds_wfcq_splice_blocking( > > > diff --git a/wfstack.c b/wfstack.c > > > index 4ccb6b9..041703b 100644 > > > --- a/wfstack.c > > > +++ b/wfstack.c > > > @@ -48,9 +48,10 @@ int cds_wfs_push(struct cds_wfs_stack *s, struct cds_wfs_node *node) > > > return _cds_wfs_push(s, node); > > > } > > > > > > -struct cds_wfs_node *cds_wfs_pop_blocking(struct cds_wfs_stack *s) > > > +struct cds_wfs_node *cds_wfs_pop_blocking(struct cds_wfs_stack *s, > > > + bool *last) > > > { > > > - return _cds_wfs_pop_blocking(s); > > > + return _cds_wfs_pop_blocking(s, last); > > > } > > > > > > struct cds_wfs_head *cds_wfs_pop_all_blocking(struct cds_wfs_stack *s) > > > @@ -83,14 +84,16 @@ void cds_wfs_pop_unlock(struct cds_wfs_stack *s) > > > _cds_wfs_pop_unlock(s); > > > } > > > > > > -struct cds_wfs_node *__cds_wfs_pop_blocking(struct cds_wfs_stack *s) > > > +struct cds_wfs_node *__cds_wfs_pop_blocking(struct cds_wfs_stack *s, > > > + bool *last) > > > { > > > - return ___cds_wfs_pop_blocking(s); > > > + return ___cds_wfs_pop_blocking(s, last); > > > } > > > > > > -struct cds_wfs_node *__cds_wfs_pop_nonblocking(struct cds_wfs_stack *s) > > > +struct cds_wfs_node *__cds_wfs_pop_nonblocking(struct cds_wfs_stack *s, > > > + bool *last) > > > { > > > - return ___cds_wfs_pop_nonblocking(s); > > > + return ___cds_wfs_pop_nonblocking(s, last); > > > } > > > > > > struct cds_wfs_head *__cds_wfs_pop_all(struct cds_wfs_stack *s) > > > > > > -- > > > Mathieu Desnoyers > > > Operating System Efficiency R&D Consultant > > > EfficiOS Inc. > > > http://www.efficios.com > > > > > > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > rp mailing list > rp at svcs.cs.pdx.edu > http://svcs.cs.pdx.edu/mailman/listinfo/rp > From mathieu.desnoyers at efficios.com Tue Jan 15 18:56:42 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 15 Jan 2013 18:56:42 -0500 Subject: [lttng-dev] [PATCH] Add ACCESS_ONCE() to avoid compiler splitting assignments In-Reply-To: <20130115181936.GA30319@linux.vnet.ibm.com> References: <20130115181936.GA30319@linux.vnet.ibm.com> Message-ID: <20130115235642.GA31367@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > As noted by Konstantin Khlebnikov, gcc can split assignment of > constants to long variables (https://lkml.org/lkml/2013/1/15/141), > though assignment of NULL (0) is OK. Assuming that a gcc bug is > fixed (http://gcc.gnu.org/bugzilla/attachment.cgi?id=29169&action=diff > has a patch), making the store be volatile keeps gcc from splitting. > > This commit therefore applies ACCESS_ONCE() to CMM_STORE_SHARED(), > which is the underlying primitive used by rcu_assign_pointer(). Hi Paul, I recognise that this is an issue in the Linux kernel, since a simple store is used and expected to be performed atomically when aligned. However, I think this does not affect liburcu, see below: > > Signed-off-by: Paul E. McKenney > > diff --git a/urcu/system.h b/urcu/system.h > index 2a45f22..7a1887e 100644 > --- a/urcu/system.h > +++ b/urcu/system.h > @@ -49,7 +49,7 @@ > */ > #define CMM_STORE_SHARED(x, v) \ > ({ \ > - __typeof__(x) _v = _CMM_STORE_SHARED(x, v); \ > + __typeof__(x) CMM_ACCESS_ONCE(_v) = _CMM_STORE_SHARED(x, v); \ Here, the macro "_CMM_STORE_SHARED(x, v)" is doing the actual store. It stores v into "x". So adding a CMM_ACCESS_ONCE(_v), as you propose here, is really only making sure the return value (usually unused), located on the stack, is accessed with a volatile access, which does not make much sense. What really matters is the _CMM_STORE_SHARED() macro: #define _CMM_STORE_SHARED(x, v) ({ CMM_ACCESS_ONCE(x) = (v); }) which already uses a volatile access for the store. So this seems to be a case where our preemptive use of volatile for stores in addition to loads made us bug-free for a gcc behavior unexpected at the time we implemented this macro. Just a touch of paranoia seems to be a good thing sometimes. ;-) Thoughts ? Thanks, Mathieu > cmm_smp_wmc(); \ > _v; \ > }) > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed Jan 16 07:50:54 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 16 Jan 2013 07:50:54 -0500 Subject: [lttng-dev] [PATCH] Add ACCESS_ONCE() to avoid compiler splitting assignments In-Reply-To: <20130115235642.GA31367@Krystal> References: <20130115181936.GA30319@linux.vnet.ibm.com> <20130115235642.GA31367@Krystal> Message-ID: <20130116125054.GA9734@Krystal> * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > As noted by Konstantin Khlebnikov, gcc can split assignment of > > constants to long variables (https://lkml.org/lkml/2013/1/15/141), > > though assignment of NULL (0) is OK. Assuming that a gcc bug is > > fixed (http://gcc.gnu.org/bugzilla/attachment.cgi?id=29169&action=diff > > has a patch), making the store be volatile keeps gcc from splitting. > > > > This commit therefore applies ACCESS_ONCE() to CMM_STORE_SHARED(), > > which is the underlying primitive used by rcu_assign_pointer(). > > Hi Paul, > > I recognise that this is an issue in the Linux kernel, since a simple > store is used and expected to be performed atomically when aligned. > However, I think this does not affect liburcu, see below: Side question: what gcc versions may issue non-atomic volatile stores ? I think we should at least document those. Bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55981 seems to target gcc 4.7.2, but I wonder when this issue first appeared on x86 and x86-64 (and if it affects other architectures as well). Thanks, Mathieu > > > > > Signed-off-by: Paul E. McKenney > > > > diff --git a/urcu/system.h b/urcu/system.h > > index 2a45f22..7a1887e 100644 > > --- a/urcu/system.h > > +++ b/urcu/system.h > > @@ -49,7 +49,7 @@ > > */ > > #define CMM_STORE_SHARED(x, v) \ > > ({ \ > > - __typeof__(x) _v = _CMM_STORE_SHARED(x, v); \ > > + __typeof__(x) CMM_ACCESS_ONCE(_v) = _CMM_STORE_SHARED(x, v); \ > > Here, the macro "_CMM_STORE_SHARED(x, v)" is doing the actual store. > It stores v into "x". So adding a CMM_ACCESS_ONCE(_v), as you propose > here, is really only making sure the return value (usually unused), > located on the stack, is accessed with a volatile access, which does not > make much sense. > > What really matters is the _CMM_STORE_SHARED() macro: > > #define _CMM_STORE_SHARED(x, v) ({ CMM_ACCESS_ONCE(x) = (v); }) > > which already uses a volatile access for the store. So this seems to be > a case where our preemptive use of volatile for stores in addition to > loads made us bug-free for a gcc behavior unexpected at the time we > implemented this macro. Just a touch of paranoia seems to be a good > thing sometimes. ;-) > > Thoughts ? > > Thanks, > > Mathieu > > > cmm_smp_wmc(); \ > > _v; \ > > }) > > > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed Jan 16 10:14:47 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 16 Jan 2013 10:14:47 -0500 Subject: [lttng-dev] [RFC PATCH lttng-ust] Introduce hash table for lttng_create_event_if_missing() Message-ID: <20130116151446.GA11082@Krystal> lttng_create_event_if_missing() takes a lot of CPU time with stress-test applications containing 1000 different TRACEPOINT_EVENT() and 1000 individual tracepoint() call-site. With tracing disabled: time ./AppWith1000_lines_TP 0 real 0m2.487s user 0m2.424s sys 0m0.000s Introducing this hash table cuts the overhead very significantly when tracing is enabled: Before patch: 72.16% AppWith1000_lin liblttng-ust.so.0.0.0 [.] lttng_create_event_if_missing 25.64% AppWith1000_lin AppWith1000_lines_TP [.] a(int) time ./AppWith1000_lines_TP 0 real 0m7.946s user 0m7.864s sys 0m0.000s After patch: 89.13% AppWith1000_lin AppWith1000_lines_TP [.] a(int) 3.30% AppWith1000_lin liblttng-ust.so.0.0.0 [.] lttng_create_event_if_missing time ./AppWith1000_lines_TP 0 real 0m2.762s user 0m2.692s sys 0m0.004s Signed-off-by: Mathieu Desnoyers --- diff --git a/include/lttng/ust-events.h b/include/lttng/ust-events.h index 095fb1e..1db8e58 100644 --- a/include/lttng/ust-events.h +++ b/include/lttng/ust-events.h @@ -362,6 +362,7 @@ struct lttng_event { int has_enablers_without_bytecode; /* Backward references: list of lttng_enabler_ref (ref to enablers) */ struct cds_list_head enablers_ref_head; + struct cds_hlist_node hlist; /* session ht of events */ }; struct channel; @@ -467,6 +468,7 @@ struct lttng_session { /* New UST 2.1 */ /* List of enablers */ struct cds_list_head enablers_head; + struct lttng_ust_event_ht events_ht; /* ht of events */ }; struct lttng_transport { diff --git a/liblttng-ust/lttng-events.c b/liblttng-ust/lttng-events.c index 5e6c90c..f70c65f 100644 --- a/liblttng-ust/lttng-events.c +++ b/liblttng-ust/lttng-events.c @@ -127,7 +127,7 @@ void synchronize_trace(void) struct lttng_session *lttng_session_create(void) { struct lttng_session *session; - int ret; + int ret, i; session = zmalloc(sizeof(struct lttng_session)); if (!session) @@ -135,6 +135,8 @@ struct lttng_session *lttng_session_create(void) CDS_INIT_LIST_HEAD(&session->chan_head); CDS_INIT_LIST_HEAD(&session->events_head); CDS_INIT_LIST_HEAD(&session->enablers_head); + for (i = 0; i < LTTNG_UST_EVENT_HT_SIZE; i++) + CDS_INIT_HLIST_HEAD(&session->events_ht.table[i]); ret = lttng_ust_uuid_generate(session->uuid); if (ret != 0) { session->uuid[0] = '\0'; @@ -329,17 +331,19 @@ int lttng_event_create(const struct lttng_event_desc *desc, { const char *event_name = desc->name; struct lttng_event *event; + struct cds_hlist_head *head; + struct cds_hlist_node *node; int ret = 0; + size_t name_len = strlen(event_name); + uint32_t hash; if (chan->used_event_id == -1U) { ret = -ENOMEM; goto full; } - /* - * This is O(n^2) (for each event, the loop is called at event - * creation). Might require a hash if we have lots of events. - */ - cds_list_for_each_entry(event, &chan->session->events_head, node) { + hash = jhash(event_name, name_len, 0); + head = &chan->session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)]; + cds_hlist_for_each_entry(event, node, head, hlist) { assert(event->desc); if (!strncmp(event->desc->name, desc->name, @@ -380,6 +384,7 @@ int lttng_event_create(const struct lttng_event_desc *desc, if (ret) goto statedump_error; cds_list_add(&event->node, &chan->session->events_head); + cds_hlist_add_head(&event->hlist, head); return 0; statedump_error: @@ -499,17 +504,24 @@ void lttng_create_event_if_missing(struct lttng_enabler *enabler) cds_list_for_each_entry(probe_desc, probe_list, head) { for (i = 0; i < probe_desc->nr_events; i++) { int found = 0, ret; + struct cds_hlist_head *head; + struct cds_hlist_node *node; + const char *event_name; + size_t name_len; + uint32_t hash; desc = probe_desc->event_desc[i]; if (!lttng_desc_match_enabler(desc, enabler)) continue; + event_name = desc->name; + name_len = strlen(event_name); /* - * For each event in session event list, - * check if already created. + * Check if already created. */ - cds_list_for_each_entry(event, - &session->events_head, node) { + hash = jhash(event_name, name_len, 0); + head = &session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)]; + cds_hlist_for_each_entry(event, node, head, hlist) { if (event->desc == desc) found = 1; } -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed Jan 16 10:52:38 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 16 Jan 2013 10:52:38 -0500 Subject: [lttng-dev] [lttng-tools PATCH] Add support for kernel uprobes In-Reply-To: <1358132617-18443-1-git-send-email-yannick.brosseau@gmail.com> References: <1358132617-18443-1-git-send-email-yannick.brosseau@gmail.com> Message-ID: <20130116155238.GA11695@Krystal> * Yannick Brosseau (yannick.brosseau at gmail.com) wrote: > Inspired by the k*probe support. > > It add a new option to enable-event --uprobe which require a path name > and an offset in the specified file. > > (The file Documentation/trace/uprobetracer.txt in the kernel source provides > and example on how to extract the offset for a symbol in a program) Asking Masami and looking at perf might help us add support for lookup by file/lineno (using dwarf info). I think in terms of usability this is really important, and should appear in tools at the same time as the basic feature based on file/offset (or at least appear in the same LTTng release). We should keep in mind that liblttng-ctl is LGPLv2.1, so we cannot use perf code as-is without asking for the author's permission first. Nothing prevents us from writing this support ourself if need be though. Thanks, Mathieu > > Signed-off-by: Yannick Brosseau > --- > include/lttng/lttng.h | 15 +++++++++ > src/bin/lttng-sessiond/cmd.c | 5 +++ > src/bin/lttng-sessiond/modprobe.c | 1 + > src/bin/lttng-sessiond/trace-kernel.c | 7 ++++ > src/bin/lttng/commands/enable_events.c | 55 ++++++++++++++++++++++++++++++++ > src/bin/lttng/commands/list.c | 8 +++++ > src/common/lttng-kernel.h | 7 ++++ > 7 files changed, 98 insertions(+) > > diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h > index e21b479..c790e7b 100644 > --- a/include/lttng/lttng.h > +++ b/include/lttng/lttng.h > @@ -72,6 +72,7 @@ enum lttng_event_type { > LTTNG_EVENT_FUNCTION_ENTRY = 3, > LTTNG_EVENT_NOOP = 4, > LTTNG_EVENT_SYSCALL = 5, > + LTTNG_EVENT_UPROBE = 6, > }; > > /* > @@ -219,6 +220,19 @@ struct lttng_event_function_attr { > }; > > /* > + * Event uprobe. > + * > + * The structures should be initialized to zero before use. > + */ > +#define LTTNG_EVENT_UPROBE_PADDING1 24 > +struct lttng_event_uprobe_attr { > + char path[LTTNG_SYMBOL_NAME_LEN]; > + uint64_t offset; > + > + char padding[LTTNG_EVENT_UPROBE_PADDING1]; > +}; > + > +/* > * Generic lttng event > * > * The structures should be initialized to zero before use. > @@ -242,6 +256,7 @@ struct lttng_event { > union { > struct lttng_event_probe_attr probe; > struct lttng_event_function_attr ftrace; > + struct lttng_event_uprobe_attr uprobe; > > char padding[LTTNG_EVENT_PADDING2]; > } attr; > diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c > index 491acde..d7fee70 100644 > --- a/src/bin/lttng-sessiond/cmd.c > +++ b/src/bin/lttng-sessiond/cmd.c > @@ -315,6 +315,11 @@ static int list_lttng_kernel_events(char *channel_name, > memcpy(&((*events)[i].attr.ftrace), &event->event->u.ftrace, > sizeof(struct lttng_kernel_function)); > break; > + case LTTNG_KERNEL_UPROBE: > + (*events)[i].type = LTTNG_EVENT_UPROBE; > + memcpy(&(*events)[i].attr.uprobe, &event->event->u.uprobe, > + sizeof(struct lttng_kernel_uprobe)); > + break; > case LTTNG_KERNEL_NOOP: > (*events)[i].type = LTTNG_EVENT_NOOP; > break; > diff --git a/src/bin/lttng-sessiond/modprobe.c b/src/bin/lttng-sessiond/modprobe.c > index 1a5a1b7..805e127 100644 > --- a/src/bin/lttng-sessiond/modprobe.c > +++ b/src/bin/lttng-sessiond/modprobe.c > @@ -35,6 +35,7 @@ const struct kern_modules_param kern_modules_list[] = { > { "lttng-ftrace", 0 }, > { "lttng-kprobes", 0 }, > { "lttng-kretprobes", 0 }, > + { "lttng-uprobes", 0 }, > { "lttng-lib-ring-buffer", 1 }, > { "lttng-ring-buffer-client-discard", 1 }, > { "lttng-ring-buffer-client-overwrite", 1 }, > diff --git a/src/bin/lttng-sessiond/trace-kernel.c b/src/bin/lttng-sessiond/trace-kernel.c > index f38cf3d..24f33f9 100644 > --- a/src/bin/lttng-sessiond/trace-kernel.c > +++ b/src/bin/lttng-sessiond/trace-kernel.c > @@ -207,6 +207,13 @@ struct ltt_kernel_event *trace_kernel_create_event(struct lttng_event *ev) > ev->attr.probe.symbol_name, LTTNG_KERNEL_SYM_NAME_LEN); > attr->u.kprobe.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; > break; > + case LTTNG_EVENT_UPROBE: > + attr->instrumentation = LTTNG_KERNEL_UPROBE; > + attr->u.uprobe.offset = ev->attr.uprobe.offset; > + strncpy(attr->u.uprobe.path, > + ev->attr.uprobe.path, LTTNG_KERNEL_SYM_NAME_LEN); > + attr->u.uprobe.path[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; > + break; > case LTTNG_EVENT_FUNCTION: > attr->instrumentation = LTTNG_KERNEL_KRETPROBE; > attr->u.kretprobe.addr = ev->attr.probe.addr; > diff --git a/src/bin/lttng/commands/enable_events.c b/src/bin/lttng/commands/enable_events.c > index b6c18e1..61cb15b 100644 > --- a/src/bin/lttng/commands/enable_events.c > +++ b/src/bin/lttng/commands/enable_events.c > @@ -38,6 +38,7 @@ static char *opt_session_name; > static int opt_userspace; > static int opt_enable_all; > static char *opt_probe; > +static char *opt_uprobe; > static char *opt_function; > static char *opt_function_entry_symbol; > static char *opt_channel_name; > @@ -52,6 +53,7 @@ enum { > OPT_HELP = 1, > OPT_TRACEPOINT, > OPT_PROBE, > + OPT_UPROBE, > OPT_FUNCTION, > OPT_FUNCTION_ENTRY, > OPT_SYSCALL, > @@ -74,6 +76,7 @@ static struct poptOption long_options[] = { > {"userspace", 'u', POPT_ARG_NONE, 0, OPT_USERSPACE, 0, 0}, > {"tracepoint", 0, POPT_ARG_NONE, 0, OPT_TRACEPOINT, 0, 0}, > {"probe", 0, POPT_ARG_STRING, &opt_probe, OPT_PROBE, 0, 0}, > + {"uprobe", 0, POPT_ARG_STRING, &opt_uprobe, OPT_UPROBE, 0, 0}, > {"function", 0, POPT_ARG_STRING, &opt_function, OPT_FUNCTION, 0, 0}, > #if 0 > /* > @@ -117,6 +120,10 @@ static void usage(FILE *ofp) > fprintf(ofp, " Dynamic probe.\n"); > fprintf(ofp, " Addr and offset can be octal (0NNN...),\n"); > fprintf(ofp, " decimal (NNN...) or hexadecimal (0xNNN...)\n"); > + fprintf(ofp, " --uprobe [path+offset]\n"); > + fprintf(ofp, " Dynamic uprobe.\n"); > + fprintf(ofp, " offset can be octal (0NNN...),\n"); > + fprintf(ofp, " decimal (NNN...) or hexadecimal (0xNNN...)\n"); > fprintf(ofp, " --function [addr | symbol | symbol+offset]\n"); > fprintf(ofp, " Dynamic function entry/return probe.\n"); > fprintf(ofp, " Addr and offset can be octal (0NNN...),\n"); > @@ -245,6 +252,42 @@ static int parse_probe_opts(struct lttng_event *ev, char *opt) > end: > return ret; > } > +/* > + * Parse uprobe options. > + */ > +static int parse_uprobe_opts(struct lttng_event *ev, char *opt) > +{ > + int ret; > + char s_hex[19]; > + char name[LTTNG_SYMBOL_NAME_LEN]; > + > + if (opt == NULL) { > + ret = -1; > + goto end; > + } > + > + /* Check for path+offset */ > + ret = sscanf(opt, "%[^'+']+%s", name, s_hex); > + if (ret == 2) { > + strncpy(ev->attr.uprobe.path, name, LTTNG_SYMBOL_NAME_LEN); > + ev->attr.uprobe.path[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; > + DBG("probe path %s", ev->attr.uprobe.path); > + if (strlen(s_hex) == 0) { > + ERR("Invalid uprobe offset %s", s_hex); > + ret = -1; > + goto end; > + } > + ev->attr.uprobe.offset = strtoul(s_hex, NULL, 0); > + DBG("uprobe offset %" PRIu64, ev->attr.uprobe.offset); > + goto end; > + } > + > + /* No match */ > + ret = -1; > + > +end: > + return ret; > +} > > /* > * Maps loglevel from string to value > @@ -471,6 +514,14 @@ static int enable_events(char *session_name) > goto error; > } > break; > + case LTTNG_EVENT_UPROBE: > + ret = parse_uprobe_opts(&ev, opt_uprobe); > + if (ret < 0) { > + ERR("Unable to parse uprobe options"); > + ret = 0; > + goto error; > + } > + break; > case LTTNG_EVENT_FUNCTION: > ret = parse_probe_opts(&ev, opt_function); > if (ret < 0) { > @@ -522,6 +573,7 @@ static int enable_events(char *session_name) > ev.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; > break; > case LTTNG_EVENT_PROBE: > + case LTTNG_EVENT_UPROBE: > case LTTNG_EVENT_FUNCTION: > case LTTNG_EVENT_FUNCTION_ENTRY: > case LTTNG_EVENT_SYSCALL: > @@ -636,6 +688,9 @@ int cmd_enable_events(int argc, const char **argv) > case OPT_PROBE: > opt_event_type = LTTNG_EVENT_PROBE; > break; > + case OPT_UPROBE: > + opt_event_type = LTTNG_EVENT_UPROBE; > + break; > case OPT_FUNCTION: > opt_event_type = LTTNG_EVENT_FUNCTION; > break; > diff --git a/src/bin/lttng/commands/list.c b/src/bin/lttng/commands/list.c > index a6ea6b8..ffae239 100644 > --- a/src/bin/lttng/commands/list.c > +++ b/src/bin/lttng/commands/list.c > @@ -231,6 +231,14 @@ static void print_events(struct lttng_event *event) > MSG("%ssymbol: %s", indent8, event->attr.probe.symbol_name); > } > break; > + case LTTNG_EVENT_UPROBE: > + MSG("%s%s (type: uprobe)%s%s", indent6, > + event->name, enabled_string(event->enabled), > + filter_string(event->filter)); > + > + MSG("%spath: %s", indent8, event->attr.uprobe.path); > + MSG("%soffset: 0x%" PRIx64, indent8, event->attr.uprobe.offset); > + break; > case LTTNG_EVENT_FUNCTION: > case LTTNG_EVENT_FUNCTION_ENTRY: > MSG("%s%s (type: function)%s%s", indent6, > diff --git a/src/common/lttng-kernel.h b/src/common/lttng-kernel.h > index fa8ba61..a43b956 100644 > --- a/src/common/lttng-kernel.h > +++ b/src/common/lttng-kernel.h > @@ -38,6 +38,7 @@ enum lttng_kernel_instrumentation { > LTTNG_KERNEL_KRETPROBE = 3, > LTTNG_KERNEL_NOOP = 4, /* not hooked */ > LTTNG_KERNEL_SYSCALL = 5, > + LTTNG_KERNEL_UPROBE = 6, > }; > > enum lttng_kernel_context_type { > @@ -96,6 +97,11 @@ struct lttng_kernel_function { > char symbol_name[LTTNG_KERNEL_SYM_NAME_LEN]; > }__attribute__((packed)); > > +struct lttng_kernel_uprobe { > + char path[LTTNG_KERNEL_SYM_NAME_LEN]; > + uint64_t offset; > +}__attribute__((packed)); > + > #define LTTNG_KERNEL_EVENT_PADDING1 16 > #define LTTNG_KERNEL_EVENT_PADDING2 LTTNG_KERNEL_SYM_NAME_LEN + 32 > struct lttng_kernel_event { > @@ -108,6 +114,7 @@ struct lttng_kernel_event { > struct lttng_kernel_kretprobe kretprobe; > struct lttng_kernel_kprobe kprobe; > struct lttng_kernel_function ftrace; > + struct lttng_kernel_uprobe uprobe; > char padding[LTTNG_KERNEL_EVENT_PADDING2]; > } u; > }__attribute__((packed)); > -- > 1.7.10.4 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Wed Jan 16 10:53:18 2013 From: dgoulet at efficios.com (David Goulet) Date: Wed, 16 Jan 2013 10:53:18 -0500 Subject: [lttng-dev] [RFC PATCH lttng-ust] Introduce hash table for lttng_create_event_if_missing() In-Reply-To: <20130116151446.GA11082@Krystal> References: <20130116151446.GA11082@Krystal> Message-ID: <50F6CCEE.4040903@efficios.com> Acked-by: David Goulet Mathieu Desnoyers: > lttng_create_event_if_missing() takes a lot of CPU time with stress-test > applications containing 1000 different TRACEPOINT_EVENT() and 1000 > individual tracepoint() call-site. > > With tracing disabled: > > time ./AppWith1000_lines_TP 0 > > real 0m2.487s > user 0m2.424s > sys 0m0.000s > > > Introducing this hash table cuts the overhead very significantly when > tracing is enabled: > > Before patch: > > 72.16% AppWith1000_lin liblttng-ust.so.0.0.0 [.] lttng_create_event_if_missing > 25.64% AppWith1000_lin AppWith1000_lines_TP [.] a(int) > > time ./AppWith1000_lines_TP 0 > > real 0m7.946s > user 0m7.864s > sys 0m0.000s > > > After patch: > > 89.13% AppWith1000_lin AppWith1000_lines_TP [.] a(int) > 3.30% AppWith1000_lin liblttng-ust.so.0.0.0 [.] lttng_create_event_if_missing > > time ./AppWith1000_lines_TP 0 > > real 0m2.762s > user 0m2.692s > sys 0m0.004s > > Signed-off-by: Mathieu Desnoyers > --- > diff --git a/include/lttng/ust-events.h b/include/lttng/ust-events.h > index 095fb1e..1db8e58 100644 > --- a/include/lttng/ust-events.h > +++ b/include/lttng/ust-events.h > @@ -362,6 +362,7 @@ struct lttng_event { > int has_enablers_without_bytecode; > /* Backward references: list of lttng_enabler_ref (ref to enablers) */ > struct cds_list_head enablers_ref_head; > + struct cds_hlist_node hlist; /* session ht of events */ > }; > > struct channel; > @@ -467,6 +468,7 @@ struct lttng_session { > /* New UST 2.1 */ > /* List of enablers */ > struct cds_list_head enablers_head; > + struct lttng_ust_event_ht events_ht; /* ht of events */ > }; > > struct lttng_transport { > diff --git a/liblttng-ust/lttng-events.c b/liblttng-ust/lttng-events.c > index 5e6c90c..f70c65f 100644 > --- a/liblttng-ust/lttng-events.c > +++ b/liblttng-ust/lttng-events.c > @@ -127,7 +127,7 @@ void synchronize_trace(void) > struct lttng_session *lttng_session_create(void) > { > struct lttng_session *session; > - int ret; > + int ret, i; > > session = zmalloc(sizeof(struct lttng_session)); > if (!session) > @@ -135,6 +135,8 @@ struct lttng_session *lttng_session_create(void) > CDS_INIT_LIST_HEAD(&session->chan_head); > CDS_INIT_LIST_HEAD(&session->events_head); > CDS_INIT_LIST_HEAD(&session->enablers_head); > + for (i = 0; i < LTTNG_UST_EVENT_HT_SIZE; i++) > + CDS_INIT_HLIST_HEAD(&session->events_ht.table[i]); > ret = lttng_ust_uuid_generate(session->uuid); > if (ret != 0) { > session->uuid[0] = '\0'; > @@ -329,17 +331,19 @@ int lttng_event_create(const struct lttng_event_desc *desc, > { > const char *event_name = desc->name; > struct lttng_event *event; > + struct cds_hlist_head *head; > + struct cds_hlist_node *node; > int ret = 0; > + size_t name_len = strlen(event_name); > + uint32_t hash; > > if (chan->used_event_id == -1U) { > ret = -ENOMEM; > goto full; > } > - /* > - * This is O(n^2) (for each event, the loop is called at event > - * creation). Might require a hash if we have lots of events. > - */ > - cds_list_for_each_entry(event, &chan->session->events_head, node) { > + hash = jhash(event_name, name_len, 0); > + head = &chan->session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)]; > + cds_hlist_for_each_entry(event, node, head, hlist) { > assert(event->desc); > if (!strncmp(event->desc->name, > desc->name, > @@ -380,6 +384,7 @@ int lttng_event_create(const struct lttng_event_desc *desc, > if (ret) > goto statedump_error; > cds_list_add(&event->node, &chan->session->events_head); > + cds_hlist_add_head(&event->hlist, head); > return 0; > > statedump_error: > @@ -499,17 +504,24 @@ void lttng_create_event_if_missing(struct lttng_enabler *enabler) > cds_list_for_each_entry(probe_desc, probe_list, head) { > for (i = 0; i < probe_desc->nr_events; i++) { > int found = 0, ret; > + struct cds_hlist_head *head; > + struct cds_hlist_node *node; > + const char *event_name; > + size_t name_len; > + uint32_t hash; > > desc = probe_desc->event_desc[i]; > if (!lttng_desc_match_enabler(desc, enabler)) > continue; > + event_name = desc->name; > + name_len = strlen(event_name); > > /* > - * For each event in session event list, > - * check if already created. > + * Check if already created. > */ > - cds_list_for_each_entry(event, > - &session->events_head, node) { > + hash = jhash(event_name, name_len, 0); > + head = &session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)]; > + cds_hlist_for_each_entry(event, node, head, hlist) { > if (event->desc == desc) > found = 1; > } > From dgoulet at efficios.com Wed Jan 16 11:02:57 2013 From: dgoulet at efficios.com (David Goulet) Date: Wed, 16 Jan 2013 11:02:57 -0500 Subject: [lttng-dev] [PATCH] Make sync_file_range() usage optional In-Reply-To: <1357979037-28550-1-git-send-email-s.martin49@gmail.com> References: <1357979037-28550-1-git-send-email-s.martin49@gmail.com> Message-ID: <50F6CF31.7050808@efficios.com> Merged! Thanks! David Samuel Martin: > Under uClibc, sync_file_range() is not available under all > architectures, so we fall back to fdatasync() in this case. > > Signed-off-by: Thomas Petazzoni > Signed-off-by: Samuel Martin > --- > configure.ac | 2 +- > src/common/compat/compat-fcntl.c | 4 ++++ > 2 files changed, 5 insertions(+), 1 deletion(-) > > diff --git a/configure.ac b/configure.ac > index 425941b..80940c0 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -150,7 +150,7 @@ AS_IF([test "x$lttng_ust_support" = "xyes"], [ > ) > ]) > AM_CONDITIONAL([HAVE_LIBLTTNG_UST_CTL], [test "x$lttng_ust_ctl_found" = xyes]) > -AC_CHECK_FUNCS([sched_getcpu sysconf]) > +AC_CHECK_FUNCS([sched_getcpu sysconf sync_file_range]) > > # check for dlopen > AC_CHECK_LIB([dl], [dlopen], > diff --git a/src/common/compat/compat-fcntl.c b/src/common/compat/compat-fcntl.c > index 5a1c757..7ff63a3 100644 > --- a/src/common/compat/compat-fcntl.c > +++ b/src/common/compat/compat-fcntl.c > @@ -23,7 +23,11 @@ > int compat_sync_file_range(int fd, off64_t offset, off64_t nbytes, > unsigned int flags) > { > +#ifdef HAVE_SYNC_FILE_RANGE > return sync_file_range(fd, offset, nbytes, flags); > +#else > + return fdatasync(fd); > +#endif > } > > #endif /* __linux__ */ From christian.babeux at efficios.com Wed Jan 16 11:19:19 2013 From: christian.babeux at efficios.com (Christian Babeux) Date: Wed, 16 Jan 2013 11:19:19 -0500 Subject: [lttng-dev] [RFC PATCH lttng-ust] Introduce hash table for lttng_create_event_if_missing() In-Reply-To: <20130116151446.GA11082@Krystal> References: <20130116151446.GA11082@Krystal> Message-ID: I was able to reproduce this overhead issue on my machine. This patch fixed it. Acked-by: Christian Babeux On Wed, Jan 16, 2013 at 10:14 AM, Mathieu Desnoyers wrote: > lttng_create_event_if_missing() takes a lot of CPU time with stress-test > applications containing 1000 different TRACEPOINT_EVENT() and 1000 > individual tracepoint() call-site. > > With tracing disabled: > > time ./AppWith1000_lines_TP 0 > > real 0m2.487s > user 0m2.424s > sys 0m0.000s > > > Introducing this hash table cuts the overhead very significantly when > tracing is enabled: > > Before patch: > > 72.16% AppWith1000_lin liblttng-ust.so.0.0.0 [.] lttng_create_event_if_missing > 25.64% AppWith1000_lin AppWith1000_lines_TP [.] a(int) > > time ./AppWith1000_lines_TP 0 > > real 0m7.946s > user 0m7.864s > sys 0m0.000s > > > After patch: > > 89.13% AppWith1000_lin AppWith1000_lines_TP [.] a(int) > 3.30% AppWith1000_lin liblttng-ust.so.0.0.0 [.] lttng_create_event_if_missing > > time ./AppWith1000_lines_TP 0 > > real 0m2.762s > user 0m2.692s > sys 0m0.004s > > Signed-off-by: Mathieu Desnoyers > --- > diff --git a/include/lttng/ust-events.h b/include/lttng/ust-events.h > index 095fb1e..1db8e58 100644 > --- a/include/lttng/ust-events.h > +++ b/include/lttng/ust-events.h > @@ -362,6 +362,7 @@ struct lttng_event { > int has_enablers_without_bytecode; > /* Backward references: list of lttng_enabler_ref (ref to enablers) */ > struct cds_list_head enablers_ref_head; > + struct cds_hlist_node hlist; /* session ht of events */ > }; > > struct channel; > @@ -467,6 +468,7 @@ struct lttng_session { > /* New UST 2.1 */ > /* List of enablers */ > struct cds_list_head enablers_head; > + struct lttng_ust_event_ht events_ht; /* ht of events */ > }; > > struct lttng_transport { > diff --git a/liblttng-ust/lttng-events.c b/liblttng-ust/lttng-events.c > index 5e6c90c..f70c65f 100644 > --- a/liblttng-ust/lttng-events.c > +++ b/liblttng-ust/lttng-events.c > @@ -127,7 +127,7 @@ void synchronize_trace(void) > struct lttng_session *lttng_session_create(void) > { > struct lttng_session *session; > - int ret; > + int ret, i; > > session = zmalloc(sizeof(struct lttng_session)); > if (!session) > @@ -135,6 +135,8 @@ struct lttng_session *lttng_session_create(void) > CDS_INIT_LIST_HEAD(&session->chan_head); > CDS_INIT_LIST_HEAD(&session->events_head); > CDS_INIT_LIST_HEAD(&session->enablers_head); > + for (i = 0; i < LTTNG_UST_EVENT_HT_SIZE; i++) > + CDS_INIT_HLIST_HEAD(&session->events_ht.table[i]); > ret = lttng_ust_uuid_generate(session->uuid); > if (ret != 0) { > session->uuid[0] = '\0'; > @@ -329,17 +331,19 @@ int lttng_event_create(const struct lttng_event_desc *desc, > { > const char *event_name = desc->name; > struct lttng_event *event; > + struct cds_hlist_head *head; > + struct cds_hlist_node *node; > int ret = 0; > + size_t name_len = strlen(event_name); > + uint32_t hash; > > if (chan->used_event_id == -1U) { > ret = -ENOMEM; > goto full; > } > - /* > - * This is O(n^2) (for each event, the loop is called at event > - * creation). Might require a hash if we have lots of events. > - */ > - cds_list_for_each_entry(event, &chan->session->events_head, node) { > + hash = jhash(event_name, name_len, 0); > + head = &chan->session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)]; > + cds_hlist_for_each_entry(event, node, head, hlist) { > assert(event->desc); > if (!strncmp(event->desc->name, > desc->name, > @@ -380,6 +384,7 @@ int lttng_event_create(const struct lttng_event_desc *desc, > if (ret) > goto statedump_error; > cds_list_add(&event->node, &chan->session->events_head); > + cds_hlist_add_head(&event->hlist, head); > return 0; > > statedump_error: > @@ -499,17 +504,24 @@ void lttng_create_event_if_missing(struct lttng_enabler *enabler) > cds_list_for_each_entry(probe_desc, probe_list, head) { > for (i = 0; i < probe_desc->nr_events; i++) { > int found = 0, ret; > + struct cds_hlist_head *head; > + struct cds_hlist_node *node; > + const char *event_name; > + size_t name_len; > + uint32_t hash; > > desc = probe_desc->event_desc[i]; > if (!lttng_desc_match_enabler(desc, enabler)) > continue; > + event_name = desc->name; > + name_len = strlen(event_name); > > /* > - * For each event in session event list, > - * check if already created. > + * Check if already created. > */ > - cds_list_for_each_entry(event, > - &session->events_head, node) { > + hash = jhash(event_name, name_len, 0); > + head = &session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)]; > + cds_hlist_for_each_entry(event, node, head, hlist) { > if (event->desc == desc) > found = 1; > } > > -- > Mathieu Desnoyers > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev From yannick.brosseau at gmail.com Wed Jan 16 11:55:27 2013 From: yannick.brosseau at gmail.com (Yannick Brosseau) Date: Wed, 16 Jan 2013 11:55:27 -0500 Subject: [lttng-dev] [lttng-tools PATCH] Add support for kernel uprobes In-Reply-To: <20130116155238.GA11695@Krystal> References: <1358132617-18443-1-git-send-email-yannick.brosseau@gmail.com> <20130116155238.GA11695@Krystal> Message-ID: <50F6DB7F.5070202@gmail.com> On 2013-01-16 10:52, Mathieu Desnoyers wrote: > * Yannick Brosseau (yannick.brosseau at gmail.com) wrote: >> Inspired by the k*probe support. >> >> It add a new option to enable-event --uprobe which require a path name >> and an offset in the specified file. >> >> (The file Documentation/trace/uprobetracer.txt in the kernel source provides >> and example on how to extract the offset for a symbol in a program) > Asking Masami and looking at perf might help us add support for lookup > by file/lineno (using dwarf info). I think in terms of usability this is > really important, and should appear in tools at the same time as the > basic feature based on file/offset (or at least appear in the same > LTTng release). > > We should keep in mind that liblttng-ctl is LGPLv2.1, so we cannot use > perf code as-is without asking for the author's permission first. > Nothing prevents us from writing this support ourself if need be though. Ok, great, I'll look into it. From mathieu.desnoyers at efficios.com Wed Jan 16 12:58:44 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 16 Jan 2013 12:58:44 -0500 Subject: [lttng-dev] [RFC PATCH lttng-ust] Introduce hash table for lttng_create_event_if_missing() In-Reply-To: References: <20130116151446.GA11082@Krystal> Message-ID: <20130116175844.GA13272@Krystal> * Christian Babeux (christian.babeux at efficios.com) wrote: > I was able to reproduce this overhead issue on my machine. > This patch fixed it. OK! Patch pushed into lttng-ust master and stable-2.1 branches. Thanks, Mathieu > > Acked-by: Christian Babeux > > On Wed, Jan 16, 2013 at 10:14 AM, Mathieu Desnoyers > wrote: > > lttng_create_event_if_missing() takes a lot of CPU time with stress-test > > applications containing 1000 different TRACEPOINT_EVENT() and 1000 > > individual tracepoint() call-site. > > > > With tracing disabled: > > > > time ./AppWith1000_lines_TP 0 > > > > real 0m2.487s > > user 0m2.424s > > sys 0m0.000s > > > > > > Introducing this hash table cuts the overhead very significantly when > > tracing is enabled: > > > > Before patch: > > > > 72.16% AppWith1000_lin liblttng-ust.so.0.0.0 [.] lttng_create_event_if_missing > > 25.64% AppWith1000_lin AppWith1000_lines_TP [.] a(int) > > > > time ./AppWith1000_lines_TP 0 > > > > real 0m7.946s > > user 0m7.864s > > sys 0m0.000s > > > > > > After patch: > > > > 89.13% AppWith1000_lin AppWith1000_lines_TP [.] a(int) > > 3.30% AppWith1000_lin liblttng-ust.so.0.0.0 [.] lttng_create_event_if_missing > > > > time ./AppWith1000_lines_TP 0 > > > > real 0m2.762s > > user 0m2.692s > > sys 0m0.004s > > > > Signed-off-by: Mathieu Desnoyers > > --- > > diff --git a/include/lttng/ust-events.h b/include/lttng/ust-events.h > > index 095fb1e..1db8e58 100644 > > --- a/include/lttng/ust-events.h > > +++ b/include/lttng/ust-events.h > > @@ -362,6 +362,7 @@ struct lttng_event { > > int has_enablers_without_bytecode; > > /* Backward references: list of lttng_enabler_ref (ref to enablers) */ > > struct cds_list_head enablers_ref_head; > > + struct cds_hlist_node hlist; /* session ht of events */ > > }; > > > > struct channel; > > @@ -467,6 +468,7 @@ struct lttng_session { > > /* New UST 2.1 */ > > /* List of enablers */ > > struct cds_list_head enablers_head; > > + struct lttng_ust_event_ht events_ht; /* ht of events */ > > }; > > > > struct lttng_transport { > > diff --git a/liblttng-ust/lttng-events.c b/liblttng-ust/lttng-events.c > > index 5e6c90c..f70c65f 100644 > > --- a/liblttng-ust/lttng-events.c > > +++ b/liblttng-ust/lttng-events.c > > @@ -127,7 +127,7 @@ void synchronize_trace(void) > > struct lttng_session *lttng_session_create(void) > > { > > struct lttng_session *session; > > - int ret; > > + int ret, i; > > > > session = zmalloc(sizeof(struct lttng_session)); > > if (!session) > > @@ -135,6 +135,8 @@ struct lttng_session *lttng_session_create(void) > > CDS_INIT_LIST_HEAD(&session->chan_head); > > CDS_INIT_LIST_HEAD(&session->events_head); > > CDS_INIT_LIST_HEAD(&session->enablers_head); > > + for (i = 0; i < LTTNG_UST_EVENT_HT_SIZE; i++) > > + CDS_INIT_HLIST_HEAD(&session->events_ht.table[i]); > > ret = lttng_ust_uuid_generate(session->uuid); > > if (ret != 0) { > > session->uuid[0] = '\0'; > > @@ -329,17 +331,19 @@ int lttng_event_create(const struct lttng_event_desc *desc, > > { > > const char *event_name = desc->name; > > struct lttng_event *event; > > + struct cds_hlist_head *head; > > + struct cds_hlist_node *node; > > int ret = 0; > > + size_t name_len = strlen(event_name); > > + uint32_t hash; > > > > if (chan->used_event_id == -1U) { > > ret = -ENOMEM; > > goto full; > > } > > - /* > > - * This is O(n^2) (for each event, the loop is called at event > > - * creation). Might require a hash if we have lots of events. > > - */ > > - cds_list_for_each_entry(event, &chan->session->events_head, node) { > > + hash = jhash(event_name, name_len, 0); > > + head = &chan->session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)]; > > + cds_hlist_for_each_entry(event, node, head, hlist) { > > assert(event->desc); > > if (!strncmp(event->desc->name, > > desc->name, > > @@ -380,6 +384,7 @@ int lttng_event_create(const struct lttng_event_desc *desc, > > if (ret) > > goto statedump_error; > > cds_list_add(&event->node, &chan->session->events_head); > > + cds_hlist_add_head(&event->hlist, head); > > return 0; > > > > statedump_error: > > @@ -499,17 +504,24 @@ void lttng_create_event_if_missing(struct lttng_enabler *enabler) > > cds_list_for_each_entry(probe_desc, probe_list, head) { > > for (i = 0; i < probe_desc->nr_events; i++) { > > int found = 0, ret; > > + struct cds_hlist_head *head; > > + struct cds_hlist_node *node; > > + const char *event_name; > > + size_t name_len; > > + uint32_t hash; > > > > desc = probe_desc->event_desc[i]; > > if (!lttng_desc_match_enabler(desc, enabler)) > > continue; > > + event_name = desc->name; > > + name_len = strlen(event_name); > > > > /* > > - * For each event in session event list, > > - * check if already created. > > + * Check if already created. > > */ > > - cds_list_for_each_entry(event, > > - &session->events_head, node) { > > + hash = jhash(event_name, name_len, 0); > > + head = &session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)]; > > + cds_hlist_for_each_entry(event, node, head, hlist) { > > if (event->desc == desc) > > found = 1; > > } > > > > -- > > Mathieu Desnoyers > > EfficiOS Inc. > > http://www.efficios.com > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From anik.mishra at ericsson.com Wed Jan 16 16:37:32 2013 From: anik.mishra at ericsson.com (Anik Mishra) Date: Wed, 16 Jan 2013 21:37:32 +0000 Subject: [lttng-dev] [RFC PATCH lttng-ust] Introduce hash table for lttng_create_event_if_missing() Message-ID: <0AF7BA51953555439020FD85D854801F039A5D@eusaamb105.ericsson.se> -----Original Message----- From: Mathieu Desnoyers [mailto:mathieu.desnoyers at efficios.com] Sent: January-16-13 10:15 AM To: lttng-dev at lists.lttng.org Subject: [lttng-dev] [RFC PATCH lttng-ust] Introduce hash table for lttng_create_event_if_missing() [...] @@ -329,17 +331,19 @@ int lttng_event_create(const struct lttng_event_desc *desc, { [...] - /* - * This is O(n^2) (for each event, the loop is called at event - * creation). Might require a hash if we have lots of events. - */ - cds_list_for_each_entry(event, &chan->session->events_head, node) { + hash = jhash(event_name, name_len, 0); + head = &chan->session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)]; + cds_hlist_for_each_entry(event, node, head, hlist) { [...] >From other code: #define LTTNG_UST_EVENT_HT_BITS 6 #define LTTNG_UST_EVENT_HT_SIZE (1U << LTTNG_UST_EVENT_HT_BITS) The way I read this, if there's a substantial number of events, you're just dividing the time required by a constant 64. The complexity remains the same. Are you sure this is really a long term solution? Anik From jeremie.galarneau at efficios.com Wed Jan 16 12:53:01 2013 From: jeremie.galarneau at efficios.com (=?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=) Date: Wed, 16 Jan 2013 17:53:01 +0000 Subject: [lttng-dev] [PATCH babeltrace] Fix: Python bindings build fix. Reflects SEEK_END API change. Message-ID: <1358358781-26056-1-git-send-email-jeremie.galarneau@efficios.com> Signed-off-by: J?r?mie Galarneau --- bindings/python/babeltrace.i.in | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bindings/python/babeltrace.i.in b/bindings/python/babeltrace.i.in index c8e4923..b693f02 100644 --- a/bindings/python/babeltrace.i.in +++ b/bindings/python/babeltrace.i.in @@ -245,8 +245,7 @@ struct bt_iter_pos *bt_iter_create_time_pos(struct bt_iter *iter, uint64_t times %rename("SEEK_RESTORE") BT_SEEK_RESTORE; %rename("SEEK_CUR") BT_SEEK_CUR; %rename("SEEK_BEGIN") BT_SEEK_BEGIN; -%rename("SEEK_END") BT_SEEK_END; - +%rename("SEEK_LAST") BT_SEEK_LAST; // This struct is taken from iterator.h // All changes to the struct must also be made here @@ -256,7 +255,7 @@ struct bt_iter_pos { BT_SEEK_RESTORE, /* uses u.restore */ BT_SEEK_CUR, BT_SEEK_BEGIN, - BT_SEEK_END, + BT_SEEK_LAST } type; union { uint64_t seek_time; -- 1.8.1.1 From mathieu.desnoyers at efficios.com Wed Jan 16 17:59:28 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 16 Jan 2013 17:59:28 -0500 Subject: [lttng-dev] [PATCH babeltrace] Fix: Python bindings build fix. Reflects SEEK_END API change. In-Reply-To: <1358358781-26056-1-git-send-email-jeremie.galarneau@efficios.com> References: <1358358781-26056-1-git-send-email-jeremie.galarneau@efficios.com> Message-ID: <20130116225928.GA16371@Krystal> * J?r?mie Galarneau (jeremie.galarneau at efficios.com) wrote: > > Signed-off-by: J?r?mie Galarneau merged into bindings/python Thanks! Mathieu > --- > bindings/python/babeltrace.i.in | 5 ++--- > 1 file changed, 2 insertions(+), 3 deletions(-) > > diff --git a/bindings/python/babeltrace.i.in b/bindings/python/babeltrace.i.in > index c8e4923..b693f02 100644 > --- a/bindings/python/babeltrace.i.in > +++ b/bindings/python/babeltrace.i.in > @@ -245,8 +245,7 @@ struct bt_iter_pos *bt_iter_create_time_pos(struct bt_iter *iter, uint64_t times > %rename("SEEK_RESTORE") BT_SEEK_RESTORE; > %rename("SEEK_CUR") BT_SEEK_CUR; > %rename("SEEK_BEGIN") BT_SEEK_BEGIN; > -%rename("SEEK_END") BT_SEEK_END; > - > +%rename("SEEK_LAST") BT_SEEK_LAST; > > // This struct is taken from iterator.h > // All changes to the struct must also be made here > @@ -256,7 +255,7 @@ struct bt_iter_pos { > BT_SEEK_RESTORE, /* uses u.restore */ > BT_SEEK_CUR, > BT_SEEK_BEGIN, > - BT_SEEK_END, > + BT_SEEK_LAST > } type; > union { > uint64_t seek_time; > -- > 1.8.1.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Thu Jan 17 10:58:48 2013 From: dgoulet at efficios.com (David Goulet) Date: Thu, 17 Jan 2013 10:58:48 -0500 Subject: [lttng-dev] [PATCH lttng-tools 1/4] Extras: Added lttng.pyc to the clean section of the Python binding makefile. In-Reply-To: <1358181949-23456-1-git-send-email-jeremie.galarneau@efficios.com> References: <1358181949-23456-1-git-send-email-jeremie.galarneau@efficios.com> Message-ID: <50F81FB8.6050805@efficios.com> All four patches have been merged! Thanks! David J?r?mie Galarneau: > > Signed-off-by: J?r?mie Galarneau > --- > extras/bindings/swig/python/Makefile.am | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/extras/bindings/swig/python/Makefile.am b/extras/bindings/swig/python/Makefile.am > index a3557b8..d592ded 100644 > --- a/extras/bindings/swig/python/Makefile.am > +++ b/extras/bindings/swig/python/Makefile.am > @@ -24,4 +24,4 @@ lttng_wrap.c: lttng.i > sed -i "s/md = d/d/g" lttng_wrap.c > sed -i "s/(void)public_symbol;/(void)public_symbol;\n md = d;/g" lttng_wrap.c > > -CLEANFILES = lttng.i lttng.py lttng_wrap.c > +CLEANFILES = lttng.i lttng.py lttng_wrap.c lttng.pyc From mohamad.gebai at polymtl.ca Fri Jan 18 11:22:16 2013 From: mohamad.gebai at polymtl.ca (Mohamad Gebai) Date: Fri, 18 Jan 2013 11:22:16 -0500 Subject: [lttng-dev] Add architecture specific tracepoints Message-ID: <1358526136.50f976b837ad0@www.imp.polymtl.ca> Hi, I would like to add some of kvm's tracepoints to lttng as only few of them are already included. The problem is that those tracepoints are architecture specific (in the kernel source: arch/x86/kvm/trace.h). The readme file in lttng-modules/instrumentation/events/lttng-module doesn't explain the procedure to do this for arch specific folders. Should I add an arch folder in lttng-modules/instrumentation/events/mainline and /lttng-module? Thanks. From yannick.brosseau at gmail.com Fri Jan 18 11:50:40 2013 From: yannick.brosseau at gmail.com (Yannick Brosseau) Date: Fri, 18 Jan 2013 11:50:40 -0500 Subject: [lttng-dev] [BABELTRACE PATCH] Add missing runall.sh to dist packaging Message-ID: <1358527840-4543-1-git-send-email-yannick.brosseau@gmail.com> Signed-off-by: Yannick Brosseau --- tests/lib/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am index f7e32c2..e9e264b 100644 --- a/tests/lib/Makefile.am +++ b/tests/lib/Makefile.am @@ -12,7 +12,7 @@ noinst_PROGRAMS = test-seeks test_seeks_SOURCES = test-seeks.c -EXTRA_DIST = README.tap +EXTRA_DIST = README.tap runall.sh check-am: ./runall.sh -- 1.7.10.4 From Daniel.Thibault at drdc-rddc.gc.ca Fri Jan 18 12:37:07 2013 From: Daniel.Thibault at drdc-rddc.gc.ca (Thibault, Daniel) Date: Fri, 18 Jan 2013 12:37:07 -0500 Subject: [lttng-dev] yacc lttng-tools problem Message-ID: <3CA1A65C03C1A34C81BBC6272782E696987823@valcartierex01.valcartier.drdc-rddc.gc.ca> I need help to get lttng-tools to compile. I have grabbed the (nearly) latest git.lttng.org packages: lttng-modules (2.1.0+-c6403de) userspace-rcu (0.7.6-da9bed2) lttng-ust (2.1.0+-340f776) (one new commit since) lttng-tools (2.1.1+-281047b) (six new commits since) The userspace-rcu repository is weird: the 0.7.6 commit which I fetched is marked as "8 days ago" but the master stops at "11 days ago". I've installed (on my Ubuntu 12.04 system) libtool, texinfo, g++, libpopt-dev, and bison. I'm not completely sure about bison: this was prompted by an earlier failed make that choked on a yacc invocation. Maybe the byacc package is better indicated? Anyway, so far lttng-modules, userspace-rcu and lttng-ust have all compiled and installed correctly. But when lttng-tools's turn comes, the make fails with: make[4]: entrant dans le r?pertoire ? /home/daniel/Documents/lttng-tools-2.1.1+-281047b/src/lib/lttng-ctl/filter ? /bin/bash ../../../../config/ylwrap filter-parser.y y.tab.c filter-parser.c y.tab.h filter-parser.h y.output filter-parser.output -- bison -y -t -d -v updating filter-parser.h updating filter-parser.output make all-am make[5]: entrant dans le r?pertoire ? /home/daniel/Documents/lttng-tools-2.1.1+-281047b/src/lib/lttng-ctl/filter ? /bin/bash ../../../../config/ylwrap filter-lexer.l .c filter-lexer.c -- : make[5]: *** [filter-lexer.c] Erreur 1 make[5]: quittant le r?pertoire ? /home/daniel/Documents/lttng-tools-2.1.1+-281047b/src/lib/lttng-ctl/filter ? make[4]: *** [all] Erreur 2 make[4]: quittant le r?pertoire ? /home/daniel/Documents/lttng-tools-2.1.1+-281047b/src/lib/lttng-ctl/filter ? make[3]: *** [all-recursive] Erreur 1 make[3]: quittant le r?pertoire ? /home/daniel/Documents/lttng-tools-2.1.1+-281047b/src/lib/lttng-ctl ? make[2]: *** [all-recursive] Erreur 1 make[2]: quittant le r?pertoire ? /home/daniel/Documents/lttng-tools-2.1.1+-281047b/src/lib ? make[1]: *** [all-recursive] Erreur 1 make[1]: quittant le r?pertoire ? /home/daniel/Documents/lttng-tools-2.1.1+-281047b/src ? make: *** [all-recursive] Erreur 1 Daniel U. Thibault R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) 2459 route de la Bravoure Qu?bec, QC? G3J 1X5 CANADA Vox?: (418) 844-4000 x4245 Fax?: (418) 844-4538 NAC?: 918V QSDJ Gouvernement du Canada?/ Government of Canada From mathieu.desnoyers at efficios.com Fri Jan 18 13:16:00 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 18 Jan 2013 13:16:00 -0500 Subject: [lttng-dev] [BABELTRACE PATCH] Add missing runall.sh to dist packaging In-Reply-To: <1358527840-4543-1-git-send-email-yannick.brosseau@gmail.com> References: <1358527840-4543-1-git-send-email-yannick.brosseau@gmail.com> Message-ID: <20130118181600.GA16664@Krystal> * Yannick Brosseau (yannick.brosseau at gmail.com) wrote: > Signed-off-by: Yannick Brosseau merged, thanks! Mathieu > --- > tests/lib/Makefile.am | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am > index f7e32c2..e9e264b 100644 > --- a/tests/lib/Makefile.am > +++ b/tests/lib/Makefile.am > @@ -12,7 +12,7 @@ noinst_PROGRAMS = test-seeks > > test_seeks_SOURCES = test-seeks.c > > -EXTRA_DIST = README.tap > +EXTRA_DIST = README.tap runall.sh > > check-am: > ./runall.sh > -- > 1.7.10.4 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Fri Jan 18 13:26:19 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 18 Jan 2013 13:26:19 -0500 Subject: [lttng-dev] yacc lttng-tools problem In-Reply-To: <3CA1A65C03C1A34C81BBC6272782E696987823@valcartierex01.valcartier.drdc-rddc.gc.ca> References: <3CA1A65C03C1A34C81BBC6272782E696987823@valcartierex01.valcartier.drdc-rddc.gc.ca> Message-ID: <20130118182619.GA17411@Krystal> * Thibault, Daniel (Daniel.Thibault at drdc-rddc.gc.ca) wrote: > I need help to get lttng-tools to compile. > > I have grabbed the (nearly) latest git.lttng.org packages: > > lttng-modules (2.1.0+-c6403de) > userspace-rcu (0.7.6-da9bed2) > lttng-ust (2.1.0+-340f776) (one new commit since) > lttng-tools (2.1.1+-281047b) (six new commits since) > > The userspace-rcu repository is weird: the 0.7.6 commit which I > fetched is marked as "8 days ago" but the master stops at "11 days > ago". 0.7.6 tags is against stable-0.7 branch, not master, so it's allright. stable-0.7 contains backports of fixes. The master branch is in preparation for an upcoming 0.8. Thanks, Mathieu > -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Fri Jan 18 13:30:20 2013 From: dgoulet at efficios.com (David Goulet) Date: Fri, 18 Jan 2013 13:30:20 -0500 Subject: [lttng-dev] yacc lttng-tools problem In-Reply-To: <3CA1A65C03C1A34C81BBC6272782E696987823@valcartierex01.valcartier.drdc-rddc.gc.ca> References: <3CA1A65C03C1A34C81BBC6272782E696987823@valcartierex01.valcartier.drdc-rddc.gc.ca> Message-ID: <50F994BC.9090503@efficios.com> Do a ./bootstrap to update or generate again ylwrap. Make sure also you have these packages: - flex >= 2.5.35 - bison >= 2.4 Thanks! David Thibault, Daniel: > I need help to get lttng-tools to compile. > > I have grabbed the (nearly) latest git.lttng.org packages: > > lttng-modules (2.1.0+-c6403de) > userspace-rcu (0.7.6-da9bed2) > lttng-ust (2.1.0+-340f776) (one new commit since) > lttng-tools (2.1.1+-281047b) (six new commits since) > > The userspace-rcu repository is weird: the 0.7.6 commit which I fetched is marked as "8 days ago" but the master stops at "11 days ago". > > I've installed (on my Ubuntu 12.04 system) libtool, texinfo, g++, libpopt-dev, and bison. I'm not completely sure about bison: this was prompted by an earlier failed make that choked on a yacc invocation. Maybe the byacc package is better indicated? > > Anyway, so far lttng-modules, userspace-rcu and lttng-ust have all compiled and installed correctly. But when lttng-tools's turn comes, the make fails with: > > make[4]: entrant dans le r?pertoire ? /home/daniel/Documents/lttng-tools-2.1.1+-281047b/src/lib/lttng-ctl/filter ? > /bin/bash ../../../../config/ylwrap filter-parser.y y.tab.c filter-parser.c y.tab.h filter-parser.h y.output filter-parser.output -- bison -y -t -d -v > updating filter-parser.h > updating filter-parser.output > make all-am > make[5]: entrant dans le r?pertoire ? /home/daniel/Documents/lttng-tools-2.1.1+-281047b/src/lib/lttng-ctl/filter ? > /bin/bash ../../../../config/ylwrap filter-lexer.l .c filter-lexer.c -- : > make[5]: *** [filter-lexer.c] Erreur 1 > make[5]: quittant le r?pertoire ? /home/daniel/Documents/lttng-tools-2.1.1+-281047b/src/lib/lttng-ctl/filter ? > make[4]: *** [all] Erreur 2 > make[4]: quittant le r?pertoire ? /home/daniel/Documents/lttng-tools-2.1.1+-281047b/src/lib/lttng-ctl/filter ? > make[3]: *** [all-recursive] Erreur 1 > make[3]: quittant le r?pertoire ? /home/daniel/Documents/lttng-tools-2.1.1+-281047b/src/lib/lttng-ctl ? > make[2]: *** [all-recursive] Erreur 1 > make[2]: quittant le r?pertoire ? /home/daniel/Documents/lttng-tools-2.1.1+-281047b/src/lib ? > make[1]: *** [all-recursive] Erreur 1 > make[1]: quittant le r?pertoire ? /home/daniel/Documents/lttng-tools-2.1.1+-281047b/src ? > make: *** [all-recursive] Erreur 1 > > Daniel U. Thibault > R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) > Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) > Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) > 2459 route de la Bravoure > Qu?bec, QC G3J 1X5 > CANADA > Vox : (418) 844-4000 x4245 > Fax : (418) 844-4538 > NAC : 918V QSDJ > Gouvernement du Canada / Government of Canada > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev From mathieu.desnoyers at efficios.com Fri Jan 18 14:03:57 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 18 Jan 2013 14:03:57 -0500 Subject: [lttng-dev] [RELEASE] LTTng-UST 2.1.1 Message-ID: <20130118190357.GA17727@Krystal> LTTng-UST, the Linux Trace Toolkit Next Generation Userspace Tracer, is port of the low-overhead tracing capabilities of the LTTng kernel tracer to user-space. The library "liblttng-ust" enables tracing of applications and libraries. Changelog: 2013-01-18 lttng-ust 2.1.1 * Introduce hash table for lttng_create_event_if_missing() * Fix: don't build C++ example if a C++ compiler isn't available Project website: http://lttng.org Download link: http://lttng.org/download (please refer to the README file for installation instructions) -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From Daniel.Thibault at drdc-rddc.gc.ca Fri Jan 18 14:10:09 2013 From: Daniel.Thibault at drdc-rddc.gc.ca (Thibault, Daniel) Date: Fri, 18 Jan 2013 14:10:09 -0500 Subject: [lttng-dev] yacc lttng-tools problem In-Reply-To: <50F994BC.9090503@efficios.com> References: <3CA1A65C03C1A34C81BBC6272782E696987823@valcartierex01.valcartier.drdc-rddc.gc.ca> <50F994BC.9090503@efficios.com> Message-ID: <3CA1A65C03C1A34C81BBC6272782E69698782F@valcartierex01.valcartier.drdc-rddc.gc.ca> -----Message d'origine----- De?: David Goulet [mailto:dgoulet at efficios.com] Envoy??: 18 janvier 2013 13:30 Make sure also you have these packages: - flex >= 2.5.35 - bison >= 2.4 David -----Fin du message d'origine----- Flex was the missing package (far, far from obvious). It works now! Daniel U. Thibault R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) 2459 route de la Bravoure Qu?bec, QC G3J 1X5 CANADA Vox : (418) 844-4000 x4245 Fax : (418) 844-4538 NAC : 918V QSDJ Gouvernement du Canada / Government of Canada From mathieu.desnoyers at efficios.com Fri Jan 18 14:15:10 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 18 Jan 2013 14:15:10 -0500 Subject: [lttng-dev] yacc lttng-tools problem In-Reply-To: <3CA1A65C03C1A34C81BBC6272782E69698782F@valcartierex01.valcartier.drdc-rddc.gc.ca> References: <3CA1A65C03C1A34C81BBC6272782E696987823@valcartierex01.valcartier.drdc-rddc.gc.ca> <50F994BC.9090503@efficios.com> <3CA1A65C03C1A34C81BBC6272782E69698782F@valcartierex01.valcartier.drdc-rddc.gc.ca> Message-ID: <20130118191510.GA17874@Krystal> * Thibault, Daniel (Daniel.Thibault at drdc-rddc.gc.ca) wrote: > -----Message d'origine----- > De?: David Goulet [mailto:dgoulet at efficios.com] > Envoy??: 18 janvier 2013 13:30 > > Make sure also you have these packages: > > - flex >= 2.5.35 > - bison >= 2.4 > > David > -----Fin du message d'origine----- > > Flex was the missing package (far, far from obvious). It works now! Please read the "README" files found in each project root directory before building. These document, amongst other important things, the dependencies that need to be installed in order to build each project. Thank you, Mathieu -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From Daniel.Thibault at drdc-rddc.gc.ca Fri Jan 18 14:20:05 2013 From: Daniel.Thibault at drdc-rddc.gc.ca (Thibault, Daniel) Date: Fri, 18 Jan 2013 14:20:05 -0500 Subject: [lttng-dev] yacc lttng-tools problem In-Reply-To: <20130118191510.GA17874@Krystal> References: <3CA1A65C03C1A34C81BBC6272782E696987823@valcartierex01.valcartier.drdc-rddc.gc.ca> <50F994BC.9090503@efficios.com> <3CA1A65C03C1A34C81BBC6272782E69698782F@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130118191510.GA17874@Krystal> Message-ID: <3CA1A65C03C1A34C81BBC6272782E696987831@valcartierex01.valcartier.drdc-rddc.gc.ca> -----Message d'origine----- De?: Mathieu Desnoyers [mailto:mathieu.desnoyers at efficios.com] Envoy??: 18 janvier 2013 14:15 > Flex was the missing package (far, far from obvious). It works now! Please read the "README" files found in each project root directory before building. These document, amongst other important things, the dependencies that need to be installed in order to build each project. Mathieu -----Fin du message d'origine----- Silly me, I had overlooked the ReadMe. Mea culpa, mea maxima culpa. Daniel U. Thibault R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) 2459 route de la Bravoure Qu?bec, QC G3J 1X5 CANADA Vox : (418) 844-4000 x4245 Fax : (418) 844-4538 NAC : 918V QSDJ Gouvernement du Canada / Government of Canada From jeremie.galarneau at efficios.com Fri Jan 18 11:45:32 2013 From: jeremie.galarneau at efficios.com (=?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=) Date: Fri, 18 Jan 2013 16:45:32 +0000 Subject: [lttng-dev] [PATCH babeltrace 1/3] Fix: Mismatching function signatures used by python bindings Message-ID: <1358527534-16401-1-git-send-email-jeremie.galarneau@efficios.com> Signed-off-by: J?r?mie Galarneau --- bindings/python/babeltrace.i.in | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/bindings/python/babeltrace.i.in b/bindings/python/babeltrace.i.in index b693f02..d45afb0 100644 --- a/bindings/python/babeltrace.i.in +++ b/bindings/python/babeltrace.i.in @@ -557,15 +557,15 @@ struct bt_ctf_event *bt_ctf_iter_read_event(struct bt_ctf_iter *iter); %rename("_bt_ctf_get_index") bt_ctf_get_index(const struct bt_ctf_event *ctf_event, const struct definition *field, unsigned int index); %rename("_bt_ctf_field_name") bt_ctf_field_name(const struct definition *def); -%rename("_bt_ctf_field_type") bt_ctf_field_type(const struct definition *def); +%rename("_bt_ctf_field_type") bt_ctf_field_type(const struct declaration *def); %rename("_bt_ctf_get_int_signedness") bt_ctf_get_int_signedness( - const struct definition *field); -%rename("_bt_ctf_get_int_base") bt_ctf_get_int_base(const struct definition *field); + const struct declaration *field); +%rename("_bt_ctf_get_int_base") bt_ctf_get_int_base(const struct declaration *field); %rename("_bt_ctf_get_int_byte_order") bt_ctf_get_int_byte_order( - const struct definition *field); -%rename("_bt_ctf_get_int_len") bt_ctf_get_int_len(const struct definition *field); -%rename("_bt_ctf_get_encoding") bt_ctf_get_encoding(const struct definition *field); -%rename("_bt_ctf_get_array_len") bt_ctf_get_array_len(const struct definition *field); + const struct declaration *field); +%rename("_bt_ctf_get_int_len") bt_ctf_get_int_len(const struct declaration *field); +%rename("_bt_ctf_get_encoding") bt_ctf_get_encoding(const struct declaration *field); +%rename("_bt_ctf_get_array_len") bt_ctf_get_array_len(const struct declaration *field); %rename("_bt_ctf_get_uint64") bt_ctf_get_uint64(const struct definition *field); %rename("_bt_ctf_get_int64") bt_ctf_get_int64(const struct definition *field); %rename("_bt_ctf_get_char_array") bt_ctf_get_char_array(const struct definition *field); @@ -588,13 +588,13 @@ const struct definition *bt_ctf_get_index(const struct bt_ctf_event *ctf_event, const struct definition *field, unsigned int index); const char *bt_ctf_field_name(const struct definition *def); -enum ctf_type_id bt_ctf_field_type(const struct definition *def); -int bt_ctf_get_int_signedness(const struct definition *field); -int bt_ctf_get_int_base(const struct definition *field); -int bt_ctf_get_int_byte_order(const struct definition *field); -ssize_t bt_ctf_get_int_len(const struct definition *field); -enum ctf_string_encoding bt_ctf_get_encoding(const struct definition *field); -int bt_ctf_get_array_len(const struct definition *field); +enum ctf_type_id bt_ctf_field_type(const struct declaration *def); +int bt_ctf_get_int_signedness(const struct declaration *field); +int bt_ctf_get_int_base(const struct declaration *field); +int bt_ctf_get_int_byte_order(const struct declaration *field); +ssize_t bt_ctf_get_int_len(const struct declaration *field); +enum ctf_string_encoding bt_ctf_get_encoding(const struct declaration *field); +int bt_ctf_get_array_len(const struct declaration *field); uint64_t bt_ctf_get_uint64(const struct definition *field); int64_t bt_ctf_get_int64(const struct definition *field); char *bt_ctf_get_char_array(const struct definition *field); -- 1.8.1.1 From jeremie.galarneau at efficios.com Fri Jan 18 11:45:33 2013 From: jeremie.galarneau at efficios.com (=?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=) Date: Fri, 18 Jan 2013 16:45:33 +0000 Subject: [lttng-dev] [PATCH babeltrace 2/3] Fix: Python 3 binding compatibility and clean intermediate files. In-Reply-To: <1358527534-16401-1-git-send-email-jeremie.galarneau@efficios.com> References: <1358527534-16401-1-git-send-email-jeremie.galarneau@efficios.com> Message-ID: <1358527534-16401-2-git-send-email-jeremie.galarneau@efficios.com> Signed-off-by: J?r?mie Galarneau --- bindings/python/Makefile.am | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bindings/python/Makefile.am b/bindings/python/Makefile.am index bf8050e..536e07f 100644 --- a/bindings/python/Makefile.am +++ b/bindings/python/Makefile.am @@ -23,6 +23,5 @@ _babeltrace_la_LIBADD = $(top_srcdir)/formats/ctf/libbabeltrace-ctf.la \ # SWIG 'warning md variable unused' fixed after SWIG build: babeltrace_wrap.c: babeltrace.i $(SWIG) -python -Wall -I. -I$(top_srcdir)/include babeltrace.i - sed -i "s/PyObject \*m, \*d, \*md;/PyObject \*m, \*d;\n#if defined(SWIGPYTHON_BUILTIN)\nPyObject *md;\n#endif/g" babeltrace_wrap.c - sed -i "s/md = d/d/g" babeltrace_wrap.c - sed -i "s/(void)public_symbol;/(void)public_symbol;\n md = d;/g" babeltrace_wrap.c + +CLEANFILES = babeltrace.i babeltrace.py babeltrace_wrap.c -- 1.8.1.1 From jeremie.galarneau at efficios.com Fri Jan 18 11:45:34 2013 From: jeremie.galarneau at efficios.com (=?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=) Date: Fri, 18 Jan 2013 16:45:34 +0000 Subject: [lttng-dev] [PATCH babeltrace 3/3] Fix: Removed Python bindings to static constructor and destructor. In-Reply-To: <1358527534-16401-1-git-send-email-jeremie.galarneau@efficios.com> References: <1358527534-16401-1-git-send-email-jeremie.galarneau@efficios.com> Message-ID: <1358527534-16401-3-git-send-email-jeremie.galarneau@efficios.com> Resolves an undefined symbol on Python module load. Signed-off-by: J?r?mie Galarneau --- bindings/python/babeltrace.i.in | 3 --- 1 file changed, 3 deletions(-) diff --git a/bindings/python/babeltrace.i.in b/bindings/python/babeltrace.i.in index d45afb0..dd49ba5 100644 --- a/bindings/python/babeltrace.i.in +++ b/bindings/python/babeltrace.i.in @@ -194,9 +194,6 @@ extern struct format *bt_lookup_format(bt_intern_str qname); extern void bt_fprintf_format_list(FILE *fp); extern int bt_register_format(struct format *format); -void format_init(void); -void format_finalize(void); - %pythoncode %{ def print_format_list(babeltrace_file): -- 1.8.1.1 From simon.marchi at polymtl.ca Fri Jan 18 17:10:35 2013 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Fri, 18 Jan 2013 17:10:35 -0500 Subject: [lttng-dev] [PATCH lttng-modules] Add system calls definitions fot the tile architecture Message-ID: <1358547035-25195-1-git-send-email-simon.marchi@polymtl.ca> The definitions were extracted using the lttng-syscalls-extractor module. The overrides were added for the system calls that appeared as sys_unknown in the trace (they don't appear in the generated list). Signed-off-by: Simon Marchi --- .../syscalls/headers/syscalls_integers.h | 4 + .../syscalls/headers/syscalls_pointers.h | 4 + ...-syscalls-2.6.40.38-MDE-4.1.2.149467_integers.h | 971 ++++++++++ ...-2.6.40.38-MDE-4.1.2.149467_integers_override.h | 50 + ...-syscalls-2.6.40.38-MDE-4.1.2.149467_pointers.h | 1872 ++++++++++++++++++++ ...-2.6.40.38-MDE-4.1.2.149467_pointers_override.h | 11 + 6 files changed, 2912 insertions(+), 0 deletions(-) create mode 100644 instrumentation/syscalls/headers/tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_integers.h create mode 100644 instrumentation/syscalls/headers/tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_integers_override.h create mode 100644 instrumentation/syscalls/headers/tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_pointers.h create mode 100644 instrumentation/syscalls/headers/tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_pointers_override.h diff --git a/instrumentation/syscalls/headers/syscalls_integers.h b/instrumentation/syscalls/headers/syscalls_integers.h index 002130a..7ca7681 100644 --- a/instrumentation/syscalls/headers/syscalls_integers.h +++ b/instrumentation/syscalls/headers/syscalls_integers.h @@ -9,3 +9,7 @@ #ifdef CONFIG_ARM #include "arm-32-syscalls-2.6.38_integers.h" #endif + +#ifdef CONFIG_TILE +#include "tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_integers.h" +#endif diff --git a/instrumentation/syscalls/headers/syscalls_pointers.h b/instrumentation/syscalls/headers/syscalls_pointers.h index 11b4979..ab94f7a 100644 --- a/instrumentation/syscalls/headers/syscalls_pointers.h +++ b/instrumentation/syscalls/headers/syscalls_pointers.h @@ -9,3 +9,7 @@ #ifdef CONFIG_ARM #include "arm-32-syscalls-2.6.38_pointers.h" #endif + +#ifdef CONFIG_TILE +#include "tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_pointers.h" +#endif diff --git a/instrumentation/syscalls/headers/tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_integers.h b/instrumentation/syscalls/headers/tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_integers.h new file mode 100644 index 0000000..8703471 --- /dev/null +++ b/instrumentation/syscalls/headers/tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_integers.h @@ -0,0 +1,971 @@ +/* THIS FILE IS AUTO-GENERATED. DO NOT EDIT */ +#ifndef CREATE_SYSCALL_TABLE + +#if !defined(_TRACE_SYSCALLS_INTEGERS_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SYSCALLS_INTEGERS_H + +#include +#include +#include "tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_integers_override.h" +#include "syscalls_integers_override.h" + +SC_DECLARE_EVENT_CLASS_NOARGS(syscalls_noargs, + TP_STRUCT__entry(), + TP_fast_assign(), + TP_printk() +) +#ifndef OVERRIDE_64_sys_vhangup +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_vhangup) +#endif +#ifndef OVERRIDE_64_sys_sync +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_sync) +#endif +#ifndef OVERRIDE_64_sys_sched_yield +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_sched_yield) +#endif +#ifndef OVERRIDE_64_sys_restart_syscall +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_restart_syscall) +#endif +#ifndef OVERRIDE_64_sys_setsid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_setsid) +#endif +#ifndef OVERRIDE_64_sys_getpid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getpid) +#endif +#ifndef OVERRIDE_64_sys_getppid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getppid) +#endif +#ifndef OVERRIDE_64_sys_getuid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getuid) +#endif +#ifndef OVERRIDE_64_sys_geteuid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_geteuid) +#endif +#ifndef OVERRIDE_64_sys_getgid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getgid) +#endif +#ifndef OVERRIDE_64_sys_getegid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getegid) +#endif +#ifndef OVERRIDE_64_sys_gettid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_gettid) +#endif +#ifndef OVERRIDE_64_sys_munlockall +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_munlockall) +#endif +#ifndef OVERRIDE_64_sys_io_destroy +SC_TRACE_EVENT(sys_io_destroy, + TP_PROTO(aio_context_t ctx), + TP_ARGS(ctx), + TP_STRUCT__entry(__field(aio_context_t, ctx)), + TP_fast_assign(tp_assign(ctx, ctx)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_epoll_create1 +SC_TRACE_EVENT(sys_epoll_create1, + TP_PROTO(int flags), + TP_ARGS(flags), + TP_STRUCT__entry(__field(int, flags)), + TP_fast_assign(tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_dup +SC_TRACE_EVENT(sys_dup, + TP_PROTO(unsigned int fildes), + TP_ARGS(fildes), + TP_STRUCT__entry(__field(unsigned int, fildes)), + TP_fast_assign(tp_assign(fildes, fildes)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_inotify_init1 +SC_TRACE_EVENT(sys_inotify_init1, + TP_PROTO(int flags), + TP_ARGS(flags), + TP_STRUCT__entry(__field(int, flags)), + TP_fast_assign(tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fchdir +SC_TRACE_EVENT(sys_fchdir, + TP_PROTO(unsigned int fd), + TP_ARGS(fd), + TP_STRUCT__entry(__field(unsigned int, fd)), + TP_fast_assign(tp_assign(fd, fd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_close +SC_TRACE_EVENT(sys_close, + TP_PROTO(unsigned int fd), + TP_ARGS(fd), + TP_STRUCT__entry(__field(unsigned int, fd)), + TP_fast_assign(tp_assign(fd, fd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fsync +SC_TRACE_EVENT(sys_fsync, + TP_PROTO(unsigned int fd), + TP_ARGS(fd), + TP_STRUCT__entry(__field(unsigned int, fd)), + TP_fast_assign(tp_assign(fd, fd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fdatasync +SC_TRACE_EVENT(sys_fdatasync, + TP_PROTO(unsigned int fd), + TP_ARGS(fd), + TP_STRUCT__entry(__field(unsigned int, fd)), + TP_fast_assign(tp_assign(fd, fd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_personality +SC_TRACE_EVENT(sys_personality, + TP_PROTO(unsigned int personality), + TP_ARGS(personality), + TP_STRUCT__entry(__field(unsigned int, personality)), + TP_fast_assign(tp_assign(personality, personality)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_exit +SC_TRACE_EVENT(sys_exit, + TP_PROTO(int error_code), + TP_ARGS(error_code), + TP_STRUCT__entry(__field(int, error_code)), + TP_fast_assign(tp_assign(error_code, error_code)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_exit_group +SC_TRACE_EVENT(sys_exit_group, + TP_PROTO(int error_code), + TP_ARGS(error_code), + TP_STRUCT__entry(__field(int, error_code)), + TP_fast_assign(tp_assign(error_code, error_code)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_unshare +SC_TRACE_EVENT(sys_unshare, + TP_PROTO(unsigned long unshare_flags), + TP_ARGS(unshare_flags), + TP_STRUCT__entry(__field(unsigned long, unshare_flags)), + TP_fast_assign(tp_assign(unshare_flags, unshare_flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_timer_getoverrun +SC_TRACE_EVENT(sys_timer_getoverrun, + TP_PROTO(timer_t timer_id), + TP_ARGS(timer_id), + TP_STRUCT__entry(__field(timer_t, timer_id)), + TP_fast_assign(tp_assign(timer_id, timer_id)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_timer_delete +SC_TRACE_EVENT(sys_timer_delete, + TP_PROTO(timer_t timer_id), + TP_ARGS(timer_id), + TP_STRUCT__entry(__field(timer_t, timer_id)), + TP_fast_assign(tp_assign(timer_id, timer_id)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sched_getscheduler +SC_TRACE_EVENT(sys_sched_getscheduler, + TP_PROTO(pid_t pid), + TP_ARGS(pid), + TP_STRUCT__entry(__field(pid_t, pid)), + TP_fast_assign(tp_assign(pid, pid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sched_get_priority_max +SC_TRACE_EVENT(sys_sched_get_priority_max, + TP_PROTO(int policy), + TP_ARGS(policy), + TP_STRUCT__entry(__field(int, policy)), + TP_fast_assign(tp_assign(policy, policy)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sched_get_priority_min +SC_TRACE_EVENT(sys_sched_get_priority_min, + TP_PROTO(int policy), + TP_ARGS(policy), + TP_STRUCT__entry(__field(int, policy)), + TP_fast_assign(tp_assign(policy, policy)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setgid +SC_TRACE_EVENT(sys_setgid, + TP_PROTO(gid_t gid), + TP_ARGS(gid), + TP_STRUCT__entry(__field(gid_t, gid)), + TP_fast_assign(tp_assign(gid, gid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setuid +SC_TRACE_EVENT(sys_setuid, + TP_PROTO(uid_t uid), + TP_ARGS(uid), + TP_STRUCT__entry(__field(uid_t, uid)), + TP_fast_assign(tp_assign(uid, uid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setfsuid +SC_TRACE_EVENT(sys_setfsuid, + TP_PROTO(uid_t uid), + TP_ARGS(uid), + TP_STRUCT__entry(__field(uid_t, uid)), + TP_fast_assign(tp_assign(uid, uid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setfsgid +SC_TRACE_EVENT(sys_setfsgid, + TP_PROTO(gid_t gid), + TP_ARGS(gid), + TP_STRUCT__entry(__field(gid_t, gid)), + TP_fast_assign(tp_assign(gid, gid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getpgid +SC_TRACE_EVENT(sys_getpgid, + TP_PROTO(pid_t pid), + TP_ARGS(pid), + TP_STRUCT__entry(__field(pid_t, pid)), + TP_fast_assign(tp_assign(pid, pid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getsid +SC_TRACE_EVENT(sys_getsid, + TP_PROTO(pid_t pid), + TP_ARGS(pid), + TP_STRUCT__entry(__field(pid_t, pid)), + TP_fast_assign(tp_assign(pid, pid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_umask +SC_TRACE_EVENT(sys_umask, + TP_PROTO(int mask), + TP_ARGS(mask), + TP_STRUCT__entry(__field(int, mask)), + TP_fast_assign(tp_assign(mask, mask)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_brk +SC_TRACE_EVENT(sys_brk, + TP_PROTO(unsigned long brk), + TP_ARGS(brk), + TP_STRUCT__entry(__field(unsigned long, brk)), + TP_fast_assign(tp_assign(brk, brk)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mlockall +SC_TRACE_EVENT(sys_mlockall, + TP_PROTO(int flags), + TP_ARGS(flags), + TP_STRUCT__entry(__field(int, flags)), + TP_fast_assign(tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_set_dataplane +SC_TRACE_EVENT(sys_set_dataplane, + TP_PROTO(int flags), + TP_ARGS(flags), + TP_STRUCT__entry(__field(int, flags)), + TP_fast_assign(tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_syncfs +SC_TRACE_EVENT(sys_syncfs, + TP_PROTO(int fd), + TP_ARGS(fd), + TP_STRUCT__entry(__field(int, fd)), + TP_fast_assign(tp_assign(fd, fd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_eventfd2 +SC_TRACE_EVENT(sys_eventfd2, + TP_PROTO(unsigned int count, int flags), + TP_ARGS(count, flags), + TP_STRUCT__entry(__field(unsigned int, count) __field(int, flags)), + TP_fast_assign(tp_assign(count, count) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_inotify_rm_watch +SC_TRACE_EVENT(sys_inotify_rm_watch, + TP_PROTO(int fd, __s32 wd), + TP_ARGS(fd, wd), + TP_STRUCT__entry(__field(int, fd) __field(__s32, wd)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(wd, wd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_ioprio_get +SC_TRACE_EVENT(sys_ioprio_get, + TP_PROTO(int which, int who), + TP_ARGS(which, who), + TP_STRUCT__entry(__field(int, which) __field(int, who)), + TP_fast_assign(tp_assign(which, which) tp_assign(who, who)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_flock +SC_TRACE_EVENT(sys_flock, + TP_PROTO(unsigned int fd, unsigned int cmd), + TP_ARGS(fd, cmd), + TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned int, cmd)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(cmd, cmd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_ftruncate +SC_TRACE_EVENT(sys_ftruncate, + TP_PROTO(unsigned int fd, unsigned long length), + TP_ARGS(fd, length), + TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned long, length)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(length, length)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fchmod +SC_TRACE_EVENT(sys_fchmod, + TP_PROTO(unsigned int fd, mode_t mode), + TP_ARGS(fd, mode), + TP_STRUCT__entry(__field(unsigned int, fd) __field(mode_t, mode)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_timerfd_create +SC_TRACE_EVENT(sys_timerfd_create, + TP_PROTO(int clockid, int flags), + TP_ARGS(clockid, flags), + TP_STRUCT__entry(__field(int, clockid) __field(int, flags)), + TP_fast_assign(tp_assign(clockid, clockid) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_kill +SC_TRACE_EVENT(sys_kill, + TP_PROTO(pid_t pid, int sig), + TP_ARGS(pid, sig), + TP_STRUCT__entry(__field(pid_t, pid) __field(int, sig)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(sig, sig)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_tkill +SC_TRACE_EVENT(sys_tkill, + TP_PROTO(pid_t pid, int sig), + TP_ARGS(pid, sig), + TP_STRUCT__entry(__field(pid_t, pid) __field(int, sig)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(sig, sig)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getpriority +SC_TRACE_EVENT(sys_getpriority, + TP_PROTO(int which, int who), + TP_ARGS(which, who), + TP_STRUCT__entry(__field(int, which) __field(int, who)), + TP_fast_assign(tp_assign(which, which) tp_assign(who, who)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setregid +SC_TRACE_EVENT(sys_setregid, + TP_PROTO(gid_t rgid, gid_t egid), + TP_ARGS(rgid, egid), + TP_STRUCT__entry(__field(gid_t, rgid) __field(gid_t, egid)), + TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setreuid +SC_TRACE_EVENT(sys_setreuid, + TP_PROTO(uid_t ruid, uid_t euid), + TP_ARGS(ruid, euid), + TP_STRUCT__entry(__field(uid_t, ruid) __field(uid_t, euid)), + TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setpgid +SC_TRACE_EVENT(sys_setpgid, + TP_PROTO(pid_t pid, pid_t pgid), + TP_ARGS(pid, pgid), + TP_STRUCT__entry(__field(pid_t, pid) __field(pid_t, pgid)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(pgid, pgid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_msgget +SC_TRACE_EVENT(sys_msgget, + TP_PROTO(key_t key, int msgflg), + TP_ARGS(key, msgflg), + TP_STRUCT__entry(__field(key_t, key) __field(int, msgflg)), + TP_fast_assign(tp_assign(key, key) tp_assign(msgflg, msgflg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_listen +SC_TRACE_EVENT(sys_listen, + TP_PROTO(int fd, int backlog), + TP_ARGS(fd, backlog), + TP_STRUCT__entry(__field(int, fd) __field(int, backlog)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(backlog, backlog)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_shutdown +SC_TRACE_EVENT(sys_shutdown, + TP_PROTO(int fd, int how), + TP_ARGS(fd, how), + TP_STRUCT__entry(__field(int, fd) __field(int, how)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(how, how)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_munmap +SC_TRACE_EVENT(sys_munmap, + TP_PROTO(unsigned long addr, size_t len), + TP_ARGS(addr, len), + TP_STRUCT__entry(__field_hex(unsigned long, addr) __field(size_t, len)), + TP_fast_assign(tp_assign(addr, addr) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mlock +SC_TRACE_EVENT(sys_mlock, + TP_PROTO(unsigned long start, size_t len), + TP_ARGS(start, len), + TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len)), + TP_fast_assign(tp_assign(start, start) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_munlock +SC_TRACE_EVENT(sys_munlock, + TP_PROTO(unsigned long start, size_t len), + TP_ARGS(start, len), + TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len)), + TP_fast_assign(tp_assign(start, start) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setns +SC_TRACE_EVENT(sys_setns, + TP_PROTO(int fd, int nstype), + TP_ARGS(fd, nstype), + TP_STRUCT__entry(__field(int, fd) __field(int, nstype)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(nstype, nstype)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_dup3 +SC_TRACE_EVENT(sys_dup3, + TP_PROTO(unsigned int oldfd, unsigned int newfd, int flags), + TP_ARGS(oldfd, newfd, flags), + TP_STRUCT__entry(__field(unsigned int, oldfd) __field(unsigned int, newfd) __field(int, flags)), + TP_fast_assign(tp_assign(oldfd, oldfd) tp_assign(newfd, newfd) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fcntl +SC_TRACE_EVENT(sys_fcntl, + TP_PROTO(unsigned int fd, unsigned int cmd, unsigned long arg), + TP_ARGS(fd, cmd, arg), + TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned int, cmd) __field(unsigned long, arg)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(cmd, cmd) tp_assign(arg, arg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_ioctl +SC_TRACE_EVENT(sys_ioctl, + TP_PROTO(unsigned int fd, unsigned int cmd, unsigned long arg), + TP_ARGS(fd, cmd, arg), + TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned int, cmd) __field(unsigned long, arg)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(cmd, cmd) tp_assign(arg, arg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_ioprio_set +SC_TRACE_EVENT(sys_ioprio_set, + TP_PROTO(int which, int who, int ioprio), + TP_ARGS(which, who, ioprio), + TP_STRUCT__entry(__field(int, which) __field(int, who) __field(int, ioprio)), + TP_fast_assign(tp_assign(which, which) tp_assign(who, who) tp_assign(ioprio, ioprio)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fchown +SC_TRACE_EVENT(sys_fchown, + TP_PROTO(unsigned int fd, uid_t user, gid_t group), + TP_ARGS(fd, user, group), + TP_STRUCT__entry(__field(unsigned int, fd) __field(uid_t, user) __field(gid_t, group)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(user, user) tp_assign(group, group)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_lseek +SC_TRACE_EVENT(sys_lseek, + TP_PROTO(unsigned int fd, off_t offset, unsigned int origin), + TP_ARGS(fd, offset, origin), + TP_STRUCT__entry(__field(unsigned int, fd) __field(off_t, offset) __field(unsigned int, origin)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(offset, offset) tp_assign(origin, origin)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_tgkill +SC_TRACE_EVENT(sys_tgkill, + TP_PROTO(pid_t tgid, pid_t pid, int sig), + TP_ARGS(tgid, pid, sig), + TP_STRUCT__entry(__field(pid_t, tgid) __field(pid_t, pid) __field(int, sig)), + TP_fast_assign(tp_assign(tgid, tgid) tp_assign(pid, pid) tp_assign(sig, sig)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setpriority +SC_TRACE_EVENT(sys_setpriority, + TP_PROTO(int which, int who, int niceval), + TP_ARGS(which, who, niceval), + TP_STRUCT__entry(__field(int, which) __field(int, who) __field(int, niceval)), + TP_fast_assign(tp_assign(which, which) tp_assign(who, who) tp_assign(niceval, niceval)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setresuid +SC_TRACE_EVENT(sys_setresuid, + TP_PROTO(uid_t ruid, uid_t euid, uid_t suid), + TP_ARGS(ruid, euid, suid), + TP_STRUCT__entry(__field(uid_t, ruid) __field(uid_t, euid) __field(uid_t, suid)), + TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid) tp_assign(suid, suid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setresgid +SC_TRACE_EVENT(sys_setresgid, + TP_PROTO(gid_t rgid, gid_t egid, gid_t sgid), + TP_ARGS(rgid, egid, sgid), + TP_STRUCT__entry(__field(gid_t, rgid) __field(gid_t, egid) __field(gid_t, sgid)), + TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid) tp_assign(sgid, sgid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_semget +SC_TRACE_EVENT(sys_semget, + TP_PROTO(key_t key, int nsems, int semflg), + TP_ARGS(key, nsems, semflg), + TP_STRUCT__entry(__field(key_t, key) __field(int, nsems) __field(int, semflg)), + TP_fast_assign(tp_assign(key, key) tp_assign(nsems, nsems) tp_assign(semflg, semflg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_shmget +SC_TRACE_EVENT(sys_shmget, + TP_PROTO(key_t key, size_t size, int shmflg), + TP_ARGS(key, size, shmflg), + TP_STRUCT__entry(__field(key_t, key) __field(size_t, size) __field(int, shmflg)), + TP_fast_assign(tp_assign(key, key) tp_assign(size, size) tp_assign(shmflg, shmflg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_socket +SC_TRACE_EVENT(sys_socket, + TP_PROTO(int family, int type, int protocol), + TP_ARGS(family, type, protocol), + TP_STRUCT__entry(__field(int, family) __field(int, type) __field(int, protocol)), + TP_fast_assign(tp_assign(family, family) tp_assign(type, type) tp_assign(protocol, protocol)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mprotect +SC_TRACE_EVENT(sys_mprotect, + TP_PROTO(unsigned long start, size_t len, unsigned long prot), + TP_ARGS(start, len, prot), + TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len) __field(unsigned long, prot)), + TP_fast_assign(tp_assign(start, start) tp_assign(len, len) tp_assign(prot, prot)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_msync +SC_TRACE_EVENT(sys_msync, + TP_PROTO(unsigned long start, size_t len, int flags), + TP_ARGS(start, len, flags), + TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len) __field(int, flags)), + TP_fast_assign(tp_assign(start, start) tp_assign(len, len) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_madvise +SC_TRACE_EVENT(sys_madvise, + TP_PROTO(unsigned long start, size_t len_in, int behavior), + TP_ARGS(start, len_in, behavior), + TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len_in) __field(int, behavior)), + TP_fast_assign(tp_assign(start, start) tp_assign(len_in, len_in) tp_assign(behavior, behavior)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_cacheflush +SC_TRACE_EVENT(sys_cacheflush, + TP_PROTO(unsigned long addr, unsigned long len, unsigned long flags), + TP_ARGS(addr, len, flags), + TP_STRUCT__entry(__field_hex(unsigned long, addr) __field(unsigned long, len) __field(unsigned long, flags)), + TP_fast_assign(tp_assign(addr, addr) tp_assign(len, len) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_tee +SC_TRACE_EVENT(sys_tee, + TP_PROTO(int fdin, int fdout, size_t len, unsigned int flags), + TP_ARGS(fdin, fdout, len, flags), + TP_STRUCT__entry(__field(int, fdin) __field(int, fdout) __field(size_t, len) __field(unsigned int, flags)), + TP_fast_assign(tp_assign(fdin, fdin) tp_assign(fdout, fdout) tp_assign(len, len) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_ptrace +SC_TRACE_EVENT(sys_ptrace, + TP_PROTO(long request, long pid, unsigned long addr, unsigned long data), + TP_ARGS(request, pid, addr, data), + TP_STRUCT__entry(__field(long, request) __field(long, pid) __field_hex(unsigned long, addr) __field(unsigned long, data)), + TP_fast_assign(tp_assign(request, request) tp_assign(pid, pid) tp_assign(addr, addr) tp_assign(data, data)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_prctl +SC_TRACE_EVENT(sys_prctl, + TP_PROTO(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5), + TP_ARGS(option, arg2, arg3, arg4, arg5), + TP_STRUCT__entry(__field(int, option) __field(unsigned long, arg2) __field(unsigned long, arg3) __field(unsigned long, arg4) __field(unsigned long, arg5)), + TP_fast_assign(tp_assign(option, option) tp_assign(arg2, arg2) tp_assign(arg3, arg3) tp_assign(arg4, arg4) tp_assign(arg5, arg5)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mremap +SC_TRACE_EVENT(sys_mremap, + TP_PROTO(unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr), + TP_ARGS(addr, old_len, new_len, flags, new_addr), + TP_STRUCT__entry(__field_hex(unsigned long, addr) __field(unsigned long, old_len) __field(unsigned long, new_len) __field(unsigned long, flags) __field_hex(unsigned long, new_addr)), + TP_fast_assign(tp_assign(addr, addr) tp_assign(old_len, old_len) tp_assign(new_len, new_len) tp_assign(flags, flags) tp_assign(new_addr, new_addr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_keyctl +SC_TRACE_EVENT(sys_keyctl, + TP_PROTO(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5), + TP_ARGS(option, arg2, arg3, arg4, arg5), + TP_STRUCT__entry(__field(int, option) __field(unsigned long, arg2) __field(unsigned long, arg3) __field(unsigned long, arg4) __field(unsigned long, arg5)), + TP_fast_assign(tp_assign(option, option) tp_assign(arg2, arg2) tp_assign(arg3, arg3) tp_assign(arg4, arg4) tp_assign(arg5, arg5)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_remap_file_pages +SC_TRACE_EVENT(sys_remap_file_pages, + TP_PROTO(unsigned long start, unsigned long size, unsigned long prot, unsigned long pgoff, unsigned long flags), + TP_ARGS(start, size, prot, pgoff, flags), + TP_STRUCT__entry(__field(unsigned long, start) __field(unsigned long, size) __field(unsigned long, prot) __field(unsigned long, pgoff) __field(unsigned long, flags)), + TP_fast_assign(tp_assign(start, start) tp_assign(size, size) tp_assign(prot, prot) tp_assign(pgoff, pgoff) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mmap +SC_TRACE_EVENT(sys_mmap, + TP_PROTO(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, off_t offset), + TP_ARGS(addr, len, prot, flags, fd, offset), + TP_STRUCT__entry(__field_hex(unsigned long, addr) __field(unsigned long, len) __field(unsigned long, prot) __field(unsigned long, flags) __field(unsigned long, fd) __field(off_t, offset)), + TP_fast_assign(tp_assign(addr, addr) tp_assign(len, len) tp_assign(prot, prot) tp_assign(flags, flags) tp_assign(fd, fd) tp_assign(offset, offset)), + TP_printk() +) +#endif + +#endif /* _TRACE_SYSCALLS_INTEGERS_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" + +#else /* CREATE_SYSCALL_TABLE */ + +#include "tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_integers_override.h" +#include "syscalls_integers_override.h" + +#ifndef OVERRIDE_TABLE_64_sys_vhangup +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_vhangup, 58, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sync +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_sync, 81, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sched_yield +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_sched_yield, 124, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_restart_syscall +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_restart_syscall, 128, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setsid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_setsid, 157, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getpid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getpid, 172, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getppid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getppid, 173, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getuid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getuid, 174, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_geteuid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_geteuid, 175, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getgid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getgid, 176, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getegid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getegid, 177, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_gettid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_gettid, 178, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_munlockall +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_munlockall, 231, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_io_destroy +TRACE_SYSCALL_TABLE(sys_io_destroy, sys_io_destroy, 1, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_eventfd2 +TRACE_SYSCALL_TABLE(sys_eventfd2, sys_eventfd2, 19, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_epoll_create1 +TRACE_SYSCALL_TABLE(sys_epoll_create1, sys_epoll_create1, 20, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_dup +TRACE_SYSCALL_TABLE(sys_dup, sys_dup, 23, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_dup3 +TRACE_SYSCALL_TABLE(sys_dup3, sys_dup3, 24, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fcntl +TRACE_SYSCALL_TABLE(sys_fcntl, sys_fcntl, 25, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_inotify_init1 +TRACE_SYSCALL_TABLE(sys_inotify_init1, sys_inotify_init1, 26, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_inotify_rm_watch +TRACE_SYSCALL_TABLE(sys_inotify_rm_watch, sys_inotify_rm_watch, 28, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_ioctl +TRACE_SYSCALL_TABLE(sys_ioctl, sys_ioctl, 29, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_ioprio_set +TRACE_SYSCALL_TABLE(sys_ioprio_set, sys_ioprio_set, 30, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_ioprio_get +TRACE_SYSCALL_TABLE(sys_ioprio_get, sys_ioprio_get, 31, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_flock +TRACE_SYSCALL_TABLE(sys_flock, sys_flock, 32, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_ftruncate +TRACE_SYSCALL_TABLE(sys_ftruncate, sys_ftruncate, 46, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fchdir +TRACE_SYSCALL_TABLE(sys_fchdir, sys_fchdir, 50, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fchmod +TRACE_SYSCALL_TABLE(sys_fchmod, sys_fchmod, 52, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fchown +TRACE_SYSCALL_TABLE(sys_fchown, sys_fchown, 55, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_close +TRACE_SYSCALL_TABLE(sys_close, sys_close, 57, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_lseek +TRACE_SYSCALL_TABLE(sys_lseek, sys_lseek, 62, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_tee +TRACE_SYSCALL_TABLE(sys_tee, sys_tee, 77, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fsync +TRACE_SYSCALL_TABLE(sys_fsync, sys_fsync, 82, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fdatasync +TRACE_SYSCALL_TABLE(sys_fdatasync, sys_fdatasync, 83, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_timerfd_create +TRACE_SYSCALL_TABLE(sys_timerfd_create, sys_timerfd_create, 85, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_personality +TRACE_SYSCALL_TABLE(sys_personality, sys_personality, 92, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_exit +TRACE_SYSCALL_TABLE(sys_exit, sys_exit, 93, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_exit_group +TRACE_SYSCALL_TABLE(sys_exit_group, sys_exit_group, 94, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_unshare +TRACE_SYSCALL_TABLE(sys_unshare, sys_unshare, 97, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_timer_getoverrun +TRACE_SYSCALL_TABLE(sys_timer_getoverrun, sys_timer_getoverrun, 109, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_timer_delete +TRACE_SYSCALL_TABLE(sys_timer_delete, sys_timer_delete, 111, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_ptrace +TRACE_SYSCALL_TABLE(sys_ptrace, sys_ptrace, 117, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sched_getscheduler +TRACE_SYSCALL_TABLE(sys_sched_getscheduler, sys_sched_getscheduler, 120, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sched_get_priority_max +TRACE_SYSCALL_TABLE(sys_sched_get_priority_max, sys_sched_get_priority_max, 125, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sched_get_priority_min +TRACE_SYSCALL_TABLE(sys_sched_get_priority_min, sys_sched_get_priority_min, 126, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_kill +TRACE_SYSCALL_TABLE(sys_kill, sys_kill, 129, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_tkill +TRACE_SYSCALL_TABLE(sys_tkill, sys_tkill, 130, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_tgkill +TRACE_SYSCALL_TABLE(sys_tgkill, sys_tgkill, 131, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setpriority +TRACE_SYSCALL_TABLE(sys_setpriority, sys_setpriority, 140, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getpriority +TRACE_SYSCALL_TABLE(sys_getpriority, sys_getpriority, 141, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setregid +TRACE_SYSCALL_TABLE(sys_setregid, sys_setregid, 143, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setgid +TRACE_SYSCALL_TABLE(sys_setgid, sys_setgid, 144, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setreuid +TRACE_SYSCALL_TABLE(sys_setreuid, sys_setreuid, 145, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setuid +TRACE_SYSCALL_TABLE(sys_setuid, sys_setuid, 146, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setresuid +TRACE_SYSCALL_TABLE(sys_setresuid, sys_setresuid, 147, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setresgid +TRACE_SYSCALL_TABLE(sys_setresgid, sys_setresgid, 149, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setfsuid +TRACE_SYSCALL_TABLE(sys_setfsuid, sys_setfsuid, 151, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setfsgid +TRACE_SYSCALL_TABLE(sys_setfsgid, sys_setfsgid, 152, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setpgid +TRACE_SYSCALL_TABLE(sys_setpgid, sys_setpgid, 154, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getpgid +TRACE_SYSCALL_TABLE(sys_getpgid, sys_getpgid, 155, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getsid +TRACE_SYSCALL_TABLE(sys_getsid, sys_getsid, 156, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_umask +TRACE_SYSCALL_TABLE(sys_umask, sys_umask, 166, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_prctl +TRACE_SYSCALL_TABLE(sys_prctl, sys_prctl, 167, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_msgget +TRACE_SYSCALL_TABLE(sys_msgget, sys_msgget, 186, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_semget +TRACE_SYSCALL_TABLE(sys_semget, sys_semget, 190, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_shmget +TRACE_SYSCALL_TABLE(sys_shmget, sys_shmget, 194, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_socket +TRACE_SYSCALL_TABLE(sys_socket, sys_socket, 198, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_listen +TRACE_SYSCALL_TABLE(sys_listen, sys_listen, 201, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_shutdown +TRACE_SYSCALL_TABLE(sys_shutdown, sys_shutdown, 210, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_brk +TRACE_SYSCALL_TABLE(sys_brk, sys_brk, 214, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_munmap +TRACE_SYSCALL_TABLE(sys_munmap, sys_munmap, 215, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mremap +TRACE_SYSCALL_TABLE(sys_mremap, sys_mremap, 216, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_keyctl +TRACE_SYSCALL_TABLE(sys_keyctl, sys_keyctl, 219, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mmap +TRACE_SYSCALL_TABLE(sys_mmap, sys_mmap, 222, 6) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mprotect +TRACE_SYSCALL_TABLE(sys_mprotect, sys_mprotect, 226, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_msync +TRACE_SYSCALL_TABLE(sys_msync, sys_msync, 227, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mlock +TRACE_SYSCALL_TABLE(sys_mlock, sys_mlock, 228, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_munlock +TRACE_SYSCALL_TABLE(sys_munlock, sys_munlock, 229, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mlockall +TRACE_SYSCALL_TABLE(sys_mlockall, sys_mlockall, 230, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_madvise +TRACE_SYSCALL_TABLE(sys_madvise, sys_madvise, 233, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_remap_file_pages +TRACE_SYSCALL_TABLE(sys_remap_file_pages, sys_remap_file_pages, 234, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_cacheflush +TRACE_SYSCALL_TABLE(sys_cacheflush, sys_cacheflush, 245, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_set_dataplane +TRACE_SYSCALL_TABLE(sys_set_dataplane, sys_set_dataplane, 246, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_syncfs +TRACE_SYSCALL_TABLE(sys_syncfs, sys_syncfs, 267, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setns +TRACE_SYSCALL_TABLE(sys_setns, sys_setns, 268, 2) +#endif + +#endif /* CREATE_SYSCALL_TABLE */ diff --git a/instrumentation/syscalls/headers/tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_integers_override.h b/instrumentation/syscalls/headers/tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_integers_override.h new file mode 100644 index 0000000..5300138 --- /dev/null +++ b/instrumentation/syscalls/headers/tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_integers_override.h @@ -0,0 +1,50 @@ +#define OVERRIDE_TABLE_64_sys_sync_file_range +#define OVERRIDE_TABLE_64_sys_fadvise64_64 +#define OVERRIDE_TABLE_64_sys_rt_sigreturn + +#ifndef CREATE_SYSCALL_TABLE + +SC_TRACE_EVENT(sys_sync_file_range, + TP_PROTO(int fd, loff_t offset, loff_t nbytes, unsigned int flags), + TP_ARGS(fd, offset, nbytes, flags), + TP_STRUCT__entry( + __field(int, fd) + __field(loff_t, offset) + __field(loff_t, nbytes) + __field_hex(unsigned int, flags)), + TP_fast_assign( + tp_assign(fd, fd) + tp_assign(offset, offset) + tp_assign(nbytes, nbytes) + tp_assign(flags, flags)), + TP_printk() +) + +SC_TRACE_EVENT(sys_fadvise64_64, + TP_PROTO(int fd, loff_t offset, loff_t len, int advice), + TP_ARGS(fd, offset, len, advice), + TP_STRUCT__entry( + __field(int, fd) + __field(loff_t, offset) + __field(loff_t, len) + __field_hex(int, advice)), + TP_fast_assign( + tp_assign(fd, fd) + tp_assign(offset, offset) + tp_assign(len, len) + tp_assign(advice, advice)), + TP_printk() +) + +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_rt_sigreturn) + +#else /* CREATE_SYSCALL_TABLE */ + +TRACE_SYSCALL_TABLE(sys_sync_file_range, sys_sync_file_range, 84, 4) +TRACE_SYSCALL_TABLE(sys_fadvise64_64, sys_fadvise64_64, 223, 4) +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_rt_sigreturn, 139, 0) + + +#endif /* CREATE_SYSCALL_TABLE */ + + diff --git a/instrumentation/syscalls/headers/tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_pointers.h b/instrumentation/syscalls/headers/tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_pointers.h new file mode 100644 index 0000000..89d8b60 --- /dev/null +++ b/instrumentation/syscalls/headers/tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_pointers.h @@ -0,0 +1,1872 @@ +/* THIS FILE IS AUTO-GENERATED. DO NOT EDIT */ +#ifndef CREATE_SYSCALL_TABLE + +#if !defined(_TRACE_SYSCALLS_POINTERS_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SYSCALLS_POINTERS_H + +#include +#include +#include "tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_pointers_override.h" +#include "syscalls_pointers_override.h" + +#ifndef OVERRIDE_64_sys_chdir +SC_TRACE_EVENT(sys_chdir, + TP_PROTO(const char * filename), + TP_ARGS(filename), + TP_STRUCT__entry(__string_from_user(filename, filename)), + TP_fast_assign(tp_copy_string_from_user(filename, filename)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_chroot +SC_TRACE_EVENT(sys_chroot, + TP_PROTO(const char * filename), + TP_ARGS(filename), + TP_STRUCT__entry(__string_from_user(filename, filename)), + TP_fast_assign(tp_copy_string_from_user(filename, filename)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_acct +SC_TRACE_EVENT(sys_acct, + TP_PROTO(const char * name), + TP_ARGS(name), + TP_STRUCT__entry(__string_from_user(name, name)), + TP_fast_assign(tp_copy_string_from_user(name, name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_set_tid_address +SC_TRACE_EVENT(sys_set_tid_address, + TP_PROTO(int * tidptr), + TP_ARGS(tidptr), + TP_STRUCT__entry(__field_hex(int *, tidptr)), + TP_fast_assign(tp_assign(tidptr, tidptr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_times +SC_TRACE_EVENT(sys_times, + TP_PROTO(struct tms * tbuf), + TP_ARGS(tbuf), + TP_STRUCT__entry(__field_hex(struct tms *, tbuf)), + TP_fast_assign(tp_assign(tbuf, tbuf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_newuname +SC_TRACE_EVENT(sys_newuname, + TP_PROTO(struct new_utsname * name), + TP_ARGS(name), + TP_STRUCT__entry(__field_hex(struct new_utsname *, name)), + TP_fast_assign(tp_assign(name, name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_adjtimex +SC_TRACE_EVENT(sys_adjtimex, + TP_PROTO(struct timex * txc_p), + TP_ARGS(txc_p), + TP_STRUCT__entry(__field_hex(struct timex *, txc_p)), + TP_fast_assign(tp_assign(txc_p, txc_p)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sysinfo +SC_TRACE_EVENT(sys_sysinfo, + TP_PROTO(struct sysinfo * info), + TP_ARGS(info), + TP_STRUCT__entry(__field_hex(struct sysinfo *, info)), + TP_fast_assign(tp_assign(info, info)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mq_unlink +SC_TRACE_EVENT(sys_mq_unlink, + TP_PROTO(const char * u_name), + TP_ARGS(u_name), + TP_STRUCT__entry(__string_from_user(u_name, u_name)), + TP_fast_assign(tp_copy_string_from_user(u_name, u_name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_shmdt +SC_TRACE_EVENT(sys_shmdt, + TP_PROTO(char * shmaddr), + TP_ARGS(shmaddr), + TP_STRUCT__entry(__field_hex(char *, shmaddr)), + TP_fast_assign(tp_assign(shmaddr, shmaddr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_swapoff +SC_TRACE_EVENT(sys_swapoff, + TP_PROTO(const char * specialfile), + TP_ARGS(specialfile), + TP_STRUCT__entry(__string_from_user(specialfile, specialfile)), + TP_fast_assign(tp_copy_string_from_user(specialfile, specialfile)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_io_setup +SC_TRACE_EVENT(sys_io_setup, + TP_PROTO(unsigned nr_events, aio_context_t * ctxp), + TP_ARGS(nr_events, ctxp), + TP_STRUCT__entry(__field(unsigned, nr_events) __field_hex(aio_context_t *, ctxp)), + TP_fast_assign(tp_assign(nr_events, nr_events) tp_assign(ctxp, ctxp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_removexattr +SC_TRACE_EVENT(sys_removexattr, + TP_PROTO(const char * pathname, const char * name), + TP_ARGS(pathname, name), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_lremovexattr +SC_TRACE_EVENT(sys_lremovexattr, + TP_PROTO(const char * pathname, const char * name), + TP_ARGS(pathname, name), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fremovexattr +SC_TRACE_EVENT(sys_fremovexattr, + TP_PROTO(int fd, const char * name), + TP_ARGS(fd, name), + TP_STRUCT__entry(__field(int, fd) __string_from_user(name, name)), + TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(name, name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getcwd +SC_TRACE_EVENT(sys_getcwd, + TP_PROTO(char * buf, unsigned long size), + TP_ARGS(buf, size), + TP_STRUCT__entry(__field_hex(char *, buf) __field(unsigned long, size)), + TP_fast_assign(tp_assign(buf, buf) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_umount +SC_TRACE_EVENT(sys_umount, + TP_PROTO(char * name, int flags), + TP_ARGS(name, flags), + TP_STRUCT__entry(__string_from_user(name, name) __field(int, flags)), + TP_fast_assign(tp_copy_string_from_user(name, name) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_pivot_root +SC_TRACE_EVENT(sys_pivot_root, + TP_PROTO(const char * new_root, const char * put_old), + TP_ARGS(new_root, put_old), + TP_STRUCT__entry(__string_from_user(new_root, new_root) __string_from_user(put_old, put_old)), + TP_fast_assign(tp_copy_string_from_user(new_root, new_root) tp_copy_string_from_user(put_old, put_old)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_statfs +SC_TRACE_EVENT(sys_statfs, + TP_PROTO(const char * pathname, struct statfs * buf), + TP_ARGS(pathname, buf), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __field_hex(struct statfs *, buf)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(buf, buf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fstatfs +SC_TRACE_EVENT(sys_fstatfs, + TP_PROTO(unsigned int fd, struct statfs * buf), + TP_ARGS(fd, buf), + TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct statfs *, buf)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(buf, buf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_truncate +SC_TRACE_EVENT(sys_truncate, + TP_PROTO(const char * path, long length), + TP_ARGS(path, length), + TP_STRUCT__entry(__string_from_user(path, path) __field(long, length)), + TP_fast_assign(tp_copy_string_from_user(path, path) tp_assign(length, length)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_pipe2 +SC_TRACE_EVENT(sys_pipe2, + TP_PROTO(int * fildes, int flags), + TP_ARGS(fildes, flags), + TP_STRUCT__entry(__field_hex(int *, fildes) __field(int, flags)), + TP_fast_assign(tp_assign(fildes, fildes) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_newfstat +SC_TRACE_EVENT(sys_newfstat, + TP_PROTO(unsigned int fd, struct stat * statbuf), + TP_ARGS(fd, statbuf), + TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct stat *, statbuf)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(statbuf, statbuf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_timerfd_gettime +SC_TRACE_EVENT(sys_timerfd_gettime, + TP_PROTO(int ufd, struct itimerspec * otmr), + TP_ARGS(ufd, otmr), + TP_STRUCT__entry(__field(int, ufd) __field_hex(struct itimerspec *, otmr)), + TP_fast_assign(tp_assign(ufd, ufd) tp_assign(otmr, otmr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_set_robust_list +SC_TRACE_EVENT(sys_set_robust_list, + TP_PROTO(struct robust_list_head * head, size_t len), + TP_ARGS(head, len), + TP_STRUCT__entry(__field_hex(struct robust_list_head *, head) __field(size_t, len)), + TP_fast_assign(tp_assign(head, head) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_nanosleep +SC_TRACE_EVENT(sys_nanosleep, + TP_PROTO(struct timespec * rqtp, struct timespec * rmtp), + TP_ARGS(rqtp, rmtp), + TP_STRUCT__entry(__field_hex(struct timespec *, rqtp) __field_hex(struct timespec *, rmtp)), + TP_fast_assign(tp_assign(rqtp, rqtp) tp_assign(rmtp, rmtp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getitimer +SC_TRACE_EVENT(sys_getitimer, + TP_PROTO(int which, struct itimerval * value), + TP_ARGS(which, value), + TP_STRUCT__entry(__field(int, which) __field_hex(struct itimerval *, value)), + TP_fast_assign(tp_assign(which, which) tp_assign(value, value)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_delete_module +SC_TRACE_EVENT(sys_delete_module, + TP_PROTO(const char * name_user, unsigned int flags), + TP_ARGS(name_user, flags), + TP_STRUCT__entry(__string_from_user(name_user, name_user) __field(unsigned int, flags)), + TP_fast_assign(tp_copy_string_from_user(name_user, name_user) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_timer_gettime +SC_TRACE_EVENT(sys_timer_gettime, + TP_PROTO(timer_t timer_id, struct itimerspec * setting), + TP_ARGS(timer_id, setting), + TP_STRUCT__entry(__field(timer_t, timer_id) __field_hex(struct itimerspec *, setting)), + TP_fast_assign(tp_assign(timer_id, timer_id) tp_assign(setting, setting)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_clock_settime +SC_TRACE_EVENT(sys_clock_settime, + TP_PROTO(const clockid_t which_clock, const struct timespec * tp), + TP_ARGS(which_clock, tp), + TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(const struct timespec *, tp)), + TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(tp, tp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_clock_gettime +SC_TRACE_EVENT(sys_clock_gettime, + TP_PROTO(const clockid_t which_clock, struct timespec * tp), + TP_ARGS(which_clock, tp), + TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct timespec *, tp)), + TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(tp, tp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_clock_getres +SC_TRACE_EVENT(sys_clock_getres, + TP_PROTO(const clockid_t which_clock, struct timespec * tp), + TP_ARGS(which_clock, tp), + TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct timespec *, tp)), + TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(tp, tp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sched_setparam +SC_TRACE_EVENT(sys_sched_setparam, + TP_PROTO(pid_t pid, struct sched_param * param), + TP_ARGS(pid, param), + TP_STRUCT__entry(__field(pid_t, pid) __field_hex(struct sched_param *, param)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(param, param)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sched_getparam +SC_TRACE_EVENT(sys_sched_getparam, + TP_PROTO(pid_t pid, struct sched_param * param), + TP_ARGS(pid, param), + TP_STRUCT__entry(__field(pid_t, pid) __field_hex(struct sched_param *, param)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(param, param)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sched_rr_get_interval +SC_TRACE_EVENT(sys_sched_rr_get_interval, + TP_PROTO(pid_t pid, struct timespec * interval), + TP_ARGS(pid, interval), + TP_STRUCT__entry(__field(pid_t, pid) __field_hex(struct timespec *, interval)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(interval, interval)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_rt_sigsuspend +SC_TRACE_EVENT(sys_rt_sigsuspend, + TP_PROTO(sigset_t * unewset, size_t sigsetsize), + TP_ARGS(unewset, sigsetsize), + TP_STRUCT__entry(__field_hex(sigset_t *, unewset) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(unewset, unewset) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_rt_sigpending +SC_TRACE_EVENT(sys_rt_sigpending, + TP_PROTO(sigset_t * set, size_t sigsetsize), + TP_ARGS(set, sigsetsize), + TP_STRUCT__entry(__field_hex(sigset_t *, set) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(set, set) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getgroups +SC_TRACE_EVENT(sys_getgroups, + TP_PROTO(int gidsetsize, gid_t * grouplist), + TP_ARGS(gidsetsize, grouplist), + TP_STRUCT__entry(__field(int, gidsetsize) __field_hex(gid_t *, grouplist)), + TP_fast_assign(tp_assign(gidsetsize, gidsetsize) tp_assign(grouplist, grouplist)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setgroups +SC_TRACE_EVENT(sys_setgroups, + TP_PROTO(int gidsetsize, gid_t * grouplist), + TP_ARGS(gidsetsize, grouplist), + TP_STRUCT__entry(__field(int, gidsetsize) __field_hex(gid_t *, grouplist)), + TP_fast_assign(tp_assign(gidsetsize, gidsetsize) tp_assign(grouplist, grouplist)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sethostname +SC_TRACE_EVENT(sys_sethostname, + TP_PROTO(char * name, int len), + TP_ARGS(name, len), + TP_STRUCT__entry(__string_from_user(name, name) __field(int, len)), + TP_fast_assign(tp_copy_string_from_user(name, name) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setdomainname +SC_TRACE_EVENT(sys_setdomainname, + TP_PROTO(char * name, int len), + TP_ARGS(name, len), + TP_STRUCT__entry(__string_from_user(name, name) __field(int, len)), + TP_fast_assign(tp_copy_string_from_user(name, name) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getrlimit +SC_TRACE_EVENT(sys_getrlimit, + TP_PROTO(unsigned int resource, struct rlimit * rlim), + TP_ARGS(resource, rlim), + TP_STRUCT__entry(__field(unsigned int, resource) __field_hex(struct rlimit *, rlim)), + TP_fast_assign(tp_assign(resource, resource) tp_assign(rlim, rlim)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setrlimit +SC_TRACE_EVENT(sys_setrlimit, + TP_PROTO(unsigned int resource, struct rlimit * rlim), + TP_ARGS(resource, rlim), + TP_STRUCT__entry(__field(unsigned int, resource) __field_hex(struct rlimit *, rlim)), + TP_fast_assign(tp_assign(resource, resource) tp_assign(rlim, rlim)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getrusage +SC_TRACE_EVENT(sys_getrusage, + TP_PROTO(int who, struct rusage * ru), + TP_ARGS(who, ru), + TP_STRUCT__entry(__field(int, who) __field_hex(struct rusage *, ru)), + TP_fast_assign(tp_assign(who, who) tp_assign(ru, ru)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_gettimeofday +SC_TRACE_EVENT(sys_gettimeofday, + TP_PROTO(struct timeval * tv, struct timezone * tz), + TP_ARGS(tv, tz), + TP_STRUCT__entry(__field_hex(struct timeval *, tv) __field_hex(struct timezone *, tz)), + TP_fast_assign(tp_assign(tv, tv) tp_assign(tz, tz)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_settimeofday +SC_TRACE_EVENT(sys_settimeofday, + TP_PROTO(struct timeval * tv, struct timezone * tz), + TP_ARGS(tv, tz), + TP_STRUCT__entry(__field_hex(struct timeval *, tv) __field_hex(struct timezone *, tz)), + TP_fast_assign(tp_assign(tv, tv) tp_assign(tz, tz)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mq_notify +SC_TRACE_EVENT(sys_mq_notify, + TP_PROTO(mqd_t mqdes, const struct sigevent * u_notification), + TP_ARGS(mqdes, u_notification), + TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(const struct sigevent *, u_notification)), + TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_notification, u_notification)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_swapon +SC_TRACE_EVENT(sys_swapon, + TP_PROTO(const char * specialfile, int swap_flags), + TP_ARGS(specialfile, swap_flags), + TP_STRUCT__entry(__string_from_user(specialfile, specialfile) __field(int, swap_flags)), + TP_fast_assign(tp_copy_string_from_user(specialfile, specialfile) tp_assign(swap_flags, swap_flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_clock_adjtime +SC_TRACE_EVENT(sys_clock_adjtime, + TP_PROTO(const clockid_t which_clock, struct timex * utx), + TP_ARGS(which_clock, utx), + TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct timex *, utx)), + TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(utx, utx)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_io_submit +SC_TRACE_EVENT(sys_io_submit, + TP_PROTO(aio_context_t ctx_id, long nr, struct iocb * * iocbpp), + TP_ARGS(ctx_id, nr, iocbpp), + TP_STRUCT__entry(__field(aio_context_t, ctx_id) __field(long, nr) __field_hex(struct iocb * *, iocbpp)), + TP_fast_assign(tp_assign(ctx_id, ctx_id) tp_assign(nr, nr) tp_assign(iocbpp, iocbpp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_io_cancel +SC_TRACE_EVENT(sys_io_cancel, + TP_PROTO(aio_context_t ctx_id, struct iocb * iocb, struct io_event * result), + TP_ARGS(ctx_id, iocb, result), + TP_STRUCT__entry(__field(aio_context_t, ctx_id) __field_hex(struct iocb *, iocb) __field_hex(struct io_event *, result)), + TP_fast_assign(tp_assign(ctx_id, ctx_id) tp_assign(iocb, iocb) tp_assign(result, result)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_listxattr +SC_TRACE_EVENT(sys_listxattr, + TP_PROTO(const char * pathname, char * list, size_t size), + TP_ARGS(pathname, list, size), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __field_hex(char *, list) __field(size_t, size)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(list, list) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_llistxattr +SC_TRACE_EVENT(sys_llistxattr, + TP_PROTO(const char * pathname, char * list, size_t size), + TP_ARGS(pathname, list, size), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __field_hex(char *, list) __field(size_t, size)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(list, list) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_flistxattr +SC_TRACE_EVENT(sys_flistxattr, + TP_PROTO(int fd, char * list, size_t size), + TP_ARGS(fd, list, size), + TP_STRUCT__entry(__field(int, fd) __field_hex(char *, list) __field(size_t, size)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(list, list) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_inotify_add_watch +SC_TRACE_EVENT(sys_inotify_add_watch, + TP_PROTO(int fd, const char * pathname, u32 mask), + TP_ARGS(fd, pathname, mask), + TP_STRUCT__entry(__field(int, fd) __string_from_user(pathname, pathname) __field(u32, mask)), + TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(pathname, pathname) tp_assign(mask, mask)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mkdirat +SC_TRACE_EVENT(sys_mkdirat, + TP_PROTO(int dfd, const char * pathname, int mode), + TP_ARGS(dfd, pathname, mode), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(pathname, pathname) __field(int, mode)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(pathname, pathname) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_unlinkat +SC_TRACE_EVENT(sys_unlinkat, + TP_PROTO(int dfd, const char * pathname, int flag), + TP_ARGS(dfd, pathname, flag), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(pathname, pathname) __field(int, flag)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(pathname, pathname) tp_assign(flag, flag)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_symlinkat +SC_TRACE_EVENT(sys_symlinkat, + TP_PROTO(const char * oldname, int newdfd, const char * newname), + TP_ARGS(oldname, newdfd, newname), + TP_STRUCT__entry(__string_from_user(oldname, oldname) __field(int, newdfd) __string_from_user(newname, newname)), + TP_fast_assign(tp_copy_string_from_user(oldname, oldname) tp_assign(newdfd, newdfd) tp_copy_string_from_user(newname, newname)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_nfsservctl +SC_TRACE_EVENT(sys_nfsservctl, + TP_PROTO(int cmd, struct nfsctl_arg * arg, void * res), + TP_ARGS(cmd, arg, res), + TP_STRUCT__entry(__field(int, cmd) __field_hex(struct nfsctl_arg *, arg) __field_hex(void *, res)), + TP_fast_assign(tp_assign(cmd, cmd) tp_assign(arg, arg) tp_assign(res, res)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_faccessat +SC_TRACE_EVENT(sys_faccessat, + TP_PROTO(int dfd, const char * filename, int mode), + TP_ARGS(dfd, filename, mode), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(int, mode)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fchmodat +SC_TRACE_EVENT(sys_fchmodat, + TP_PROTO(int dfd, const char * filename, mode_t mode), + TP_ARGS(dfd, filename, mode), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(mode_t, mode)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getdents64 +SC_TRACE_EVENT(sys_getdents64, + TP_PROTO(unsigned int fd, struct linux_dirent64 * dirent, unsigned int count), + TP_ARGS(fd, dirent, count), + TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct linux_dirent64 *, dirent) __field(unsigned int, count)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(dirent, dirent) tp_assign(count, count)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_read +SC_TRACE_EVENT(sys_read, + TP_PROTO(unsigned int fd, char * buf, size_t count), + TP_ARGS(fd, buf, count), + TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(char *, buf) __field(size_t, count)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(buf, buf) tp_assign(count, count)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_write +SC_TRACE_EVENT(sys_write, + TP_PROTO(unsigned int fd, const char * buf, size_t count), + TP_ARGS(fd, buf, count), + TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(const char *, buf) __field(size_t, count)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(buf, buf) tp_assign(count, count)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_readv +SC_TRACE_EVENT(sys_readv, + TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen), + TP_ARGS(fd, vec, vlen), + TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_writev +SC_TRACE_EVENT(sys_writev, + TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen), + TP_ARGS(fd, vec, vlen), + TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_get_robust_list +SC_TRACE_EVENT(sys_get_robust_list, + TP_PROTO(int pid, struct robust_list_head * * head_ptr, size_t * len_ptr), + TP_ARGS(pid, head_ptr, len_ptr), + TP_STRUCT__entry(__field(int, pid) __field_hex(struct robust_list_head * *, head_ptr) __field_hex(size_t *, len_ptr)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(head_ptr, head_ptr) tp_assign(len_ptr, len_ptr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setitimer +SC_TRACE_EVENT(sys_setitimer, + TP_PROTO(int which, struct itimerval * value, struct itimerval * ovalue), + TP_ARGS(which, value, ovalue), + TP_STRUCT__entry(__field(int, which) __field_hex(struct itimerval *, value) __field_hex(struct itimerval *, ovalue)), + TP_fast_assign(tp_assign(which, which) tp_assign(value, value) tp_assign(ovalue, ovalue)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_init_module +SC_TRACE_EVENT(sys_init_module, + TP_PROTO(void * umod, unsigned long len, const char * uargs), + TP_ARGS(umod, len, uargs), + TP_STRUCT__entry(__field_hex(void *, umod) __field(unsigned long, len) __field_hex(const char *, uargs)), + TP_fast_assign(tp_assign(umod, umod) tp_assign(len, len) tp_assign(uargs, uargs)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_timer_create +SC_TRACE_EVENT(sys_timer_create, + TP_PROTO(const clockid_t which_clock, struct sigevent * timer_event_spec, timer_t * created_timer_id), + TP_ARGS(which_clock, timer_event_spec, created_timer_id), + TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct sigevent *, timer_event_spec) __field_hex(timer_t *, created_timer_id)), + TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(timer_event_spec, timer_event_spec) tp_assign(created_timer_id, created_timer_id)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_syslog +SC_TRACE_EVENT(sys_syslog, + TP_PROTO(int type, char * buf, int len), + TP_ARGS(type, buf, len), + TP_STRUCT__entry(__field(int, type) __field_hex(char *, buf) __field(int, len)), + TP_fast_assign(tp_assign(type, type) tp_assign(buf, buf) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sched_setscheduler +SC_TRACE_EVENT(sys_sched_setscheduler, + TP_PROTO(pid_t pid, int policy, struct sched_param * param), + TP_ARGS(pid, policy, param), + TP_STRUCT__entry(__field(pid_t, pid) __field(int, policy) __field_hex(struct sched_param *, param)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(policy, policy) tp_assign(param, param)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sched_setaffinity +SC_TRACE_EVENT(sys_sched_setaffinity, + TP_PROTO(pid_t pid, unsigned int len, unsigned long * user_mask_ptr), + TP_ARGS(pid, len, user_mask_ptr), + TP_STRUCT__entry(__field(pid_t, pid) __field(unsigned int, len) __field_hex(unsigned long *, user_mask_ptr)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(len, len) tp_assign(user_mask_ptr, user_mask_ptr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sched_getaffinity +SC_TRACE_EVENT(sys_sched_getaffinity, + TP_PROTO(pid_t pid, unsigned int len, unsigned long * user_mask_ptr), + TP_ARGS(pid, len, user_mask_ptr), + TP_STRUCT__entry(__field(pid_t, pid) __field(unsigned int, len) __field_hex(unsigned long *, user_mask_ptr)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(len, len) tp_assign(user_mask_ptr, user_mask_ptr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_rt_sigqueueinfo +SC_TRACE_EVENT(sys_rt_sigqueueinfo, + TP_PROTO(pid_t pid, int sig, siginfo_t * uinfo), + TP_ARGS(pid, sig, uinfo), + TP_STRUCT__entry(__field(pid_t, pid) __field(int, sig) __field_hex(siginfo_t *, uinfo)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(sig, sig) tp_assign(uinfo, uinfo)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getresuid +SC_TRACE_EVENT(sys_getresuid, + TP_PROTO(uid_t * ruid, uid_t * euid, uid_t * suid), + TP_ARGS(ruid, euid, suid), + TP_STRUCT__entry(__field_hex(uid_t *, ruid) __field_hex(uid_t *, euid) __field_hex(uid_t *, suid)), + TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid) tp_assign(suid, suid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getresgid +SC_TRACE_EVENT(sys_getresgid, + TP_PROTO(gid_t * rgid, gid_t * egid, gid_t * sgid), + TP_ARGS(rgid, egid, sgid), + TP_STRUCT__entry(__field_hex(gid_t *, rgid) __field_hex(gid_t *, egid) __field_hex(gid_t *, sgid)), + TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid) tp_assign(sgid, sgid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getcpu +SC_TRACE_EVENT(sys_getcpu, + TP_PROTO(unsigned * cpup, unsigned * nodep, struct getcpu_cache * unused), + TP_ARGS(cpup, nodep, unused), + TP_STRUCT__entry(__field_hex(unsigned *, cpup) __field_hex(unsigned *, nodep) __field_hex(struct getcpu_cache *, unused)), + TP_fast_assign(tp_assign(cpup, cpup) tp_assign(nodep, nodep) tp_assign(unused, unused)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mq_getsetattr +SC_TRACE_EVENT(sys_mq_getsetattr, + TP_PROTO(mqd_t mqdes, const struct mq_attr * u_mqstat, struct mq_attr * u_omqstat), + TP_ARGS(mqdes, u_mqstat, u_omqstat), + TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(const struct mq_attr *, u_mqstat) __field_hex(struct mq_attr *, u_omqstat)), + TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_mqstat, u_mqstat) tp_assign(u_omqstat, u_omqstat)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_msgctl +SC_TRACE_EVENT(sys_msgctl, + TP_PROTO(int msqid, int cmd, struct msqid_ds * buf), + TP_ARGS(msqid, cmd, buf), + TP_STRUCT__entry(__field(int, msqid) __field(int, cmd) __field_hex(struct msqid_ds *, buf)), + TP_fast_assign(tp_assign(msqid, msqid) tp_assign(cmd, cmd) tp_assign(buf, buf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_semop +SC_TRACE_EVENT(sys_semop, + TP_PROTO(int semid, struct sembuf * tsops, unsigned nsops), + TP_ARGS(semid, tsops, nsops), + TP_STRUCT__entry(__field(int, semid) __field_hex(struct sembuf *, tsops) __field(unsigned, nsops)), + TP_fast_assign(tp_assign(semid, semid) tp_assign(tsops, tsops) tp_assign(nsops, nsops)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_shmctl +SC_TRACE_EVENT(sys_shmctl, + TP_PROTO(int shmid, int cmd, struct shmid_ds * buf), + TP_ARGS(shmid, cmd, buf), + TP_STRUCT__entry(__field(int, shmid) __field(int, cmd) __field_hex(struct shmid_ds *, buf)), + TP_fast_assign(tp_assign(shmid, shmid) tp_assign(cmd, cmd) tp_assign(buf, buf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_shmat +SC_TRACE_EVENT(sys_shmat, + TP_PROTO(int shmid, char * shmaddr, int shmflg), + TP_ARGS(shmid, shmaddr, shmflg), + TP_STRUCT__entry(__field(int, shmid) __field_hex(char *, shmaddr) __field(int, shmflg)), + TP_fast_assign(tp_assign(shmid, shmid) tp_assign(shmaddr, shmaddr) tp_assign(shmflg, shmflg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_bind +SC_TRACE_EVENT(sys_bind, + TP_PROTO(int fd, struct sockaddr * umyaddr, int addrlen), + TP_ARGS(fd, umyaddr, addrlen), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct sockaddr *, umyaddr) __field_hex(int, addrlen)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(umyaddr, umyaddr) tp_assign(addrlen, addrlen)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_accept +SC_TRACE_EVENT(sys_accept, + TP_PROTO(int fd, struct sockaddr * upeer_sockaddr, int * upeer_addrlen), + TP_ARGS(fd, upeer_sockaddr, upeer_addrlen), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct sockaddr *, upeer_sockaddr) __field_hex(int *, upeer_addrlen)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(upeer_sockaddr, upeer_sockaddr) tp_assign(upeer_addrlen, upeer_addrlen)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_connect +SC_TRACE_EVENT(sys_connect, + TP_PROTO(int fd, struct sockaddr * uservaddr, int addrlen), + TP_ARGS(fd, uservaddr, addrlen), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct sockaddr *, uservaddr) __field_hex(int, addrlen)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(uservaddr, uservaddr) tp_assign(addrlen, addrlen)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getsockname +SC_TRACE_EVENT(sys_getsockname, + TP_PROTO(int fd, struct sockaddr * usockaddr, int * usockaddr_len), + TP_ARGS(fd, usockaddr, usockaddr_len), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct sockaddr *, usockaddr) __field_hex(int *, usockaddr_len)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(usockaddr, usockaddr) tp_assign(usockaddr_len, usockaddr_len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getpeername +SC_TRACE_EVENT(sys_getpeername, + TP_PROTO(int fd, struct sockaddr * usockaddr, int * usockaddr_len), + TP_ARGS(fd, usockaddr, usockaddr_len), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct sockaddr *, usockaddr) __field_hex(int *, usockaddr_len)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(usockaddr, usockaddr) tp_assign(usockaddr_len, usockaddr_len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sendmsg +SC_TRACE_EVENT(sys_sendmsg, + TP_PROTO(int fd, struct msghdr * msg, unsigned flags), + TP_ARGS(fd, msg, flags), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct msghdr *, msg) __field(unsigned, flags)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(msg, msg) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_recvmsg +SC_TRACE_EVENT(sys_recvmsg, + TP_PROTO(int fd, struct msghdr * msg, unsigned int flags), + TP_ARGS(fd, msg, flags), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct msghdr *, msg) __field(unsigned int, flags)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(msg, msg) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mincore +SC_TRACE_EVENT(sys_mincore, + TP_PROTO(unsigned long start, size_t len, unsigned char * vec), + TP_ARGS(start, len, vec), + TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len) __field_hex(unsigned char *, vec)), + TP_fast_assign(tp_assign(start, start) tp_assign(len, len) tp_assign(vec, vec)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_set_mempolicy +SC_TRACE_EVENT(sys_set_mempolicy, + TP_PROTO(int mode, unsigned long * nmask, unsigned long maxnode), + TP_ARGS(mode, nmask, maxnode), + TP_STRUCT__entry(__field(int, mode) __field_hex(unsigned long *, nmask) __field(unsigned long, maxnode)), + TP_fast_assign(tp_assign(mode, mode) tp_assign(nmask, nmask) tp_assign(maxnode, maxnode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_open_by_handle_at +SC_TRACE_EVENT(sys_open_by_handle_at, + TP_PROTO(int mountdirfd, struct file_handle * handle, int flags), + TP_ARGS(mountdirfd, handle, flags), + TP_STRUCT__entry(__field(int, mountdirfd) __field_hex(struct file_handle *, handle) __field(int, flags)), + TP_fast_assign(tp_assign(mountdirfd, mountdirfd) tp_assign(handle, handle) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getxattr +SC_TRACE_EVENT(sys_getxattr, + TP_PROTO(const char * pathname, const char * name, void * value, size_t size), + TP_ARGS(pathname, name, value, size), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(void *, value) __field(size_t, size)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_lgetxattr +SC_TRACE_EVENT(sys_lgetxattr, + TP_PROTO(const char * pathname, const char * name, void * value, size_t size), + TP_ARGS(pathname, name, value, size), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(void *, value) __field(size_t, size)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fgetxattr +SC_TRACE_EVENT(sys_fgetxattr, + TP_PROTO(int fd, const char * name, void * value, size_t size), + TP_ARGS(fd, name, value, size), + TP_STRUCT__entry(__field(int, fd) __string_from_user(name, name) __field_hex(void *, value) __field(size_t, size)), + TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_epoll_ctl +SC_TRACE_EVENT(sys_epoll_ctl, + TP_PROTO(int epfd, int op, int fd, struct epoll_event * event), + TP_ARGS(epfd, op, fd, event), + TP_STRUCT__entry(__field(int, epfd) __field(int, op) __field(int, fd) __field_hex(struct epoll_event *, event)), + TP_fast_assign(tp_assign(epfd, epfd) tp_assign(op, op) tp_assign(fd, fd) tp_assign(event, event)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mknodat +SC_TRACE_EVENT(sys_mknodat, + TP_PROTO(int dfd, const char * filename, int mode, unsigned dev), + TP_ARGS(dfd, filename, mode, dev), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(int, mode) __field(unsigned, dev)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(mode, mode) tp_assign(dev, dev)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_renameat +SC_TRACE_EVENT(sys_renameat, + TP_PROTO(int olddfd, const char * oldname, int newdfd, const char * newname), + TP_ARGS(olddfd, oldname, newdfd, newname), + TP_STRUCT__entry(__field(int, olddfd) __string_from_user(oldname, oldname) __field(int, newdfd) __string_from_user(newname, newname)), + TP_fast_assign(tp_assign(olddfd, olddfd) tp_copy_string_from_user(oldname, oldname) tp_assign(newdfd, newdfd) tp_copy_string_from_user(newname, newname)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_openat +SC_TRACE_EVENT(sys_openat, + TP_PROTO(int dfd, const char * filename, int flags, int mode), + TP_ARGS(dfd, filename, flags, mode), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(int, flags) __field(int, mode)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(flags, flags) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_quotactl +SC_TRACE_EVENT(sys_quotactl, + TP_PROTO(unsigned int cmd, const char * special, qid_t id, void * addr), + TP_ARGS(cmd, special, id, addr), + TP_STRUCT__entry(__field(unsigned int, cmd) __field_hex(const char *, special) __field(qid_t, id) __field_hex(void *, addr)), + TP_fast_assign(tp_assign(cmd, cmd) tp_assign(special, special) tp_assign(id, id) tp_assign(addr, addr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sendfile64 +SC_TRACE_EVENT(sys_sendfile64, + TP_PROTO(int out_fd, int in_fd, loff_t * offset, size_t count), + TP_ARGS(out_fd, in_fd, offset, count), + TP_STRUCT__entry(__field(int, out_fd) __field(int, in_fd) __field_hex(loff_t *, offset) __field(size_t, count)), + TP_fast_assign(tp_assign(out_fd, out_fd) tp_assign(in_fd, in_fd) tp_assign(offset, offset) tp_assign(count, count)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_signalfd4 +SC_TRACE_EVENT(sys_signalfd4, + TP_PROTO(int ufd, sigset_t * user_mask, size_t sizemask, int flags), + TP_ARGS(ufd, user_mask, sizemask, flags), + TP_STRUCT__entry(__field(int, ufd) __field_hex(sigset_t *, user_mask) __field(size_t, sizemask) __field(int, flags)), + TP_fast_assign(tp_assign(ufd, ufd) tp_assign(user_mask, user_mask) tp_assign(sizemask, sizemask) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_vmsplice +SC_TRACE_EVENT(sys_vmsplice, + TP_PROTO(int fd, const struct iovec * iov, unsigned long nr_segs, unsigned int flags), + TP_ARGS(fd, iov, nr_segs, flags), + TP_STRUCT__entry(__field(int, fd) __field_hex(const struct iovec *, iov) __field(unsigned long, nr_segs) __field(unsigned int, flags)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(iov, iov) tp_assign(nr_segs, nr_segs) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_readlinkat +SC_TRACE_EVENT(sys_readlinkat, + TP_PROTO(int dfd, const char * pathname, char * buf, int bufsiz), + TP_ARGS(dfd, pathname, buf, bufsiz), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(pathname, pathname) __field_hex(char *, buf) __field(int, bufsiz)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(pathname, pathname) tp_assign(buf, buf) tp_assign(bufsiz, bufsiz)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_newfstatat +SC_TRACE_EVENT(sys_newfstatat, + TP_PROTO(int dfd, const char * filename, struct stat * statbuf, int flag), + TP_ARGS(dfd, filename, statbuf, flag), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field_hex(struct stat *, statbuf) __field(int, flag)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf) tp_assign(flag, flag)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_timerfd_settime +SC_TRACE_EVENT(sys_timerfd_settime, + TP_PROTO(int ufd, int flags, const struct itimerspec * utmr, struct itimerspec * otmr), + TP_ARGS(ufd, flags, utmr, otmr), + TP_STRUCT__entry(__field(int, ufd) __field(int, flags) __field_hex(const struct itimerspec *, utmr) __field_hex(struct itimerspec *, otmr)), + TP_fast_assign(tp_assign(ufd, ufd) tp_assign(flags, flags) tp_assign(utmr, utmr) tp_assign(otmr, otmr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_utimensat +SC_TRACE_EVENT(sys_utimensat, + TP_PROTO(int dfd, const char * filename, struct timespec * utimes, int flags), + TP_ARGS(dfd, filename, utimes, flags), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field_hex(struct timespec *, utimes) __field(int, flags)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(utimes, utimes) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_timer_settime +SC_TRACE_EVENT(sys_timer_settime, + TP_PROTO(timer_t timer_id, int flags, const struct itimerspec * new_setting, struct itimerspec * old_setting), + TP_ARGS(timer_id, flags, new_setting, old_setting), + TP_STRUCT__entry(__field(timer_t, timer_id) __field(int, flags) __field_hex(const struct itimerspec *, new_setting) __field_hex(struct itimerspec *, old_setting)), + TP_fast_assign(tp_assign(timer_id, timer_id) tp_assign(flags, flags) tp_assign(new_setting, new_setting) tp_assign(old_setting, old_setting)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_clock_nanosleep +SC_TRACE_EVENT(sys_clock_nanosleep, + TP_PROTO(const clockid_t which_clock, int flags, const struct timespec * rqtp, struct timespec * rmtp), + TP_ARGS(which_clock, flags, rqtp, rmtp), + TP_STRUCT__entry(__field(const clockid_t, which_clock) __field(int, flags) __field_hex(const struct timespec *, rqtp) __field_hex(struct timespec *, rmtp)), + TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(flags, flags) tp_assign(rqtp, rqtp) tp_assign(rmtp, rmtp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_rt_sigaction +SC_TRACE_EVENT(sys_rt_sigaction, + TP_PROTO(int sig, const struct sigaction * act, struct sigaction * oact, size_t sigsetsize), + TP_ARGS(sig, act, oact, sigsetsize), + TP_STRUCT__entry(__field(int, sig) __field_hex(const struct sigaction *, act) __field_hex(struct sigaction *, oact) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(sig, sig) tp_assign(act, act) tp_assign(oact, oact) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_rt_sigprocmask +SC_TRACE_EVENT(sys_rt_sigprocmask, + TP_PROTO(int how, sigset_t * nset, sigset_t * oset, size_t sigsetsize), + TP_ARGS(how, nset, oset, sigsetsize), + TP_STRUCT__entry(__field(int, how) __field_hex(sigset_t *, nset) __field_hex(sigset_t *, oset) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(how, how) tp_assign(nset, nset) tp_assign(oset, oset) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_rt_sigtimedwait +SC_TRACE_EVENT(sys_rt_sigtimedwait, + TP_PROTO(const sigset_t * uthese, siginfo_t * uinfo, const struct timespec * uts, size_t sigsetsize), + TP_ARGS(uthese, uinfo, uts, sigsetsize), + TP_STRUCT__entry(__field_hex(const sigset_t *, uthese) __field_hex(siginfo_t *, uinfo) __field_hex(const struct timespec *, uts) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(uthese, uthese) tp_assign(uinfo, uinfo) tp_assign(uts, uts) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_reboot +SC_TRACE_EVENT(sys_reboot, + TP_PROTO(int magic1, int magic2, unsigned int cmd, void * arg), + TP_ARGS(magic1, magic2, cmd, arg), + TP_STRUCT__entry(__field(int, magic1) __field(int, magic2) __field(unsigned int, cmd) __field_hex(void *, arg)), + TP_fast_assign(tp_assign(magic1, magic1) tp_assign(magic2, magic2) tp_assign(cmd, cmd) tp_assign(arg, arg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mq_open +SC_TRACE_EVENT(sys_mq_open, + TP_PROTO(const char * u_name, int oflag, mode_t mode, struct mq_attr * u_attr), + TP_ARGS(u_name, oflag, mode, u_attr), + TP_STRUCT__entry(__string_from_user(u_name, u_name) __field(int, oflag) __field(mode_t, mode) __field_hex(struct mq_attr *, u_attr)), + TP_fast_assign(tp_copy_string_from_user(u_name, u_name) tp_assign(oflag, oflag) tp_assign(mode, mode) tp_assign(u_attr, u_attr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_msgsnd +SC_TRACE_EVENT(sys_msgsnd, + TP_PROTO(int msqid, struct msgbuf * msgp, size_t msgsz, int msgflg), + TP_ARGS(msqid, msgp, msgsz, msgflg), + TP_STRUCT__entry(__field(int, msqid) __field_hex(struct msgbuf *, msgp) __field(size_t, msgsz) __field(int, msgflg)), + TP_fast_assign(tp_assign(msqid, msqid) tp_assign(msgp, msgp) tp_assign(msgsz, msgsz) tp_assign(msgflg, msgflg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_semtimedop +SC_TRACE_EVENT(sys_semtimedop, + TP_PROTO(int semid, struct sembuf * tsops, unsigned nsops, const struct timespec * timeout), + TP_ARGS(semid, tsops, nsops, timeout), + TP_STRUCT__entry(__field(int, semid) __field_hex(struct sembuf *, tsops) __field(unsigned, nsops) __field_hex(const struct timespec *, timeout)), + TP_fast_assign(tp_assign(semid, semid) tp_assign(tsops, tsops) tp_assign(nsops, nsops) tp_assign(timeout, timeout)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_socketpair +SC_TRACE_EVENT(sys_socketpair, + TP_PROTO(int family, int type, int protocol, int * usockvec), + TP_ARGS(family, type, protocol, usockvec), + TP_STRUCT__entry(__field(int, family) __field(int, type) __field(int, protocol) __field_hex(int *, usockvec)), + TP_fast_assign(tp_assign(family, family) tp_assign(type, type) tp_assign(protocol, protocol) tp_assign(usockvec, usockvec)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_request_key +SC_TRACE_EVENT(sys_request_key, + TP_PROTO(const char * _type, const char * _description, const char * _callout_info, key_serial_t destringid), + TP_ARGS(_type, _description, _callout_info, destringid), + TP_STRUCT__entry(__string_from_user(_type, _type) __field_hex(const char *, _description) __field_hex(const char *, _callout_info) __field(key_serial_t, destringid)), + TP_fast_assign(tp_copy_string_from_user(_type, _type) tp_assign(_description, _description) tp_assign(_callout_info, _callout_info) tp_assign(destringid, destringid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_migrate_pages +SC_TRACE_EVENT(sys_migrate_pages, + TP_PROTO(pid_t pid, unsigned long maxnode, const unsigned long * old_nodes, const unsigned long * new_nodes), + TP_ARGS(pid, maxnode, old_nodes, new_nodes), + TP_STRUCT__entry(__field(pid_t, pid) __field(unsigned long, maxnode) __field_hex(const unsigned long *, old_nodes) __field_hex(const unsigned long *, new_nodes)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(maxnode, maxnode) tp_assign(old_nodes, old_nodes) tp_assign(new_nodes, new_nodes)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_rt_tgsigqueueinfo +SC_TRACE_EVENT(sys_rt_tgsigqueueinfo, + TP_PROTO(pid_t tgid, pid_t pid, int sig, siginfo_t * uinfo), + TP_ARGS(tgid, pid, sig, uinfo), + TP_STRUCT__entry(__field(pid_t, tgid) __field(pid_t, pid) __field(int, sig) __field_hex(siginfo_t *, uinfo)), + TP_fast_assign(tp_assign(tgid, tgid) tp_assign(pid, pid) tp_assign(sig, sig) tp_assign(uinfo, uinfo)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_accept4 +SC_TRACE_EVENT(sys_accept4, + TP_PROTO(int fd, struct sockaddr * upeer_sockaddr, int * upeer_addrlen, int flags), + TP_ARGS(fd, upeer_sockaddr, upeer_addrlen, flags), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct sockaddr *, upeer_sockaddr) __field_hex(int *, upeer_addrlen) __field(int, flags)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(upeer_sockaddr, upeer_sockaddr) tp_assign(upeer_addrlen, upeer_addrlen) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_wait4 +SC_TRACE_EVENT(sys_wait4, + TP_PROTO(pid_t upid, int * stat_addr, int options, struct rusage * ru), + TP_ARGS(upid, stat_addr, options, ru), + TP_STRUCT__entry(__field(pid_t, upid) __field_hex(int *, stat_addr) __field(int, options) __field_hex(struct rusage *, ru)), + TP_fast_assign(tp_assign(upid, upid) tp_assign(stat_addr, stat_addr) tp_assign(options, options) tp_assign(ru, ru)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_prlimit64 +SC_TRACE_EVENT(sys_prlimit64, + TP_PROTO(pid_t pid, unsigned int resource, const struct rlimit64 * new_rlim, struct rlimit64 * old_rlim), + TP_ARGS(pid, resource, new_rlim, old_rlim), + TP_STRUCT__entry(__field(pid_t, pid) __field(unsigned int, resource) __field_hex(const struct rlimit64 *, new_rlim) __field_hex(struct rlimit64 *, old_rlim)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(resource, resource) tp_assign(new_rlim, new_rlim) tp_assign(old_rlim, old_rlim)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sendmmsg +SC_TRACE_EVENT(sys_sendmmsg, + TP_PROTO(int fd, struct mmsghdr * mmsg, unsigned int vlen, unsigned int flags), + TP_ARGS(fd, mmsg, vlen, flags), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct mmsghdr *, mmsg) __field(unsigned int, vlen) __field(unsigned int, flags)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(mmsg, mmsg) tp_assign(vlen, vlen) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_io_getevents +SC_TRACE_EVENT(sys_io_getevents, + TP_PROTO(aio_context_t ctx_id, long min_nr, long nr, struct io_event * events, struct timespec * timeout), + TP_ARGS(ctx_id, min_nr, nr, events, timeout), + TP_STRUCT__entry(__field(aio_context_t, ctx_id) __field(long, min_nr) __field(long, nr) __field_hex(struct io_event *, events) __field_hex(struct timespec *, timeout)), + TP_fast_assign(tp_assign(ctx_id, ctx_id) tp_assign(min_nr, min_nr) tp_assign(nr, nr) tp_assign(events, events) tp_assign(timeout, timeout)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setxattr +SC_TRACE_EVENT(sys_setxattr, + TP_PROTO(const char * pathname, const char * name, const void * value, size_t size, int flags), + TP_ARGS(pathname, name, value, size, flags), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(const void *, value) __field(size_t, size) __field(int, flags)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_lsetxattr +SC_TRACE_EVENT(sys_lsetxattr, + TP_PROTO(const char * pathname, const char * name, const void * value, size_t size, int flags), + TP_ARGS(pathname, name, value, size, flags), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(const void *, value) __field(size_t, size) __field(int, flags)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fsetxattr +SC_TRACE_EVENT(sys_fsetxattr, + TP_PROTO(int fd, const char * name, const void * value, size_t size, int flags), + TP_ARGS(fd, name, value, size, flags), + TP_STRUCT__entry(__field(int, fd) __string_from_user(name, name) __field_hex(const void *, value) __field(size_t, size) __field(int, flags)), + TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_linkat +SC_TRACE_EVENT(sys_linkat, + TP_PROTO(int olddfd, const char * oldname, int newdfd, const char * newname, int flags), + TP_ARGS(olddfd, oldname, newdfd, newname, flags), + TP_STRUCT__entry(__field(int, olddfd) __string_from_user(oldname, oldname) __field(int, newdfd) __string_from_user(newname, newname) __field(int, flags)), + TP_fast_assign(tp_assign(olddfd, olddfd) tp_copy_string_from_user(oldname, oldname) tp_assign(newdfd, newdfd) tp_copy_string_from_user(newname, newname) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mount +SC_TRACE_EVENT(sys_mount, + TP_PROTO(char * dev_name, char * dir_name, char * type, unsigned long flags, void * data), + TP_ARGS(dev_name, dir_name, type, flags, data), + TP_STRUCT__entry(__string_from_user(dev_name, dev_name) __string_from_user(dir_name, dir_name) __string_from_user(type, type) __field(unsigned long, flags) __field_hex(void *, data)), + TP_fast_assign(tp_copy_string_from_user(dev_name, dev_name) tp_copy_string_from_user(dir_name, dir_name) tp_copy_string_from_user(type, type) tp_assign(flags, flags) tp_assign(data, data)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fchownat +SC_TRACE_EVENT(sys_fchownat, + TP_PROTO(int dfd, const char * filename, uid_t user, gid_t group, int flag), + TP_ARGS(dfd, filename, user, group, flag), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(uid_t, user) __field(gid_t, group) __field(int, flag)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(user, user) tp_assign(group, group) tp_assign(flag, flag)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_preadv +SC_TRACE_EVENT(sys_preadv, + TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen, unsigned long pos_l, unsigned long pos_h), + TP_ARGS(fd, vec, vlen, pos_l, pos_h), + TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen) __field(unsigned long, pos_l) __field(unsigned long, pos_h)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen) tp_assign(pos_l, pos_l) tp_assign(pos_h, pos_h)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_pwritev +SC_TRACE_EVENT(sys_pwritev, + TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen, unsigned long pos_l, unsigned long pos_h), + TP_ARGS(fd, vec, vlen, pos_l, pos_h), + TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen) __field(unsigned long, pos_l) __field(unsigned long, pos_h)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen) tp_assign(pos_l, pos_l) tp_assign(pos_h, pos_h)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_ppoll +SC_TRACE_EVENT(sys_ppoll, + TP_PROTO(struct pollfd * ufds, unsigned int nfds, struct timespec * tsp, const sigset_t * sigmask, size_t sigsetsize), + TP_ARGS(ufds, nfds, tsp, sigmask, sigsetsize), + TP_STRUCT__entry(__field_hex(struct pollfd *, ufds) __field(unsigned int, nfds) __field_hex(struct timespec *, tsp) __field_hex(const sigset_t *, sigmask) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(ufds, ufds) tp_assign(nfds, nfds) tp_assign(tsp, tsp) tp_assign(sigmask, sigmask) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_waitid +SC_TRACE_EVENT(sys_waitid, + TP_PROTO(int which, pid_t upid, struct siginfo * infop, int options, struct rusage * ru), + TP_ARGS(which, upid, infop, options, ru), + TP_STRUCT__entry(__field(int, which) __field(pid_t, upid) __field_hex(struct siginfo *, infop) __field(int, options) __field_hex(struct rusage *, ru)), + TP_fast_assign(tp_assign(which, which) tp_assign(upid, upid) tp_assign(infop, infop) tp_assign(options, options) tp_assign(ru, ru)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mq_timedsend +SC_TRACE_EVENT(sys_mq_timedsend, + TP_PROTO(mqd_t mqdes, const char * u_msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec * u_abs_timeout), + TP_ARGS(mqdes, u_msg_ptr, msg_len, msg_prio, u_abs_timeout), + TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(const char *, u_msg_ptr) __field(size_t, msg_len) __field(unsigned int, msg_prio) __field_hex(const struct timespec *, u_abs_timeout)), + TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_msg_ptr, u_msg_ptr) tp_assign(msg_len, msg_len) tp_assign(msg_prio, msg_prio) tp_assign(u_abs_timeout, u_abs_timeout)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mq_timedreceive +SC_TRACE_EVENT(sys_mq_timedreceive, + TP_PROTO(mqd_t mqdes, char * u_msg_ptr, size_t msg_len, unsigned int * u_msg_prio, const struct timespec * u_abs_timeout), + TP_ARGS(mqdes, u_msg_ptr, msg_len, u_msg_prio, u_abs_timeout), + TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(char *, u_msg_ptr) __field(size_t, msg_len) __field_hex(unsigned int *, u_msg_prio) __field_hex(const struct timespec *, u_abs_timeout)), + TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_msg_ptr, u_msg_ptr) tp_assign(msg_len, msg_len) tp_assign(u_msg_prio, u_msg_prio) tp_assign(u_abs_timeout, u_abs_timeout)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_msgrcv +SC_TRACE_EVENT(sys_msgrcv, + TP_PROTO(int msqid, struct msgbuf * msgp, size_t msgsz, long msgtyp, int msgflg), + TP_ARGS(msqid, msgp, msgsz, msgtyp, msgflg), + TP_STRUCT__entry(__field(int, msqid) __field_hex(struct msgbuf *, msgp) __field(size_t, msgsz) __field(long, msgtyp) __field(int, msgflg)), + TP_fast_assign(tp_assign(msqid, msqid) tp_assign(msgp, msgp) tp_assign(msgsz, msgsz) tp_assign(msgtyp, msgtyp) tp_assign(msgflg, msgflg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setsockopt +SC_TRACE_EVENT(sys_setsockopt, + TP_PROTO(int fd, int level, int optname, char * optval, int optlen), + TP_ARGS(fd, level, optname, optval, optlen), + TP_STRUCT__entry(__field(int, fd) __field(int, level) __field(int, optname) __field_hex(char *, optval) __field(int, optlen)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(level, level) tp_assign(optname, optname) tp_assign(optval, optval) tp_assign(optlen, optlen)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getsockopt +SC_TRACE_EVENT(sys_getsockopt, + TP_PROTO(int fd, int level, int optname, char * optval, int * optlen), + TP_ARGS(fd, level, optname, optval, optlen), + TP_STRUCT__entry(__field(int, fd) __field(int, level) __field(int, optname) __field_hex(char *, optval) __field_hex(int *, optlen)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(level, level) tp_assign(optname, optname) tp_assign(optval, optval) tp_assign(optlen, optlen)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_add_key +SC_TRACE_EVENT(sys_add_key, + TP_PROTO(const char * _type, const char * _description, const void * _payload, size_t plen, key_serial_t ringid), + TP_ARGS(_type, _description, _payload, plen, ringid), + TP_STRUCT__entry(__string_from_user(_type, _type) __field_hex(const char *, _description) __field_hex(const void *, _payload) __field(size_t, plen) __field(key_serial_t, ringid)), + TP_fast_assign(tp_copy_string_from_user(_type, _type) tp_assign(_description, _description) tp_assign(_payload, _payload) tp_assign(plen, plen) tp_assign(ringid, ringid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_get_mempolicy +SC_TRACE_EVENT(sys_get_mempolicy, + TP_PROTO(int * policy, unsigned long * nmask, unsigned long maxnode, unsigned long addr, unsigned long flags), + TP_ARGS(policy, nmask, maxnode, addr, flags), + TP_STRUCT__entry(__field_hex(int *, policy) __field_hex(unsigned long *, nmask) __field(unsigned long, maxnode) __field_hex(unsigned long, addr) __field(unsigned long, flags)), + TP_fast_assign(tp_assign(policy, policy) tp_assign(nmask, nmask) tp_assign(maxnode, maxnode) tp_assign(addr, addr) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_perf_event_open +SC_TRACE_EVENT(sys_perf_event_open, + TP_PROTO(struct perf_event_attr * attr_uptr, pid_t pid, int cpu, int group_fd, unsigned long flags), + TP_ARGS(attr_uptr, pid, cpu, group_fd, flags), + TP_STRUCT__entry(__field_hex(struct perf_event_attr *, attr_uptr) __field(pid_t, pid) __field(int, cpu) __field(int, group_fd) __field(unsigned long, flags)), + TP_fast_assign(tp_assign(attr_uptr, attr_uptr) tp_assign(pid, pid) tp_assign(cpu, cpu) tp_assign(group_fd, group_fd) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_recvmmsg +SC_TRACE_EVENT(sys_recvmmsg, + TP_PROTO(int fd, struct mmsghdr * mmsg, unsigned int vlen, unsigned int flags, struct timespec * timeout), + TP_ARGS(fd, mmsg, vlen, flags, timeout), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct mmsghdr *, mmsg) __field(unsigned int, vlen) __field(unsigned int, flags) __field_hex(struct timespec *, timeout)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(mmsg, mmsg) tp_assign(vlen, vlen) tp_assign(flags, flags) tp_assign(timeout, timeout)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_name_to_handle_at +SC_TRACE_EVENT(sys_name_to_handle_at, + TP_PROTO(int dfd, const char * name, struct file_handle * handle, int * mnt_id, int flag), + TP_ARGS(dfd, name, handle, mnt_id, flag), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(name, name) __field_hex(struct file_handle *, handle) __field_hex(int *, mnt_id) __field(int, flag)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(name, name) tp_assign(handle, handle) tp_assign(mnt_id, mnt_id) tp_assign(flag, flag)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_epoll_pwait +SC_TRACE_EVENT(sys_epoll_pwait, + TP_PROTO(int epfd, struct epoll_event * events, int maxevents, int timeout, const sigset_t * sigmask, size_t sigsetsize), + TP_ARGS(epfd, events, maxevents, timeout, sigmask, sigsetsize), + TP_STRUCT__entry(__field(int, epfd) __field_hex(struct epoll_event *, events) __field(int, maxevents) __field(int, timeout) __field_hex(const sigset_t *, sigmask) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(epfd, epfd) tp_assign(events, events) tp_assign(maxevents, maxevents) tp_assign(timeout, timeout) tp_assign(sigmask, sigmask) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_pselect6 +SC_TRACE_EVENT(sys_pselect6, + TP_PROTO(int n, fd_set * inp, fd_set * outp, fd_set * exp, struct timespec * tsp, void * sig), + TP_ARGS(n, inp, outp, exp, tsp, sig), + TP_STRUCT__entry(__field(int, n) __field_hex(fd_set *, inp) __field_hex(fd_set *, outp) __field_hex(fd_set *, exp) __field_hex(struct timespec *, tsp) __field_hex(void *, sig)), + TP_fast_assign(tp_assign(n, n) tp_assign(inp, inp) tp_assign(outp, outp) tp_assign(exp, exp) tp_assign(tsp, tsp) tp_assign(sig, sig)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_splice +SC_TRACE_EVENT(sys_splice, + TP_PROTO(int fd_in, loff_t * off_in, int fd_out, loff_t * off_out, size_t len, unsigned int flags), + TP_ARGS(fd_in, off_in, fd_out, off_out, len, flags), + TP_STRUCT__entry(__field(int, fd_in) __field_hex(loff_t *, off_in) __field(int, fd_out) __field_hex(loff_t *, off_out) __field(size_t, len) __field(unsigned int, flags)), + TP_fast_assign(tp_assign(fd_in, fd_in) tp_assign(off_in, off_in) tp_assign(fd_out, fd_out) tp_assign(off_out, off_out) tp_assign(len, len) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_futex +SC_TRACE_EVENT(sys_futex, + TP_PROTO(u32 * uaddr, int op, u32 val, struct timespec * utime, u32 * uaddr2, u32 val3), + TP_ARGS(uaddr, op, val, utime, uaddr2, val3), + TP_STRUCT__entry(__field_hex(u32 *, uaddr) __field(int, op) __field(u32, val) __field_hex(struct timespec *, utime) __field_hex(u32 *, uaddr2) __field(u32, val3)), + TP_fast_assign(tp_assign(uaddr, uaddr) tp_assign(op, op) tp_assign(val, val) tp_assign(utime, utime) tp_assign(uaddr2, uaddr2) tp_assign(val3, val3)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sendto +SC_TRACE_EVENT(sys_sendto, + TP_PROTO(int fd, void * buff, size_t len, unsigned flags, struct sockaddr * addr, int addr_len), + TP_ARGS(fd, buff, len, flags, addr, addr_len), + TP_STRUCT__entry(__field(int, fd) __field_hex(void *, buff) __field(size_t, len) __field(unsigned, flags) __field_hex(struct sockaddr *, addr) __field_hex(int, addr_len)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(buff, buff) tp_assign(len, len) tp_assign(flags, flags) tp_assign(addr, addr) tp_assign(addr_len, addr_len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_recvfrom +SC_TRACE_EVENT(sys_recvfrom, + TP_PROTO(int fd, void * ubuf, size_t size, unsigned flags, struct sockaddr * addr, int * addr_len), + TP_ARGS(fd, ubuf, size, flags, addr, addr_len), + TP_STRUCT__entry(__field(int, fd) __field_hex(void *, ubuf) __field(size_t, size) __field(unsigned, flags) __field_hex(struct sockaddr *, addr) __field_hex(int *, addr_len)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(ubuf, ubuf) tp_assign(size, size) tp_assign(flags, flags) tp_assign(addr, addr) tp_assign(addr_len, addr_len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mbind +SC_TRACE_EVENT(sys_mbind, + TP_PROTO(unsigned long start, unsigned long len, unsigned long mode, unsigned long * nmask, unsigned long maxnode, unsigned flags), + TP_ARGS(start, len, mode, nmask, maxnode, flags), + TP_STRUCT__entry(__field(unsigned long, start) __field(unsigned long, len) __field(unsigned long, mode) __field_hex(unsigned long *, nmask) __field(unsigned long, maxnode) __field(unsigned, flags)), + TP_fast_assign(tp_assign(start, start) tp_assign(len, len) tp_assign(mode, mode) tp_assign(nmask, nmask) tp_assign(maxnode, maxnode) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_move_pages +SC_TRACE_EVENT(sys_move_pages, + TP_PROTO(pid_t pid, unsigned long nr_pages, const void * * pages, const int * nodes, int * status, int flags), + TP_ARGS(pid, nr_pages, pages, nodes, status, flags), + TP_STRUCT__entry(__field(pid_t, pid) __field(unsigned long, nr_pages) __field_hex(const void * *, pages) __field_hex(const int *, nodes) __field_hex(int *, status) __field(int, flags)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(nr_pages, nr_pages) tp_assign(pages, pages) tp_assign(nodes, nodes) tp_assign(status, status) tp_assign(flags, flags)), + TP_printk() +) +#endif + +#endif /* _TRACE_SYSCALLS_POINTERS_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" + +#else /* CREATE_SYSCALL_TABLE */ + +#include "tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_pointers_override.h" +#include "syscalls_pointers_override.h" + +#ifndef OVERRIDE_TABLE_64_sys_io_setup +TRACE_SYSCALL_TABLE(sys_io_setup, sys_io_setup, 0, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_io_submit +TRACE_SYSCALL_TABLE(sys_io_submit, sys_io_submit, 2, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_io_cancel +TRACE_SYSCALL_TABLE(sys_io_cancel, sys_io_cancel, 3, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_io_getevents +TRACE_SYSCALL_TABLE(sys_io_getevents, sys_io_getevents, 4, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setxattr +TRACE_SYSCALL_TABLE(sys_setxattr, sys_setxattr, 5, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_lsetxattr +TRACE_SYSCALL_TABLE(sys_lsetxattr, sys_lsetxattr, 6, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fsetxattr +TRACE_SYSCALL_TABLE(sys_fsetxattr, sys_fsetxattr, 7, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getxattr +TRACE_SYSCALL_TABLE(sys_getxattr, sys_getxattr, 8, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_lgetxattr +TRACE_SYSCALL_TABLE(sys_lgetxattr, sys_lgetxattr, 9, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fgetxattr +TRACE_SYSCALL_TABLE(sys_fgetxattr, sys_fgetxattr, 10, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_listxattr +TRACE_SYSCALL_TABLE(sys_listxattr, sys_listxattr, 11, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_llistxattr +TRACE_SYSCALL_TABLE(sys_llistxattr, sys_llistxattr, 12, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_flistxattr +TRACE_SYSCALL_TABLE(sys_flistxattr, sys_flistxattr, 13, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_removexattr +TRACE_SYSCALL_TABLE(sys_removexattr, sys_removexattr, 14, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_lremovexattr +TRACE_SYSCALL_TABLE(sys_lremovexattr, sys_lremovexattr, 15, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fremovexattr +TRACE_SYSCALL_TABLE(sys_fremovexattr, sys_fremovexattr, 16, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getcwd +TRACE_SYSCALL_TABLE(sys_getcwd, sys_getcwd, 17, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_epoll_ctl +TRACE_SYSCALL_TABLE(sys_epoll_ctl, sys_epoll_ctl, 21, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_epoll_pwait +TRACE_SYSCALL_TABLE(sys_epoll_pwait, sys_epoll_pwait, 22, 6) +#endif +#ifndef OVERRIDE_TABLE_64_sys_inotify_add_watch +TRACE_SYSCALL_TABLE(sys_inotify_add_watch, sys_inotify_add_watch, 27, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mknodat +TRACE_SYSCALL_TABLE(sys_mknodat, sys_mknodat, 33, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mkdirat +TRACE_SYSCALL_TABLE(sys_mkdirat, sys_mkdirat, 34, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_unlinkat +TRACE_SYSCALL_TABLE(sys_unlinkat, sys_unlinkat, 35, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_symlinkat +TRACE_SYSCALL_TABLE(sys_symlinkat, sys_symlinkat, 36, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_linkat +TRACE_SYSCALL_TABLE(sys_linkat, sys_linkat, 37, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_renameat +TRACE_SYSCALL_TABLE(sys_renameat, sys_renameat, 38, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_umount +TRACE_SYSCALL_TABLE(sys_umount, sys_umount, 39, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mount +TRACE_SYSCALL_TABLE(sys_mount, sys_mount, 40, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_pivot_root +TRACE_SYSCALL_TABLE(sys_pivot_root, sys_pivot_root, 41, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_nfsservctl +TRACE_SYSCALL_TABLE(sys_nfsservctl, sys_nfsservctl, 42, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_statfs +TRACE_SYSCALL_TABLE(sys_statfs, sys_statfs, 43, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fstatfs +TRACE_SYSCALL_TABLE(sys_fstatfs, sys_fstatfs, 44, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_truncate +TRACE_SYSCALL_TABLE(sys_truncate, sys_truncate, 45, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_faccessat +TRACE_SYSCALL_TABLE(sys_faccessat, sys_faccessat, 48, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_chdir +TRACE_SYSCALL_TABLE(sys_chdir, sys_chdir, 49, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_chroot +TRACE_SYSCALL_TABLE(sys_chroot, sys_chroot, 51, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fchmodat +TRACE_SYSCALL_TABLE(sys_fchmodat, sys_fchmodat, 53, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fchownat +TRACE_SYSCALL_TABLE(sys_fchownat, sys_fchownat, 54, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_openat +TRACE_SYSCALL_TABLE(sys_openat, sys_openat, 56, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_pipe2 +TRACE_SYSCALL_TABLE(sys_pipe2, sys_pipe2, 59, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_quotactl +TRACE_SYSCALL_TABLE(sys_quotactl, sys_quotactl, 60, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getdents64 +TRACE_SYSCALL_TABLE(sys_getdents64, sys_getdents64, 61, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_read +TRACE_SYSCALL_TABLE(sys_read, sys_read, 63, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_write +TRACE_SYSCALL_TABLE(sys_write, sys_write, 64, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_readv +TRACE_SYSCALL_TABLE(sys_readv, sys_readv, 65, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_writev +TRACE_SYSCALL_TABLE(sys_writev, sys_writev, 66, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_preadv +TRACE_SYSCALL_TABLE(sys_preadv, sys_preadv, 69, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_pwritev +TRACE_SYSCALL_TABLE(sys_pwritev, sys_pwritev, 70, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sendfile64 +TRACE_SYSCALL_TABLE(sys_sendfile64, sys_sendfile64, 71, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_pselect6 +TRACE_SYSCALL_TABLE(sys_pselect6, sys_pselect6, 72, 6) +#endif +#ifndef OVERRIDE_TABLE_64_sys_ppoll +TRACE_SYSCALL_TABLE(sys_ppoll, sys_ppoll, 73, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_signalfd4 +TRACE_SYSCALL_TABLE(sys_signalfd4, sys_signalfd4, 74, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_vmsplice +TRACE_SYSCALL_TABLE(sys_vmsplice, sys_vmsplice, 75, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_splice +TRACE_SYSCALL_TABLE(sys_splice, sys_splice, 76, 6) +#endif +#ifndef OVERRIDE_TABLE_64_sys_readlinkat +TRACE_SYSCALL_TABLE(sys_readlinkat, sys_readlinkat, 78, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_newfstatat +TRACE_SYSCALL_TABLE(sys_newfstatat, sys_newfstatat, 79, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_newfstat +TRACE_SYSCALL_TABLE(sys_newfstat, sys_newfstat, 80, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_timerfd_settime +TRACE_SYSCALL_TABLE(sys_timerfd_settime, sys_timerfd_settime, 86, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_timerfd_gettime +TRACE_SYSCALL_TABLE(sys_timerfd_gettime, sys_timerfd_gettime, 87, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_utimensat +TRACE_SYSCALL_TABLE(sys_utimensat, sys_utimensat, 88, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_acct +TRACE_SYSCALL_TABLE(sys_acct, sys_acct, 89, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_waitid +TRACE_SYSCALL_TABLE(sys_waitid, sys_waitid, 95, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_set_tid_address +TRACE_SYSCALL_TABLE(sys_set_tid_address, sys_set_tid_address, 96, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_futex +TRACE_SYSCALL_TABLE(sys_futex, sys_futex, 98, 6) +#endif +#ifndef OVERRIDE_TABLE_64_sys_set_robust_list +TRACE_SYSCALL_TABLE(sys_set_robust_list, sys_set_robust_list, 99, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_get_robust_list +TRACE_SYSCALL_TABLE(sys_get_robust_list, sys_get_robust_list, 100, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_nanosleep +TRACE_SYSCALL_TABLE(sys_nanosleep, sys_nanosleep, 101, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getitimer +TRACE_SYSCALL_TABLE(sys_getitimer, sys_getitimer, 102, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setitimer +TRACE_SYSCALL_TABLE(sys_setitimer, sys_setitimer, 103, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_init_module +TRACE_SYSCALL_TABLE(sys_init_module, sys_init_module, 105, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_delete_module +TRACE_SYSCALL_TABLE(sys_delete_module, sys_delete_module, 106, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_timer_create +TRACE_SYSCALL_TABLE(sys_timer_create, sys_timer_create, 107, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_timer_gettime +TRACE_SYSCALL_TABLE(sys_timer_gettime, sys_timer_gettime, 108, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_timer_settime +TRACE_SYSCALL_TABLE(sys_timer_settime, sys_timer_settime, 110, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_clock_settime +TRACE_SYSCALL_TABLE(sys_clock_settime, sys_clock_settime, 112, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_clock_gettime +TRACE_SYSCALL_TABLE(sys_clock_gettime, sys_clock_gettime, 113, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_clock_getres +TRACE_SYSCALL_TABLE(sys_clock_getres, sys_clock_getres, 114, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_clock_nanosleep +TRACE_SYSCALL_TABLE(sys_clock_nanosleep, sys_clock_nanosleep, 115, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_syslog +TRACE_SYSCALL_TABLE(sys_syslog, sys_syslog, 116, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sched_setparam +TRACE_SYSCALL_TABLE(sys_sched_setparam, sys_sched_setparam, 118, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sched_setscheduler +TRACE_SYSCALL_TABLE(sys_sched_setscheduler, sys_sched_setscheduler, 119, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sched_getparam +TRACE_SYSCALL_TABLE(sys_sched_getparam, sys_sched_getparam, 121, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sched_setaffinity +TRACE_SYSCALL_TABLE(sys_sched_setaffinity, sys_sched_setaffinity, 122, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sched_getaffinity +TRACE_SYSCALL_TABLE(sys_sched_getaffinity, sys_sched_getaffinity, 123, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sched_rr_get_interval +TRACE_SYSCALL_TABLE(sys_sched_rr_get_interval, sys_sched_rr_get_interval, 127, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_rt_sigsuspend +TRACE_SYSCALL_TABLE(sys_rt_sigsuspend, sys_rt_sigsuspend, 133, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_rt_sigaction +TRACE_SYSCALL_TABLE(sys_rt_sigaction, sys_rt_sigaction, 134, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_rt_sigprocmask +TRACE_SYSCALL_TABLE(sys_rt_sigprocmask, sys_rt_sigprocmask, 135, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_rt_sigpending +TRACE_SYSCALL_TABLE(sys_rt_sigpending, sys_rt_sigpending, 136, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_rt_sigtimedwait +TRACE_SYSCALL_TABLE(sys_rt_sigtimedwait, sys_rt_sigtimedwait, 137, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_rt_sigqueueinfo +TRACE_SYSCALL_TABLE(sys_rt_sigqueueinfo, sys_rt_sigqueueinfo, 138, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_reboot +TRACE_SYSCALL_TABLE(sys_reboot, sys_reboot, 142, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getresuid +TRACE_SYSCALL_TABLE(sys_getresuid, sys_getresuid, 148, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getresgid +TRACE_SYSCALL_TABLE(sys_getresgid, sys_getresgid, 150, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_times +TRACE_SYSCALL_TABLE(sys_times, sys_times, 153, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getgroups +TRACE_SYSCALL_TABLE(sys_getgroups, sys_getgroups, 158, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setgroups +TRACE_SYSCALL_TABLE(sys_setgroups, sys_setgroups, 159, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_newuname +TRACE_SYSCALL_TABLE(sys_newuname, sys_newuname, 160, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sethostname +TRACE_SYSCALL_TABLE(sys_sethostname, sys_sethostname, 161, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setdomainname +TRACE_SYSCALL_TABLE(sys_setdomainname, sys_setdomainname, 162, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getrlimit +TRACE_SYSCALL_TABLE(sys_getrlimit, sys_getrlimit, 163, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setrlimit +TRACE_SYSCALL_TABLE(sys_setrlimit, sys_setrlimit, 164, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getrusage +TRACE_SYSCALL_TABLE(sys_getrusage, sys_getrusage, 165, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getcpu +TRACE_SYSCALL_TABLE(sys_getcpu, sys_getcpu, 168, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_gettimeofday +TRACE_SYSCALL_TABLE(sys_gettimeofday, sys_gettimeofday, 169, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_settimeofday +TRACE_SYSCALL_TABLE(sys_settimeofday, sys_settimeofday, 170, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_adjtimex +TRACE_SYSCALL_TABLE(sys_adjtimex, sys_adjtimex, 171, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sysinfo +TRACE_SYSCALL_TABLE(sys_sysinfo, sys_sysinfo, 179, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mq_open +TRACE_SYSCALL_TABLE(sys_mq_open, sys_mq_open, 180, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mq_unlink +TRACE_SYSCALL_TABLE(sys_mq_unlink, sys_mq_unlink, 181, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mq_timedsend +TRACE_SYSCALL_TABLE(sys_mq_timedsend, sys_mq_timedsend, 182, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mq_timedreceive +TRACE_SYSCALL_TABLE(sys_mq_timedreceive, sys_mq_timedreceive, 183, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mq_notify +TRACE_SYSCALL_TABLE(sys_mq_notify, sys_mq_notify, 184, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mq_getsetattr +TRACE_SYSCALL_TABLE(sys_mq_getsetattr, sys_mq_getsetattr, 185, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_msgctl +TRACE_SYSCALL_TABLE(sys_msgctl, sys_msgctl, 187, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_msgrcv +TRACE_SYSCALL_TABLE(sys_msgrcv, sys_msgrcv, 188, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_msgsnd +TRACE_SYSCALL_TABLE(sys_msgsnd, sys_msgsnd, 189, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_semtimedop +TRACE_SYSCALL_TABLE(sys_semtimedop, sys_semtimedop, 192, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_semop +TRACE_SYSCALL_TABLE(sys_semop, sys_semop, 193, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_shmctl +TRACE_SYSCALL_TABLE(sys_shmctl, sys_shmctl, 195, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_shmat +TRACE_SYSCALL_TABLE(sys_shmat, sys_shmat, 196, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_shmdt +TRACE_SYSCALL_TABLE(sys_shmdt, sys_shmdt, 197, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_socketpair +TRACE_SYSCALL_TABLE(sys_socketpair, sys_socketpair, 199, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_bind +TRACE_SYSCALL_TABLE(sys_bind, sys_bind, 200, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_accept +TRACE_SYSCALL_TABLE(sys_accept, sys_accept, 202, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_connect +TRACE_SYSCALL_TABLE(sys_connect, sys_connect, 203, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getsockname +TRACE_SYSCALL_TABLE(sys_getsockname, sys_getsockname, 204, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getpeername +TRACE_SYSCALL_TABLE(sys_getpeername, sys_getpeername, 205, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sendto +TRACE_SYSCALL_TABLE(sys_sendto, sys_sendto, 206, 6) +#endif +#ifndef OVERRIDE_TABLE_64_sys_recvfrom +TRACE_SYSCALL_TABLE(sys_recvfrom, sys_recvfrom, 207, 6) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setsockopt +TRACE_SYSCALL_TABLE(sys_setsockopt, sys_setsockopt, 208, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getsockopt +TRACE_SYSCALL_TABLE(sys_getsockopt, sys_getsockopt, 209, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sendmsg +TRACE_SYSCALL_TABLE(sys_sendmsg, sys_sendmsg, 211, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_recvmsg +TRACE_SYSCALL_TABLE(sys_recvmsg, sys_recvmsg, 212, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_add_key +TRACE_SYSCALL_TABLE(sys_add_key, sys_add_key, 217, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_request_key +TRACE_SYSCALL_TABLE(sys_request_key, sys_request_key, 218, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_swapon +TRACE_SYSCALL_TABLE(sys_swapon, sys_swapon, 224, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_swapoff +TRACE_SYSCALL_TABLE(sys_swapoff, sys_swapoff, 225, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mincore +TRACE_SYSCALL_TABLE(sys_mincore, sys_mincore, 232, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mbind +TRACE_SYSCALL_TABLE(sys_mbind, sys_mbind, 235, 6) +#endif +#ifndef OVERRIDE_TABLE_64_sys_get_mempolicy +TRACE_SYSCALL_TABLE(sys_get_mempolicy, sys_get_mempolicy, 236, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_set_mempolicy +TRACE_SYSCALL_TABLE(sys_set_mempolicy, sys_set_mempolicy, 237, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_migrate_pages +TRACE_SYSCALL_TABLE(sys_migrate_pages, sys_migrate_pages, 238, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_move_pages +TRACE_SYSCALL_TABLE(sys_move_pages, sys_move_pages, 239, 6) +#endif +#ifndef OVERRIDE_TABLE_64_sys_rt_tgsigqueueinfo +TRACE_SYSCALL_TABLE(sys_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo, 240, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_perf_event_open +TRACE_SYSCALL_TABLE(sys_perf_event_open, sys_perf_event_open, 241, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_accept4 +TRACE_SYSCALL_TABLE(sys_accept4, sys_accept4, 242, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_recvmmsg +TRACE_SYSCALL_TABLE(sys_recvmmsg, sys_recvmmsg, 243, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_wait4 +TRACE_SYSCALL_TABLE(sys_wait4, sys_wait4, 260, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_prlimit64 +TRACE_SYSCALL_TABLE(sys_prlimit64, sys_prlimit64, 261, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_name_to_handle_at +TRACE_SYSCALL_TABLE(sys_name_to_handle_at, sys_name_to_handle_at, 264, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_open_by_handle_at +TRACE_SYSCALL_TABLE(sys_open_by_handle_at, sys_open_by_handle_at, 265, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_clock_adjtime +TRACE_SYSCALL_TABLE(sys_clock_adjtime, sys_clock_adjtime, 266, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sendmmsg +TRACE_SYSCALL_TABLE(sys_sendmmsg, sys_sendmmsg, 269, 4) +#endif + +#endif /* CREATE_SYSCALL_TABLE */ diff --git a/instrumentation/syscalls/headers/tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_pointers_override.h b/instrumentation/syscalls/headers/tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_pointers_override.h new file mode 100644 index 0000000..f0b6379 --- /dev/null +++ b/instrumentation/syscalls/headers/tile-64-syscalls-2.6.40.38-MDE-4.1.2.149467_pointers_override.h @@ -0,0 +1,11 @@ +#define OVERRIDE_TABLE_64_sys_execve +#define OVERRIDE_TABLE_64_sys_clone + +#ifndef CREATE_SYSCALL_TABLE + +#else /* CREATE_SYSCALL_TABLE */ + +TRACE_SYSCALL_TABLE(sys_execve, sys_execve, 221, 3) +TRACE_SYSCALL_TABLE(sys_clone, sys_clone, 220, 4) + +#endif /* CREATE_SYSCALL_TABLE */ -- 1.7.1 From sunyin51 at gmail.com Sat Jan 19 12:27:42 2013 From: sunyin51 at gmail.com (yin sun) Date: Sat, 19 Jan 2013 09:27:42 -0800 Subject: [lttng-dev] [BABELTRACE] view logs while tracing started Message-ID: Hi, I am new here. The example always need to stop tracing then view the log. Is it possible to view it while tracing is on. I try to do that it always fail. How to make it work. Thanks, /Yin From paulmck at linux.vnet.ibm.com Sat Jan 19 14:17:52 2013 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Sat, 19 Jan 2013 11:17:52 -0800 Subject: [lttng-dev] [PATCH] Add ACCESS_ONCE() to avoid compiler splitting assignments In-Reply-To: <20130116125054.GA9734@Krystal> References: <20130115181936.GA30319@linux.vnet.ibm.com> <20130115235642.GA31367@Krystal> <20130116125054.GA9734@Krystal> Message-ID: <20130119191752.GA3159@linux.vnet.ibm.com> On Wed, Jan 16, 2013 at 07:50:54AM -0500, Mathieu Desnoyers wrote: > * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > As noted by Konstantin Khlebnikov, gcc can split assignment of > > > constants to long variables (https://lkml.org/lkml/2013/1/15/141), > > > though assignment of NULL (0) is OK. Assuming that a gcc bug is > > > fixed (http://gcc.gnu.org/bugzilla/attachment.cgi?id=29169&action=diff > > > has a patch), making the store be volatile keeps gcc from splitting. > > > > > > This commit therefore applies ACCESS_ONCE() to CMM_STORE_SHARED(), > > > which is the underlying primitive used by rcu_assign_pointer(). > > > > Hi Paul, > > > > I recognise that this is an issue in the Linux kernel, since a simple > > store is used and expected to be performed atomically when aligned. > > However, I think this does not affect liburcu, see below: > > Side question: what gcc versions may issue non-atomic volatile stores ? > I think we should at least document those. Bug > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55981 seems to target gcc > 4.7.2, but I wonder when this issue first appeared on x86 and x86-64 > (and if it affects other architectures as well). I have no idea which versions are affected. The bug is in the x86 backend, so is specific to x86, but there might well be similar bugs in other architectures. > Thanks, > > Mathieu > > > > > > > > > Signed-off-by: Paul E. McKenney > > > > > > diff --git a/urcu/system.h b/urcu/system.h > > > index 2a45f22..7a1887e 100644 > > > --- a/urcu/system.h > > > +++ b/urcu/system.h > > > @@ -49,7 +49,7 @@ > > > */ > > > #define CMM_STORE_SHARED(x, v) \ > > > ({ \ > > > - __typeof__(x) _v = _CMM_STORE_SHARED(x, v); \ > > > + __typeof__(x) CMM_ACCESS_ONCE(_v) = _CMM_STORE_SHARED(x, v); \ > > > > Here, the macro "_CMM_STORE_SHARED(x, v)" is doing the actual store. > > It stores v into "x". So adding a CMM_ACCESS_ONCE(_v), as you propose > > here, is really only making sure the return value (usually unused), > > located on the stack, is accessed with a volatile access, which does not > > make much sense. > > > > What really matters is the _CMM_STORE_SHARED() macro: > > > > #define _CMM_STORE_SHARED(x, v) ({ CMM_ACCESS_ONCE(x) = (v); }) > > > > which already uses a volatile access for the store. So this seems to be > > a case where our preemptive use of volatile for stores in addition to > > loads made us bug-free for a gcc behavior unexpected at the time we > > implemented this macro. Just a touch of paranoia seems to be a good > > thing sometimes. ;-) > > > > Thoughts ? Here is my thought: You should ignore my "fix". Please accept my apologies for my confusion! Thanx, Paul > > Thanks, > > > > Mathieu > > > > > cmm_smp_wmc(); \ > > > _v; \ > > > }) > > > > > > > > > _______________________________________________ > > > lttng-dev mailing list > > > lttng-dev at lists.lttng.org > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > -- > > Mathieu Desnoyers > > EfficiOS Inc. > > http://www.efficios.com > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > EfficiOS Inc. > http://www.efficios.com > From mathieu.desnoyers at efficios.com Sun Jan 20 12:59:47 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 20 Jan 2013 12:59:47 -0500 Subject: [lttng-dev] [PATCH babeltrace 3/3] Fix: Removed Python bindings to static constructor and destructor. In-Reply-To: <1358527534-16401-3-git-send-email-jeremie.galarneau@efficios.com> References: <1358527534-16401-1-git-send-email-jeremie.galarneau@efficios.com> <1358527534-16401-3-git-send-email-jeremie.galarneau@efficios.com> Message-ID: <20130120175947.GA19512@Krystal> * J?r?mie Galarneau (jeremie.galarneau at efficios.com) wrote: > Resolves an undefined symbol on Python module load. All 3 patches merged, thanks! Mathieu > > Signed-off-by: J?r?mie Galarneau > --- > bindings/python/babeltrace.i.in | 3 --- > 1 file changed, 3 deletions(-) > > diff --git a/bindings/python/babeltrace.i.in b/bindings/python/babeltrace.i.in > index d45afb0..dd49ba5 100644 > --- a/bindings/python/babeltrace.i.in > +++ b/bindings/python/babeltrace.i.in > @@ -194,9 +194,6 @@ extern struct format *bt_lookup_format(bt_intern_str qname); > extern void bt_fprintf_format_list(FILE *fp); > extern int bt_register_format(struct format *format); > > -void format_init(void); > -void format_finalize(void); > - > %pythoncode %{ > > def print_format_list(babeltrace_file): > -- > 1.8.1.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Sun Jan 20 15:51:31 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 20 Jan 2013 15:51:31 -0500 Subject: [lttng-dev] [PATCH] Add ACCESS_ONCE() to avoid compiler splitting assignments In-Reply-To: <20130119191752.GA3159@linux.vnet.ibm.com> References: <20130115181936.GA30319@linux.vnet.ibm.com> <20130115235642.GA31367@Krystal> <20130116125054.GA9734@Krystal> <20130119191752.GA3159@linux.vnet.ibm.com> Message-ID: <20130120205131.GB19512@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > On Wed, Jan 16, 2013 at 07:50:54AM -0500, Mathieu Desnoyers wrote: > > * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > As noted by Konstantin Khlebnikov, gcc can split assignment of > > > > constants to long variables (https://lkml.org/lkml/2013/1/15/141), > > > > though assignment of NULL (0) is OK. Assuming that a gcc bug is > > > > fixed (http://gcc.gnu.org/bugzilla/attachment.cgi?id=29169&action=diff > > > > has a patch), making the store be volatile keeps gcc from splitting. > > > > > > > > This commit therefore applies ACCESS_ONCE() to CMM_STORE_SHARED(), > > > > which is the underlying primitive used by rcu_assign_pointer(). > > > > > > Hi Paul, > > > > > > I recognise that this is an issue in the Linux kernel, since a simple > > > store is used and expected to be performed atomically when aligned. > > > However, I think this does not affect liburcu, see below: > > > > Side question: what gcc versions may issue non-atomic volatile stores ? > > I think we should at least document those. Bug > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55981 seems to target gcc > > 4.7.2, but I wonder when this issue first appeared on x86 and x86-64 > > (and if it affects other architectures as well). > > I have no idea which versions are affected. The bug is in the x86 > backend, so is specific to x86, but there might well be similar bugs > in other architectures. Results for my quick tests so far: gcc version 4.4.7 (Debian 4.4.7-2) gcc version 4.6.3 (Debian 4.6.3-11) gcc version 4.7.2 (Debian 4.7.2-5) for x86-64 are affected (all gcc installed currently on my Debian laptop). I made a simpler test case than the one shown on the bugzilla, which triggers the issue with -O0 and -O1 (-O2 and -Os optimisations seems not to show this issue with the simpler test case). So far, it seems to only affect stores from immediate value operands (and only some patterns). Debian clang version 3.0-6 (tags/RELEASE_30/final) (based on LLVM 3.0) is not affected for x86-64. My test case looks like this: * non-atomic-pointer.c: volatile void *var; void fct(void) { asm volatile ("/* test_begin */" : : : "memory"); var = (void *) 0x100000002; var = (void *) 0x300000004; asm volatile ("/* test_end */" : : : "memory"); } * build.sh: #!/bin/bash FLAGS="-S ${*}" function do_build { $1 ${FLAGS} -o non-atomic-pointer-$1.S.output non-atomic-pointer.c } do_build gcc-4.4 do_build gcc-4.6 do_build gcc-4.7 do_build gcc-4.7 do_build g++-4.6 do_build g++-4.7 do_build clang * check.py (might need adaptation for each architecture and O2, Os): #!/usr/bin/env python import sys, string, os, re # count the number of lines with "mov*" instructions between test_begin # and test_end. Should be 2. Report error if not. f = open (sys.argv[1], "r") lines = f.readlines() within_range = 0 mov_count = 0 error = 0 re_mov = re.compile(' mov.*') re_begin = re.compile('.*test_begin.*') re_end = re.compile('.*test_end.*') output = "" for line in lines: if re_begin.match(line): within_range = 1 elif re_end.match(line): within_range = 0 elif (within_range and re_mov.match(line)): output += line mov_count += 1 if mov_count > 2: error = 1 f.close() if error > 0: print "[Error] expect 2 mov, found " + str(mov_count) print output 1 else: 0 > > > Thanks, > > > > Mathieu > > > > > > > > > > > > > Signed-off-by: Paul E. McKenney > > > > > > > > diff --git a/urcu/system.h b/urcu/system.h > > > > index 2a45f22..7a1887e 100644 > > > > --- a/urcu/system.h > > > > +++ b/urcu/system.h > > > > @@ -49,7 +49,7 @@ > > > > */ > > > > #define CMM_STORE_SHARED(x, v) \ > > > > ({ \ > > > > - __typeof__(x) _v = _CMM_STORE_SHARED(x, v); \ > > > > + __typeof__(x) CMM_ACCESS_ONCE(_v) = _CMM_STORE_SHARED(x, v); \ > > > > > > Here, the macro "_CMM_STORE_SHARED(x, v)" is doing the actual store. > > > It stores v into "x". So adding a CMM_ACCESS_ONCE(_v), as you propose > > > here, is really only making sure the return value (usually unused), > > > located on the stack, is accessed with a volatile access, which does not > > > make much sense. > > > > > > What really matters is the _CMM_STORE_SHARED() macro: > > > > > > #define _CMM_STORE_SHARED(x, v) ({ CMM_ACCESS_ONCE(x) = (v); }) > > > > > > which already uses a volatile access for the store. So this seems to be > > > a case where our preemptive use of volatile for stores in addition to > > > loads made us bug-free for a gcc behavior unexpected at the time we > > > implemented this macro. Just a touch of paranoia seems to be a good > > > thing sometimes. ;-) > > > > > > Thoughts ? > > Here is my thought: You should ignore my "fix". Please accept my > apologies for my confusion! No worries! Thanks for bringing this issue to my attention. I'm thinking we might want to create a test throwing code with random immediate values into my python checker script, for various architectures for a couple of weeks, and see what breaks. Also, it might be good to test whether some register inputs can generate code that write into an unsigned long non-atomically. This would be even more worrying. Thanks, Mathieu > > Thanx, Paul > > > > Thanks, > > > > > > Mathieu > > > > > > > cmm_smp_wmc(); \ > > > > _v; \ > > > > }) > > > > > > > > > > > > _______________________________________________ > > > > lttng-dev mailing list > > > > lttng-dev at lists.lttng.org > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > -- > > > Mathieu Desnoyers > > > EfficiOS Inc. > > > http://www.efficios.com > > > > > > _______________________________________________ > > > lttng-dev mailing list > > > lttng-dev at lists.lttng.org > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > -- > > Mathieu Desnoyers > > EfficiOS Inc. > > http://www.efficios.com > > > -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Sun Jan 20 18:04:07 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 20 Jan 2013 18:04:07 -0500 Subject: [lttng-dev] [rp] [RFC PATCH urcu] Add "last" output parameter to pop/dequeue In-Reply-To: <20130115183825.GR3384@linux.vnet.ibm.com> References: <20121213114456.GA9780@Krystal> <20121214163609.GD2542@linux.vnet.ibm.com> <20121217144008.GA5086@Krystal> <20130115183825.GR3384@linux.vnet.ibm.com> Message-ID: <20130120230407.GA22804@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > [Sorry for the delay, finally getting back to this.] > > On Mon, Dec 17, 2012 at 09:40:09AM -0500, Mathieu Desnoyers wrote: > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > On Thu, Dec 13, 2012 at 06:44:56AM -0500, Mathieu Desnoyers wrote: > > > > I noticed that in addition to having: > > > > > > > > - push/enqueue returning whether the stack/queue was empty prior to the > > > > operation, > > > > - pop_all/splice, by nature, emptying the stack/queue, > > > > > > > > it can be interesting to make pop/dequeue operations return whether they > > > > are returning the last element of the stack/queue (therefore emptying > > > > it). This allow extending the test-cases covering the number of empty > > > > stack/queue encountered by both push/enqueuer and pop/dequeuer threads > > > > not only to push/enqueue paired with pop_all/splice, but also to > > > > pop/dequeue. > > > > > > > > In the case of wfstack, this unfortunately requires to modify an already > > > > exposed API. As a RFC, one question we should answer is how we want to > > > > handle the way forward: should we add new functions to the wfstack API > > > > and leave the existing ones alone ? > > > > > > > > Thoughts ? > > > > > > Hmmm... What is the use case, given that a push might happen immediately > > > after the pop said that the stack/queue was empty? Of course, if we > > > somehow know that there are no concurrent pushes, we could instead > > > check for empty. > > > > > > So what am I missing here? > > > > The setup for those use-cases is the following (I'm using the stack as > > example, but the same applies to queue): > > > > - we have N threads doing push and using the push return value that > > states whether it pushed into an empty stack. > > - we have M threads doing "pop", using the return value to know if it > > pops a stack into an empty-stack-state. Following the locking > > requirements, we protect those M threads'pop by a mutex, but they > > don't need to be protected against push. > > > > Just to help understanding where the idea comes from, let's start with > > another use-case that is similar (push/pop_all). Knowing whether we > > pushed into an empty stack along with pop_all become very useful when > > you want to combine the stack with a higher level batching semantic > > linked to the elements present within the stack. > > > > In the case of grace period batching, for instance, I used > > "push"/"pop_all" to provide this kind of semantic: if we push into an > > empty stack, we know we will have to go through the grace period. If we > > are pushed into a non-empty stack, we just wait to be awakened by the > > first thread which was pushed into the stack. This requires that we use > > "pop_all" before going though the grace period. > > > > Now more specifically about "pop", one use-case I have in mind is > > energy-efficient handling of empty stacks. With M threads executing > > "pop", let's suppose we want them to be blocked on a futex when there is > > nothing to do. Now the tricky part is: how can we do this without adding > > overhead (extra load/stores) to the stack ? > > > > If we have the ability to know whether we are popping the last element > > of a stack, we can use this information to go into a futex wait state > > after having handled the last element. Since the threads doing "push" > > would monitor whether they push into an empty stack, they would wake us > > whenever needed. > > > > If instead we choose to simply wait until one of the M threads discovers > > that the stack is actually empty, we are issuing extra "pop" (which > > fails) each time the stack is empty. In the worse-case, if a queue > > always flip between 0 and 1 elements, we double the number of "pop" > > needed to handle the same amount of nodes. > > > > Otherwise, if we choose to add an explicit check to see whether the > > stack is empty, we are adding an extra load of the head node for every > > pop. > > > > Another use-case I see is low-overhead monitoring of stack usage > > efficiency. For this kind of use-case, we might want to know, both > > within push and pop threads, if we are underutilizing our system > > resources. Having the ability to know that we are reaching empty state > > without any extra overhead to stack memory traffic gives us this > > ability. > > > > I must admit that the use-cases for returning whether pop takes the last > > element is not as strong as the batching case with push/pop_all, mainly > > because AFAIU, we can achieve the same result by doing an extra check of > > stack emptiness state (either by an explicit empty() check, or by > > issuing an extra pop that will see an empty stack). What we are saving > > here is the extra overhead on stack cache-lines cause by this extra > > check. > > > > Another use-case, although maybe less compelling, is for validation. > > With concurrent threads doing push/pop/pop_all operations on the stack, > > we can perform the following check: If we empty the stack at the end of > > test execution, the > > > > number of push-to-empty-stack > > > > must be equal to the > > > > number of pop_all-from-non-empty-stack > > + number of pop-last-element-from-non-empty-stack > > > > We should note that this validation could not be performed if "pop" is > > not returning whether it popped the last stack element (checked > > atomically with the pop operation). This is a use-case where adding an > > extra check on the pop-side would not work (it needs to be performed > > atomically with pop). > > > > And maybe there are other use-cases that are currently beyond my > > imagination too. > > > > Thoughts ? > > Sounds like a job for a separate API member that can be added when > needed. I do admit that you have legitimate use cases, but I do not > believe that they will be the common case. Agreed, this won't be the common case. I'll propose new API members for this. Thanks, Mathieu > > Maybe due to failure of imagination on my part, but... ;-) > > Thanx, Paul > > > Thanks, > > > > Mathieu > > > > > > > > > > Thanx, Paul > > > > > > > Thanks, > > > > > > > > Mathieu > > > > > > > > --- > > > > diff --git a/tests/test_urcu_wfcq.c b/tests/test_urcu_wfcq.c > > > > index 91285a5..de9566d 100644 > > > > --- a/tests/test_urcu_wfcq.c > > > > +++ b/tests/test_urcu_wfcq.c > > > > @@ -168,6 +168,7 @@ static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); > > > > static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); > > > > static DEFINE_URCU_TLS(unsigned long long, nr_empty_dest_enqueues); > > > > static DEFINE_URCU_TLS(unsigned long long, nr_splice); > > > > +static DEFINE_URCU_TLS(unsigned long long, nr_dequeue_last); > > > > > > > > static unsigned int nr_enqueuers; > > > > static unsigned int nr_dequeuers; > > > > @@ -228,11 +229,15 @@ fail: > > > > static void do_test_dequeue(enum test_sync sync) > > > > { > > > > struct cds_wfcq_node *node; > > > > + bool last; > > > > > > > > if (sync == TEST_SYNC_MUTEX) > > > > - node = cds_wfcq_dequeue_blocking(&head, &tail); > > > > + node = cds_wfcq_dequeue_blocking(&head, &tail, &last); > > > > else > > > > - node = __cds_wfcq_dequeue_blocking(&head, &tail); > > > > + node = __cds_wfcq_dequeue_blocking(&head, &tail, &last); > > > > + > > > > + if (last) > > > > + URCU_TLS(nr_dequeue_last)++; > > > > > > > > if (node) { > > > > free(node); > > > > @@ -263,6 +268,7 @@ static void do_test_splice(enum test_sync sync) > > > > break; > > > > case CDS_WFCQ_RET_DEST_EMPTY: > > > > URCU_TLS(nr_splice)++; > > > > + URCU_TLS(nr_dequeue_last)++; > > > > /* ok */ > > > > break; > > > > case CDS_WFCQ_RET_DEST_NON_EMPTY: > > > > @@ -325,16 +331,21 @@ static void *thr_dequeuer(void *_count) > > > > count[0] = URCU_TLS(nr_dequeues); > > > > count[1] = URCU_TLS(nr_successful_dequeues); > > > > count[2] = URCU_TLS(nr_splice); > > > > + count[3] = URCU_TLS(nr_dequeue_last); > > > > return ((void*)2); > > > > } > > > > > > > > -static void test_end(unsigned long long *nr_dequeues) > > > > +static void test_end(unsigned long long *nr_dequeues, > > > > + unsigned long long *nr_dequeue_last) > > > > { > > > > struct cds_wfcq_node *node; > > > > + bool last; > > > > > > > > do { > > > > - node = cds_wfcq_dequeue_blocking(&head, &tail); > > > > + node = cds_wfcq_dequeue_blocking(&head, &tail, &last); > > > > if (node) { > > > > + if (last) > > > > + (*nr_dequeue_last)++; > > > > free(node); > > > > (*nr_dequeues)++; > > > > } > > > > @@ -367,7 +378,7 @@ int main(int argc, char **argv) > > > > unsigned long long tot_successful_enqueues = 0, > > > > tot_successful_dequeues = 0, > > > > tot_empty_dest_enqueues = 0, > > > > - tot_splice = 0; > > > > + tot_splice = 0, tot_dequeue_last = 0; > > > > unsigned long long end_dequeues = 0; > > > > int i, a, retval = 0; > > > > > > > > @@ -480,7 +491,7 @@ int main(int argc, char **argv) > > > > tid_enqueuer = malloc(sizeof(*tid_enqueuer) * nr_enqueuers); > > > > tid_dequeuer = malloc(sizeof(*tid_dequeuer) * nr_dequeuers); > > > > count_enqueuer = malloc(3 * sizeof(*count_enqueuer) * nr_enqueuers); > > > > - count_dequeuer = malloc(3 * sizeof(*count_dequeuer) * nr_dequeuers); > > > > + count_dequeuer = malloc(4 * sizeof(*count_dequeuer) * nr_dequeuers); > > > > cds_wfcq_init(&head, &tail); > > > > > > > > next_aff = 0; > > > > @@ -493,7 +504,7 @@ int main(int argc, char **argv) > > > > } > > > > for (i = 0; i < nr_dequeuers; i++) { > > > > err = pthread_create(&tid_dequeuer[i], NULL, thr_dequeuer, > > > > - &count_dequeuer[3 * i]); > > > > + &count_dequeuer[4 * i]); > > > > if (err != 0) > > > > exit(1); > > > > } > > > > @@ -533,34 +544,37 @@ int main(int argc, char **argv) > > > > err = pthread_join(tid_dequeuer[i], &tret); > > > > if (err != 0) > > > > exit(1); > > > > - tot_dequeues += count_dequeuer[3 * i]; > > > > - tot_successful_dequeues += count_dequeuer[3 * i + 1]; > > > > - tot_splice += count_dequeuer[3 * i + 2]; > > > > + tot_dequeues += count_dequeuer[4 * i]; > > > > + tot_successful_dequeues += count_dequeuer[4 * i + 1]; > > > > + tot_splice += count_dequeuer[4 * i + 2]; > > > > + tot_dequeue_last += count_dequeuer[4 * i + 3]; > > > > } > > > > > > > > - test_end(&end_dequeues); > > > > + test_end(&end_dequeues, &tot_dequeue_last); > > > > > > > > printf_verbose("total number of enqueues : %llu, dequeues %llu\n", > > > > tot_enqueues, tot_dequeues); > > > > printf_verbose("total number of successful enqueues : %llu, " > > > > "enqueues to empty dest : %llu, " > > > > "successful dequeues %llu, " > > > > - "splice : %llu\n", > > > > + "splice : %llu, dequeue_last : %llu\n", > > > > tot_successful_enqueues, > > > > tot_empty_dest_enqueues, > > > > tot_successful_dequeues, > > > > - tot_splice); > > > > + tot_splice, tot_dequeue_last); > > > > printf("SUMMARY %-25s testdur %4lu nr_enqueuers %3u wdelay %6lu " > > > > "nr_dequeuers %3u " > > > > "rdur %6lu nr_enqueues %12llu nr_dequeues %12llu " > > > > "successful enqueues %12llu enqueues to empty dest %12llu " > > > > "successful dequeues %12llu splice %12llu " > > > > + "dequeue_last %llu " > > > > "end_dequeues %llu nr_ops %12llu\n", > > > > argv[0], duration, nr_enqueuers, wdelay, > > > > nr_dequeuers, rduration, tot_enqueues, tot_dequeues, > > > > tot_successful_enqueues, > > > > tot_empty_dest_enqueues, > > > > - tot_successful_dequeues, tot_splice, end_dequeues, > > > > + tot_successful_dequeues, tot_splice, tot_dequeue_last, > > > > + end_dequeues, > > > > tot_enqueues + tot_dequeues); > > > > > > > > if (tot_successful_enqueues != tot_successful_dequeues + end_dequeues) { > > > > @@ -576,12 +590,11 @@ int main(int argc, char **argv) > > > > * exactly as many empty queues than the number of non-empty > > > > * src splice. > > > > */ > > > > - if (test_wait_empty && test_splice && !test_dequeue > > > > - && tot_empty_dest_enqueues != tot_splice) { > > > > + if (tot_empty_dest_enqueues != tot_dequeue_last) { > > > > printf("WARNING! Discrepancy between empty enqueue (%llu) and " > > > > - "number of non-empty splice (%llu)\n", > > > > + "number of dequeue of last element (%llu)\n", > > > > tot_empty_dest_enqueues, > > > > - tot_splice); > > > > + tot_dequeue_last); > > > > retval = 1; > > > > } > > > > free(count_enqueuer); > > > > diff --git a/tests/test_urcu_wfs.c b/tests/test_urcu_wfs.c > > > > index 259ca24..6c54153 100644 > > > > --- a/tests/test_urcu_wfs.c > > > > +++ b/tests/test_urcu_wfs.c > > > > @@ -171,6 +171,7 @@ static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); > > > > static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); > > > > static DEFINE_URCU_TLS(unsigned long long, nr_empty_dest_enqueues); > > > > static DEFINE_URCU_TLS(unsigned long long, nr_pop_all); > > > > +static DEFINE_URCU_TLS(unsigned long long, nr_pop_last); > > > > > > > > static unsigned int nr_enqueuers; > > > > static unsigned int nr_dequeuers; > > > > @@ -230,14 +231,17 @@ fail: > > > > static void do_test_pop(enum test_sync sync) > > > > { > > > > struct cds_wfs_node *node; > > > > + bool last; > > > > > > > > if (sync == TEST_SYNC_MUTEX) > > > > cds_wfs_pop_lock(&s); > > > > - node = __cds_wfs_pop_blocking(&s); > > > > + node = __cds_wfs_pop_blocking(&s, &last); > > > > if (sync == TEST_SYNC_MUTEX) > > > > cds_wfs_pop_unlock(&s); > > > > > > > > if (node) { > > > > + if (last) > > > > + URCU_TLS(nr_pop_last)++; > > > > free(node); > > > > URCU_TLS(nr_successful_dequeues)++; > > > > } > > > > @@ -260,6 +264,7 @@ static void do_test_pop_all(enum test_sync sync) > > > > return; > > > > > > > > URCU_TLS(nr_pop_all)++; > > > > + URCU_TLS(nr_pop_last)++; > > > > > > > > cds_wfs_for_each_blocking_safe(head, node, n) { > > > > free(node); > > > > @@ -308,24 +313,30 @@ static void *thr_dequeuer(void *_count) > > > > > > > > printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " > > > > "dequeues %llu, successful_dequeues %llu " > > > > - "pop_all %llu\n", > > > > + "pop_all %llu pop_last %llu\n", > > > > pthread_self(), > > > > (unsigned long) gettid(), > > > > URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues), > > > > - URCU_TLS(nr_pop_all)); > > > > + URCU_TLS(nr_pop_all), > > > > + URCU_TLS(nr_pop_last)); > > > > count[0] = URCU_TLS(nr_dequeues); > > > > count[1] = URCU_TLS(nr_successful_dequeues); > > > > count[2] = URCU_TLS(nr_pop_all); > > > > + count[3] = URCU_TLS(nr_pop_last); > > > > return ((void*)2); > > > > } > > > > > > > > -static void test_end(struct cds_wfs_stack *s, unsigned long long *nr_dequeues) > > > > +static void test_end(struct cds_wfs_stack *s, unsigned long long *nr_dequeues, > > > > + unsigned long long *nr_pop_last) > > > > { > > > > struct cds_wfs_node *node; > > > > + bool last; > > > > > > > > do { > > > > - node = cds_wfs_pop_blocking(s); > > > > + node = cds_wfs_pop_blocking(s, &last); > > > > if (node) { > > > > + if (last) > > > > + (*nr_pop_last)++; > > > > free(node); > > > > (*nr_dequeues)++; > > > > } > > > > @@ -358,7 +369,7 @@ int main(int argc, char **argv) > > > > unsigned long long tot_successful_enqueues = 0, > > > > tot_successful_dequeues = 0, > > > > tot_empty_dest_enqueues = 0, > > > > - tot_pop_all = 0; > > > > + tot_pop_all = 0, tot_pop_last = 0; > > > > unsigned long long end_dequeues = 0; > > > > int i, a, retval = 0; > > > > > > > > @@ -471,7 +482,7 @@ int main(int argc, char **argv) > > > > tid_enqueuer = malloc(sizeof(*tid_enqueuer) * nr_enqueuers); > > > > tid_dequeuer = malloc(sizeof(*tid_dequeuer) * nr_dequeuers); > > > > count_enqueuer = malloc(3 * sizeof(*count_enqueuer) * nr_enqueuers); > > > > - count_dequeuer = malloc(3 * sizeof(*count_dequeuer) * nr_dequeuers); > > > > + count_dequeuer = malloc(4 * sizeof(*count_dequeuer) * nr_dequeuers); > > > > cds_wfs_init(&s); > > > > > > > > next_aff = 0; > > > > @@ -484,7 +495,7 @@ int main(int argc, char **argv) > > > > } > > > > for (i = 0; i < nr_dequeuers; i++) { > > > > err = pthread_create(&tid_dequeuer[i], NULL, thr_dequeuer, > > > > - &count_dequeuer[3 * i]); > > > > + &count_dequeuer[4 * i]); > > > > if (err != 0) > > > > exit(1); > > > > } > > > > @@ -524,34 +535,36 @@ int main(int argc, char **argv) > > > > err = pthread_join(tid_dequeuer[i], &tret); > > > > if (err != 0) > > > > exit(1); > > > > - tot_dequeues += count_dequeuer[3 * i]; > > > > - tot_successful_dequeues += count_dequeuer[3 * i + 1]; > > > > - tot_pop_all += count_dequeuer[3 * i + 2]; > > > > + tot_dequeues += count_dequeuer[4 * i]; > > > > + tot_successful_dequeues += count_dequeuer[4 * i + 1]; > > > > + tot_pop_all += count_dequeuer[4 * i + 2]; > > > > + tot_pop_last += count_dequeuer[4 * i + 3]; > > > > } > > > > > > > > - test_end(&s, &end_dequeues); > > > > + test_end(&s, &end_dequeues, &tot_pop_last); > > > > > > > > printf_verbose("total number of enqueues : %llu, dequeues %llu\n", > > > > tot_enqueues, tot_dequeues); > > > > printf_verbose("total number of successful enqueues : %llu, " > > > > "enqueues to empty dest : %llu, " > > > > "successful dequeues %llu, " > > > > - "pop_all : %llu\n", > > > > + "pop_all : %llu, pop_last : %llu\n", > > > > tot_successful_enqueues, > > > > tot_empty_dest_enqueues, > > > > tot_successful_dequeues, > > > > - tot_pop_all); > > > > + tot_pop_all, tot_pop_last); > > > > printf("SUMMARY %-25s testdur %4lu nr_enqueuers %3u wdelay %6lu " > > > > "nr_dequeuers %3u " > > > > "rdur %6lu nr_enqueues %12llu nr_dequeues %12llu " > > > > "successful enqueues %12llu enqueues to empty dest %12llu " > > > > "successful dequeues %12llu pop_all %12llu " > > > > - "end_dequeues %llu nr_ops %12llu\n", > > > > + "pop_last %llu end_dequeues %llu nr_ops %12llu\n", > > > > argv[0], duration, nr_enqueuers, wdelay, > > > > nr_dequeuers, rduration, tot_enqueues, tot_dequeues, > > > > tot_successful_enqueues, > > > > tot_empty_dest_enqueues, > > > > - tot_successful_dequeues, tot_pop_all, end_dequeues, > > > > + tot_successful_dequeues, tot_pop_all, tot_pop_last, > > > > + end_dequeues, > > > > tot_enqueues + tot_dequeues); > > > > if (tot_successful_enqueues != tot_successful_dequeues + end_dequeues) { > > > > printf("WARNING! Discrepancy between nr succ. enqueues %llu vs " > > > > @@ -561,16 +574,14 @@ int main(int argc, char **argv) > > > > retval = 1; > > > > } > > > > /* > > > > - * If only using pop_all to dequeue, the enqueuer should see > > > > - * exactly as many empty queues than the number of non-empty > > > > - * stacks dequeued. > > > > + * The enqueuer should see exactly as many empty queues than the > > > > + * number of non-empty stacks dequeued. > > > > */ > > > > - if (test_wait_empty && test_pop_all && !test_pop > > > > - && tot_empty_dest_enqueues != tot_pop_all) { > > > > + if (tot_empty_dest_enqueues != tot_pop_last) { > > > > printf("WARNING! Discrepancy between empty enqueue (%llu) and " > > > > - "number of non-empty pop_all (%llu)\n", > > > > + "number of pop last (%llu)\n", > > > > tot_empty_dest_enqueues, > > > > - tot_pop_all); > > > > + tot_pop_last); > > > > retval = 1; > > > > } > > > > free(count_enqueuer); > > > > diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h > > > > index 4b3535a..33c99ed 100644 > > > > --- a/urcu/static/wfcqueue.h > > > > +++ b/urcu/static/wfcqueue.h > > > > @@ -352,16 +352,23 @@ ___cds_wfcq_next_nonblocking(struct cds_wfcq_head *head, > > > > static inline struct cds_wfcq_node * > > > > ___cds_wfcq_dequeue(struct cds_wfcq_head *head, > > > > struct cds_wfcq_tail *tail, > > > > + bool *last, > > > > int blocking) > > > > { > > > > struct cds_wfcq_node *node, *next; > > > > > > > > - if (_cds_wfcq_empty(head, tail)) > > > > + if (_cds_wfcq_empty(head, tail)) { > > > > + if (last) > > > > + *last = 0; > > > > return NULL; > > > > + } > > > > > > > > node = ___cds_wfcq_node_sync_next(&head->node, blocking); > > > > - if (!blocking && node == CDS_WFCQ_WOULDBLOCK) > > > > + if (!blocking && node == CDS_WFCQ_WOULDBLOCK) { > > > > + if (last) > > > > + *last = 0; > > > > return CDS_WFCQ_WOULDBLOCK; > > > > + } > > > > > > > > if ((next = CMM_LOAD_SHARED(node->next)) == NULL) { > > > > /* > > > > @@ -379,8 +386,11 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, > > > > * content. > > > > */ > > > > _cds_wfcq_node_init(&head->node); > > > > - if (uatomic_cmpxchg(&tail->p, node, &head->node) == node) > > > > + if (uatomic_cmpxchg(&tail->p, node, &head->node) == node) { > > > > + if (last) > > > > + *last = 1; > > > > return node; > > > > + } > > > > next = ___cds_wfcq_node_sync_next(node, blocking); > > > > /* > > > > * In nonblocking mode, if we would need to block to > > > > @@ -389,6 +399,8 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, > > > > */ > > > > if (!blocking && next == CDS_WFCQ_WOULDBLOCK) { > > > > head->node.next = node; > > > > + if (last) > > > > + *last = 0; > > > > return CDS_WFCQ_WOULDBLOCK; > > > > } > > > > } > > > > @@ -400,6 +412,8 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, > > > > > > > > /* Load q->head.next before loading node's content */ > > > > cmm_smp_read_barrier_depends(); > > > > + if (last) > > > > + *last = 0; > > > > return node; > > > > } > > > > > > > > @@ -414,9 +428,9 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, > > > > */ > > > > static inline struct cds_wfcq_node * > > > > ___cds_wfcq_dequeue_blocking(struct cds_wfcq_head *head, > > > > - struct cds_wfcq_tail *tail) > > > > + struct cds_wfcq_tail *tail, bool *last) > > > > { > > > > - return ___cds_wfcq_dequeue(head, tail, 1); > > > > + return ___cds_wfcq_dequeue(head, tail, last, 1); > > > > } > > > > > > > > /* > > > > @@ -427,9 +441,9 @@ ___cds_wfcq_dequeue_blocking(struct cds_wfcq_head *head, > > > > */ > > > > static inline struct cds_wfcq_node * > > > > ___cds_wfcq_dequeue_nonblocking(struct cds_wfcq_head *head, > > > > - struct cds_wfcq_tail *tail) > > > > + struct cds_wfcq_tail *tail, bool *last) > > > > { > > > > - return ___cds_wfcq_dequeue(head, tail, 0); > > > > + return ___cds_wfcq_dequeue(head, tail, last, 0); > > > > } > > > > > > > > /* > > > > @@ -542,12 +556,12 @@ ___cds_wfcq_splice_nonblocking( > > > > */ > > > > static inline struct cds_wfcq_node * > > > > _cds_wfcq_dequeue_blocking(struct cds_wfcq_head *head, > > > > - struct cds_wfcq_tail *tail) > > > > + struct cds_wfcq_tail *tail, bool *last) > > > > { > > > > struct cds_wfcq_node *retval; > > > > > > > > _cds_wfcq_dequeue_lock(head, tail); > > > > - retval = ___cds_wfcq_dequeue_blocking(head, tail); > > > > + retval = ___cds_wfcq_dequeue_blocking(head, tail, last); > > > > _cds_wfcq_dequeue_unlock(head, tail); > > > > return retval; > > > > } > > > > diff --git a/urcu/static/wfstack.h b/urcu/static/wfstack.h > > > > index 9bc9519..2ebda27 100644 > > > > --- a/urcu/static/wfstack.h > > > > +++ b/urcu/static/wfstack.h > > > > @@ -161,23 +161,35 @@ ___cds_wfs_node_sync_next(struct cds_wfs_node *node, int blocking) > > > > > > > > static inline > > > > struct cds_wfs_node * > > > > -___cds_wfs_pop(struct cds_wfs_stack *s, int blocking) > > > > +___cds_wfs_pop(struct cds_wfs_stack *s, bool *last, int blocking) > > > > { > > > > struct cds_wfs_head *head, *new_head; > > > > struct cds_wfs_node *next; > > > > > > > > for (;;) { > > > > head = CMM_LOAD_SHARED(s->head); > > > > - if (___cds_wfs_end(head)) > > > > + if (___cds_wfs_end(head)) { > > > > + if (last) > > > > + *last = 0; > > > > return NULL; > > > > + } > > > > next = ___cds_wfs_node_sync_next(&head->node, blocking); > > > > - if (!blocking && next == CDS_WFS_WOULDBLOCK) > > > > + if (!blocking && next == CDS_WFS_WOULDBLOCK) { > > > > + if (last) > > > > + *last = 0; > > > > return CDS_WFS_WOULDBLOCK; > > > > + } > > > > new_head = caa_container_of(next, struct cds_wfs_head, node); > > > > - if (uatomic_cmpxchg(&s->head, head, new_head) == head) > > > > + if (uatomic_cmpxchg(&s->head, head, new_head) == head) { > > > > + if (last) > > > > + *last = ___cds_wfs_end(new_head); > > > > return &head->node; > > > > - if (!blocking) > > > > + } > > > > + if (!blocking) { > > > > + if (last) > > > > + *last = 0; > > > > return CDS_WFS_WOULDBLOCK; > > > > + } > > > > /* busy-loop if head changed under us */ > > > > } > > > > } > > > > @@ -200,9 +212,9 @@ ___cds_wfs_pop(struct cds_wfs_stack *s, int blocking) > > > > */ > > > > static inline > > > > struct cds_wfs_node * > > > > -___cds_wfs_pop_blocking(struct cds_wfs_stack *s) > > > > +___cds_wfs_pop_blocking(struct cds_wfs_stack *s, bool *last) > > > > { > > > > - return ___cds_wfs_pop(s, 1); > > > > + return ___cds_wfs_pop(s, last, 1); > > > > } > > > > > > > > /* > > > > @@ -213,9 +225,9 @@ ___cds_wfs_pop_blocking(struct cds_wfs_stack *s) > > > > */ > > > > static inline > > > > struct cds_wfs_node * > > > > -___cds_wfs_pop_nonblocking(struct cds_wfs_stack *s) > > > > +___cds_wfs_pop_nonblocking(struct cds_wfs_stack *s, bool *last) > > > > { > > > > - return ___cds_wfs_pop(s, 0); > > > > + return ___cds_wfs_pop(s, last, 0); > > > > } > > > > > > > > /* > > > > @@ -284,12 +296,12 @@ static inline void _cds_wfs_pop_unlock(struct cds_wfs_stack *s) > > > > */ > > > > static inline > > > > struct cds_wfs_node * > > > > -_cds_wfs_pop_blocking(struct cds_wfs_stack *s) > > > > +_cds_wfs_pop_blocking(struct cds_wfs_stack *s, bool *last) > > > > { > > > > struct cds_wfs_node *retnode; > > > > > > > > _cds_wfs_pop_lock(s); > > > > - retnode = ___cds_wfs_pop_blocking(s); > > > > + retnode = ___cds_wfs_pop_blocking(s, last); > > > > _cds_wfs_pop_unlock(s); > > > > return retnode; > > > > } > > > > diff --git a/urcu/wfcqueue.h b/urcu/wfcqueue.h > > > > index b6be9f3..4b9e73b 100644 > > > > --- a/urcu/wfcqueue.h > > > > +++ b/urcu/wfcqueue.h > > > > @@ -197,7 +197,8 @@ extern bool cds_wfcq_enqueue(struct cds_wfcq_head *head, > > > > */ > > > > extern struct cds_wfcq_node *cds_wfcq_dequeue_blocking( > > > > struct cds_wfcq_head *head, > > > > - struct cds_wfcq_tail *tail); > > > > + struct cds_wfcq_tail *tail, > > > > + bool *last); > > > > > > > > /* > > > > * cds_wfcq_splice_blocking: enqueue all src_q nodes at the end of dest_q. > > > > @@ -229,7 +230,8 @@ extern enum cds_wfcq_ret cds_wfcq_splice_blocking( > > > > */ > > > > extern struct cds_wfcq_node *__cds_wfcq_dequeue_blocking( > > > > struct cds_wfcq_head *head, > > > > - struct cds_wfcq_tail *tail); > > > > + struct cds_wfcq_tail *tail, > > > > + bool *last); > > > > > > > > /* > > > > * __cds_wfcq_dequeue_nonblocking: dequeue a node from a wait-free queue. > > > > @@ -239,7 +241,8 @@ extern struct cds_wfcq_node *__cds_wfcq_dequeue_blocking( > > > > */ > > > > extern struct cds_wfcq_node *__cds_wfcq_dequeue_nonblocking( > > > > struct cds_wfcq_head *head, > > > > - struct cds_wfcq_tail *tail); > > > > + struct cds_wfcq_tail *tail, > > > > + bool *last); > > > > > > > > /* > > > > * __cds_wfcq_splice_blocking: enqueue all src_q nodes at the end of dest_q. > > > > diff --git a/urcu/wfstack.h b/urcu/wfstack.h > > > > index 03fee8f..1e4b848 100644 > > > > --- a/urcu/wfstack.h > > > > +++ b/urcu/wfstack.h > > > > @@ -147,7 +147,8 @@ extern int cds_wfs_push(struct cds_wfs_stack *s, struct cds_wfs_node *node); > > > > * > > > > * Calls __cds_wfs_pop_blocking with an internal pop mutex held. > > > > */ > > > > -extern struct cds_wfs_node *cds_wfs_pop_blocking(struct cds_wfs_stack *s); > > > > +extern struct cds_wfs_node *cds_wfs_pop_blocking(struct cds_wfs_stack *s, > > > > + bool *last); > > > > > > > > /* > > > > * cds_wfs_pop_all_blocking: pop all nodes from a stack. > > > > @@ -219,7 +220,8 @@ extern void cds_wfs_pop_unlock(struct cds_wfs_stack *s); > > > > * 3) Ensuring that only ONE thread can call __cds_wfs_pop_blocking() > > > > * and __cds_wfs_pop_all(). (multi-provider/single-consumer scheme). > > > > */ > > > > -extern struct cds_wfs_node *__cds_wfs_pop_blocking(struct cds_wfs_stack *s); > > > > +extern struct cds_wfs_node *__cds_wfs_pop_blocking(struct cds_wfs_stack *s, > > > > + bool *last); > > > > > > > > /* > > > > * __cds_wfs_pop_nonblocking: pop a node from the stack. > > > > @@ -227,7 +229,8 @@ extern struct cds_wfs_node *__cds_wfs_pop_blocking(struct cds_wfs_stack *s); > > > > * Same as __cds_wfs_pop_blocking, but returns CDS_WFS_WOULDBLOCK if > > > > * it needs to block. > > > > */ > > > > -extern struct cds_wfs_node *__cds_wfs_pop_nonblocking(struct cds_wfs_stack *s); > > > > +extern struct cds_wfs_node *__cds_wfs_pop_nonblocking(struct cds_wfs_stack *s, > > > > + bool *last); > > > > > > > > /* > > > > * __cds_wfs_pop_all: pop all nodes from a stack. > > > > diff --git a/wfcqueue.c b/wfcqueue.c > > > > index ab0eb93..7baefdf 100644 > > > > --- a/wfcqueue.c > > > > +++ b/wfcqueue.c > > > > @@ -68,9 +68,10 @@ void cds_wfcq_dequeue_unlock(struct cds_wfcq_head *head, > > > > > > > > struct cds_wfcq_node *cds_wfcq_dequeue_blocking( > > > > struct cds_wfcq_head *head, > > > > - struct cds_wfcq_tail *tail) > > > > + struct cds_wfcq_tail *tail, > > > > + bool *last) > > > > { > > > > - return _cds_wfcq_dequeue_blocking(head, tail); > > > > + return _cds_wfcq_dequeue_blocking(head, tail, last); > > > > } > > > > > > > > enum cds_wfcq_ret cds_wfcq_splice_blocking( > > > > @@ -85,16 +86,18 @@ enum cds_wfcq_ret cds_wfcq_splice_blocking( > > > > > > > > struct cds_wfcq_node *__cds_wfcq_dequeue_blocking( > > > > struct cds_wfcq_head *head, > > > > - struct cds_wfcq_tail *tail) > > > > + struct cds_wfcq_tail *tail, > > > > + bool *last) > > > > { > > > > - return ___cds_wfcq_dequeue_blocking(head, tail); > > > > + return ___cds_wfcq_dequeue_blocking(head, tail, last); > > > > } > > > > > > > > struct cds_wfcq_node *__cds_wfcq_dequeue_nonblocking( > > > > struct cds_wfcq_head *head, > > > > - struct cds_wfcq_tail *tail) > > > > + struct cds_wfcq_tail *tail, > > > > + bool *last) > > > > { > > > > - return ___cds_wfcq_dequeue_nonblocking(head, tail); > > > > + return ___cds_wfcq_dequeue_nonblocking(head, tail, last); > > > > } > > > > > > > > enum cds_wfcq_ret __cds_wfcq_splice_blocking( > > > > diff --git a/wfstack.c b/wfstack.c > > > > index 4ccb6b9..041703b 100644 > > > > --- a/wfstack.c > > > > +++ b/wfstack.c > > > > @@ -48,9 +48,10 @@ int cds_wfs_push(struct cds_wfs_stack *s, struct cds_wfs_node *node) > > > > return _cds_wfs_push(s, node); > > > > } > > > > > > > > -struct cds_wfs_node *cds_wfs_pop_blocking(struct cds_wfs_stack *s) > > > > +struct cds_wfs_node *cds_wfs_pop_blocking(struct cds_wfs_stack *s, > > > > + bool *last) > > > > { > > > > - return _cds_wfs_pop_blocking(s); > > > > + return _cds_wfs_pop_blocking(s, last); > > > > } > > > > > > > > struct cds_wfs_head *cds_wfs_pop_all_blocking(struct cds_wfs_stack *s) > > > > @@ -83,14 +84,16 @@ void cds_wfs_pop_unlock(struct cds_wfs_stack *s) > > > > _cds_wfs_pop_unlock(s); > > > > } > > > > > > > > -struct cds_wfs_node *__cds_wfs_pop_blocking(struct cds_wfs_stack *s) > > > > +struct cds_wfs_node *__cds_wfs_pop_blocking(struct cds_wfs_stack *s, > > > > + bool *last) > > > > { > > > > - return ___cds_wfs_pop_blocking(s); > > > > + return ___cds_wfs_pop_blocking(s, last); > > > > } > > > > > > > > -struct cds_wfs_node *__cds_wfs_pop_nonblocking(struct cds_wfs_stack *s) > > > > +struct cds_wfs_node *__cds_wfs_pop_nonblocking(struct cds_wfs_stack *s, > > > > + bool *last) > > > > { > > > > - return ___cds_wfs_pop_nonblocking(s); > > > > + return ___cds_wfs_pop_nonblocking(s, last); > > > > } > > > > > > > > struct cds_wfs_head *__cds_wfs_pop_all(struct cds_wfs_stack *s) > > > > > > > > -- > > > > Mathieu Desnoyers > > > > Operating System Efficiency R&D Consultant > > > > EfficiOS Inc. > > > > http://www.efficios.com > > > > > > > > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > > > _______________________________________________ > > rp mailing list > > rp at svcs.cs.pdx.edu > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Sun Jan 20 18:08:58 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 20 Jan 2013 18:08:58 -0500 Subject: [lttng-dev] [RFC PATCH v2] wfstack: return whether pop is popping the last element Message-ID: <20130120230858.GB22804@Krystal> Newly introduced "with_state" pop API members return stack state atomically sampled with the pop operation. Allow testing behavior of pop with respect to number of push-to-empty and pop-all-from-non-empty. Signed-off-by: Mathieu Desnoyers --- diff --git a/tests/test_urcu_wfs.c b/tests/test_urcu_wfs.c index 259ca24..9892354 100644 --- a/tests/test_urcu_wfs.c +++ b/tests/test_urcu_wfs.c @@ -171,6 +171,7 @@ static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); static DEFINE_URCU_TLS(unsigned long long, nr_empty_dest_enqueues); static DEFINE_URCU_TLS(unsigned long long, nr_pop_all); +static DEFINE_URCU_TLS(unsigned long long, nr_pop_last); static unsigned int nr_enqueuers; static unsigned int nr_dequeuers; @@ -230,14 +231,17 @@ fail: static void do_test_pop(enum test_sync sync) { struct cds_wfs_node *node; + int state; if (sync == TEST_SYNC_MUTEX) cds_wfs_pop_lock(&s); - node = __cds_wfs_pop_blocking(&s); + node = __cds_wfs_pop_with_state_blocking(&s, &state); if (sync == TEST_SYNC_MUTEX) cds_wfs_pop_unlock(&s); if (node) { + if (state & CDS_WFS_STATE_LAST) + URCU_TLS(nr_pop_last)++; free(node); URCU_TLS(nr_successful_dequeues)++; } @@ -260,6 +264,7 @@ static void do_test_pop_all(enum test_sync sync) return; URCU_TLS(nr_pop_all)++; + URCU_TLS(nr_pop_last)++; cds_wfs_for_each_blocking_safe(head, node, n) { free(node); @@ -308,24 +313,30 @@ static void *thr_dequeuer(void *_count) printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " "dequeues %llu, successful_dequeues %llu " - "pop_all %llu\n", + "pop_all %llu pop_last %llu\n", pthread_self(), (unsigned long) gettid(), URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues), - URCU_TLS(nr_pop_all)); + URCU_TLS(nr_pop_all), + URCU_TLS(nr_pop_last)); count[0] = URCU_TLS(nr_dequeues); count[1] = URCU_TLS(nr_successful_dequeues); count[2] = URCU_TLS(nr_pop_all); + count[3] = URCU_TLS(nr_pop_last); return ((void*)2); } -static void test_end(struct cds_wfs_stack *s, unsigned long long *nr_dequeues) +static void test_end(struct cds_wfs_stack *s, unsigned long long *nr_dequeues, + unsigned long long *nr_pop_last) { struct cds_wfs_node *node; + int state; do { - node = cds_wfs_pop_blocking(s); + node = cds_wfs_pop_with_state_blocking(s, &state); if (node) { + if (state & CDS_WFS_STATE_LAST) + (*nr_pop_last)++; free(node); (*nr_dequeues)++; } @@ -358,7 +369,7 @@ int main(int argc, char **argv) unsigned long long tot_successful_enqueues = 0, tot_successful_dequeues = 0, tot_empty_dest_enqueues = 0, - tot_pop_all = 0; + tot_pop_all = 0, tot_pop_last = 0; unsigned long long end_dequeues = 0; int i, a, retval = 0; @@ -471,7 +482,7 @@ int main(int argc, char **argv) tid_enqueuer = malloc(sizeof(*tid_enqueuer) * nr_enqueuers); tid_dequeuer = malloc(sizeof(*tid_dequeuer) * nr_dequeuers); count_enqueuer = malloc(3 * sizeof(*count_enqueuer) * nr_enqueuers); - count_dequeuer = malloc(3 * sizeof(*count_dequeuer) * nr_dequeuers); + count_dequeuer = malloc(4 * sizeof(*count_dequeuer) * nr_dequeuers); cds_wfs_init(&s); next_aff = 0; @@ -484,7 +495,7 @@ int main(int argc, char **argv) } for (i = 0; i < nr_dequeuers; i++) { err = pthread_create(&tid_dequeuer[i], NULL, thr_dequeuer, - &count_dequeuer[3 * i]); + &count_dequeuer[4 * i]); if (err != 0) exit(1); } @@ -524,34 +535,36 @@ int main(int argc, char **argv) err = pthread_join(tid_dequeuer[i], &tret); if (err != 0) exit(1); - tot_dequeues += count_dequeuer[3 * i]; - tot_successful_dequeues += count_dequeuer[3 * i + 1]; - tot_pop_all += count_dequeuer[3 * i + 2]; + tot_dequeues += count_dequeuer[4 * i]; + tot_successful_dequeues += count_dequeuer[4 * i + 1]; + tot_pop_all += count_dequeuer[4 * i + 2]; + tot_pop_last += count_dequeuer[4 * i + 3]; } - test_end(&s, &end_dequeues); + test_end(&s, &end_dequeues, &tot_pop_last); printf_verbose("total number of enqueues : %llu, dequeues %llu\n", tot_enqueues, tot_dequeues); printf_verbose("total number of successful enqueues : %llu, " "enqueues to empty dest : %llu, " "successful dequeues %llu, " - "pop_all : %llu\n", + "pop_all : %llu, pop_last : %llu\n", tot_successful_enqueues, tot_empty_dest_enqueues, tot_successful_dequeues, - tot_pop_all); + tot_pop_all, tot_pop_last); printf("SUMMARY %-25s testdur %4lu nr_enqueuers %3u wdelay %6lu " "nr_dequeuers %3u " "rdur %6lu nr_enqueues %12llu nr_dequeues %12llu " "successful enqueues %12llu enqueues to empty dest %12llu " "successful dequeues %12llu pop_all %12llu " - "end_dequeues %llu nr_ops %12llu\n", + "pop_last %llu end_dequeues %llu nr_ops %12llu\n", argv[0], duration, nr_enqueuers, wdelay, nr_dequeuers, rduration, tot_enqueues, tot_dequeues, tot_successful_enqueues, tot_empty_dest_enqueues, - tot_successful_dequeues, tot_pop_all, end_dequeues, + tot_successful_dequeues, tot_pop_all, tot_pop_last, + end_dequeues, tot_enqueues + tot_dequeues); if (tot_successful_enqueues != tot_successful_dequeues + end_dequeues) { printf("WARNING! Discrepancy between nr succ. enqueues %llu vs " @@ -561,16 +574,14 @@ int main(int argc, char **argv) retval = 1; } /* - * If only using pop_all to dequeue, the enqueuer should see - * exactly as many empty queues than the number of non-empty - * stacks dequeued. + * The enqueuer should see exactly as many empty queues than the + * number of non-empty stacks dequeued. */ - if (test_wait_empty && test_pop_all && !test_pop - && tot_empty_dest_enqueues != tot_pop_all) { + if (tot_empty_dest_enqueues != tot_pop_last) { printf("WARNING! Discrepancy between empty enqueue (%llu) and " - "number of non-empty pop_all (%llu)\n", + "number of pop last (%llu)\n", tot_empty_dest_enqueues, - tot_pop_all); + tot_pop_last); retval = 1; } free(count_enqueuer); diff --git a/urcu/static/wfstack.h b/urcu/static/wfstack.h index 9bc9519..db0d5b8 100644 --- a/urcu/static/wfstack.h +++ b/urcu/static/wfstack.h @@ -161,29 +161,37 @@ ___cds_wfs_node_sync_next(struct cds_wfs_node *node, int blocking) static inline struct cds_wfs_node * -___cds_wfs_pop(struct cds_wfs_stack *s, int blocking) +___cds_wfs_pop(struct cds_wfs_stack *s, int *state, int blocking) { struct cds_wfs_head *head, *new_head; struct cds_wfs_node *next; + if (state) + *state = 0; for (;;) { head = CMM_LOAD_SHARED(s->head); - if (___cds_wfs_end(head)) + if (___cds_wfs_end(head)) { return NULL; + } next = ___cds_wfs_node_sync_next(&head->node, blocking); - if (!blocking && next == CDS_WFS_WOULDBLOCK) + if (!blocking && next == CDS_WFS_WOULDBLOCK) { return CDS_WFS_WOULDBLOCK; + } new_head = caa_container_of(next, struct cds_wfs_head, node); - if (uatomic_cmpxchg(&s->head, head, new_head) == head) + if (uatomic_cmpxchg(&s->head, head, new_head) == head) { + if (state && ___cds_wfs_end(new_head)) + *state |= CDS_WFS_STATE_LAST; return &head->node; - if (!blocking) + } + if (!blocking) { return CDS_WFS_WOULDBLOCK; + } /* busy-loop if head changed under us */ } } /* - * __cds_wfs_pop_blocking: pop a node from the stack. + * __cds_wfs_pop_with_state_blocking: pop a node from the stack, with state. * * Returns NULL if stack is empty. * @@ -197,12 +205,36 @@ ___cds_wfs_pop(struct cds_wfs_stack *s, int blocking) * __cds_wfs_pop_blocking and __cds_wfs_pop_all callers. * 3) Ensuring that only ONE thread can call __cds_wfs_pop_blocking() * and __cds_wfs_pop_all(). (multi-provider/single-consumer scheme). + * + * "state" saves state flags atomically sampled with pop operation. */ static inline struct cds_wfs_node * +___cds_wfs_pop_with_state_blocking(struct cds_wfs_stack *s, int *state) +{ + return ___cds_wfs_pop(s, state, 1); +} + +static inline +struct cds_wfs_node * ___cds_wfs_pop_blocking(struct cds_wfs_stack *s) { - return ___cds_wfs_pop(s, 1); + return ___cds_wfs_pop_with_state_blocking(s, NULL); +} + +/* + * __cds_wfs_pop_with_state_nonblocking: pop a node from the stack. + * + * Same as __cds_wfs_pop_with_state_blocking, but returns + * CDS_WFS_WOULDBLOCK if it needs to block. + * + * "state" saves state flags atomically sampled with pop operation. + */ +static inline +struct cds_wfs_node * +___cds_wfs_pop_with_state_nonblocking(struct cds_wfs_stack *s, int *state) +{ + return ___cds_wfs_pop(s, state, 0); } /* @@ -215,7 +247,7 @@ static inline struct cds_wfs_node * ___cds_wfs_pop_nonblocking(struct cds_wfs_stack *s) { - return ___cds_wfs_pop(s, 0); + return ___cds_wfs_pop_with_state_nonblocking(s, NULL); } /* @@ -280,21 +312,31 @@ static inline void _cds_wfs_pop_unlock(struct cds_wfs_stack *s) } /* - * Call __cds_wfs_pop_blocking with an internal pop mutex held. + * Call __cds_wfs_pop_with_state_blocking with an internal pop mutex held. */ static inline struct cds_wfs_node * -_cds_wfs_pop_blocking(struct cds_wfs_stack *s) +_cds_wfs_pop_with_state_blocking(struct cds_wfs_stack *s, int *state) { struct cds_wfs_node *retnode; _cds_wfs_pop_lock(s); - retnode = ___cds_wfs_pop_blocking(s); + retnode = ___cds_wfs_pop_with_state_blocking(s, state); _cds_wfs_pop_unlock(s); return retnode; } /* + * Call _cds_wfs_pop_with_state_blocking without saving any state. + */ +static inline +struct cds_wfs_node * +_cds_wfs_pop_blocking(struct cds_wfs_stack *s) +{ + return _cds_wfs_pop_with_state_blocking(s, NULL); +} + +/* * Call __cds_wfs_pop_all with an internal pop mutex held. */ static inline diff --git a/urcu/wfstack.h b/urcu/wfstack.h index 34ddb3f..fc0b44b 100644 --- a/urcu/wfstack.h +++ b/urcu/wfstack.h @@ -60,6 +60,10 @@ extern "C" { #define CDS_WFS_WOULDBLOCK ((void *) -1UL) +enum cds_wfs_state { + CDS_WFS_STATE_LAST = (1U << 0), +}; + /* * struct cds_wfs_node is returned by __cds_wfs_pop, and also used as * iterator on stack. It is not safe to dereference the node next @@ -95,6 +99,7 @@ struct cds_wfs_stack { /* Locking performed internally */ #define cds_wfs_pop_blocking _cds_wfs_pop_blocking +#define cds_wfs_pop_with_state_blocking _cds_wfs_pop_with_state_blocking #define cds_wfs_pop_all_blocking _cds_wfs_pop_all_blocking /* @@ -111,7 +116,11 @@ struct cds_wfs_stack { /* Synchronization ensured by the caller. See synchronization table. */ #define __cds_wfs_pop_blocking ___cds_wfs_pop_blocking +#define __cds_wfs_pop_with_state_blocking \ + ___cds_wfs_pop_with_state_blocking #define __cds_wfs_pop_nonblocking ___cds_wfs_pop_nonblocking +#define __cds_wfs_pop_with_state_nonblocking \ + ___cds_wfs_pop_with_state_nonblocking #define __cds_wfs_pop_all ___cds_wfs_pop_all #else /* !_LGPL_SOURCE */ @@ -152,6 +161,15 @@ extern int cds_wfs_push(struct cds_wfs_stack *s, struct cds_wfs_node *node); extern struct cds_wfs_node *cds_wfs_pop_blocking(struct cds_wfs_stack *s); /* + * cds_wfs_pop_with_state_blocking: pop a node from the stack, with state. + * + * Same as cds_wfs_pop_blocking, but stores whether the stack was + * empty into state (CDS_WFS_STATE_LAST). + */ +extern struct cds_wfs_node * + cds_wfs_pop_with_state_blocking(struct cds_wfs_stack *s, int *state); + +/* * cds_wfs_pop_all_blocking: pop all nodes from a stack. * * Calls __cds_wfs_pop_all with an internal pop mutex held. @@ -224,6 +242,15 @@ extern void cds_wfs_pop_unlock(struct cds_wfs_stack *s); extern struct cds_wfs_node *__cds_wfs_pop_blocking(struct cds_wfs_stack *s); /* + * __cds_wfs_pop_with_state_blocking: pop a node from the stack, with state. + * + * Same as __cds_wfs_pop_blocking, but stores whether the stack was + * empty into state (CDS_WFS_STATE_LAST). + */ +extern struct cds_wfs_node * + __cds_wfs_pop_with_state_blocking(struct cds_wfs_stack *s, int *state); + +/* * __cds_wfs_pop_nonblocking: pop a node from the stack. * * Same as __cds_wfs_pop_blocking, but returns CDS_WFS_WOULDBLOCK if @@ -232,6 +259,16 @@ extern struct cds_wfs_node *__cds_wfs_pop_blocking(struct cds_wfs_stack *s); extern struct cds_wfs_node *__cds_wfs_pop_nonblocking(struct cds_wfs_stack *s); /* + * __cds_wfs_pop_with_state_nonblocking: pop a node from the stack, with state. + * + * Same as __cds_wfs_pop_nonblocking, but stores whether the stack was + * empty into state (CDS_WFS_STATE_LAST). + */ +extern struct cds_wfs_node * + __cds_wfs_pop_with_state_nonblocking(struct cds_wfs_stack *s, + int *state); + +/* * __cds_wfs_pop_all: pop all nodes from a stack. * * __cds_wfs_pop_all does not require any synchronization with other diff --git a/wfstack.c b/wfstack.c index 4ccb6b9..c8bd7e6 100644 --- a/wfstack.c +++ b/wfstack.c @@ -53,6 +53,12 @@ struct cds_wfs_node *cds_wfs_pop_blocking(struct cds_wfs_stack *s) return _cds_wfs_pop_blocking(s); } +struct cds_wfs_node * + cds_wfs_pop_with_state_blocking(struct cds_wfs_stack *s, int *state) +{ + return _cds_wfs_pop_with_state_blocking(s, state); +} + struct cds_wfs_head *cds_wfs_pop_all_blocking(struct cds_wfs_stack *s) { return _cds_wfs_pop_all_blocking(s); @@ -88,11 +94,24 @@ struct cds_wfs_node *__cds_wfs_pop_blocking(struct cds_wfs_stack *s) return ___cds_wfs_pop_blocking(s); } +struct cds_wfs_node * + __cds_wfs_pop_with_state_blocking(struct cds_wfs_stack *s, int *state) +{ + return ___cds_wfs_pop_with_state_blocking(s, state); +} + struct cds_wfs_node *__cds_wfs_pop_nonblocking(struct cds_wfs_stack *s) { return ___cds_wfs_pop_nonblocking(s); } +struct cds_wfs_node * + __cds_wfs_pop_with_state_nonblocking(struct cds_wfs_stack *s, + int *state) +{ + return ___cds_wfs_pop_with_state_nonblocking(s, state); +} + struct cds_wfs_head *__cds_wfs_pop_all(struct cds_wfs_stack *s) { return ___cds_wfs_pop_all(s); -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Sun Jan 20 18:10:14 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 20 Jan 2013 18:10:14 -0500 Subject: [lttng-dev] [RFC PATCH v2] wfcqueue: return whether dequeue is dequeuing last element Message-ID: <20130120231014.GC22804@Krystal> Newly introduced "with_state" dequeue API members return queue state atomically sampled with the dequeue operation. Allow testing behavior of dequeue with respect to number of enqueue-to-empty and splice-from-non-empty. Signed-off-by: Mathieu Desnoyers --- diff --git a/tests/test_urcu_wfcq.c b/tests/test_urcu_wfcq.c index 91285a5..12acc93 100644 --- a/tests/test_urcu_wfcq.c +++ b/tests/test_urcu_wfcq.c @@ -168,6 +168,7 @@ static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); static DEFINE_URCU_TLS(unsigned long long, nr_empty_dest_enqueues); static DEFINE_URCU_TLS(unsigned long long, nr_splice); +static DEFINE_URCU_TLS(unsigned long long, nr_dequeue_last); static unsigned int nr_enqueuers; static unsigned int nr_dequeuers; @@ -228,11 +229,17 @@ fail: static void do_test_dequeue(enum test_sync sync) { struct cds_wfcq_node *node; + int state; if (sync == TEST_SYNC_MUTEX) - node = cds_wfcq_dequeue_blocking(&head, &tail); + node = cds_wfcq_dequeue_with_state_blocking(&head, &tail, + &state); else - node = __cds_wfcq_dequeue_blocking(&head, &tail); + node = __cds_wfcq_dequeue_with_state_blocking(&head, &tail, + &state); + + if (state & CDS_WFCQ_STATE_LAST) + URCU_TLS(nr_dequeue_last)++; if (node) { free(node); @@ -263,6 +270,7 @@ static void do_test_splice(enum test_sync sync) break; case CDS_WFCQ_RET_DEST_EMPTY: URCU_TLS(nr_splice)++; + URCU_TLS(nr_dequeue_last)++; /* ok */ break; case CDS_WFCQ_RET_DEST_NON_EMPTY: @@ -325,16 +333,22 @@ static void *thr_dequeuer(void *_count) count[0] = URCU_TLS(nr_dequeues); count[1] = URCU_TLS(nr_successful_dequeues); count[2] = URCU_TLS(nr_splice); + count[3] = URCU_TLS(nr_dequeue_last); return ((void*)2); } -static void test_end(unsigned long long *nr_dequeues) +static void test_end(unsigned long long *nr_dequeues, + unsigned long long *nr_dequeue_last) { struct cds_wfcq_node *node; + int state; do { - node = cds_wfcq_dequeue_blocking(&head, &tail); + node = cds_wfcq_dequeue_with_state_blocking(&head, &tail, + &state); if (node) { + if (state & CDS_WFCQ_STATE_LAST) + (*nr_dequeue_last)++; free(node); (*nr_dequeues)++; } @@ -367,7 +381,7 @@ int main(int argc, char **argv) unsigned long long tot_successful_enqueues = 0, tot_successful_dequeues = 0, tot_empty_dest_enqueues = 0, - tot_splice = 0; + tot_splice = 0, tot_dequeue_last = 0; unsigned long long end_dequeues = 0; int i, a, retval = 0; @@ -480,7 +494,7 @@ int main(int argc, char **argv) tid_enqueuer = malloc(sizeof(*tid_enqueuer) * nr_enqueuers); tid_dequeuer = malloc(sizeof(*tid_dequeuer) * nr_dequeuers); count_enqueuer = malloc(3 * sizeof(*count_enqueuer) * nr_enqueuers); - count_dequeuer = malloc(3 * sizeof(*count_dequeuer) * nr_dequeuers); + count_dequeuer = malloc(4 * sizeof(*count_dequeuer) * nr_dequeuers); cds_wfcq_init(&head, &tail); next_aff = 0; @@ -493,7 +507,7 @@ int main(int argc, char **argv) } for (i = 0; i < nr_dequeuers; i++) { err = pthread_create(&tid_dequeuer[i], NULL, thr_dequeuer, - &count_dequeuer[3 * i]); + &count_dequeuer[4 * i]); if (err != 0) exit(1); } @@ -533,34 +547,37 @@ int main(int argc, char **argv) err = pthread_join(tid_dequeuer[i], &tret); if (err != 0) exit(1); - tot_dequeues += count_dequeuer[3 * i]; - tot_successful_dequeues += count_dequeuer[3 * i + 1]; - tot_splice += count_dequeuer[3 * i + 2]; + tot_dequeues += count_dequeuer[4 * i]; + tot_successful_dequeues += count_dequeuer[4 * i + 1]; + tot_splice += count_dequeuer[4 * i + 2]; + tot_dequeue_last += count_dequeuer[4 * i + 3]; } - test_end(&end_dequeues); + test_end(&end_dequeues, &tot_dequeue_last); printf_verbose("total number of enqueues : %llu, dequeues %llu\n", tot_enqueues, tot_dequeues); printf_verbose("total number of successful enqueues : %llu, " "enqueues to empty dest : %llu, " "successful dequeues %llu, " - "splice : %llu\n", + "splice : %llu, dequeue_last : %llu\n", tot_successful_enqueues, tot_empty_dest_enqueues, tot_successful_dequeues, - tot_splice); + tot_splice, tot_dequeue_last); printf("SUMMARY %-25s testdur %4lu nr_enqueuers %3u wdelay %6lu " "nr_dequeuers %3u " "rdur %6lu nr_enqueues %12llu nr_dequeues %12llu " "successful enqueues %12llu enqueues to empty dest %12llu " "successful dequeues %12llu splice %12llu " + "dequeue_last %llu " "end_dequeues %llu nr_ops %12llu\n", argv[0], duration, nr_enqueuers, wdelay, nr_dequeuers, rduration, tot_enqueues, tot_dequeues, tot_successful_enqueues, tot_empty_dest_enqueues, - tot_successful_dequeues, tot_splice, end_dequeues, + tot_successful_dequeues, tot_splice, tot_dequeue_last, + end_dequeues, tot_enqueues + tot_dequeues); if (tot_successful_enqueues != tot_successful_dequeues + end_dequeues) { @@ -576,12 +593,11 @@ int main(int argc, char **argv) * exactly as many empty queues than the number of non-empty * src splice. */ - if (test_wait_empty && test_splice && !test_dequeue - && tot_empty_dest_enqueues != tot_splice) { + if (tot_empty_dest_enqueues != tot_dequeue_last) { printf("WARNING! Discrepancy between empty enqueue (%llu) and " - "number of non-empty splice (%llu)\n", + "number of dequeue of last element (%llu)\n", tot_empty_dest_enqueues, - tot_splice); + tot_dequeue_last); retval = 1; } free(count_enqueuer); diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h index 4b3535a..c3f0328 100644 --- a/urcu/static/wfcqueue.h +++ b/urcu/static/wfcqueue.h @@ -350,18 +350,24 @@ ___cds_wfcq_next_nonblocking(struct cds_wfcq_head *head, } static inline struct cds_wfcq_node * -___cds_wfcq_dequeue(struct cds_wfcq_head *head, +___cds_wfcq_dequeue_with_state(struct cds_wfcq_head *head, struct cds_wfcq_tail *tail, + int *state, int blocking) { struct cds_wfcq_node *node, *next; - if (_cds_wfcq_empty(head, tail)) + if (state) + *state = 0; + + if (_cds_wfcq_empty(head, tail)) { return NULL; + } node = ___cds_wfcq_node_sync_next(&head->node, blocking); - if (!blocking && node == CDS_WFCQ_WOULDBLOCK) + if (!blocking && node == CDS_WFCQ_WOULDBLOCK) { return CDS_WFCQ_WOULDBLOCK; + } if ((next = CMM_LOAD_SHARED(node->next)) == NULL) { /* @@ -379,8 +385,11 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, * content. */ _cds_wfcq_node_init(&head->node); - if (uatomic_cmpxchg(&tail->p, node, &head->node) == node) + if (uatomic_cmpxchg(&tail->p, node, &head->node) == node) { + if (state) + *state |= CDS_WFCQ_STATE_LAST; return node; + } next = ___cds_wfcq_node_sync_next(node, blocking); /* * In nonblocking mode, if we would need to block to @@ -404,7 +413,7 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, } /* - * __cds_wfcq_dequeue_blocking: dequeue a node from the queue. + * __cds_wfcq_dequeue_with_state_blocking: dequeue node from queue, with state. * * Content written into the node before enqueue is guaranteed to be * consistent, but no other memory ordering is ensured. @@ -413,23 +422,49 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, * caller. */ static inline struct cds_wfcq_node * +___cds_wfcq_dequeue_with_state_blocking(struct cds_wfcq_head *head, + struct cds_wfcq_tail *tail, int *state) +{ + return ___cds_wfcq_dequeue_with_state(head, tail, state, 1); +} + +/* + * ___cds_wfcq_dequeue_blocking: dequeue node from queue. + * + * Same as __cds_wfcq_dequeue_with_state_blocking, but without saving + * state. + */ +static inline struct cds_wfcq_node * ___cds_wfcq_dequeue_blocking(struct cds_wfcq_head *head, struct cds_wfcq_tail *tail) { - return ___cds_wfcq_dequeue(head, tail, 1); + return ___cds_wfcq_dequeue_with_state_blocking(head, tail, NULL); } /* - * __cds_wfcq_dequeue_nonblocking: dequeue a node from a wait-free queue. + * __cds_wfcq_dequeue_with_state_nonblocking: dequeue node, with state. * * Same as __cds_wfcq_dequeue_blocking, but returns CDS_WFCQ_WOULDBLOCK * if it needs to block. */ static inline struct cds_wfcq_node * +___cds_wfcq_dequeue_with_state_nonblocking(struct cds_wfcq_head *head, + struct cds_wfcq_tail *tail, int *state) +{ + return ___cds_wfcq_dequeue_with_state(head, tail, state, 0); +} + +/* + * ___cds_wfcq_dequeue_nonblocking: dequeue node from queue. + * + * Same as __cds_wfcq_dequeue_with_state_nonblocking, but without saving + * state. + */ +static inline struct cds_wfcq_node * ___cds_wfcq_dequeue_nonblocking(struct cds_wfcq_head *head, struct cds_wfcq_tail *tail) { - return ___cds_wfcq_dequeue(head, tail, 0); + return ___cds_wfcq_dequeue_with_state_nonblocking(head, tail, NULL); } /* @@ -532,7 +567,7 @@ ___cds_wfcq_splice_nonblocking( } /* - * cds_wfcq_dequeue_blocking: dequeue a node from a wait-free queue. + * cds_wfcq_dequeue_with_state_blocking: dequeue a node from a wait-free queue. * * Content written into the node before enqueue is guaranteed to be * consistent, but no other memory ordering is ensured. @@ -541,18 +576,30 @@ ___cds_wfcq_splice_nonblocking( * It is valid to reuse and free a dequeued node immediately. */ static inline struct cds_wfcq_node * -_cds_wfcq_dequeue_blocking(struct cds_wfcq_head *head, - struct cds_wfcq_tail *tail) +_cds_wfcq_dequeue_with_state_blocking(struct cds_wfcq_head *head, + struct cds_wfcq_tail *tail, int *state) { struct cds_wfcq_node *retval; _cds_wfcq_dequeue_lock(head, tail); - retval = ___cds_wfcq_dequeue_blocking(head, tail); + retval = ___cds_wfcq_dequeue_with_state_blocking(head, tail, state); _cds_wfcq_dequeue_unlock(head, tail); return retval; } /* + * cds_wfcq_dequeue_blocking: dequeue node from queue. + * + * Same as cds_wfcq_dequeue_blocking, but without saving state. + */ +static inline struct cds_wfcq_node * +_cds_wfcq_dequeue_blocking(struct cds_wfcq_head *head, + struct cds_wfcq_tail *tail) +{ + return _cds_wfcq_dequeue_with_state_blocking(head, tail, NULL); +} + +/* * cds_wfcq_splice_blocking: enqueue all src_q nodes at the end of dest_q. * * Dequeue all nodes from src_q. diff --git a/urcu/wfcqueue.h b/urcu/wfcqueue.h index b6be9f3..5dcf07e 100644 --- a/urcu/wfcqueue.h +++ b/urcu/wfcqueue.h @@ -52,6 +52,10 @@ enum cds_wfcq_ret { CDS_WFCQ_RET_SRC_EMPTY = 2, }; +enum cds_wfcq_state { + CDS_WFCQ_STATE_LAST = (1U << 0), +}; + struct cds_wfcq_node { struct cds_wfcq_node *next; }; @@ -85,12 +89,16 @@ struct cds_wfcq_tail { /* Locking performed within cds_wfcq calls. */ #define cds_wfcq_dequeue_blocking _cds_wfcq_dequeue_blocking +#define cds_wfcq_dequeue_with_state_blocking \ + _cds_wfcq_dequeue_with_state_blocking #define cds_wfcq_splice_blocking _cds_wfcq_splice_blocking #define cds_wfcq_first_blocking _cds_wfcq_first_blocking #define cds_wfcq_next_blocking _cds_wfcq_next_blocking /* Locking ensured by caller by holding cds_wfcq_dequeue_lock() */ #define __cds_wfcq_dequeue_blocking ___cds_wfcq_dequeue_blocking +#define __cds_wfcq_dequeue_with_state_blocking \ + ___cds_wfcq_dequeue_with_state_blocking #define __cds_wfcq_splice_blocking ___cds_wfcq_splice_blocking #define __cds_wfcq_first_blocking ___cds_wfcq_first_blocking #define __cds_wfcq_next_blocking ___cds_wfcq_next_blocking @@ -101,6 +109,8 @@ struct cds_wfcq_tail { * need to block. splice returns nonzero if it needs to block. */ #define __cds_wfcq_dequeue_nonblocking ___cds_wfcq_dequeue_nonblocking +#define __cds_wfcq_dequeue_with_state_nonblocking \ + ___cds_wfcq_dequeue_with_state_nonblocking #define __cds_wfcq_splice_nonblocking ___cds_wfcq_splice_nonblocking #define __cds_wfcq_first_nonblocking ___cds_wfcq_first_nonblocking #define __cds_wfcq_next_nonblocking ___cds_wfcq_next_nonblocking @@ -200,6 +210,17 @@ extern struct cds_wfcq_node *cds_wfcq_dequeue_blocking( struct cds_wfcq_tail *tail); /* + * cds_wfcq_dequeue_with_state_blocking: dequeue with state. + * + * Same as cds_wfcq_dequeue_blocking, but saves whether dequeueing the + * last node of the queue into state (CDS_WFCQ_STATE_LAST). + */ +extern struct cds_wfcq_node *cds_wfcq_dequeue_with_state_blocking( + struct cds_wfcq_head *head, + struct cds_wfcq_tail *tail, + int *state); + +/* * cds_wfcq_splice_blocking: enqueue all src_q nodes at the end of dest_q. * * Dequeue all nodes from src_q. @@ -232,6 +253,17 @@ extern struct cds_wfcq_node *__cds_wfcq_dequeue_blocking( struct cds_wfcq_tail *tail); /* + * __cds_wfcq_dequeue_with_state_blocking: dequeue with state. + * + * Same as __cds_wfcq_dequeue_blocking, but saves whether dequeueing the + * last node of the queue into state (CDS_WFCQ_STATE_LAST). + */ +extern struct cds_wfcq_node *__cds_wfcq_dequeue_with_state_blocking( + struct cds_wfcq_head *head, + struct cds_wfcq_tail *tail, + int *state); + +/* * __cds_wfcq_dequeue_nonblocking: dequeue a node from a wait-free queue. * * Same as __cds_wfcq_dequeue_blocking, but returns CDS_WFCQ_WOULDBLOCK @@ -242,6 +274,17 @@ extern struct cds_wfcq_node *__cds_wfcq_dequeue_nonblocking( struct cds_wfcq_tail *tail); /* + * __cds_wfcq_dequeue_with_state_blocking: dequeue with state. + * + * Same as __cds_wfcq_dequeue_nonblocking, but saves whether dequeueing + * the last node of the queue into state (CDS_WFCQ_STATE_LAST). + */ +extern struct cds_wfcq_node *__cds_wfcq_dequeue_with_state_nonblocking( + struct cds_wfcq_head *head, + struct cds_wfcq_tail *tail, + int *state); + +/* * __cds_wfcq_splice_blocking: enqueue all src_q nodes at the end of dest_q. * * Dequeue all nodes from src_q. diff --git a/wfcqueue.c b/wfcqueue.c index ab0eb93..4950c10 100644 --- a/wfcqueue.c +++ b/wfcqueue.c @@ -73,6 +73,14 @@ struct cds_wfcq_node *cds_wfcq_dequeue_blocking( return _cds_wfcq_dequeue_blocking(head, tail); } +struct cds_wfcq_node *cds_wfcq_dequeue_with_state_blocking( + struct cds_wfcq_head *head, + struct cds_wfcq_tail *tail, + int *state) +{ + return _cds_wfcq_dequeue_with_state_blocking(head, tail, state); +} + enum cds_wfcq_ret cds_wfcq_splice_blocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, @@ -90,6 +98,14 @@ struct cds_wfcq_node *__cds_wfcq_dequeue_blocking( return ___cds_wfcq_dequeue_blocking(head, tail); } +struct cds_wfcq_node *__cds_wfcq_dequeue_with_state_blocking( + struct cds_wfcq_head *head, + struct cds_wfcq_tail *tail, + int *state) +{ + return ___cds_wfcq_dequeue_with_state_blocking(head, tail, state); +} + struct cds_wfcq_node *__cds_wfcq_dequeue_nonblocking( struct cds_wfcq_head *head, struct cds_wfcq_tail *tail) @@ -97,6 +113,14 @@ struct cds_wfcq_node *__cds_wfcq_dequeue_nonblocking( return ___cds_wfcq_dequeue_nonblocking(head, tail); } +struct cds_wfcq_node *__cds_wfcq_dequeue_with_state_nonblocking( + struct cds_wfcq_head *head, + struct cds_wfcq_tail *tail, + int *state) +{ + return ___cds_wfcq_dequeue_with_state_nonblocking(head, tail, state); +} + enum cds_wfcq_ret __cds_wfcq_splice_blocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From tailai.ly at alibaba-inc.com Sun Jan 20 00:42:40 2013 From: tailai.ly at alibaba-inc.com (=?UTF-8?B?5rOw5p2l?=) Date: Sun, 20 Jan 2013 13:42:40 +0800 Subject: [lttng-dev] Query on the rcu red-black tree status Message-ID: <50FB83D0.8010908@alibaba-inc.com> Hi List I am developer of Sheepdog project, which is a heavy user of urcu library. I noticed there is a branch which implement rcu red-black tree and it seems to halt on the late 2011. Is there roadmap to merge this into master branch? Thanks, Yuan From mathieu.desnoyers at efficios.com Sun Jan 20 20:05:50 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 20 Jan 2013 20:05:50 -0500 Subject: [lttng-dev] Query on the rcu red-black tree status In-Reply-To: <50FB83D0.8010908@alibaba-inc.com> References: <50FB83D0.8010908@alibaba-inc.com> Message-ID: <20130121010550.GA2364@Krystal> * ?? (tailai.ly at alibaba-inc.com) wrote: > Hi List > > I am developer of Sheepdog project, which is a heavy user of urcu > library. I noticed there is a branch which implement rcu red-black tree > and it seems to halt on the late 2011. Is there roadmap to merge this > into master branch? Hi Yuan, There are a couple of factors that are making me uncomfortable with pulling the RCU red-black tree (single-producer, multiple RCU consumers Red Black tree) into the Userspace RCU master branch at this point. It might be a good think to bring them up for discussion: 1) My own understanding of the code is not sufficient to vouch for it. The code, which has been sitting here since late 2011: git://git.lttng.org/userspace-rcu.git branch: rbtree2 Files: urcu/rcurbtree.h (API) urcu-rbtree.c (implementation) tests/test_urcu_rbtree.c (tests, example usage) I implemented this code to show that it is possible to implement a red-black tree that allows completely wait-free RCU readers, but along the way, the code grew to a certain level of complexity. For instance, I could not say that I would be comfortable to do changes to it without very thorough testing. I don't currently feel confident about my own ability to understand each corner-case of this code. If something breaks, the turn-around time to identify the fault might be unacceptably long. 2) Lack of review. If I look at my recent experience with the wait-free and lock-free queues and stack, as well as with the RCU lock-free hash table, a lot of review, discussion about semantics, added testing from many people, as well as feedback from API users are all necessary to get to a point where we can feel comfortable with the implementation, the level of documentation, as well as the API per se. I don't think the RCU red-black tree is at this level yet. 3) Not tested thoroughly enough for my own standards. Even though I created some stress-tests for the data structure that make me rather confident that it works well, we would need to farther in terms of test-cases: creating customized stress-tests that purposefully stress specific aspects of the data structure (e.g. corner-cases that happen rarely) would increase my own confidence in the quality of the implementation. 4) No user so far. This is always a chicken-and-egg problem: we need users to get feedback on the API, but as soon as we settle on an API and release a version with it, it becomes very painful to change it (in fact, we create new APIs and slowly deprecate an old one rather than break an API). So, ideally, I prefer to wait until some users actually show interest (like you are currently doing) before I merge APIs into the master branch. This lets us do some back-and-forth and allow the API to evolve before we finalize it. 5) I am currently working on other, similar data structures As you are probably aware, I am currently working on a RCU implementation of Judy Arrays, which target Multiple-Producers Multiple-Consumers use-cases. The design is well underway, but the implementation is far from complete (I do this part-time as a research track within my own company). At some point, I want to compare the RBtree and RCU judy array implementations in terms of performance, scalability, real-time behavior, and other aspects. I feel it is important that we compare those, and learn from this comparison, before pushing those data structures into production. Thoughts, comments, and feedback are welcome! Thanks, Mathieu > > Thanks, > Yuan -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From tailai.ly at alibaba-inc.com Sun Jan 20 20:51:08 2013 From: tailai.ly at alibaba-inc.com (=?UTF-8?B?5rOw5p2l?=) Date: Mon, 21 Jan 2013 09:51:08 +0800 Subject: [lttng-dev] Query on the rcu red-black tree status In-Reply-To: <20130121010550.GA2364@Krystal> References: <50FB83D0.8010908@alibaba-inc.com> <20130121010550.GA2364@Krystal> Message-ID: <50FC9F0C.9090404@alibaba-inc.com> On 01/21/2013 09:05 AM, Mathieu Desnoyers wrote: > * ?? (tailai.ly at alibaba-inc.com) wrote: >> Hi List >> >> I am developer of Sheepdog project, which is a heavy user of urcu >> library. I noticed there is a branch which implement rcu red-black tree >> and it seems to halt on the late 2011. Is there roadmap to merge this >> into master branch? > > Hi Yuan, > > There are a couple of factors that are making me uncomfortable with > pulling the RCU red-black tree (single-producer, multiple RCU consumers > Red Black tree) into the Userspace RCU master branch at this point. > It might be a good think to bring them up for discussion: > > 1) My own understanding of the code is not sufficient to vouch for it. > > The code, which has been sitting here since late 2011: > > git://git.lttng.org/userspace-rcu.git branch: rbtree2 > > Files: > > urcu/rcurbtree.h (API) > urcu-rbtree.c (implementation) > tests/test_urcu_rbtree.c (tests, example usage) > > I implemented this code to show that it is possible to implement a > red-black tree that allows completely wait-free RCU readers, but along > the way, the code grew to a certain level of complexity. For instance, I > could not say that I would be comfortable to do changes to it without > very thorough testing. I don't currently feel confident about my own > ability to understand each corner-case of this code. If something > breaks, the turn-around time to identify the fault might be unacceptably > long. > > 2) Lack of review. > > If I look at my recent experience with the wait-free and lock-free > queues and stack, as well as with the RCU lock-free hash table, a lot of > review, discussion about semantics, added testing from many people, as > well as feedback from API users are all necessary to get to a point > where we can feel comfortable with the implementation, the level of > documentation, as well as the API per se. I don't think the RCU > red-black tree is at this level yet. > > 3) Not tested thoroughly enough for my own standards. > > Even though I created some stress-tests for the data structure that make > me rather confident that it works well, we would need to farther in > terms of test-cases: creating customized stress-tests that purposefully > stress specific aspects of the data structure (e.g. corner-cases that > happen rarely) would increase my own confidence in the quality of the > implementation. > > 4) No user so far. > > This is always a chicken-and-egg problem: we need users to get feedback > on the API, but as soon as we settle on an API and release a version > with it, it becomes very painful to change it (in fact, we create new > APIs and slowly deprecate an old one rather than break an API). So, > ideally, I prefer to wait until some users actually show interest (like > you are currently doing) before I merge APIs into the master branch. > This lets us do some back-and-forth and allow the API to evolve before > we finalize it. > > 5) I am currently working on other, similar data structures > > As you are probably aware, I am currently working on a RCU > implementation of Judy Arrays, which target Multiple-Producers > Multiple-Consumers use-cases. The design is well underway, but the > implementation is far from complete (I do this part-time as a research > track within my own company). At some point, I want to compare the > RBtree and RCU judy array implementations in terms of performance, > scalability, real-time behavior, and other aspects. I feel it is > important that we compare those, and learn from this comparison, before > pushing those data structures into production. > > Thoughts, comments, and feedback are welcome! > > Thanks, > Hi Mathieu Thanks for your detailed explanation and I have taken note of it. Judy Arrays looks more powerful, looks forward to seeing it in a production level. Thanks, Yuan From namei.unix at gmail.com Sun Jan 20 21:01:39 2013 From: namei.unix at gmail.com (Liu Yuan) Date: Mon, 21 Jan 2013 10:01:39 +0800 Subject: [lttng-dev] Query on the rculist Message-ID: <50FCA183.8030201@gmail.com> Hi List, I noticed that there are just few functions suffixed with rcu for rculist. And from the source of Linux kernel rculist, I came up with some comments saying that list_empty_rcu() can be simply achieved by calling list_empty(). Is this true to urcu too? My questions is, are following equivalents true? list_empty_rcu -> list_empty list_del_init_rcu -> list_del_init If there are more equivalents, please show light on it. Thanks, Yuan From amit.balboul at shinesec.com Mon Jan 21 06:48:51 2013 From: amit.balboul at shinesec.com (Amit Balboul) Date: Mon, 21 Jan 2013 13:48:51 +0200 Subject: [lttng-dev] lttng on android Message-ID: Hi, Is there a way to build the LTTng tools to Android (3.0.31) on ARM ?? I've managed to compile the modules(2.0.6), put them in the Android device and modprobe them. Now I would like to extract the traces logs from the device. How can I do it ? Is there any support for this at all in the LTTng project ? Thank you for your response ! Amit. -------------- next part -------------- An HTML attachment was scrubbed... URL: From mathieu.desnoyers at efficios.com Mon Jan 21 09:16:46 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 21 Jan 2013 09:16:46 -0500 Subject: [lttng-dev] Query on the rculist In-Reply-To: <50FCA183.8030201@gmail.com> References: <50FCA183.8030201@gmail.com> Message-ID: <20130121141645.GB31140@Krystal> * Liu Yuan (namei.unix at gmail.com) wrote: > Hi List, > > I noticed that there are just few functions suffixed with rcu for > rculist. And from the source of Linux kernel rculist, I came up with > some comments saying that list_empty_rcu() can be simply achieved by > calling list_empty(). Is this true to urcu too? My questions is, are > following equivalents true? > > list_empty_rcu -> list_empty Yes. > list_del_init_rcu -> list_del_init No. > > If there are more equivalents, please show light on it. I will prepare a patch to extend and document the list and rculist APIs. Your feedback is welcome. Thanks! Mathieu > > Thanks, > Yuan -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon Jan 21 09:23:02 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 21 Jan 2013 09:23:02 -0500 Subject: [lttng-dev] [PATCH urcu] expand and cleanup list.h and rculist.h Message-ID: <20130121142302.GA32570@Krystal> Cleanup urcu/list.h and urcu/rculist.h: adopt Userspace RCU project coding style, comment each function thoroughly. Add the following API members: - cds_list_for_each_safe() - cds_list_for_each_entry_reverse_safe() - cds_list_add_tail_rcu() Document that cds_list_empty() can be used on RCU lists without protection. Signed-off-by: Mathieu Desnoyers --- diff --git a/urcu/list.h b/urcu/list.h index 5d04394..f1fece4 100644 --- a/urcu/list.h +++ b/urcu/list.h @@ -5,7 +5,7 @@ * * Copyright (C) 2009 Pierre-Marc Fournier * Conversion to RCU list. - * Copyright (C) 2010 Mathieu Desnoyers + * Copyright (C) 2010-2013 Mathieu Desnoyers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,86 +25,124 @@ #ifndef _CDS_LIST_H #define _CDS_LIST_H 1 -/* The definitions of this file are adopted from those which can be - found in the Linux kernel headers to enable people familiar with - the latter find their way in these sources as well. */ - +/* + * The definitions of this file are adopted from those which can be + * found in the Linux kernel headers to enable people familiar with the + * latter find their way in these sources as well. + */ -/* Basic type for the double-link list. */ -struct cds_list_head -{ - struct cds_list_head *next; - struct cds_list_head *prev; +/* Basic type for the double-link list. */ +struct cds_list_head { + struct cds_list_head *next; + struct cds_list_head *prev; }; +/* Define a variable with the head and tail of the list. */ +#define CDS_LIST_HEAD(name) \ + struct cds_list_head name = CDS_LIST_HEAD_INIT(name) -/* Define a variable with the head and tail of the list. */ -#define CDS_LIST_HEAD(name) \ - struct cds_list_head name = { &(name), &(name) } - -/* Initialize a new list head. */ -#define CDS_INIT_LIST_HEAD(ptr) \ - (ptr)->next = (ptr)->prev = (ptr) - -#define CDS_LIST_HEAD_INIT(name) { .prev = &(name), .next = &(name) } +#define CDS_LIST_HEAD_INIT(name) { .prev = &(name), .next = &(name) } -/* Add new element at the head of the list. */ -static inline void -cds_list_add (struct cds_list_head *newp, struct cds_list_head *head) +/* + * @CSD_INIT_LIST_HEAD: Initialize a new list head. + * @head: head of list to initialize. + */ +static inline +void CDS_INIT_LIST_HEAD(struct cds_list_head *head) { - head->next->prev = newp; - newp->next = head->next; - newp->prev = head; - head->next = newp; + head->next = head; + head->prev = head; } - -/* Add new element at the tail of the list. */ -static inline void -cds_list_add_tail (struct cds_list_head *newp, struct cds_list_head *head) +/* + * cds_list_add: Add new element at the head of the list. + * @newp: new element. + * @head: list head. + * + * Mutual exclusion against other updates and reads to list is required. + */ +static inline +void cds_list_add(struct cds_list_head *newp, struct cds_list_head *head) { - head->prev->next = newp; - newp->next = head; - newp->prev = head->prev; - head->prev = newp; + head->next->prev = newp; + newp->next = head->next; + newp->prev = head; + head->next = newp; } +/* + * cds_list_add_tail: Add new element at the tail of the list. + * @newp: new element. + * @head: list head. + * + * Mutual exclusion against other updates and reads to list is required. + */ +static inline +void cds_list_add_tail(struct cds_list_head *newp, struct cds_list_head *head) +{ + head->prev->next = newp; + newp->next = head; + newp->prev = head->prev; + head->prev = newp; +} -/* Remove element from list. */ -static inline void -__cds_list_del (struct cds_list_head *prev, struct cds_list_head *next) +static inline +void __cds_list_del(struct cds_list_head *prev, struct cds_list_head *next) { - next->prev = prev; - prev->next = next; + next->prev = prev; + prev->next = next; } -/* Remove element from list. */ -static inline void -cds_list_del (struct cds_list_head *elem) +/* + * cds_list_del: Remove element from list. + * @elem: element to remove. + * + * Mutual exclusion against other updates and reads to list is required. + */ +static inline +void cds_list_del(struct cds_list_head *elem) { - __cds_list_del (elem->prev, elem->next); + __cds_list_del(elem->prev, elem->next); } -/* Remove element from list, initializing the element's list pointers. */ -static inline void -cds_list_del_init (struct cds_list_head *elem) +/* + * cds_list_del_init: Remove element from list, init element. + * @elem: element to remove. + * + * Remove element from list, initializing the element's list pointers. + * Mutual exclusion against other updates and reads to list is required. + */ +static inline +void cds_list_del_init(struct cds_list_head *elem) { cds_list_del(elem); CDS_INIT_LIST_HEAD(elem); } -/* delete from list, add to another list as head */ -static inline void -cds_list_move (struct cds_list_head *elem, struct cds_list_head *head) +/* + * cds_list_move: Delete from list, add to another list as head. + * @elem: element to move. + * @head: head of list to move into. + * + * Mutual exclusion against other updates and reads to both lists is + * required. + */ +static inline +void cds_list_move(struct cds_list_head *elem, struct cds_list_head *head) { - __cds_list_del (elem->prev, elem->next); - cds_list_add (elem, head); + __cds_list_del(elem->prev, elem->next); + cds_list_add(elem, head); } -/* replace an old entry. +/* + * cds_list_replace: replace an old entry. + * @old: old entry. + * @_new: new entry. + * + * Mutual exclusion against other updates and reads to list is required. */ -static inline void -cds_list_replace(struct cds_list_head *old, struct cds_list_head *_new) +static inline +void cds_list_replace(struct cds_list_head *old, struct cds_list_head *_new) { _new->next = old->next; _new->prev = old->prev; @@ -112,75 +150,192 @@ cds_list_replace(struct cds_list_head *old, struct cds_list_head *_new) _new->next->prev = _new; } -/* Join two lists. */ -static inline void -cds_list_splice (struct cds_list_head *add, struct cds_list_head *head) +/* + * cds_list_empty: returns whether list is empty + * + * Return nonzero if list is empty, zero otherwise. + * cds_list_empty() can be used on RCU lists. RCU read-side lock is not + * required. + */ +static inline +int cds_list_empty(struct cds_list_head *head) { - /* Do nothing if the list which gets added is empty. */ - if (add != add->next) - { - add->next->prev = head; - add->prev->next = head->next; - head->next->prev = add->prev; - head->next = add->next; - } + return head == head->next; } -/* Get typed element from list at a given position. */ -#define cds_list_entry(ptr, type, member) \ - ((type *) ((char *) (ptr) - (unsigned long) (&((type *) 0)->member))) - +/* + * cds_list_splice: Join two lists. + * @add: head of list to merge into @head. + * @head: head of list to be merged into. + * + * Merge @add into @head. + * Mutual exclusion against other updates and reads to both lists is + * required. + */ +static inline +void cds_list_splice(struct cds_list_head *add, struct cds_list_head *head) +{ + /* Do nothing if the list which gets added is empty. */ + if (cds_list_empty(add)) + return; + add->next->prev = head; + add->prev->next = head->next; + head->next->prev = add->prev; + head->next = add->next; +} -/* Get first entry from a list. */ -#define cds_list_first_entry(ptr, type, member) \ - cds_list_entry((ptr)->next, type, member) +/* + * cds_list_replace_init: replace old entry by new one, init new entry. + * @old: old entry to replace. + * @_new: new entry to replace with. + * + * Mutual exclusion against other updates and reads to list is required. + */ +static inline +void cds_list_replace_init(struct cds_list_head *old, + struct cds_list_head *_new) +{ + struct cds_list_head *head = old->next; + cds_list_del(old); + cds_list_add_tail(_new, head); + CDS_INIT_LIST_HEAD(old); +} +/* + * cds_list_entry: Get typed element from list at a given position. + * @ptr: node pointer (struct cds_list_head *). + * @type: type containing the list node field. + * @member: field name of list node within containing type. + */ +#define cds_list_entry(ptr, type, member) \ + ((type *) ((char *) (ptr) - (unsigned long) (&((type *) 0)->member))) -/* Iterate forward over the elements of the list. */ -#define cds_list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) +/* + * cds_list_first_entry: Get first entry from a list. + * @head: list head (struct cds_list_head *). + * @type: type containing the list node field. + * @member: field name of list node within containing type. + * + * This should *not* be used on an empty list. Test for list emptiness + * before using @cds_list_first_entry. + */ +#define cds_list_first_entry(head, type, member) \ + cds_list_entry((head)->next, type, member) +/* + * cds_list_for_each: Iterate forward over the elements of the list. + * @pos: pointer to use as iterator (struct cds_list_head *). + * @head: list head (struct cds_list_head *). + * + * Mutual exclusion against updates to list is required. + * It is not safe to remove elements within loop iteration. + */ +#define cds_list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); pos = pos->next) -/* Iterate backward over the elements of the list. */ -#define cds_list_for_each_prev(pos, head) \ - for (pos = (head)->prev; pos != (head); pos = pos->prev) +/* + * cds_list_for_each_safe: Iterate forward, safe against removal. + * @pos: pointer to use as iterator (struct cds_list_head *). + * @p: temporary pointer to store @pos copy (struct cds_list_head *). + * @head: list head (struct cds_list_head *). + * + * Mutual exclusion against updates to list is required. + * The list elements can be removed from the list within loop iteration. + */ +#define cds_list_for_each_safe(pos, p, head) \ + for (pos = (head)->next, p = pos->next; \ + pos != (head); \ + pos = p; p = pos->next) +/* + * cds_list_for_each_prev: Iterate backward over the elements of the list. + * @pos: pointer to use as iterator (struct cds_list_head *). + * @head: list head (struct cds_list_head *). + * + * Mutual exclusion against updates to list is required. + * It is not safe to remove elements within loop iteration. + */ +#define cds_list_for_each_prev(pos, head) \ + for (pos = (head)->prev; pos != (head); pos = pos->prev) -/* Iterate backwards over the elements list. The list elements can be - removed from the list while doing this. */ -#define cds_list_for_each_prev_safe(pos, p, head) \ - for (pos = (head)->prev, p = pos->prev; \ - pos != (head); \ - pos = p, p = pos->prev) +/* + * cds_list_for_each_prev_safe: Iterate backwards, safe against removal. + * @pos: pointer to use as iterator (struct cds_list_head *). + * @p: temporary pointer to store @pos copy (struct cds_list_head *). + * @head: list head (struct cds_list_head *). + * + * Mutual exclusion against updates to list is required. + * The list elements can be removed from the list within loop iteration. + */ +#define cds_list_for_each_prev_safe(pos, p, head) \ + for (pos = (head)->prev, p = pos->prev; \ + pos != (head); \ + pos = p, p = pos->prev) -#define cds_list_for_each_entry(pos, head, member) \ +/* + * cds_list_for_each_entry: Iterate forward over entries of the list. + * @pos: pointer to use as iterator (type of list node container). + * @head: list head (struct cds_list_head *). + * @member: field name of list node field within container type. + * + * Mutual exclusion against updates to list is required. + * It is not safe to remove elements within loop iteration. + */ +#define cds_list_for_each_entry(pos, head, member) \ for (pos = cds_list_entry((head)->next, __typeof__(*pos), member); \ - &pos->member != (head); \ - pos = cds_list_entry(pos->member.next, __typeof__(*pos), member)) + &pos->member != (head); \ + pos = cds_list_entry(pos->member.next, \ + __typeof__(*pos), member)) -#define cds_list_for_each_entry_reverse(pos, head, member) \ +/* + * cds_list_for_each_entry_reverse: Iterate backwards over entries of the list. + * @pos: pointer to use as iterator (type of list node container). + * @head: list head (struct cds_list_head *). + * @member: field name of list node field within container type. + * + * Mutual exclusion against updates to list is required. + * It is not safe to remove elements within loop iteration. + */ +#define cds_list_for_each_entry_reverse(pos, head, member) \ for (pos = cds_list_entry((head)->prev, __typeof__(*pos), member); \ - &pos->member != (head); \ - pos = cds_list_entry(pos->member.prev, __typeof__(*pos), member)) + &pos->member != (head); \ + pos = cds_list_entry(pos->member.prev, \ + __typeof__(*pos), member)) -#define cds_list_for_each_entry_safe(pos, p, head, member) \ +/* + * cds_list_for_each_entry_safe: Iterate forward, safe against removal. + * @pos: pointer to use as iterator (pointer to list node container). + * @p: temporary pointer to store @pos copy (pointer to list node container). + * @head: list head (struct cds_list_head *). + * @member: field name of list node field within container type. + * + * Mutual exclusion against updates to list is required. + * The list elements can be removed from the list within loop iteration. + */ +#define cds_list_for_each_entry_safe(pos, p, head, member) \ for (pos = cds_list_entry((head)->next, __typeof__(*pos), member), \ - p = cds_list_entry(pos->member.next, __typeof__(*pos), member); \ - &pos->member != (head); \ - pos = p, p = cds_list_entry(pos->member.next, __typeof__(*pos), member)) + p = cds_list_entry(pos->member.next, \ + __typeof__(*pos), member); \ + &pos->member != (head); \ + pos = p, p = cds_list_entry(pos->member.next, \ + __typeof__(*pos), member)) -static inline int cds_list_empty(struct cds_list_head *head) -{ - return head == head->next; -} - -static inline void cds_list_replace_init(struct cds_list_head *old, - struct cds_list_head *_new) -{ - struct cds_list_head *head = old->next; - cds_list_del(old); - cds_list_add_tail(_new, head); - CDS_INIT_LIST_HEAD(old); -} +/* + * cds_list_for_each_entry_reverse_safe: Iterate backwards, safe for removal. + * @pos: pointer to use as iterator (pointer to list node container). + * @p: temporary pointer to store @pos copy (pointer to list node container). + * @head: list head (struct cds_list_head *). + * @member: field name of list node field within container type. + * + * Mutual exclusion against updates to list is required. + * The list elements can be removed from the list within loop iteration. + */ +#define cds_list_for_each_entry_reverse_safe(pos, p, head, member) \ + for (pos = cds_list_entry((head)->prev, __typeof__(*pos), member), \ + p = cds_list_entry(pos->member.prev, \ + __typeof__(*pos), member); \ + &pos->member != (head); \ + pos = p, p = cds_list_entry(pos->member.prev, \ + __typeof__(*pos), member)) #endif /* _CDS_LIST_H */ diff --git a/urcu/rculist.h b/urcu/rculist.h index 3604a96..e6615ba 100644 --- a/urcu/rculist.h +++ b/urcu/rculist.h @@ -5,7 +5,7 @@ * * Copyright (C) 2009 Pierre-Marc Fournier * Conversion to RCU list. - * Copyright (C) 2010 Mathieu Desnoyers + * Copyright (C) 2010-2013 Mathieu Desnoyers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,9 +29,16 @@ #include #include -/* Add new element at the head of the list. +/* + * cds_list_add_rcu: Add new element at the head of the list. + * @newp: new element. + * @head: list head. + * + * Mutual exclusion against other updates to the list is required. + * RCU-safe for concurrent traversals. */ -static inline void cds_list_add_rcu(struct cds_list_head *newp, struct cds_list_head *head) +static inline +void cds_list_add_rcu(struct cds_list_head *newp, struct cds_list_head *head) { newp->next = head->next; newp->prev = head; @@ -40,9 +47,36 @@ static inline void cds_list_add_rcu(struct cds_list_head *newp, struct cds_list_ head->next = newp; } -/* replace an old entry atomically. +/* + * cds_list_add_tail_rcu: Add new element at the tail of the list. + * @newp: new element. + * @head: list head. + * + * Mutual exclusion against other updates to the list is required. + * RCU-safe for concurrent traversals. + */ +static inline +void cds_list_add_tail_rcu(struct cds_list_head *newp, + struct cds_list_head *head) +{ + newp->next = head; + newp->prev = head->prev; + cmm_smp_wmb(); + head->prev = newp; + head->prev->next = newp; +} + +/* + * cds_list_replace_rcu: replace an old entry atomically. + * @old: old entry. + * @_new: new entry. + * + * Replace old entry atomically with respect to concurrent readers. + * Mutual exclusion against other updates to the list is required. + * RCU-safe for concurrent traversals. */ -static inline void cds_list_replace_rcu(struct cds_list_head *old, struct cds_list_head *_new) +static inline +void cds_list_replace_rcu(struct cds_list_head *old, struct cds_list_head *_new) { _new->next = old->next; _new->prev = old->prev; @@ -50,29 +84,53 @@ static inline void cds_list_replace_rcu(struct cds_list_head *old, struct cds_li _new->next->prev = _new; } -/* Remove element from list. */ -static inline void cds_list_del_rcu(struct cds_list_head *elem) +/* + * cds_list_del_rcu: Remove element from list. + * @elem: new element. + * + * Mutual exclusion against other updates to the list is required. + * RCU-safe for concurrent traversals. + */ +static inline +void cds_list_del_rcu(struct cds_list_head *elem) { elem->next->prev = elem->prev; elem->prev->next = elem->next; } /* - * Iteration through all elements of the list must be done while rcu_read_lock() - * is held. + * cds_list_empty() can be used on RCU lists. RCU read-side lock is not + * required. */ -/* Iterate forward over the elements of the list. */ -#define cds_list_for_each_rcu(pos, head) \ - for (pos = rcu_dereference((head)->next); pos != (head); \ - pos = rcu_dereference(pos->next)) - +/* + * cds_list_for_each_rcu: RCU-safe iteration over the elements of the list. + * @pos: iteration position (struct cds_list_head *). + * @head: list head (struct cds_list_head *). + * + * Iteration direction: forward. + * Iteration through all elements of the list must be done while + * rcu_read_lock() is held. + */ +#define cds_list_for_each_rcu(pos, head) \ + for (pos = rcu_dereference((head)->next); pos != (head); \ + pos = rcu_dereference(pos->next)) -/* Iterate through elements of the list. +/* + * cds_list_for_each_entry_rcu: RCU-safe iteration over entries of the list. + * @pos: iteration position (pointer to entry type). + * @head: list head (struct cds_list_head *). + * @member: field name of the list node within entry type. + * + * Iteration direction: forward. + * Iteration through all elements of the list must be done while + * rcu_read_lock() is held. */ -#define cds_list_for_each_entry_rcu(pos, head, member) \ - for (pos = cds_list_entry(rcu_dereference((head)->next), __typeof__(*pos), member); \ +#define cds_list_for_each_entry_rcu(pos, head, member) \ + for (pos = cds_list_entry(rcu_dereference((head)->next), \ + __typeof__(*pos), member); \ &pos->member != (head); \ - pos = cds_list_entry(rcu_dereference(pos->member.next), __typeof__(*pos), member)) + pos = cds_list_entry(rcu_dereference(pos->member.next), \ + __typeof__(*pos), member)) #endif /* _URCU_RCULIST_H */ -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From Daniel.Thibault at drdc-rddc.gc.ca Mon Jan 21 09:52:55 2013 From: Daniel.Thibault at drdc-rddc.gc.ca (Thibault, Daniel) Date: Mon, 21 Jan 2013 09:52:55 -0500 Subject: [lttng-dev] Odd dependency for lttng-ust Message-ID: <3CA1A65C03C1A34C81BBC6272782E696987880@valcartierex01.valcartier.drdc-rddc.gc.ca> I'm starting from a clean Ubuntu 12.04 installation after adding the various prerequisites of the git.lttng.org LTTng 2 packages: LTTng 2 Packages (in the proper dependency order): lttng-modules (2.1.0+-c6403de) userspace-rcu (0.7.6-da9bed2) lttng-ust (2.1.0+-340f776) lttng-tools (2.1.1+-281047b) Prerequisites installed: automake binutils-gold bison flex libpopt-dev libtool libuuid1 python-dev swig2.0 kernel's headers (i.e. linux-headers-generic) texinfo g++ After making and installing lttng-modules and userspace-rcu successfully, lttng-ust's configure fails with: checking for _cds_lfht_new in -lurcu-cds... no configure: error: Cannot find liburcu-cds lib, part of Userspace RCU 0.7 or better. This occurs even though userspace-rcu installed /usr/local/lib/liburcu-cds. It seems I must install liburcu-dev from the LTTng PPA (because the current Ubuntu liburcu-dev is 0.6.7 while lttng-ust requires 0.7 or better) before I can configure lttng-ust properly. This is a weird bootstrapping problem: could the userspace-rcu package's install be incomplete? Daniel U. Thibault R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) 2459 route de la Bravoure Qu?bec, QC? G3J 1X5 CANADA Vox?: (418) 844-4000 x4245 Fax?: (418) 844-4538 NAC?: 918V QSDJ Gouvernement du Canada?/ Government of Canada From mathieu.desnoyers at efficios.com Mon Jan 21 09:59:54 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 21 Jan 2013 09:59:54 -0500 Subject: [lttng-dev] Odd dependency for lttng-ust In-Reply-To: <3CA1A65C03C1A34C81BBC6272782E696987880@valcartierex01.valcartier.drdc-rddc.gc.ca> References: <3CA1A65C03C1A34C81BBC6272782E696987880@valcartierex01.valcartier.drdc-rddc.gc.ca> Message-ID: <20130121145954.GA1472@Krystal> * Thibault, Daniel (Daniel.Thibault at drdc-rddc.gc.ca) wrote: > I'm starting from a clean Ubuntu 12.04 installation after adding the various prerequisites of the git.lttng.org LTTng 2 packages: > > LTTng 2 Packages (in the proper dependency order): > > lttng-modules (2.1.0+-c6403de) > userspace-rcu (0.7.6-da9bed2) > lttng-ust (2.1.0+-340f776) > lttng-tools (2.1.1+-281047b) > > Prerequisites installed: > > automake > binutils-gold > bison > flex > libpopt-dev > libtool > libuuid1 > python-dev > swig2.0 > kernel's headers (i.e. linux-headers-generic) > texinfo > g++ > > After making and installing lttng-modules and userspace-rcu successfully, lttng-ust's configure fails with: > > checking for _cds_lfht_new in -lurcu-cds... no > configure: error: Cannot find > liburcu-cds lib, part of Userspace RCU 0.7 or better. > > This occurs even though userspace-rcu installed > /usr/local/lib/liburcu-cds. It seems I must install liburcu-dev from > the LTTng PPA (because the current Ubuntu liburcu-dev is 0.6.7 while > lttng-ust requires 0.7 or better) before I can configure lttng-ust > properly. This is a weird bootstrapping problem: could the > userspace-rcu package's install be incomplete? Quoting the lttng-tools README file: " - liburcu Userspace RCU library, by Mathieu Desnoyers and Paul E. McKenney -> Tested with liburcu >= v0.7.2" Therefore you need to install Userspace RCU 0.7.2 or later. A dependency is not only on a package, but also on a range of versions. Thanks, Mathieu > > Daniel U. Thibault > R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) > Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) > Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) > 2459 route de la Bravoure > Qu?bec, QC? G3J 1X5 > CANADA > Vox?: (418) 844-4000 x4245 > Fax?: (418) 844-4538 > NAC?: 918V QSDJ > Gouvernement du Canada?/ Government of Canada > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon Jan 21 10:21:56 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 21 Jan 2013 10:21:56 -0500 Subject: [lttng-dev] [PATCH] Fix I/O-related error values in ustctl Message-ID: <20130121152156.GA1912@Krystal> These internal ustctl API members document >=0 as OK values. Make sure reply recv errors are returned as errors. Clarify ustctl_create_stream() error values. Signed-off-by: Mathieu Desnoyers --- diff --git a/include/lttng/ust-ctl.h b/include/lttng/ust-ctl.h index c2b255c..11beaba 100644 --- a/include/lttng/ust-ctl.h +++ b/include/lttng/ust-ctl.h @@ -23,7 +23,7 @@ /* * Error values: all the following functions return: - * >= 0: Sucess (LTTNG_UST_OK) + * >= 0: Success (LTTNG_UST_OK) * < 0: error code. */ int ustctl_register_done(int sock); @@ -34,8 +34,6 @@ int ustctl_open_metadata(int sock, int session_handle, int ustctl_create_channel(int sock, int session_handle, struct lttng_ust_channel_attr *chops, struct lttng_ust_object_data **channel_data); -int ustctl_create_stream(int sock, struct lttng_ust_object_data *channel_data, - struct lttng_ust_object_data **stream_data); int ustctl_create_event(int sock, struct lttng_ust_event *ev, struct lttng_ust_object_data *channel_data, struct lttng_ust_object_data **event_data); @@ -51,6 +49,15 @@ int ustctl_start_session(int sock, int handle); int ustctl_stop_session(int sock, int handle); /* + * Return -ENOENT if no more stream is available for creation. + * Return 0 on success. + * Return negative error value on system error. + * Return positive error value on UST error. + */ +int ustctl_create_stream(int sock, struct lttng_ust_object_data *channel_data, + struct lttng_ust_object_data **stream_data); + +/* * ustctl_tracepoint_list returns a tracepoint list handle, or negative * error value. */ diff --git a/liblttng-ust-comm/lttng-ust-comm.c b/liblttng-ust-comm/lttng-ust-comm.c index 9a67ea1..db9910d 100644 --- a/liblttng-ust-comm/lttng-ust-comm.c +++ b/liblttng-ust-comm/lttng-ust-comm.c @@ -435,7 +435,10 @@ int ustcomm_send_app_cmd(int sock, ret = ustcomm_send_app_msg(sock, lum); if (ret) return ret; - return ustcomm_recv_app_reply(sock, lur, lum->handle, lum->cmd); + ret = ustcomm_recv_app_reply(sock, lur, lum->handle, lum->cmd); + if (ret > 0) + return -EIO; + return ret; } /* -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From matthew.khouzam at ericsson.com Mon Jan 21 10:23:47 2013 From: matthew.khouzam at ericsson.com (Matthew Khouzam) Date: Mon, 21 Jan 2013 10:23:47 -0500 Subject: [lttng-dev] lttng on android In-Reply-To: References: Message-ID: <50FD5D83.5070308@ericsson.com> I believe a group at l'ecole polytechnique de Montreal is working on this, Genvieve, could you please comment more? On 13-01-21 06:48 AM, Amit Balboul wrote: > Hi, > > Is there a way to build the LTTng tools to Android (3.0.31) on ARM ?? > > I've managed to compile the modules(2.0.6), put them in the Android > device and modprobe them. > Now I would like to extract the traces logs from the device. > How can I do it ? > Is there any support for this at all in the LTTng project ? > > > Thank you for your response ! > > Amit. > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From Daniel.Thibault at drdc-rddc.gc.ca Mon Jan 21 10:24:26 2013 From: Daniel.Thibault at drdc-rddc.gc.ca (Thibault, Daniel) Date: Mon, 21 Jan 2013 10:24:26 -0500 Subject: [lttng-dev] Odd dependency for lttng-ust In-Reply-To: <20130121145954.GA1472@Krystal> References: <3CA1A65C03C1A34C81BBC6272782E696987880@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121145954.GA1472@Krystal> Message-ID: <3CA1A65C03C1A34C81BBC6272782E696987887@valcartierex01.valcartier.drdc-rddc.gc.ca> -----Message d'origine----- Quoting the lttng-tools README file: " - liburcu Userspace RCU library, by Mathieu Desnoyers and Paul E. McKenney -> Tested with liburcu >= v0.7.2" Therefore you need to install Userspace RCU 0.7.2 or later. A dependency is not only on a package, but also on a range of versions. Mathieu -----Fin du message d'origine----- But shouldn't the userspace RCU library be installed by the userspace-rcu package? That's the gist of my puzzlement. By the time I get to lttng-ust's configure, I've installed lttng-modules and userspace-rcu. Doing an install of git.lttng.org's userspace-rcu should be equivalent to installing the liburcu-dev package from repository, no? Daniel U. Thibault R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) 2459 route de la Bravoure Qu?bec, QC G3J 1X5 CANADA Vox : (418) 844-4000 x4245 Fax : (418) 844-4538 NAC : 918V QSDJ Gouvernement du Canada / Government of Canada From mathieu.desnoyers at efficios.com Mon Jan 21 10:29:49 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 21 Jan 2013 10:29:49 -0500 Subject: [lttng-dev] Odd dependency for lttng-ust In-Reply-To: <3CA1A65C03C1A34C81BBC6272782E696987887@valcartierex01.valcartier.drdc-rddc.gc.ca> References: <3CA1A65C03C1A34C81BBC6272782E696987880@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121145954.GA1472@Krystal> <3CA1A65C03C1A34C81BBC6272782E696987887@valcartierex01.valcartier.drdc-rddc.gc.ca> Message-ID: <20130121152949.GB1912@Krystal> * Thibault, Daniel (Daniel.Thibault at drdc-rddc.gc.ca) wrote: > -----Message d'origine----- > Quoting the lttng-tools README file: > " - liburcu > Userspace RCU library, by Mathieu Desnoyers and Paul E. McKenney > -> Tested with liburcu >= v0.7.2" > > Therefore you need to install Userspace RCU 0.7.2 or later. > A dependency is not only on a package, but also on a range of versions. > > Mathieu > -----Fin du message d'origine----- > > But shouldn't the userspace RCU library be installed by the > userspace-rcu package? That's the gist of my puzzlement. By the > time I get to lttng-ust's configure, I've installed lttng-modules > and userspace-rcu. Doing an install of git.lttng.org's > userspace-rcu should be equivalent to installing the liburcu-dev > package from repository, no? No. Distribution packages usually lag behind the project upstream. Ubuntu 12.04 has been released last year, and their policy don't allow them to update the packages within this specific distribution version. This is why you run into trouble when you try to mix distribution packages (from last year) with the current development head. Don't mix packages from distributions with packages built from sources when version dependencies don't match. All the required dependency information is found in the README files of each project. Thanks, Mathieu > > Daniel U. Thibault > R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) > Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) > Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) > 2459 route de la Bravoure > Qu?bec, QC G3J 1X5 > CANADA > Vox : (418) 844-4000 x4245 > Fax : (418) 844-4538 > NAC : 918V QSDJ > Gouvernement du Canada / Government of Canada > -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From gbastien at versatic.net Mon Jan 21 10:43:46 2013 From: gbastien at versatic.net (=?ISO-8859-1?Q?Genevi=E8ve_Bastien?=) Date: Mon, 21 Jan 2013 10:43:46 -0500 Subject: [lttng-dev] lttng on android In-Reply-To: <50FD5D83.5070308@ericsson.com> References: <50FD5D83.5070308@ericsson.com> Message-ID: <50FD6232.3060209@versatic.net> Hi Amit, Indeed there is a group of students working on putting lttng on android, maybe make it work through adb. As the semester advances, they may publish some of their work and hopefully by the end of april, lttng will be supported and documented on Android. In the meantime, if you have managed to compile and modprobe the modules, have you tried obtaining a trace from the command line. What does it do, what message do you get? Genevi?ve On 01/21/2013 10:23 AM, Matthew Khouzam wrote: > I believe a group at l'ecole polytechnique de Montreal is working on > this, Genvieve, could you please comment more? > > On 13-01-21 06:48 AM, Amit Balboul wrote: >> Hi, >> >> Is there a way to build the LTTng tools to Android (3.0.31) on ARM ?? >> >> I've managed to compile the modules(2.0.6), put them in the Android >> device and modprobe them. >> Now I would like to extract the traces logs from the device. >> How can I do it ? >> Is there any support for this at all in the LTTng project ? >> >> >> Thank you for your response ! >> >> Amit. >> >> >> _______________________________________________ >> lttng-dev mailing list >> lttng-dev at lists.lttng.org >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From Daniel.Thibault at drdc-rddc.gc.ca Mon Jan 21 10:44:16 2013 From: Daniel.Thibault at drdc-rddc.gc.ca (Thibault, Daniel) Date: Mon, 21 Jan 2013 10:44:16 -0500 Subject: [lttng-dev] Odd dependency for lttng-ust In-Reply-To: <20130121152949.GB1912@Krystal> References: <3CA1A65C03C1A34C81BBC6272782E696987880@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121145954.GA1472@Krystal> <3CA1A65C03C1A34C81BBC6272782E696987887@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121152949.GB1912@Krystal> Message-ID: <3CA1A65C03C1A34C81BBC6272782E69698788F@valcartierex01.valcartier.drdc-rddc.gc.ca> -----Message d'origine----- De?: Mathieu Desnoyers [mailto:mathieu.desnoyers at efficios.com] Envoy??: 21 janvier 2013 10:30 No. Distribution packages usually lag behind the project upstream. Ubuntu 12.04 has been released last year, and their policy don't allow them to update the packages within this specific distribution version. This is why you run into trouble when you try to mix distribution packages (from last year) with the current development head. Don't mix packages from distributions with packages built from sources when version dependencies don't match. All the required dependency information is found in the README files of each project. Mathieu -----Fin du message d'origine----- But I'm not mixing old packages with new: I tried fetching everything from git.lttng.org. The README for lttng-ust reads in part: PREREQUISITES: - liburcu Userspace RCU library, by Mathieu Desnoyers and Paul E. McKenney -> This release depends on liburcu v0.7.2 * Debian/Ubuntu package: liburcu-dev * Website: http://lttng.org/urcu * Releases: http://lttng.org/files/urcu * GitWeb: http://lttng.org/cgi-bin/gitweb.cgi?p=userspace-rcu.git;a=summary * Git: git://lttng.org/userspace-rcu.git Doesn't this say that I can get the required liburcu from git.lttng.org's userspace-rcu? Could it be version 0.7.6 is not retro-compatible with 0.7.2 (that is to say, lttng-ust requires 0.7.2, and 0.7.2 only, not "0.7.2 or later")? Daniel U. Thibault R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) 2459 route de la Bravoure Qu?bec, QC G3J 1X5 CANADA Vox : (418) 844-4000 x4245 Fax : (418) 844-4538 [Valcartier]\\vsi-wdut-o980, [Secteur-SI]\\edge NAC : 918V QSDJ Gouvernement du Canada / Government of Canada LinkedIn: Research Gate: From francis.labarre at gmail.com Mon Jan 21 10:45:11 2013 From: francis.labarre at gmail.com (Francis Labarre) Date: Mon, 21 Jan 2013 10:45:11 -0500 Subject: [lttng-dev] lttng on android In-Reply-To: <50FD5D83.5070308@ericsson.com> References: <50FD5D83.5070308@ericsson.com> Message-ID: Hi, I'm one of the student working on porting lttng to android at Ecole Polytechnique Montreal. As of right now we haven't begun to develop tools to support creating and extracting traces on android devices. It should take a few months before we finish the project, in the mean time you could look at these previous porting attempts: https://docs.google.com/open?id=0B2aE_idi5Wt8MzZER1dLTGxRWmloU3ZZWEY1cUdzZw http://lists.lttng.org/pipermail/lttng-dev/2012-February/017626.html Have a nice day! Francis Labarre -------------- next part -------------- An HTML attachment was scrubbed... URL: From pierre-luc.st-charles at polymtl.ca Mon Jan 21 10:46:10 2013 From: pierre-luc.st-charles at polymtl.ca (Pierre-Luc St-Charles) Date: Mon, 21 Jan 2013 10:46:10 -0500 Subject: [lttng-dev] lttng on android In-Reply-To: <50FD5D83.5070308@ericsson.com> References: <50FD5D83.5070308@ericsson.com> Message-ID: We are indeed exploring a few ways to extract the traces through ADB at the moment, but our work has barely taken off yet; we should have a more solid grasp on the subject in a few more days. Until then, I believe other students that are part of this work group are on the mailing list (and they could have explored the topic a bit more than I did), and might be able to give you a few more details today or tomorrow. On Mon, Jan 21, 2013 at 10:23 AM, Matthew Khouzam < matthew.khouzam at ericsson.com> wrote: > I believe a group at l'ecole polytechnique de Montreal is working on > this, Genvieve, could you please comment more? > > > On 13-01-21 06:48 AM, Amit Balboul wrote: > > Hi, > > Is there a way to build the LTTng tools to Android (3.0.31) on ARM ?? > > I've managed to compile the modules(2.0.6), put them in the Android > device and modprobe them. > Now I would like to extract the traces logs from the device. > How can I do it ? > Is there any support for this at all in the LTTng project ? > > > Thank you for your response ! > > Amit. > > > _______________________________________________ > lttng-dev mailing listlttng-dev at lists.lttng.orghttp://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mathieu.desnoyers at efficios.com Mon Jan 21 10:47:43 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 21 Jan 2013 10:47:43 -0500 Subject: [lttng-dev] Odd dependency for lttng-ust In-Reply-To: <3CA1A65C03C1A34C81BBC6272782E69698788F@valcartierex01.valcartier.drdc-rddc.gc.ca> References: <3CA1A65C03C1A34C81BBC6272782E696987880@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121145954.GA1472@Krystal> <3CA1A65C03C1A34C81BBC6272782E696987887@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121152949.GB1912@Krystal> <3CA1A65C03C1A34C81BBC6272782E69698788F@valcartierex01.valcartier.drdc-rddc.gc.ca> Message-ID: <20130121154743.GA2474@Krystal> * Thibault, Daniel (Daniel.Thibault at drdc-rddc.gc.ca) wrote: > -----Message d'origine----- > De?: Mathieu Desnoyers [mailto:mathieu.desnoyers at efficios.com] > Envoy??: 21 janvier 2013 10:30 > > No. Distribution packages usually lag behind the project upstream. > Ubuntu 12.04 has been released last year, and their policy don't allow them to update the packages within this specific distribution version. > > This is why you run into trouble when you try to mix distribution packages (from last year) with the current development head. > > Don't mix packages from distributions with packages built from sources when version dependencies don't match. All the required dependency information is found in the README files of each project. > > Mathieu > -----Fin du message d'origine----- > > But I'm not mixing old packages with new: I tried fetching everything from git.lttng.org. The README for lttng-ust reads in part: > > PREREQUISITES: > - liburcu > Userspace RCU library, by Mathieu Desnoyers and Paul E. McKenney > -> This release depends on liburcu v0.7.2 > * Debian/Ubuntu package: liburcu-dev > * Website: http://lttng.org/urcu > * Releases: http://lttng.org/files/urcu > * GitWeb: http://lttng.org/cgi-bin/gitweb.cgi?p=userspace-rcu.git;a=summary > * Git: git://lttng.org/userspace-rcu.git > > Doesn't this say that I can get the required liburcu from git.lttng.org's userspace-rcu? Could it be version 0.7.6 is not retro-compatible with 0.7.2 (that is to say, lttng-ust requires 0.7.2, and 0.7.2 only, not "0.7.2 or later")? 0.7.6 should work. You might want to check the list of packages installed by your distribution to see if an old userspace RCU package is installed into /usr/ and overrides the one you installed within /usr/local/. Thanks, Mathieu > > Daniel U. Thibault > R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) > Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) > Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) > 2459 route de la Bravoure > Qu?bec, QC G3J 1X5 > CANADA > Vox : (418) 844-4000 x4245 > Fax : (418) 844-4538 > [Valcartier]\\vsi-wdut-o980, [Secteur-SI]\\edge > NAC : 918V QSDJ > Gouvernement du Canada / Government of Canada > > LinkedIn: > Research Gate: -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Mon Jan 21 10:53:24 2013 From: dgoulet at efficios.com (David Goulet) Date: Mon, 21 Jan 2013 10:53:24 -0500 Subject: [lttng-dev] Odd dependency for lttng-ust In-Reply-To: <3CA1A65C03C1A34C81BBC6272782E69698788F@valcartierex01.valcartier.drdc-rddc.gc.ca> References: <3CA1A65C03C1A34C81BBC6272782E696987880@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121145954.GA1472@Krystal> <3CA1A65C03C1A34C81BBC6272782E696987887@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121152949.GB1912@Krystal> <3CA1A65C03C1A34C81BBC6272782E69698788F@valcartierex01.valcartier.drdc-rddc.gc.ca> Message-ID: <50FD6474.6070207@efficios.com> Also, I do still forget it still today but after installing URCU and UST: $ sudo ldconfig :) David Thibault, Daniel: > -----Message d'origine----- > De : Mathieu Desnoyers [mailto:mathieu.desnoyers at efficios.com] > Envoy? : 21 janvier 2013 10:30 > > No. Distribution packages usually lag behind the project upstream. > Ubuntu 12.04 has been released last year, and their policy don't allow them to update the packages within this specific distribution version. > > This is why you run into trouble when you try to mix distribution packages (from last year) with the current development head. > > Don't mix packages from distributions with packages built from sources when version dependencies don't match. All the required dependency information is found in the README files of each project. > > Mathieu > -----Fin du message d'origine----- > > But I'm not mixing old packages with new: I tried fetching everything from git.lttng.org. The README for lttng-ust reads in part: > > PREREQUISITES: > - liburcu > Userspace RCU library, by Mathieu Desnoyers and Paul E. McKenney > -> This release depends on liburcu v0.7.2 > * Debian/Ubuntu package: liburcu-dev > * Website: http://lttng.org/urcu > * Releases: http://lttng.org/files/urcu > * GitWeb: http://lttng.org/cgi-bin/gitweb.cgi?p=userspace-rcu.git;a=summary > * Git: git://lttng.org/userspace-rcu.git > > Doesn't this say that I can get the required liburcu from git.lttng.org's userspace-rcu? Could it be version 0.7.6 is not retro-compatible with 0.7.2 (that is to say, lttng-ust requires 0.7.2, and 0.7.2 only, not "0.7.2 or later")? > > Daniel U. Thibault > R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) > Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) > Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) > 2459 route de la Bravoure > Qu?bec, QC G3J 1X5 > CANADA > Vox : (418) 844-4000 x4245 > Fax : (418) 844-4538 > [Valcartier]\\vsi-wdut-o980, [Secteur-SI]\\edge > NAC : 918V QSDJ > Gouvernement du Canada / Government of Canada > > LinkedIn: > Research Gate: > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev From dgoulet at efficios.com Mon Jan 21 10:54:57 2013 From: dgoulet at efficios.com (David Goulet) Date: Mon, 21 Jan 2013 10:54:57 -0500 Subject: [lttng-dev] [PATCH] Fix I/O-related error values in ustctl In-Reply-To: <20130121152156.GA1912@Krystal> References: <20130121152156.GA1912@Krystal> Message-ID: <50FD64D1.1080202@efficios.com> Acked-by: David Goulet Mathieu Desnoyers: > These internal ustctl API members document >=0 as OK values. Make sure > reply recv errors are returned as errors. > > Clarify ustctl_create_stream() error values. > > Signed-off-by: Mathieu Desnoyers > --- > diff --git a/include/lttng/ust-ctl.h b/include/lttng/ust-ctl.h > index c2b255c..11beaba 100644 > --- a/include/lttng/ust-ctl.h > +++ b/include/lttng/ust-ctl.h > @@ -23,7 +23,7 @@ > > /* > * Error values: all the following functions return: > - * >= 0: Sucess (LTTNG_UST_OK) > + * >= 0: Success (LTTNG_UST_OK) > * < 0: error code. > */ > int ustctl_register_done(int sock); > @@ -34,8 +34,6 @@ int ustctl_open_metadata(int sock, int session_handle, > int ustctl_create_channel(int sock, int session_handle, > struct lttng_ust_channel_attr *chops, > struct lttng_ust_object_data **channel_data); > -int ustctl_create_stream(int sock, struct lttng_ust_object_data *channel_data, > - struct lttng_ust_object_data **stream_data); > int ustctl_create_event(int sock, struct lttng_ust_event *ev, > struct lttng_ust_object_data *channel_data, > struct lttng_ust_object_data **event_data); > @@ -51,6 +49,15 @@ int ustctl_start_session(int sock, int handle); > int ustctl_stop_session(int sock, int handle); > > /* > + * Return -ENOENT if no more stream is available for creation. > + * Return 0 on success. > + * Return negative error value on system error. > + * Return positive error value on UST error. > + */ > +int ustctl_create_stream(int sock, struct lttng_ust_object_data *channel_data, > + struct lttng_ust_object_data **stream_data); > + > +/* > * ustctl_tracepoint_list returns a tracepoint list handle, or negative > * error value. > */ > diff --git a/liblttng-ust-comm/lttng-ust-comm.c b/liblttng-ust-comm/lttng-ust-comm.c > index 9a67ea1..db9910d 100644 > --- a/liblttng-ust-comm/lttng-ust-comm.c > +++ b/liblttng-ust-comm/lttng-ust-comm.c > @@ -435,7 +435,10 @@ int ustcomm_send_app_cmd(int sock, > ret = ustcomm_send_app_msg(sock, lum); > if (ret) > return ret; > - return ustcomm_recv_app_reply(sock, lur, lum->handle, lum->cmd); > + ret = ustcomm_recv_app_reply(sock, lur, lum->handle, lum->cmd); > + if (ret > 0) > + return -EIO; > + return ret; > } > > /* > From mathieu.desnoyers at efficios.com Mon Jan 21 10:58:06 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 21 Jan 2013 10:58:06 -0500 Subject: [lttng-dev] [PATCH] Fix I/O-related error values in ustctl In-Reply-To: <50FD64D1.1080202@efficios.com> References: <20130121152156.GA1912@Krystal> <50FD64D1.1080202@efficios.com> Message-ID: <20130121155805.GA2934@Krystal> * David Goulet (dgoulet at efficios.com) wrote: > Acked-by: David Goulet merged into master branch and stable-2.1. Thanks, Mathieu > > Mathieu Desnoyers: > > These internal ustctl API members document >=0 as OK values. Make sure > > reply recv errors are returned as errors. > > > > Clarify ustctl_create_stream() error values. > > > > Signed-off-by: Mathieu Desnoyers > > --- > > diff --git a/include/lttng/ust-ctl.h b/include/lttng/ust-ctl.h > > index c2b255c..11beaba 100644 > > --- a/include/lttng/ust-ctl.h > > +++ b/include/lttng/ust-ctl.h > > @@ -23,7 +23,7 @@ > > > > /* > > * Error values: all the following functions return: > > - * >= 0: Sucess (LTTNG_UST_OK) > > + * >= 0: Success (LTTNG_UST_OK) > > * < 0: error code. > > */ > > int ustctl_register_done(int sock); > > @@ -34,8 +34,6 @@ int ustctl_open_metadata(int sock, int session_handle, > > int ustctl_create_channel(int sock, int session_handle, > > struct lttng_ust_channel_attr *chops, > > struct lttng_ust_object_data **channel_data); > > -int ustctl_create_stream(int sock, struct lttng_ust_object_data *channel_data, > > - struct lttng_ust_object_data **stream_data); > > int ustctl_create_event(int sock, struct lttng_ust_event *ev, > > struct lttng_ust_object_data *channel_data, > > struct lttng_ust_object_data **event_data); > > @@ -51,6 +49,15 @@ int ustctl_start_session(int sock, int handle); > > int ustctl_stop_session(int sock, int handle); > > > > /* > > + * Return -ENOENT if no more stream is available for creation. > > + * Return 0 on success. > > + * Return negative error value on system error. > > + * Return positive error value on UST error. > > + */ > > +int ustctl_create_stream(int sock, struct lttng_ust_object_data *channel_data, > > + struct lttng_ust_object_data **stream_data); > > + > > +/* > > * ustctl_tracepoint_list returns a tracepoint list handle, or negative > > * error value. > > */ > > diff --git a/liblttng-ust-comm/lttng-ust-comm.c b/liblttng-ust-comm/lttng-ust-comm.c > > index 9a67ea1..db9910d 100644 > > --- a/liblttng-ust-comm/lttng-ust-comm.c > > +++ b/liblttng-ust-comm/lttng-ust-comm.c > > @@ -435,7 +435,10 @@ int ustcomm_send_app_cmd(int sock, > > ret = ustcomm_send_app_msg(sock, lum); > > if (ret) > > return ret; > > - return ustcomm_recv_app_reply(sock, lur, lum->handle, lum->cmd); > > + ret = ustcomm_recv_app_reply(sock, lur, lum->handle, lum->cmd); > > + if (ret > 0) > > + return -EIO; > > + return ret; > > } > > > > /* > > -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From Daniel.Thibault at drdc-rddc.gc.ca Mon Jan 21 11:50:02 2013 From: Daniel.Thibault at drdc-rddc.gc.ca (Thibault, Daniel) Date: Mon, 21 Jan 2013 11:50:02 -0500 Subject: [lttng-dev] Odd dependency for lttng-ust In-Reply-To: <50FD6474.6070207@efficios.com> References: <3CA1A65C03C1A34C81BBC6272782E696987880@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121145954.GA1472@Krystal> <3CA1A65C03C1A34C81BBC6272782E696987887@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121152949.GB1912@Krystal> <3CA1A65C03C1A34C81BBC6272782E69698788F@valcartierex01.valcartier.drdc-rddc.gc.ca> <50FD6474.6070207@efficios.com> Message-ID: <3CA1A65C03C1A34C81BBC6272782E6969878A7@valcartierex01.valcartier.drdc-rddc.gc.ca> -----Message d'origine----- De?: David Goulet [mailto:dgoulet at efficios.com] Envoy??: 21 janvier 2013 10:53 Also, I do still forget it still today but after installing URCU and UST: $ sudo ldconfig David -----Fin du message d'origine----- But 'sudo make install' invokes 'ldconfig -n /usr/local/lib'... Tried again, without fetching liburcu-dev from the LTTng PPA. The packages added to the basic Ubuntu 12.04 install are: automake 1:1.11.3-1ubuntu2 binutils-gold 2.22-6ubuntu1 bison 1:2.5.dsfg-2.1 flex 2.5.35-10ubuntu3 libpopt-dev 1.16-3ubuntu1 libtool 2.4.2-1ubuntu1 libuuid1 2.20.1-1ubuntu3 python-dev 2.7.3-0ubuntu2 swig2.0 2.0.4+really2.0.4-4ubuntu2 linux-headers-3.2.0-36-virtual texinfo 4.13a.dfsg.1-8ubuntu2 g++ 4:4.6.3-1ubuntu5 This time I did sudo ldconfig after each install (both commands had nothing to say). After making and installing lttng-modules and userspace-rcu successfully, lttng-ust's configure fails about a dozen checks earlier than the liburcu-cds check with: checking for uuid_generate in -luuid... no checking for uuid_create in -lc... no configure: error: Cannot find libuuid uuid_generate nor libc uuid_create. Use LDFLAGS=-Ldir to specify their location. Even though libuuid1 (includes libuuid-perl, uuid-dev, uuid-runtime) is installed. I need to fix this new stumbling block before we can address the liburcu-cds problem. Logs available. Daniel U. Thibault R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) 2459 route de la Bravoure Qu?bec, QC G3J 1X5 CANADA Vox : (418) 844-4000 x4245 Fax : (418) 844-4538 NAC : 918V QSDJ Gouvernement du Canada / Government of Canada From mathieu.desnoyers at efficios.com Mon Jan 21 12:06:55 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 21 Jan 2013 12:06:55 -0500 Subject: [lttng-dev] Odd dependency for lttng-ust In-Reply-To: <3CA1A65C03C1A34C81BBC6272782E6969878A7@valcartierex01.valcartier.drdc-rddc.gc.ca> References: <3CA1A65C03C1A34C81BBC6272782E696987880@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121145954.GA1472@Krystal> <3CA1A65C03C1A34C81BBC6272782E696987887@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121152949.GB1912@Krystal> <3CA1A65C03C1A34C81BBC6272782E69698788F@valcartierex01.valcartier.drdc-rddc.gc.ca> <50FD6474.6070207@efficios.com> <3CA1A65C03C1A34C81BBC6272782E6969878A7@valcartierex01.valcartier.drdc-rddc.gc.ca> Message-ID: <20130121170655.GA4268@Krystal> * Thibault, Daniel (Daniel.Thibault at drdc-rddc.gc.ca) wrote: > -----Message d'origine----- > De?: David Goulet [mailto:dgoulet at efficios.com] > Envoy??: 21 janvier 2013 10:53 > > Also, I do still forget it still today but after installing URCU and UST: > > $ sudo ldconfig > > David > -----Fin du message d'origine----- > > But 'sudo make install' invokes 'ldconfig -n /usr/local/lib'... > > Tried again, without fetching liburcu-dev from the LTTng PPA. The packages added to the basic Ubuntu 12.04 install are: > > automake 1:1.11.3-1ubuntu2 > binutils-gold 2.22-6ubuntu1 > bison 1:2.5.dsfg-2.1 > flex 2.5.35-10ubuntu3 > libpopt-dev 1.16-3ubuntu1 > libtool 2.4.2-1ubuntu1 > libuuid1 2.20.1-1ubuntu3 > python-dev 2.7.3-0ubuntu2 > swig2.0 2.0.4+really2.0.4-4ubuntu2 > linux-headers-3.2.0-36-virtual > texinfo 4.13a.dfsg.1-8ubuntu2 > g++ 4:4.6.3-1ubuntu5 > > This time I did sudo ldconfig after each install (both commands had nothing to say). After making and installing lttng-modules and userspace-rcu successfully, lttng-ust's configure fails about a dozen checks earlier than the liburcu-cds check with: > > checking for uuid_generate in -luuid... no > checking for uuid_create in -lc... no > configure: error: Cannot find libuuid uuid_generate nor libc uuid_create. Use LDFLAGS=-Ldir to specify their location. > > Even though libuuid1 (includes libuuid-perl, uuid-dev, uuid-runtime) is installed. I need to fix this new stumbling block before we can address the liburcu-cds problem. Please provide the complete output of: dpkg -l on your system. (it is rather long, please attach it to an email) Thanks, Mathieu > > Logs available. > > Daniel U. Thibault > R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) > Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) > Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) > 2459 route de la Bravoure > Qu?bec, QC G3J 1X5 > CANADA > Vox : (418) 844-4000 x4245 > Fax : (418) 844-4538 > NAC : 918V QSDJ > Gouvernement du Canada / Government of Canada > -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From Daniel.Thibault at drdc-rddc.gc.ca Mon Jan 21 12:31:48 2013 From: Daniel.Thibault at drdc-rddc.gc.ca (Thibault, Daniel) Date: Mon, 21 Jan 2013 12:31:48 -0500 Subject: [lttng-dev] Odd dependency for lttng-ust In-Reply-To: <20130121170655.GA4268@Krystal> References: <3CA1A65C03C1A34C81BBC6272782E696987880@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121145954.GA1472@Krystal> <3CA1A65C03C1A34C81BBC6272782E696987887@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121152949.GB1912@Krystal> <3CA1A65C03C1A34C81BBC6272782E69698788F@valcartierex01.valcartier.drdc-rddc.gc.ca> <50FD6474.6070207@efficios.com> <3CA1A65C03C1A34C81BBC6272782E6969878A7@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121170655.GA4268@Krystal> Message-ID: <3CA1A65C03C1A34C81BBC6272782E6969878AE@valcartierex01.valcartier.drdc-rddc.gc.ca> -----Message d'origine----- De?: Mathieu Desnoyers [mailto:mathieu.desnoyers at efficios.com] Envoy??: 21 janvier 2013 12:07 > Even though libuuid1 (includes libuuid-perl, uuid-dev, uuid-runtime) is installed. I need to fix this new stumbling block before we can address the liburcu-cds problem. Please provide the complete output of: dpkg -l on your system. (it is rather long, please attach it to an email) Mathieu -----Fin du message d'origine----- Concerning the uuid problem, uuid-dev had not been installed; it needs to be specified separately from libuuid1. Now lttng-ust's configure ends with: checking for uuid_generate in -luuid... yes checking for inline... inline checking for stdlib.h... (cached) yes checking for GNU libc compatible malloc... yes checking for gettimeofday... yes checking for munmap... yes checking for socket... yes checking for strerror... yes checking for strtol... yes checking for sched_getcpu... yes checking for sysconf... yes checking urcu-bp.h usability... yes checking urcu-bp.h presence... yes checking for urcu-bp.h... yes checking for _cds_lfht_new in -lurcu-cds... no configure: error: Cannot find liburcu-cds lib, part of Userspace RCU 0.7 or better. Use LDFLAGS=-Ldir to specify its location. dpkg -l output attached. Daniel U. Thibault R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) 2459 route de la Bravoure Qu?bec, QC G3J 1X5 CANADA Vox : (418) 844-4000 x4245 Fax : (418) 844-4538 NAC : 918V QSDJ Gouvernement du Canada / Government of Canada -------------- next part -------------- A non-text attachment was scrubbed... Name: dpkg.txt.tar.gz Type: application/x-gzip Size: 37333 bytes Desc: dpkg.txt.tar.gz URL: From mathieu.desnoyers at efficios.com Mon Jan 21 13:38:46 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 21 Jan 2013 13:38:46 -0500 Subject: [lttng-dev] Odd dependency for lttng-ust In-Reply-To: <3CA1A65C03C1A34C81BBC6272782E6969878AE@valcartierex01.valcartier.drdc-rddc.gc.ca> References: <3CA1A65C03C1A34C81BBC6272782E696987880@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121145954.GA1472@Krystal> <3CA1A65C03C1A34C81BBC6272782E696987887@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121152949.GB1912@Krystal> <3CA1A65C03C1A34C81BBC6272782E69698788F@valcartierex01.valcartier.drdc-rddc.gc.ca> <50FD6474.6070207@efficios.com> <3CA1A65C03C1A34C81BBC6272782E6969878A7@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121170655.GA4268@Krystal> <3CA1A65C03C1A34C81BBC6272782E6969878AE@valcartierex01.valcartier.drdc-rddc.gc.ca> Message-ID: <20130121183846.GA6838@Krystal> * Thibault, Daniel (Daniel.Thibault at drdc-rddc.gc.ca) wrote: > -----Message d'origine----- > De?: Mathieu Desnoyers [mailto:mathieu.desnoyers at efficios.com] > Envoy??: 21 janvier 2013 12:07 > > > Even though libuuid1 (includes libuuid-perl, uuid-dev, uuid-runtime) is installed. I need to fix this new stumbling block before we can address the liburcu-cds problem. > > Please provide the complete output of: > dpkg -l > on your system. (it is rather long, please attach it to an email) > > Mathieu > -----Fin du message d'origine----- > > Concerning the uuid problem, uuid-dev had not been installed; it needs to be specified separately from libuuid1. Now lttng-ust's configure ends with: > > checking for uuid_generate in -luuid... yes > checking for inline... inline > checking for stdlib.h... (cached) yes > checking for GNU libc compatible malloc... yes > checking for gettimeofday... yes > checking for munmap... yes > checking for socket... yes > checking for strerror... yes > checking for strtol... yes > checking for sched_getcpu... yes > checking for sysconf... yes > checking urcu-bp.h usability... yes > checking urcu-bp.h presence... yes > checking for urcu-bp.h... yes > checking for _cds_lfht_new in -lurcu-cds... no > configure: error: Cannot find > liburcu-cds lib, part of Userspace RCU 0.7 or better. Use LDFLAGS=-Ldir to specify its location. As the error messages suggests, please try: LDFLAGS=-L/usr/local/lib ./configure instead of "./configure" Thanks, Mathieu > > dpkg -l output attached. > > Daniel U. Thibault > R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) > Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) > Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) > 2459 route de la Bravoure > Qu?bec, QC G3J 1X5 > CANADA > Vox : (418) 844-4000 x4245 > Fax : (418) 844-4538 > NAC : 918V QSDJ > Gouvernement du Canada / Government of Canada > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon Jan 21 14:06:02 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 21 Jan 2013 14:06:02 -0500 Subject: [lttng-dev] [RFC PATCH lttng-ust] Introduce hash table for lttng_create_event_if_missing() In-Reply-To: <0AF7BA51953555439020FD85D854801F039A5D@eusaamb105.ericsson.se> References: <0AF7BA51953555439020FD85D854801F039A5D@eusaamb105.ericsson.se> Message-ID: <20130121190602.GD7137@Krystal> * Anik Mishra (anik.mishra at ericsson.com) wrote: > -----Original Message----- > From: Mathieu Desnoyers [mailto:mathieu.desnoyers at efficios.com] > Sent: January-16-13 10:15 AM > To: lttng-dev at lists.lttng.org > Subject: [lttng-dev] [RFC PATCH lttng-ust] Introduce hash table for lttng_create_event_if_missing() > > [...] > @@ -329,17 +331,19 @@ int lttng_event_create(const struct lttng_event_desc *desc, { > [...] > - /* > - * This is O(n^2) (for each event, the loop is called at event > - * creation). Might require a hash if we have lots of events. > - */ > - cds_list_for_each_entry(event, &chan->session->events_head, node) { > + hash = jhash(event_name, name_len, 0); > + head = &chan->session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)]; > + cds_hlist_for_each_entry(event, node, head, hlist) { > [...] > > From other code: > #define LTTNG_UST_EVENT_HT_BITS 6 > #define LTTNG_UST_EVENT_HT_SIZE (1U << LTTNG_UST_EVENT_HT_BITS) > > The way I read this, if there's a substantial number of events, > you're just dividing the time required by a constant 64. The > complexity remains the same. Are you sure this is really a long term > solution? If we have much more than 10k _different_ TRACEPOINT_EVENT in the code, we'll probably have other issues to fix. Thanks, Mathieu -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From jeremie.galarneau at efficios.com Mon Jan 21 09:17:54 2013 From: jeremie.galarneau at efficios.com (=?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=) Date: Mon, 21 Jan 2013 14:17:54 +0000 Subject: [lttng-dev] [PATCH babeltrace] Fix: Double free in bt_context_remove_trace(). Message-ID: <1358777874-24083-1-git-send-email-jeremie.galarneau@efficios.com> ctf_close_trace was being called twice when calling bt_context_remove_trace thus causing free() to be called on an invalid pointer. Calling bt_context_remove_trace() would call ctf_close_trace() once via the close_handle callback registered on the ctf format struct and a second call would take place from bt_trace_handle_destroy() which is registered as the value_destroy_func on the trace_handles hash table of the current context. The first explicit call to handle->format->close_trace is unnecessary. The crash is reproducible by invoking the tests-python.py script. Signed-off-by: J?r?mie Galarneau --- lib/context.c | 8 +------- lib/trace-handle.c | 5 ++++- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/context.c b/lib/context.c index 5516e49..05fb994 100644 --- a/lib/context.c +++ b/lib/context.c @@ -156,7 +156,6 @@ end: int bt_context_remove_trace(struct bt_context *ctx, int handle_id) { struct bt_trace_handle *handle; - int ret; if (!ctx) return -EINVAL; @@ -168,12 +167,7 @@ int bt_context_remove_trace(struct bt_context *ctx, int handle_id) /* Remove from containers */ trace_collection_remove(ctx->tc, handle->td); - /* Close the trace */ - ret = handle->format->close_trace(handle->td); - if (ret) { - fprintf(stderr, "Error in close_trace callback\n"); - return ret; - } + /* Remove and free the handle */ g_hash_table_remove(ctx->trace_handles, (gpointer) (unsigned long) handle_id); diff --git a/lib/trace-handle.c b/lib/trace-handle.c index 0da565b..17a6e0d 100644 --- a/lib/trace-handle.c +++ b/lib/trace-handle.c @@ -49,7 +49,10 @@ struct bt_trace_handle *bt_trace_handle_create(struct bt_context *ctx) void bt_trace_handle_destroy(struct bt_trace_handle *th) { - th->format->close_trace(th->td); + if (th->format->close_trace(th->td)) { + fprintf(stderr, "Error in close_trace callback\n"); + } + g_free(th); } -- 1.8.1.1 From mathieu.desnoyers at efficios.com Mon Jan 21 14:32:25 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 21 Jan 2013 14:32:25 -0500 Subject: [lttng-dev] [PATCH babeltrace] Fix: Double free in bt_context_remove_trace(). In-Reply-To: <1358777874-24083-1-git-send-email-jeremie.galarneau@efficios.com> References: <1358777874-24083-1-git-send-email-jeremie.galarneau@efficios.com> Message-ID: <20130121193225.GA8005@Krystal> * J?r?mie Galarneau (jeremie.galarneau at efficios.com) wrote: > ctf_close_trace was being called twice when calling bt_context_remove_trace thus > causing free() to be called on an invalid pointer. > > Calling bt_context_remove_trace() would call ctf_close_trace() once via the > close_handle callback registered on the ctf format struct and a second call would > take place from bt_trace_handle_destroy() which is registered as the > value_destroy_func on the trace_handles hash table of the current context. > > The first explicit call to handle->format->close_trace is unnecessary. > > The crash is reproducible by invoking the tests-python.py script. I think we should leave the close_trace calls in both locations, but set handle->td to -1 when we close it, and test for negative handle ID before doing the close. Thanks, Mathieu > > Signed-off-by: J?r?mie Galarneau > --- > lib/context.c | 8 +------- > lib/trace-handle.c | 5 ++++- > 2 files changed, 5 insertions(+), 8 deletions(-) > > diff --git a/lib/context.c b/lib/context.c > index 5516e49..05fb994 100644 > --- a/lib/context.c > +++ b/lib/context.c > @@ -156,7 +156,6 @@ end: > int bt_context_remove_trace(struct bt_context *ctx, int handle_id) > { > struct bt_trace_handle *handle; > - int ret; > > if (!ctx) > return -EINVAL; > @@ -168,12 +167,7 @@ int bt_context_remove_trace(struct bt_context *ctx, int handle_id) > > /* Remove from containers */ > trace_collection_remove(ctx->tc, handle->td); > - /* Close the trace */ > - ret = handle->format->close_trace(handle->td); > - if (ret) { > - fprintf(stderr, "Error in close_trace callback\n"); > - return ret; > - } > + > /* Remove and free the handle */ > g_hash_table_remove(ctx->trace_handles, > (gpointer) (unsigned long) handle_id); > diff --git a/lib/trace-handle.c b/lib/trace-handle.c > index 0da565b..17a6e0d 100644 > --- a/lib/trace-handle.c > +++ b/lib/trace-handle.c > @@ -49,7 +49,10 @@ struct bt_trace_handle *bt_trace_handle_create(struct bt_context *ctx) > > void bt_trace_handle_destroy(struct bt_trace_handle *th) > { > - th->format->close_trace(th->td); > + if (th->format->close_trace(th->td)) { > + fprintf(stderr, "Error in close_trace callback\n"); > + } > + > g_free(th); > } > > -- > 1.8.1.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From Daniel.Thibault at drdc-rddc.gc.ca Mon Jan 21 14:34:29 2013 From: Daniel.Thibault at drdc-rddc.gc.ca (Thibault, Daniel) Date: Mon, 21 Jan 2013 14:34:29 -0500 Subject: [lttng-dev] Odd dependency for lttng-ust In-Reply-To: <20130121183846.GA6838@Krystal> References: <3CA1A65C03C1A34C81BBC6272782E696987880@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121145954.GA1472@Krystal> <3CA1A65C03C1A34C81BBC6272782E696987887@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121152949.GB1912@Krystal> <3CA1A65C03C1A34C81BBC6272782E69698788F@valcartierex01.valcartier.drdc-rddc.gc.ca> <50FD6474.6070207@efficios.com> <3CA1A65C03C1A34C81BBC6272782E6969878A7@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121170655.GA4268@Krystal> <3CA1A65C03C1A34C81BBC6272782E6969878AE@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121183846.GA6838@Krystal> Message-ID: <3CA1A65C03C1A34C81BBC6272782E6969878C8@valcartierex01.valcartier.drdc-rddc.gc.ca> -----Message d'origine----- De?: Mathieu Desnoyers [mailto:mathieu.desnoyers at efficios.com] Envoy??: 21 janvier 2013 13:39 As the error messages suggests, please try: LDFLAGS=-L/usr/local/lib ./configure instead of "./configure" Mathieu -----Fin du message d'origine----- Interesting, that prefix does allow configure to complete successfully. lttng-tools runs into the same problem as lttng-ust, and requires the same LDFLAGS prefix for its configure. No other problems arise. So how do we fix userspace-rcu so the bootstrap -configure - make - install sequence doesn't run into this problem? I'm presuming here that userspace-rcu's install needs to be touched up. Or maybe lttng-ust's (and lttng-tools's) bootstrap. (It's a problem because the ReadMe for the lttng-ust and lttng-tools packages stipulate a plain ./configure invocation: as they currently stand, the instructions fail) Daniel U. Thibault R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) 2459 route de la Bravoure Qu?bec, QC G3J 1X5 CANADA Vox : (418) 844-4000 x4245 Fax : (418) 844-4538 NAC : 918V QSDJ Gouvernement du Canada / Government of Canada From christian.babeux at efficios.com Mon Jan 21 15:06:51 2013 From: christian.babeux at efficios.com (Christian Babeux) Date: Mon, 21 Jan 2013 15:06:51 -0500 Subject: [lttng-dev] Odd dependency for lttng-ust In-Reply-To: <3CA1A65C03C1A34C81BBC6272782E6969878C8@valcartierex01.valcartier.drdc-rddc.gc.ca> References: <3CA1A65C03C1A34C81BBC6272782E696987880@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121145954.GA1472@Krystal> <3CA1A65C03C1A34C81BBC6272782E696987887@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121152949.GB1912@Krystal> <3CA1A65C03C1A34C81BBC6272782E69698788F@valcartierex01.valcartier.drdc-rddc.gc.ca> <50FD6474.6070207@efficios.com> <3CA1A65C03C1A34C81BBC6272782E6969878A7@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121170655.GA4268@Krystal> <3CA1A65C03C1A34C81BBC6272782E6969878AE@valcartierex01.valcartier.drdc-rddc.gc.ca> <20130121183846.GA6838@Krystal> <3CA1A65C03C1A34C81BBC6272782E6969878C8@valcartierex01.valcartier.drdc-rddc.gc.ca> Message-ID: Hi Daniel, Could you make sure that all previous liburcu versions are properly uninstalled (e.g. no liburcu* in /usr/lib)? I think that you might have an old version installed and that configure is looking up the library via the default LD_LIBRARY_PATH which contains /usr/lib before /usr/local/lib and hence you see the error that "checking for _cds_lfht_new in -lurcu-cds no" even though a newer version is present in /usr/local/lib. As a general guideline, make sure when you install packages from source that you uninstall previous version that might have been installed by your package manager in order to minimize potential conflicts. Christian On Mon, Jan 21, 2013 at 2:34 PM, Thibault, Daniel wrote: > -----Message d'origine----- > De : Mathieu Desnoyers [mailto:mathieu.desnoyers at efficios.com] > Envoy? : 21 janvier 2013 13:39 > > As the error messages suggests, please try: > LDFLAGS=-L/usr/local/lib ./configure > instead of "./configure" > > Mathieu > -----Fin du message d'origine----- > > Interesting, that prefix does allow configure to complete successfully. lttng-tools runs into the same problem as lttng-ust, and requires the same LDFLAGS prefix for its configure. No other problems arise. > > So how do we fix userspace-rcu so the bootstrap -configure - make - install sequence doesn't run into this problem? I'm presuming here that userspace-rcu's install needs to be touched up. Or maybe lttng-ust's (and lttng-tools's) bootstrap. > > (It's a problem because the ReadMe for the lttng-ust and lttng-tools packages stipulate a plain ./configure invocation: as they currently stand, the instructions fail) > > Daniel U. Thibault > R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) > Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) > Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) > 2459 route de la Bravoure > Qu?bec, QC G3J 1X5 > CANADA > Vox : (418) 844-4000 x4245 > Fax : (418) 844-4538 > NAC : 918V QSDJ > Gouvernement du Canada / Government of Canada > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev From jeremie.galarneau at efficios.com Mon Jan 21 10:58:12 2013 From: jeremie.galarneau at efficios.com (=?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=) Date: Mon, 21 Jan 2013 15:58:12 +0000 Subject: [lttng-dev] [RFC PATCH v2 babeltrace] Fix: Double free when calling bt_context_remove_trace(). Message-ID: <1358783892-30542-1-git-send-email-jeremie.galarneau@efficios.com> ctf_close_trace was being called twice when calling bt_context_remove_trace thus causing free() to be called on an invalid pointer. Calling bt_context_remove_trace() would call ctf_close_trace() once via the close_handle callback registered on the ctf format struct and a second call would take place from bt_trace_handle_destroy() which is registered as the value_destroy_func on the trace_handles hash table of the current context. bt_trace_handle_destroy() now only deallocates the trace handle and does not perform the trace closing. This makes the bt_trace_handle_create/destroy and bt_context_add/remove_trace parts of the public API symmetric. The crash is reproducible by invoking the tests-python.py script. Signed-off-by: J?r?mie Galarneau --- lib/trace-handle.c | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/trace-handle.c b/lib/trace-handle.c index 0da565b..455e440 100644 --- a/lib/trace-handle.c +++ b/lib/trace-handle.c @@ -49,7 +49,6 @@ struct bt_trace_handle *bt_trace_handle_create(struct bt_context *ctx) void bt_trace_handle_destroy(struct bt_trace_handle *th) { - th->format->close_trace(th->td); g_free(th); } -- 1.8.1.1 From julien.desfossez at polymtl.ca Mon Jan 21 17:04:41 2013 From: julien.desfossez at polymtl.ca (Julien Desfossez) Date: Mon, 21 Jan 2013 17:04:41 -0500 Subject: [lttng-dev] [PATCH babeltrace] Fix: Double free in bt_context_remove_trace(). In-Reply-To: <20130121193225.GA8005@Krystal> References: <1358777874-24083-1-git-send-email-jeremie.galarneau@efficios.com> <20130121193225.GA8005@Krystal> Message-ID: <50FDBB79.5050908@polymtl.ca> On 21/01/13 02:32 PM, Mathieu Desnoyers wrote: > * J?r?mie Galarneau (jeremie.galarneau at efficios.com) wrote: >> ctf_close_trace was being called twice when calling bt_context_remove_trace thus >> causing free() to be called on an invalid pointer. >> >> Calling bt_context_remove_trace() would call ctf_close_trace() once via the >> close_handle callback registered on the ctf format struct and a second call would >> take place from bt_trace_handle_destroy() which is registered as the >> value_destroy_func on the trace_handles hash table of the current context. >> >> The first explicit call to handle->format->close_trace is unnecessary. >> >> The crash is reproducible by invoking the tests-python.py script. > > I think we should leave the close_trace calls in both locations, but set > handle->td to -1 when we close it, and test for negative handle ID > before doing the close. I agree, we need the two calls to close, one is called when we remove a trace manually and the other one is called when we destroy the context. Setting and testing the td to -1 will solve the problem and will avoid calling close_trace at all if not needed. Thanks, Julien > > Thanks, > > Mathieu > >> >> Signed-off-by: J?r?mie Galarneau >> --- >> lib/context.c | 8 +------- >> lib/trace-handle.c | 5 ++++- >> 2 files changed, 5 insertions(+), 8 deletions(-) >> >> diff --git a/lib/context.c b/lib/context.c >> index 5516e49..05fb994 100644 >> --- a/lib/context.c >> +++ b/lib/context.c >> @@ -156,7 +156,6 @@ end: >> int bt_context_remove_trace(struct bt_context *ctx, int handle_id) >> { >> struct bt_trace_handle *handle; >> - int ret; >> >> if (!ctx) >> return -EINVAL; >> @@ -168,12 +167,7 @@ int bt_context_remove_trace(struct bt_context *ctx, int handle_id) >> >> /* Remove from containers */ >> trace_collection_remove(ctx->tc, handle->td); >> - /* Close the trace */ >> - ret = handle->format->close_trace(handle->td); >> - if (ret) { >> - fprintf(stderr, "Error in close_trace callback\n"); >> - return ret; >> - } >> + >> /* Remove and free the handle */ >> g_hash_table_remove(ctx->trace_handles, >> (gpointer) (unsigned long) handle_id); >> diff --git a/lib/trace-handle.c b/lib/trace-handle.c >> index 0da565b..17a6e0d 100644 >> --- a/lib/trace-handle.c >> +++ b/lib/trace-handle.c >> @@ -49,7 +49,10 @@ struct bt_trace_handle *bt_trace_handle_create(struct bt_context *ctx) >> >> void bt_trace_handle_destroy(struct bt_trace_handle *th) >> { >> - th->format->close_trace(th->td); >> + if (th->format->close_trace(th->td)) { >> + fprintf(stderr, "Error in close_trace callback\n"); >> + } >> + >> g_free(th); >> } >> >> -- >> 1.8.1.1 >> >> >> _______________________________________________ >> lttng-dev mailing list >> lttng-dev at lists.lttng.org >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > From mathieu.desnoyers at efficios.com Mon Jan 21 17:13:54 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 21 Jan 2013 17:13:54 -0500 Subject: [lttng-dev] [PATCH babeltrace] Fix: Double free in bt_context_remove_trace(). In-Reply-To: <50FDBB79.5050908@polymtl.ca> References: <1358777874-24083-1-git-send-email-jeremie.galarneau@efficios.com> <20130121193225.GA8005@Krystal> <50FDBB79.5050908@polymtl.ca> Message-ID: <20130121221354.GA11580@Krystal> * Julien Desfossez (julien.desfossez at polymtl.ca) wrote: > On 21/01/13 02:32 PM, Mathieu Desnoyers wrote: > > * J?r?mie Galarneau (jeremie.galarneau at efficios.com) wrote: > >> ctf_close_trace was being called twice when calling bt_context_remove_trace thus > >> causing free() to be called on an invalid pointer. > >> > >> Calling bt_context_remove_trace() would call ctf_close_trace() once via the > >> close_handle callback registered on the ctf format struct and a second call would > >> take place from bt_trace_handle_destroy() which is registered as the > >> value_destroy_func on the trace_handles hash table of the current context. > >> > >> The first explicit call to handle->format->close_trace is unnecessary. > >> > >> The crash is reproducible by invoking the tests-python.py script. > > > > I think we should leave the close_trace calls in both locations, but set > > handle->td to -1 when we close it, and test for negative handle ID > > before doing the close. > > I agree, we need the two calls to close, one is called when we remove a > trace manually and the other one is called when we destroy the context. > Setting and testing the td to -1 will solve the problem and will avoid > calling close_trace at all if not needed. Can we ever call bt_trace_handle_destroy() manually on a handle that needs the trace to be closed ? After careful review, I don't think so... (see patch v2 from J?r?mie). Thanks, Mathieu > > Thanks, > > Julien > > > > > Thanks, > > > > Mathieu > > > >> > >> Signed-off-by: J?r?mie Galarneau > >> --- > >> lib/context.c | 8 +------- > >> lib/trace-handle.c | 5 ++++- > >> 2 files changed, 5 insertions(+), 8 deletions(-) > >> > >> diff --git a/lib/context.c b/lib/context.c > >> index 5516e49..05fb994 100644 > >> --- a/lib/context.c > >> +++ b/lib/context.c > >> @@ -156,7 +156,6 @@ end: > >> int bt_context_remove_trace(struct bt_context *ctx, int handle_id) > >> { > >> struct bt_trace_handle *handle; > >> - int ret; > >> > >> if (!ctx) > >> return -EINVAL; > >> @@ -168,12 +167,7 @@ int bt_context_remove_trace(struct bt_context *ctx, int handle_id) > >> > >> /* Remove from containers */ > >> trace_collection_remove(ctx->tc, handle->td); > >> - /* Close the trace */ > >> - ret = handle->format->close_trace(handle->td); > >> - if (ret) { > >> - fprintf(stderr, "Error in close_trace callback\n"); > >> - return ret; > >> - } > >> + > >> /* Remove and free the handle */ > >> g_hash_table_remove(ctx->trace_handles, > >> (gpointer) (unsigned long) handle_id); > >> diff --git a/lib/trace-handle.c b/lib/trace-handle.c > >> index 0da565b..17a6e0d 100644 > >> --- a/lib/trace-handle.c > >> +++ b/lib/trace-handle.c > >> @@ -49,7 +49,10 @@ struct bt_trace_handle *bt_trace_handle_create(struct bt_context *ctx) > >> > >> void bt_trace_handle_destroy(struct bt_trace_handle *th) > >> { > >> - th->format->close_trace(th->td); > >> + if (th->format->close_trace(th->td)) { > >> + fprintf(stderr, "Error in close_trace callback\n"); > >> + } > >> + > >> g_free(th); > >> } > >> > >> -- > >> 1.8.1.1 > >> > >> > >> _______________________________________________ > >> lttng-dev mailing list > >> lttng-dev at lists.lttng.org > >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From simon.marchi at polymtl.ca Mon Jan 21 19:54:55 2013 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Mon, 21 Jan 2013 19:54:55 -0500 Subject: [lttng-dev] [PATCH 1/4] tile: move declaration of sys_call_table to Message-ID: <1358816098-13070-1-git-send-email-simon.marchi@polymtl.ca> When activating syscall tracing, kernel/trace/trace_syscalls.c doesn't find sys_call_table because it includes , not . Also, looking at the other architectures, that is probably where it should be. Signed-off-by: Simon Marchi --- arch/tile/include/asm/syscall.h | 6 ++++++ arch/tile/include/asm/syscalls.h | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/tile/include/asm/syscall.h b/arch/tile/include/asm/syscall.h index d35e0dc..9644b88 100644 --- a/arch/tile/include/asm/syscall.h +++ b/arch/tile/include/asm/syscall.h @@ -22,6 +22,12 @@ #include #include +/* The array of function pointers for syscalls. */ +extern void *sys_call_table[]; +#ifdef CONFIG_COMPAT +extern void *compat_sys_call_table[]; +#endif + /* * Only the low 32 bits of orig_r0 are meaningful, so we return int. * This importantly ignores the high bits on 64-bit, so comparisons diff --git a/arch/tile/include/asm/syscalls.h b/arch/tile/include/asm/syscalls.h index 4c8462a..3b18317 100644 --- a/arch/tile/include/asm/syscalls.h +++ b/arch/tile/include/asm/syscalls.h @@ -24,12 +24,6 @@ #include #include -/* The array of function pointers for syscalls. */ -extern void *sys_call_table[]; -#ifdef CONFIG_COMPAT -extern void *compat_sys_call_table[]; -#endif - /* * Note that by convention, any syscall which requires the current * register set takes an additional "struct pt_regs *" pointer; a -- 1.7.1 From simon.marchi at polymtl.ca Mon Jan 21 19:54:56 2013 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Mon, 21 Jan 2013 19:54:56 -0500 Subject: [lttng-dev] [PATCH 2/4] tile: Add definition of NR_syscalls In-Reply-To: <1358816098-13070-1-git-send-email-simon.marchi@polymtl.ca> References: <1358816098-13070-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <1358816098-13070-2-git-send-email-simon.marchi@polymtl.ca> It is required by the syscall tracepoint mechanism. Signed-off-by: Simon Marchi --- arch/tile/include/uapi/asm/unistd.h | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/arch/tile/include/uapi/asm/unistd.h b/arch/tile/include/uapi/asm/unistd.h index cd7b6dd..c763c86 100644 --- a/arch/tile/include/uapi/asm/unistd.h +++ b/arch/tile/include/uapi/asm/unistd.h @@ -20,6 +20,8 @@ /* Use the standard ABI for syscalls. */ #include +#define NR_syscalls (__NR_syscalls) + /* Additional Tilera-specific syscalls. */ #define __NR_cacheflush (__NR_arch_specific_syscall + 1) __SYSCALL(__NR_cacheflush, sys_cacheflush) -- 1.7.1 From simon.marchi at polymtl.ca Mon Jan 21 19:54:57 2013 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Mon, 21 Jan 2013 19:54:57 -0500 Subject: [lttng-dev] [PATCH 3/4] tile: Add support for TIF_SYSCALL_TRACEPOINT In-Reply-To: <1358816098-13070-1-git-send-email-simon.marchi@polymtl.ca> References: <1358816098-13070-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <1358816098-13070-3-git-send-email-simon.marchi@polymtl.ca> This patch adds support for the TIF_SYSCALL_TRACEPOINT on the tile architecture. Basically, it calls the appropriate tracepoints on syscall entry and exit. Signed-off-by: Simon Marchi --- arch/tile/include/asm/thread_info.h | 8 ++++++++ arch/tile/kernel/intvec_64.S | 14 ++++++++++---- arch/tile/kernel/ptrace.c | 17 ++++++++++++++--- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/arch/tile/include/asm/thread_info.h b/arch/tile/include/asm/thread_info.h index e9c670d..c96331e 100644 --- a/arch/tile/include/asm/thread_info.h +++ b/arch/tile/include/asm/thread_info.h @@ -124,6 +124,7 @@ extern void _cpu_idle(void); #define TIF_SECCOMP 6 /* secure computing */ #define TIF_MEMDIE 7 /* OOM killer at work */ #define TIF_NOTIFY_RESUME 8 /* callback before returning to user */ +#define TIF_SYSCALL_TRACEPOINT 9 /* syscall tracepoint instrumentation */ #define _TIF_SIGPENDING (1< #include +#define CREATE_TRACE_POINTS +#include + void user_enable_single_step(struct task_struct *child) { set_tsk_thread_flag(child, TIF_SINGLESTEP); @@ -249,16 +252,24 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, int do_syscall_trace_enter(struct pt_regs *regs) { - if (tracehook_report_syscall_entry(regs)) { - regs->regs[TREG_SYSCALL_NR] = -1; + if (test_thread_flag(TIF_SYSCALL_TRACE)) { + if (tracehook_report_syscall_entry(regs)) + regs->regs[TREG_SYSCALL_NR] = -1; } + if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) + trace_sys_enter(regs, regs->regs[TREG_SYSCALL_NR]); + return regs->regs[TREG_SYSCALL_NR]; } void do_syscall_trace_exit(struct pt_regs *regs) { - tracehook_report_syscall_exit(regs, 0); + if (test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall_exit(regs, 0); + + if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) + trace_sys_exit(regs, regs->regs[TREG_SYSCALL_NR]); } void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code) -- 1.7.1 From simon.marchi at polymtl.ca Mon Jan 21 19:54:58 2013 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Mon, 21 Jan 2013 19:54:58 -0500 Subject: [lttng-dev] [PATCH 4/4] tile: select HAVE_SYSCALL_TRACEPOINTS In-Reply-To: <1358816098-13070-1-git-send-email-simon.marchi@polymtl.ca> References: <1358816098-13070-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <1358816098-13070-4-git-send-email-simon.marchi@polymtl.ca> Signed-off-by: Simon Marchi --- arch/tile/Kconfig | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 8cab409..1adb853 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig @@ -22,6 +22,7 @@ config TILE select GENERIC_CLOCKEVENTS select MODULES_USE_ELF_RELA select HAVE_ARCH_TRACEHOOK + select HAVE_SYSCALL_TRACEPOINTS # FIXME: investigate whether we need/want these options. # select HAVE_IOREMAP_PROT -- 1.7.1 From mathieu.desnoyers at efficios.com Mon Jan 21 20:06:53 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 21 Jan 2013 20:06:53 -0500 Subject: [lttng-dev] [PATCH 2/4] tile: Add definition of NR_syscalls In-Reply-To: <1358816098-13070-2-git-send-email-simon.marchi@polymtl.ca> References: <1358816098-13070-1-git-send-email-simon.marchi@polymtl.ca> <1358816098-13070-2-git-send-email-simon.marchi@polymtl.ca> Message-ID: <20130122010653.GA27148@Krystal> * Simon Marchi (simon.marchi at polymtl.ca) wrote: > It is required by the syscall tracepoint mechanism. > > Signed-off-by: Simon Marchi > --- > arch/tile/include/uapi/asm/unistd.h | 2 ++ > 1 files changed, 2 insertions(+), 0 deletions(-) > > diff --git a/arch/tile/include/uapi/asm/unistd.h b/arch/tile/include/uapi/asm/unistd.h > index cd7b6dd..c763c86 100644 > --- a/arch/tile/include/uapi/asm/unistd.h > +++ b/arch/tile/include/uapi/asm/unistd.h > @@ -20,6 +20,8 @@ > /* Use the standard ABI for syscalls. */ > #include > > +#define NR_syscalls (__NR_syscalls) The parenthesis around __NR_syscalls seems unnecessary. (unless parenthesis would happen to be missing around a __NR_syscalls definition with multiple identifiers, but clearly, the parenthesis don't belong here). Thanks, Mathieu > + > /* Additional Tilera-specific syscalls. */ > #define __NR_cacheflush (__NR_arch_specific_syscall + 1) > __SYSCALL(__NR_cacheflush, sys_cacheflush) > -- > 1.7.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From rusty at rustcorp.com.au Mon Jan 21 17:59:49 2013 From: rusty at rustcorp.com.au (Rusty Russell) Date: Tue, 22 Jan 2013 09:29:49 +1030 Subject: [lttng-dev] Coding blog: lockless queues In-Reply-To: <20130110165942.GA5133@Krystal> References: <20130110165942.GA5133@Krystal> Message-ID: <87ip6quopm.fsf@rustcorp.com.au> Mathieu Desnoyers writes: > Hi Rusty! > > I've stumbled on your blog post: http://rusty.ozlabs.org/?p=317 > > and I find that you looked at the RCU lock-free queue implementation in > the Userspace RCU project, but not at the wait-free concurrent queue > implementation we have (wait-free enqueue, blocking dequeue), which does > not require RCU at all and might be a much better fit for what you are > trying to achieve. Clearly, I stopped reading too early! It's a very nice implementation... If I revisit this, I'll do a code review and post it on my blog. Thanks! Rusty. From eag0628 at gmail.com Tue Jan 22 09:24:09 2013 From: eag0628 at gmail.com (Lai Jiangshan) Date: Tue, 22 Jan 2013 22:24:09 +0800 Subject: [lttng-dev] Query on the rculist In-Reply-To: <20130121141645.GB31140@Krystal> References: <50FCA183.8030201@gmail.com> <20130121141645.GB31140@Krystal> Message-ID: <50FEA109.6060404@gmail.com> ? 2013/1/21 22:16, Mathieu Desnoyers ??: > * Liu Yuan (namei.unix at gmail.com) wrote: >> Hi List, >> >> I noticed that there are just few functions suffixed with rcu for >> rculist. And from the source of Linux kernel rculist, I came up with >> some comments saying that list_empty_rcu() can be simply achieved by >> calling list_empty(). Is this true to urcu too? My questions is, are >> following equivalents true? >> >> list_empty_rcu -> list_empty > > Yes. > >> list_del_init_rcu -> list_del_init > > No. Add a trivial comment. There is no list_del_init_rcu(), "init" hurts "rcu". If you need a re-initialized object after deletion, you should use synchronzie_rcu(): list_del_rcu(); synchronize_rcu(); CDS_INIT_LIST_HEAD(); > >> >> If there are more equivalents, please show light on it. > > I will prepare a patch to extend and document the list and rculist APIs. > Your feedback is welcome. > > Thanks! > > Mathieu > >> >> Thanks, >> Yuan > From Daniel.Thibault at drdc-rddc.gc.ca Tue Jan 22 12:22:51 2013 From: Daniel.Thibault at drdc-rddc.gc.ca (Thibault, Daniel) Date: Tue, 22 Jan 2013 12:22:51 -0500 Subject: [lttng-dev] LTTng modules not loading? Message-ID: <3CA1A65C03C1A34C81BBC6272782E696987933@valcartierex01.valcartier.drdc-rddc.gc.ca> My two Ubuntu installations have the same set of LTTng modules and tools (they were all built from the same git.lttng.org packages) but different kernels and installation histories. The "clean" machine has kernel linux-virtual (3.2.0-36-virtual), the other one has linux-generic (3.2.0-35-generic). After installing LTTng and rebooting, the clean machine does *not* load the lttng kernel modules, while the other one does. /etc/modules and /etc/modprobe.d are the same, the .ko are present in /lib/modules//extra in both cases. The clean machine's lttng kernel modules can be loaded using modprobe without demur, so there is no problem there. At first I thought this was because the clean machine had not installed the dkms package yet, but adding it made no difference: the lttng modules do not load. How can I get the clean machine to load the lttng kernel modules at boot time? Daniel U. Thibault R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) 2459 route de la Bravoure Qu?bec, QC G3J 1X5 CANADA Vox : (418) 844-4000 x4245 Fax : (418) 844-4538 NAC : 918V QSDJ Gouvernement du Canada / Government of Canada From dgoulet at efficios.com Tue Jan 22 12:28:03 2013 From: dgoulet at efficios.com (David Goulet) Date: Tue, 22 Jan 2013 12:28:03 -0500 Subject: [lttng-dev] LTTng modules not loading? In-Reply-To: <3CA1A65C03C1A34C81BBC6272782E696987933@valcartierex01.valcartier.drdc-rddc.gc.ca> References: <3CA1A65C03C1A34C81BBC6272782E696987933@valcartierex01.valcartier.drdc-rddc.gc.ca> Message-ID: <50FECC23.4040207@efficios.com> Usually, it's the lttng-sessiond's job to load the kernel modules. So the quick fix here would be to start a session daemon at boot with of course root privileges. Thanks! David Thibault, Daniel: > My two Ubuntu installations have the same set of LTTng modules and tools (they were all built from the same git.lttng.org packages) but different kernels and installation histories. The "clean" machine has kernel linux-virtual (3.2.0-36-virtual), the other one has linux-generic (3.2.0-35-generic). After installing LTTng and rebooting, the clean machine does *not* load the lttng kernel modules, while the other one does. /etc/modules and /etc/modprobe.d are the same, the .ko are present in /lib/modules//extra in both cases. The clean machine's lttng kernel modules can be loaded using modprobe without demur, so there is no problem there. > > At first I thought this was because the clean machine had not installed the dkms package yet, but adding it made no difference: the lttng modules do not load. > > How can I get the clean machine to load the lttng kernel modules at boot time? > > Daniel U. Thibault > R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) > Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) > Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) > 2459 route de la Bravoure > Qu?bec, QC G3J 1X5 > CANADA > Vox : (418) 844-4000 x4245 > Fax : (418) 844-4538 > NAC : 918V QSDJ > Gouvernement du Canada / Government of Canada > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev From cmetcalf at tilera.com Tue Jan 22 15:23:40 2013 From: cmetcalf at tilera.com (Chris Metcalf) Date: Tue, 22 Jan 2013 15:23:40 -0500 Subject: [lttng-dev] [PATCH 4/4] tile: select HAVE_SYSCALL_TRACEPOINTS In-Reply-To: <1358816098-13070-4-git-send-email-simon.marchi@polymtl.ca> References: <1358816098-13070-1-git-send-email-simon.marchi@polymtl.ca> <1358816098-13070-4-git-send-email-simon.marchi@polymtl.ca> Message-ID: <50FEF54C.40209@tilera.com> On 1/21/2013 7:54 PM, Simon Marchi wrote: > Signed-off-by: Simon Marchi > --- > arch/tile/Kconfig | 1 + > 1 files changed, 1 insertions(+), 0 deletions(-) Thanks! I took the series of four patches into the tile tree for 3.9 (removing the parentheses around the definition of NR_syscalls). -- Chris Metcalf, Tilera Corp. http://www.tilera.com From Daniel.Thibault at drdc-rddc.gc.ca Tue Jan 22 15:32:01 2013 From: Daniel.Thibault at drdc-rddc.gc.ca (Thibault, Daniel) Date: Tue, 22 Jan 2013 15:32:01 -0500 Subject: [lttng-dev] Automating lttng-sessiond startup Message-ID: <3CA1A65C03C1A34C81BBC6272782E69698797F@valcartierex01.valcartier.drdc-rddc.gc.ca> To answer my own earlier question, the Ubuntu lttng packages (but not the git.lttng.org packages) automate the launch of the lttng-sessiond daemon through the Upstart service, by adding /etc/init/lttng-sessiond.conf: description "LTTng 2.0 central tracing registry session daemon" author "St?phane Graber " start on local-filesystems stop on runlevel [06] respawn exec lttng-sessiond You need only create this file (as root) to have the git.lttng.org LTTng installation on a par with the Ubuntu packages'. Daniel U. Thibault R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) 2459 route de la Bravoure Qu?bec, QC? G3J 1X5 CANADA Vox?: (418) 844-4000 x4245 Fax?: (418) 844-4538 NAC?: 918V QSDJ Gouvernement du Canada?/ Government of Canada From mathieu.desnoyers at efficios.com Tue Jan 22 16:51:14 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 22 Jan 2013 16:51:14 -0500 Subject: [lttng-dev] Automating lttng-sessiond startup In-Reply-To: <3CA1A65C03C1A34C81BBC6272782E69698797F@valcartierex01.valcartier.drdc-rddc.gc.ca> References: <3CA1A65C03C1A34C81BBC6272782E69698797F@valcartierex01.valcartier.drdc-rddc.gc.ca> Message-ID: <20130122215114.GA30918@Krystal> We plan to put these init scripts into extras/ within lttng-tools at some point, with appropriate documentation. This part of the install process is rather hard to automate nowadays, since every distribution has its own init system (upstrart, initrd, others). Thanks, Mathieu * Thibault, Daniel (Daniel.Thibault at drdc-rddc.gc.ca) wrote: > To answer my own earlier question, the Ubuntu lttng packages (but not the git.lttng.org packages) automate the launch of the lttng-sessiond daemon through the Upstart service, by adding /etc/init/lttng-sessiond.conf: > > description "LTTng 2.0 central tracing registry session daemon" > author "St?phane Graber " > start on local-filesystems > stop on runlevel [06] > respawn > exec lttng-sessiond > > You need only create this file (as root) to have the git.lttng.org LTTng installation on a par with the Ubuntu packages'. > > Daniel U. Thibault > R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) > Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) > Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) > 2459 route de la Bravoure > Qu?bec, QC? G3J 1X5 > CANADA > Vox?: (418) 844-4000 x4245 > Fax?: (418) 844-4538 > NAC?: 918V QSDJ > Gouvernement du Canada?/ Government of Canada > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From jeremie.galarneau at efficios.com Tue Jan 22 18:47:25 2013 From: jeremie.galarneau at efficios.com (=?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=) Date: Tue, 22 Jan 2013 23:47:25 +0000 Subject: [lttng-dev] [PATCH babeltrace 1/2] Add missing shebangs to Python examples. Message-ID: <1358898446-1622-1-git-send-email-jeremie.galarneau@efficios.com> Signed-off-by: J?r?mie Galarneau --- bindings/python/examples/babeltrace_and_lttng.py | 1 + bindings/python/examples/eventcount.py | 1 + bindings/python/examples/eventcountlist.py | 1 + bindings/python/examples/events_per_cpu.py | 1 + bindings/python/examples/example-api-test.py | 1 + bindings/python/examples/histogram.py | 1 + bindings/python/examples/sched_switch.py | 1 + bindings/python/examples/softirqtimes.py | 1 + bindings/python/examples/syscalls_by_pid.py | 1 + 9 files changed, 9 insertions(+) mode change 100644 => 100755 bindings/python/examples/babeltrace_and_lttng.py mode change 100644 => 100755 bindings/python/examples/eventcount.py mode change 100644 => 100755 bindings/python/examples/eventcountlist.py mode change 100644 => 100755 bindings/python/examples/events_per_cpu.py mode change 100644 => 100755 bindings/python/examples/example-api-test.py mode change 100644 => 100755 bindings/python/examples/histogram.py mode change 100644 => 100755 bindings/python/examples/sched_switch.py mode change 100644 => 100755 bindings/python/examples/softirqtimes.py mode change 100644 => 100755 bindings/python/examples/syscalls_by_pid.py diff --git a/bindings/python/examples/babeltrace_and_lttng.py b/bindings/python/examples/babeltrace_and_lttng.py old mode 100644 new mode 100755 index cb44796..5ab358c --- a/bindings/python/examples/babeltrace_and_lttng.py +++ b/bindings/python/examples/babeltrace_and_lttng.py @@ -1,3 +1,4 @@ +#!/usr/bin/python # babeltrace_and_lttng.py # # Babeltrace and LTTng example script diff --git a/bindings/python/examples/eventcount.py b/bindings/python/examples/eventcount.py old mode 100644 new mode 100755 index 5e96a43..0cc9e19 --- a/bindings/python/examples/eventcount.py +++ b/bindings/python/examples/eventcount.py @@ -1,3 +1,4 @@ +#!/usr/bin/python # eventcount.py # # Babeltrace event count example script diff --git a/bindings/python/examples/eventcountlist.py b/bindings/python/examples/eventcountlist.py old mode 100644 new mode 100755 index 945a960..eb413a8 --- a/bindings/python/examples/eventcountlist.py +++ b/bindings/python/examples/eventcountlist.py @@ -1,3 +1,4 @@ +#!/usr/bin/python # eventcountlist.py # # Babeltrace event count list example script diff --git a/bindings/python/examples/events_per_cpu.py b/bindings/python/examples/events_per_cpu.py old mode 100644 new mode 100755 index be497ec..7e871d1 --- a/bindings/python/examples/events_per_cpu.py +++ b/bindings/python/examples/events_per_cpu.py @@ -1,3 +1,4 @@ +#!/usr/bin/python # events_per_cpu.py # # Babeltrace events per cpu example script diff --git a/bindings/python/examples/example-api-test.py b/bindings/python/examples/example-api-test.py old mode 100644 new mode 100755 index 104f2d5..37e9f4b --- a/bindings/python/examples/example-api-test.py +++ b/bindings/python/examples/example-api-test.py @@ -1,3 +1,4 @@ +#!/usr/bin/python # example_api_test.py # # Babeltrace example script based on the Babeltrace API test script diff --git a/bindings/python/examples/histogram.py b/bindings/python/examples/histogram.py old mode 100644 new mode 100755 index 44616a6..533abeb --- a/bindings/python/examples/histogram.py +++ b/bindings/python/examples/histogram.py @@ -1,3 +1,4 @@ +#!/usr/bin/python # histogram.py # # Babeltrace histogram example script diff --git a/bindings/python/examples/sched_switch.py b/bindings/python/examples/sched_switch.py old mode 100644 new mode 100755 index 7ae834b..cee882f --- a/bindings/python/examples/sched_switch.py +++ b/bindings/python/examples/sched_switch.py @@ -1,3 +1,4 @@ +#!/usr/bin/python # sched_switch.py # # Babeltrace example script with sched_switch events diff --git a/bindings/python/examples/softirqtimes.py b/bindings/python/examples/softirqtimes.py old mode 100644 new mode 100755 index 903bf3e..8e465d2 --- a/bindings/python/examples/softirqtimes.py +++ b/bindings/python/examples/softirqtimes.py @@ -1,3 +1,4 @@ +#!/usr/bin/python # softirqtimes.py # # Babeltrace time of softirqs example script diff --git a/bindings/python/examples/syscalls_by_pid.py b/bindings/python/examples/syscalls_by_pid.py old mode 100644 new mode 100755 index 3ae342e..30ece11 --- a/bindings/python/examples/syscalls_by_pid.py +++ b/bindings/python/examples/syscalls_by_pid.py @@ -1,3 +1,4 @@ +#!/usr/bin/python # syscall_by_pid.py # # Babeltrace syscall by pid example script -- 1.8.1.1 From jeremie.galarneau at efficios.com Tue Jan 22 18:47:26 2013 From: jeremie.galarneau at efficios.com (=?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=) Date: Tue, 22 Jan 2013 23:47:26 +0000 Subject: [lttng-dev] [PATCH babeltrace 2/2] Fix: Unified types expected by the Definition Python interface. In-Reply-To: <1358898446-1622-1-git-send-email-jeremie.galarneau@efficios.com> References: <1358898446-1622-1-git-send-email-jeremie.galarneau@efficios.com> Message-ID: <1358898446-1622-2-git-send-email-jeremie.galarneau@efficios.com> This change makes the Python iterator test case execute successfully. Signed-off-by: J?r?mie Galarneau --- bindings/python/babeltrace.i.in | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/bindings/python/babeltrace.i.in b/bindings/python/babeltrace.i.in index dd49ba5..a5426c8 100644 --- a/bindings/python/babeltrace.i.in +++ b/bindings/python/babeltrace.i.in @@ -553,8 +553,8 @@ struct bt_ctf_event *bt_ctf_iter_read_event(struct bt_ctf_iter *iter); const struct definition *scope, const char *field); %rename("_bt_ctf_get_index") bt_ctf_get_index(const struct bt_ctf_event *ctf_event, const struct definition *field, unsigned int index); -%rename("_bt_ctf_field_name") bt_ctf_field_name(const struct definition *def); -%rename("_bt_ctf_field_type") bt_ctf_field_type(const struct declaration *def); +%rename("_bt_ctf_field_name") bt_ctf_field_name(const struct definition *field); +%rename("_bt_ctf_field_type") bt_ctf_field_type(const struct declaration *field); %rename("_bt_ctf_get_int_signedness") bt_ctf_get_int_signedness( const struct declaration *field); %rename("_bt_ctf_get_int_base") bt_ctf_get_int_base(const struct declaration *field); @@ -572,6 +572,8 @@ struct bt_ctf_event *bt_ctf_iter_read_event(struct bt_ctf_iter *iter); bt_ctf_event_decl *event); %rename("_bt_ctf_get_decl_field_name") bt_ctf_get_decl_field_name( const struct bt_ctf_field_decl *field); +%rename("_bt_ctf_get_decl_from_def") bt_ctf_get_decl_from_def( + const struct definition *field); const struct definition *bt_ctf_get_top_level_scope(const struct bt_ctf_event *ctf_event, enum bt_ctf_scope scope); @@ -584,8 +586,8 @@ const struct definition *bt_ctf_get_field(const struct bt_ctf_event *ctf_event, const struct definition *bt_ctf_get_index(const struct bt_ctf_event *ctf_event, const struct definition *field, unsigned int index); -const char *bt_ctf_field_name(const struct definition *def); -enum ctf_type_id bt_ctf_field_type(const struct declaration *def); +const char *bt_ctf_field_name(const struct definition *field); +enum ctf_type_id bt_ctf_field_type(const struct declaration *field); int bt_ctf_get_int_signedness(const struct declaration *field); int bt_ctf_get_int_base(const struct declaration *field); int bt_ctf_get_int_byte_order(const struct declaration *field); @@ -599,6 +601,7 @@ char *bt_ctf_get_string(const struct definition *field); int bt_ctf_field_get_error(void); const char *bt_ctf_get_decl_event_name(const struct bt_ctf_event_decl *event); const char *bt_ctf_get_decl_field_name(const struct bt_ctf_field_decl *field); +const struct declaration *bt_ctf_get_decl_from_def(const struct definition *field); %pythoncode%{ @@ -839,25 +842,25 @@ class ctf: def field_type(self): """Return the type of a field or -1 if unknown.""" - return _bt_ctf_field_type(self._d) + return _bt_ctf_field_type(_bt_ctf_get_decl_from_def(self._d)) def get_int_signedness(self): """ Return the signedness of an integer: 0 if unsigned; 1 if signed; -1 on error. """ - return _bt_ctf_get_int_signedness(self._d) + return _bt_ctf_get_int_signedness(_bt_ctf_get_decl_from_def(self._d)) def get_int_base(self): """Return the base of an int or a negative value on error.""" - return _bt_ctf_get_int_base(self._d) + return _bt_ctf_get_int_base(_bt_ctf_get_decl_from_def(self._d)) def get_int_byte_order(self): """ Return the byte order of an int or a negative value on error. """ - return _bt_ctf_get_int_byte_order(self._d) + return _bt_ctf_get_int_byte_order(_bt_ctf_get_decl_from_def(self._d)) def get_int_len(self): """ @@ -871,14 +874,14 @@ class ctf: Return the encoding of an int or a string. Return a negative value on error. """ - return _bt_ctf_get_encoding(self._d) + return _bt_ctf_get_encoding(_bt_ctf_get_decl_from_def(self._d)) def get_array_len(self): """ Return the len of an array or a negative value on error. """ - return _bt_ctf_get_array_len(self._d) + return _bt_ctf_get_array_len(_bt_ctf_get_decl_from_def(self._d)) def get_uint64(self): """ -- 1.8.1.1 From mathieu.desnoyers at efficios.com Wed Jan 23 09:45:50 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 23 Jan 2013 09:45:50 -0500 Subject: [lttng-dev] [PATCH babeltrace 1/2] Add missing shebangs to Python examples. In-Reply-To: <1358898446-1622-1-git-send-email-jeremie.galarneau@efficios.com> References: <1358898446-1622-1-git-send-email-jeremie.galarneau@efficios.com> Message-ID: <20130123144550.GA3952@Krystal> * J?r?mie Galarneau (jeremie.galarneau at efficios.com) wrote: > > Signed-off-by: J?r?mie Galarneau > --- > bindings/python/examples/babeltrace_and_lttng.py | 1 + > bindings/python/examples/eventcount.py | 1 + > bindings/python/examples/eventcountlist.py | 1 + > bindings/python/examples/events_per_cpu.py | 1 + > bindings/python/examples/example-api-test.py | 1 + > bindings/python/examples/histogram.py | 1 + > bindings/python/examples/sched_switch.py | 1 + > bindings/python/examples/softirqtimes.py | 1 + > bindings/python/examples/syscalls_by_pid.py | 1 + > 9 files changed, 9 insertions(+) > mode change 100644 => 100755 bindings/python/examples/babeltrace_and_lttng.py > mode change 100644 => 100755 bindings/python/examples/eventcount.py > mode change 100644 => 100755 bindings/python/examples/eventcountlist.py > mode change 100644 => 100755 bindings/python/examples/events_per_cpu.py > mode change 100644 => 100755 bindings/python/examples/example-api-test.py > mode change 100644 => 100755 bindings/python/examples/histogram.py > mode change 100644 => 100755 bindings/python/examples/sched_switch.py > mode change 100644 => 100755 bindings/python/examples/softirqtimes.py > mode change 100644 => 100755 bindings/python/examples/syscalls_by_pid.py > > diff --git a/bindings/python/examples/babeltrace_and_lttng.py b/bindings/python/examples/babeltrace_and_lttng.py > old mode 100644 > new mode 100755 > index cb44796..5ab358c > --- a/bindings/python/examples/babeltrace_and_lttng.py > +++ b/bindings/python/examples/babeltrace_and_lttng.py > @@ -1,3 +1,4 @@ > +#!/usr/bin/python Please compare with other lttng projects (see tools tests), where I think we use "env" and then python. So I'm not sure which roule we want to go, but I think this has to do with Debian not having the same symlinks that other distros wrt python 2 and 3. Thanks, Mathieu > # babeltrace_and_lttng.py > # > # Babeltrace and LTTng example script > diff --git a/bindings/python/examples/eventcount.py b/bindings/python/examples/eventcount.py > old mode 100644 > new mode 100755 > index 5e96a43..0cc9e19 > --- a/bindings/python/examples/eventcount.py > +++ b/bindings/python/examples/eventcount.py > @@ -1,3 +1,4 @@ > +#!/usr/bin/python > # eventcount.py > # > # Babeltrace event count example script > diff --git a/bindings/python/examples/eventcountlist.py b/bindings/python/examples/eventcountlist.py > old mode 100644 > new mode 100755 > index 945a960..eb413a8 > --- a/bindings/python/examples/eventcountlist.py > +++ b/bindings/python/examples/eventcountlist.py > @@ -1,3 +1,4 @@ > +#!/usr/bin/python > # eventcountlist.py > # > # Babeltrace event count list example script > diff --git a/bindings/python/examples/events_per_cpu.py b/bindings/python/examples/events_per_cpu.py > old mode 100644 > new mode 100755 > index be497ec..7e871d1 > --- a/bindings/python/examples/events_per_cpu.py > +++ b/bindings/python/examples/events_per_cpu.py > @@ -1,3 +1,4 @@ > +#!/usr/bin/python > # events_per_cpu.py > # > # Babeltrace events per cpu example script > diff --git a/bindings/python/examples/example-api-test.py b/bindings/python/examples/example-api-test.py > old mode 100644 > new mode 100755 > index 104f2d5..37e9f4b > --- a/bindings/python/examples/example-api-test.py > +++ b/bindings/python/examples/example-api-test.py > @@ -1,3 +1,4 @@ > +#!/usr/bin/python > # example_api_test.py > # > # Babeltrace example script based on the Babeltrace API test script > diff --git a/bindings/python/examples/histogram.py b/bindings/python/examples/histogram.py > old mode 100644 > new mode 100755 > index 44616a6..533abeb > --- a/bindings/python/examples/histogram.py > +++ b/bindings/python/examples/histogram.py > @@ -1,3 +1,4 @@ > +#!/usr/bin/python > # histogram.py > # > # Babeltrace histogram example script > diff --git a/bindings/python/examples/sched_switch.py b/bindings/python/examples/sched_switch.py > old mode 100644 > new mode 100755 > index 7ae834b..cee882f > --- a/bindings/python/examples/sched_switch.py > +++ b/bindings/python/examples/sched_switch.py > @@ -1,3 +1,4 @@ > +#!/usr/bin/python > # sched_switch.py > # > # Babeltrace example script with sched_switch events > diff --git a/bindings/python/examples/softirqtimes.py b/bindings/python/examples/softirqtimes.py > old mode 100644 > new mode 100755 > index 903bf3e..8e465d2 > --- a/bindings/python/examples/softirqtimes.py > +++ b/bindings/python/examples/softirqtimes.py > @@ -1,3 +1,4 @@ > +#!/usr/bin/python > # softirqtimes.py > # > # Babeltrace time of softirqs example script > diff --git a/bindings/python/examples/syscalls_by_pid.py b/bindings/python/examples/syscalls_by_pid.py > old mode 100644 > new mode 100755 > index 3ae342e..30ece11 > --- a/bindings/python/examples/syscalls_by_pid.py > +++ b/bindings/python/examples/syscalls_by_pid.py > @@ -1,3 +1,4 @@ > +#!/usr/bin/python > # syscall_by_pid.py > # > # Babeltrace syscall by pid example script > -- > 1.8.1.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From christian.babeux at efficios.com Wed Jan 23 12:05:48 2013 From: christian.babeux at efficios.com (Christian Babeux) Date: Wed, 23 Jan 2013 12:05:48 -0500 Subject: [lttng-dev] [PATCH babeltrace 1/2] Add missing shebangs to Python examples. In-Reply-To: <20130123144550.GA3952@Krystal> References: <1358898446-1622-1-git-send-email-jeremie.galarneau@efficios.com> <20130123144550.GA3952@Krystal> Message-ID: > Please compare with other lttng projects (see tools tests), where I > think we use "env" and then python. So I'm not sure which roule we want > to go, but I think this has to do with Debian not having the same > symlinks that other distros wrt python 2 and 3. I would recommend using "#!/usr/bin/env python" so it will default to the Python interpreter available on the machine. Take note that we might have issues with Python 3 interpreters if the scripts are not fully compliant. Thanks, Christian From Erik.Ostermueller at fisglobal.com Wed Jan 23 13:03:15 2013 From: Erik.Ostermueller at fisglobal.com (Ostermueller, Erik) Date: Wed, 23 Jan 2013 18:03:15 +0000 Subject: [lttng-dev] tracing of non-JNI java in IBM jvm In-Reply-To: <439402897.6438391.1357930537656.JavaMail.root@vmware.com> References: <439402897.6438391.1357930537656.JavaMail.root@vmware.com> Message-ID: Aaron, Sorry to have disappeared from this discussion. What if we went is a slightly different direction. The InTrace tool (http://mchr3k.github.com/org.intrace/) will log start/stop times of dynamically instrumented methods to a text file (proprietary format). What if we simply wrote a process to convert that log to CTF, and view the trace with the lttng eclipse plug-in, unmodified. The idea would be to, at first, just support these two views: http://wiki.eclipse.org/Linux_Tools_Project/LTTng/User_Guide#Control_Flow_View http://wiki.eclipse.org/Linux_Tools_Project/LTTng/User_Guide#Statistics_View --Erik -----Original Message----- From: Aaron Spear [mailto:aspear at vmware.com] Sent: Friday, January 11, 2013 12:56 PM To: Ostermueller, Erik Cc: lttng-dev at lists.lttng.org; Alexandre Montplaisir Subject: Re: [lttng-dev] tracing of non-JNI java in IBM jvm ----- Original Message ----- > From: "Erik Ostermueller" > To: "Alexandre Montplaisir" > Cc: lttng-dev at lists.lttng.org > Sent: Friday, January 11, 2013 9:26:51 AM > Subject: Re: [lttng-dev] tracing of non-JNI java in IBM jvm > > Thanks Alex for the quick reply....now I get it. > I'll jump in on that other thread you mentioned. > > There is a tool called InTrace that does some of this work. > Perhaps some design ideas or even code could be stolen from here: > http://mchr3k.github.com/org.intrace/ > This project: > * implements the java.lang.instrumentation api, which can be used to > plug a tracing tool into an already-running JVM. > * allows you to instrument/de-instrument various classes without > restarting the JVM. > * Uses http://asm.ow2.org/ to inject byte code for entry/exit tracing > methods. > * stores thread id (good) but does nothing to sort/organize activity > by thread id into a session(bad) > * no graphing/aggregating of performance metrics...just displays > entry/exit times, method parameters, etc... Hi Erik, I think that what you are mentioning is certainly one thing that is needed. To me I see a couple of different components here: 1) implementation of java.util.logging interfaces as well as SLF4J interfaces, as well as a dedicated LTTng java API for registering custom event typess. This would be used for static, compile time instrumentation of java apps. 2) an implementation that uses the tooling you mention above for dynamic instrumentation of any running java app. You basically would define trace and install trace points on the fly. This would be really, really powerful. The implementations of the above would have to be quite different from the way that things are done currently with UST. Currently UST uses macros in C files to define the various tracepoints statically. We would need to have API's that could be called dynamically to define tracepoints, so that the java code could do this. I have not actually looked under the hood with the current UST implementation to see what the implications are for this. It seems to me that we would want to have a Java API usage similar to what you can do with SLF4J: class MyClass { private static final Tracer tracer = LTTngFactory.getTracer("MyComponentName"); private static final String MY_TRACEPOINT = "MyTracepointWithIntegerStringAndLong"; static { // register a tracepoint. this goes through JNI and creates a tracepoint // in UST that has the given name and the specified objects tracer.registerTracepoint(MY_TRACEPOINT, new Object[]{Integer.class,String.class,Long.class}); } public void someMethod() { Integer someInteger = 123456; String someString = "this is the string"; Long someLong = 56789; tracer.trace(MY_TRACEPOINT,someInteger,someString,someLong); } } Then over the top of this you have implementations of SLF4J, java.util.logging, whatever. The infrastructure required in the JNI side for this would be the same implementation needed by the binding to the InTrace technology to dynamically create tracepoints. I need all of this right now, and am willing to spend time in the next few months to implement it. cheers, Aaron Spear, Staff Engineer, VMware Inc _____________ The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you. From aspear at vmware.com Wed Jan 23 14:45:08 2013 From: aspear at vmware.com (Aaron Spear) Date: Wed, 23 Jan 2013 11:45:08 -0800 (PST) Subject: [lttng-dev] tracing of non-JNI java in IBM jvm In-Reply-To: Message-ID: <2081361152.17856221.1358970308809.JavaMail.root@vmware.com> Hi Erik, I am happy to report that I already implemented what I mentioned before as a *prototype*. My solution has the following: -JNI library and classes that use UST to log function entries-exits. So I end up with a CTF log that has function entries and exits. -extension to in-trace agent library to use this library for function entries and exits. So, you can select a subset of classes to instrument dynamically. -clone of the Control Flow View that understands this particular function entry and exit event schema -I have threads as the parent, and then whatever functions the thread calls as children. If you collapse the thread, you still see intervals over which it is running which is nice. The net result is that you can see Gantt charts of function calls in *any* java application. All you have to do is 1) launch the java app injecting the custom in-trace agent 2) start lttng ust tracing 3) connect to the java app's injected agent and select what classes you want instrumented See the attached screenshot that shows a very simple java application that spawns 5 threads, and each thread calls 4 functions and then exits. I think that the idea is pretty cool and have the intent to contribute it if there is interest. This implementation is not yet ready to show anyone as I hacked it together for a paper that I am writing. Here are a few of the caveats about it: 1) the current implementation is quite intrusive on the java side. Sloppy use of strings in particular. It needs some careful architecting. I have a number of ideas on this front, but have not yet had bandwidth to implement them. 2) There are lots of details to be worked out with the in-trace integration. The current collection UI really needs some help. I tried briefly to get the eclipse plugin to work with Eclipse 4, but only the RCP app seems to work for me. I think that the "Connections" view needs to have different collection agents plugged in and you should be able to connect to a java app and dynamically select classes to instrument and/or select from sets of classes/methods. 3) My vision is to create a viewer that could do arbitrary state over time, and use CTF extensions to feed this so that the implementation is entirely data driven. Basically any hierarchy of parent-child entries with state under them. This particular one is, like the LTTng Control Flow View, hard coded to the event schema right now, but I can see how we can make it more general. I should say that the guys that wrote the framework did a good job of making it useable for different things (nice work guys!) Note that you could in fact use it for instrumenting native applications as well of course. The "DynamoRIO" project in particular does the same sort of thing as In Trace does (only more efficiently) so I think this is quite viable as a collection mechanism. cheers! Aaron Spear ----- Original Message ----- > From: "Erik Ostermueller" > To: "Aaron Spear" > Cc: lttng-dev at lists.lttng.org, "Alexandre Montplaisir" > Sent: Wednesday, January 23, 2013 11:03:15 AM > Subject: RE: [lttng-dev] tracing of non-JNI java in IBM jvm > > Aaron, > > Sorry to have disappeared from this discussion. > What if we went is a slightly different direction. > > The InTrace tool (http://mchr3k.github.com/org.intrace/) will log > start/stop times of dynamically instrumented methods to a text file > (proprietary format). > What if we simply wrote a process to convert that log to CTF, and > view the trace with the lttng eclipse plug-in, unmodified. > > The idea would be to, at first, just support these two views: > http://wiki.eclipse.org/Linux_Tools_Project/LTTng/User_Guide#Control_Flow_View > http://wiki.eclipse.org/Linux_Tools_Project/LTTng/User_Guide#Statistics_View > > --Erik > > > > -----Original Message----- > From: Aaron Spear [mailto:aspear at vmware.com] > Sent: Friday, January 11, 2013 12:56 PM > To: Ostermueller, Erik > Cc: lttng-dev at lists.lttng.org; Alexandre Montplaisir > Subject: Re: [lttng-dev] tracing of non-JNI java in IBM jvm > > > ----- Original Message ----- > > From: "Erik Ostermueller" > > To: "Alexandre Montplaisir" > > Cc: lttng-dev at lists.lttng.org > > Sent: Friday, January 11, 2013 9:26:51 AM > > Subject: Re: [lttng-dev] tracing of non-JNI java in IBM jvm > > > > Thanks Alex for the quick reply....now I get it. > > I'll jump in on that other thread you mentioned. > > > > There is a tool called InTrace that does some of this work. > > Perhaps some design ideas or even code could be stolen from here: > > http://mchr3k.github.com/org.intrace/ > > This project: > > * implements the java.lang.instrumentation api, which can be used > > to > > plug a tracing tool into an already-running JVM. > > * allows you to instrument/de-instrument various classes without > > restarting the JVM. > > * Uses http://asm.ow2.org/ to inject byte code for entry/exit > > tracing > > methods. > > * stores thread id (good) but does nothing to sort/organize > > activity > > by thread id into a session(bad) > > * no graphing/aggregating of performance metrics...just displays > > entry/exit times, method parameters, etc... > > Hi Erik, > > I think that what you are mentioning is certainly one thing that is > needed. To me I see a couple of different components here: > 1) implementation of java.util.logging interfaces as well as SLF4J > interfaces, as well as a dedicated LTTng java API for registering > custom event typess. This would be used for static, compile time > instrumentation of java apps. > 2) an implementation that uses the tooling you mention above for > dynamic instrumentation of any running java app. You basically > would define trace and install trace points on the fly. This would > be really, really powerful. > > The implementations of the above would have to be quite different > from the way that things are done currently with UST. Currently UST > uses macros in C files to define the various tracepoints statically. > We would need to have API's that could be called dynamically to > define tracepoints, so that the java code could do this. I have not > actually looked under the hood with the current UST implementation > to see what the implications are for this. > > It seems to me that we would want to have a Java API usage similar to > what you can do with SLF4J: > > class MyClass { > private static final Tracer tracer = > LTTngFactory.getTracer("MyComponentName"); > private static final String MY_TRACEPOINT = > "MyTracepointWithIntegerStringAndLong"; > > static { > // register a tracepoint. this goes through JNI and > creates a tracepoint > // in UST that has the given name and the specified objects > tracer.registerTracepoint(MY_TRACEPOINT, > new > Object[]{Integer.class,String.class,Long.class}); > } > > public void someMethod() { > Integer someInteger = 123456; > String someString = "this is the string"; > Long someLong = 56789; > > tracer.trace(MY_TRACEPOINT,someInteger,someString,someLong); > } > } > > Then over the top of this you have implementations of SLF4J, > java.util.logging, whatever. The infrastructure required in the JNI > side for this would be the same implementation needed by the binding > to the InTrace technology to dynamically create tracepoints. > > I need all of this right now, and am willing to spend time in the > next few months to implement it. > > cheers, > Aaron Spear, Staff Engineer, VMware Inc > > _____________ > The information contained in this message is proprietary and/or > confidential. If you are not the intended recipient, please: (i) > delete the message and all copies; (ii) do not disclose, distribute > or use the message in any manner; and (iii) notify the sender > immediately. In addition, please be aware that any message addressed > to our domain is subject to archiving and review by persons other > than the intended recipient. Thank you > -------------- next part -------------- A non-text attachment was scrubbed... Name: execution-flow-view.png Type: image/png Size: 197827 bytes Desc: not available URL: From yangw.wang5 at unb.ca Wed Jan 23 15:09:30 2013 From: yangw.wang5 at unb.ca (Yang Wang) Date: Wed, 23 Jan 2013 20:09:30 +0000 Subject: [lttng-dev] bug? Message-ID: <8E0A14A4C9B95B459AE214584119C1EB3BC909B3@Hal.ad.unb.ca> Hello, I am Yang Wang, I am currently using lttng to trace my JVM. During my using lttng in tracing JVM, I found three problems, 1) in lttng-ust-2.1.0/include/lttng/ust-tracepoint-event.h why using an assertion "assert(!ret);" (Line676)? not allowing double registering and init? if double registering or initialization (provider), why not allowed just returning silently instead of aborting"? How about comments assert(!ret); ==>//assert(!ret); what is the side-effects of doing this? 2) The other problem is in ./userspace-rcu-0.7.5/urcu/list.h Line85 I have to add a guard "if" statement as the assertion in my program fails otherwise static inline void __cds_list_del (struct cds_list_head *prev, struct cds_list_head *next) { if (prev != NULL && next != NULL) { //assert(prev != NULL && next != NULL); next->prev = prev; prev->next = next; } 3) Now my instrumented prog is ready to run. Here is my commands: lttng create lttng enable-event -u -a lttng start ./prog The (lttng) instrumented prog is stuck there without any outputs related to lttng tracing, how can I know what happen inside. In other words, does lttng have any mechanism to trace itself? Thanks Yang -------------- next part -------------- An HTML attachment was scrubbed... URL: From Erik.Ostermueller at fisglobal.com Wed Jan 23 16:46:34 2013 From: Erik.Ostermueller at fisglobal.com (Ostermueller, Erik) Date: Wed, 23 Jan 2013 21:46:34 +0000 Subject: [lttng-dev] tracing of non-JNI java in IBM jvm In-Reply-To: <2081361152.17856221.1358970308809.JavaMail.root@vmware.com> References: <2081361152.17856221.1358970308809.JavaMail.root@vmware.com> Message-ID: Aaron wrote: >> not yet ready to show anyone as I hacked it together Hacked, shmacked. Pour that code into a jar file ship it! ...just kidding. Seriously, though, I'd love to test out your prototype to get a feel for all the pieces involved -- I'm new to lttng. If the prototype grows into something more release-able, I might have a small amount of time to contribute some code....if nothing else, I'd be happy to some load and do some profiling of the solution. Would also be nice to optionally capture some "state" to attach to a single gantt trace. For example, SOA developers (they're so picky) would want the XML input that led to a performance problem that has been traced. The uses would be responsible for identifying which method return val or parm contained input XML. In Trace already knows how to capture that. Would then want the new solution to dump the XML onto thread local storage (or similar) so it could be included (somehow) in the trace output. Does CTF support storage of additional data like this? I'm the kernel folks are rolling their eyes... sounds like a lot of overhead....but CompuWare's DynaTrace already does this with impressively low overhead. --Erik -----Original Message----- From: Aaron Spear [mailto:aspear at vmware.com] Sent: Wednesday, January 23, 2013 1:45 PM To: Ostermueller, Erik Cc: lttng-dev at lists.lttng.org; Alexandre Montplaisir; linuxtools-dev at eclipse.org Subject: Re: [lttng-dev] tracing of non-JNI java in IBM jvm Hi Erik, I am happy to report that I already implemented what I mentioned before as a *prototype*. My solution has the following: -JNI library and classes that use UST to log function entries-exits. So I end up with a CTF log that has function entries and exits. -extension to in-trace agent library to use this library for function entries and exits. So, you can select a subset of classes to instrument dynamically. -clone of the Control Flow View that understands this particular function entry and exit event schema -I have threads as the parent, and then whatever functions the thread calls as children. If you collapse the thread, you still see intervals over which it is running which is nice. The net result is that you can see Gantt charts of function calls in *any* java application. All you have to do is 1) launch the java app injecting the custom in-trace agent 2) start lttng ust tracing 3) connect to the java app's injected agent and select what classes you want instrumented See the attached screenshot that shows a very simple java application that spawns 5 threads, and each thread calls 4 functions and then exits. I think that the idea is pretty cool and have the intent to contribute it if there is interest. This implementation is not yet ready to show anyone as I hacked it together for a paper that I am writing. Here are a few of the caveats about it: 1) the current implementation is quite intrusive on the java side. Sloppy use of strings in particular. It needs some careful architecting. I have a number of ideas on this front, but have not yet had bandwidth to implement them. 2) There are lots of details to be worked out with the in-trace integration. The current collection UI really needs some help. I tried briefly to get the eclipse plugin to work with Eclipse 4, but only the RCP app seems to work for me. I think that the "Connections" view needs to have different collection agents plugged in and you should be able to connect to a java app and dynamically select classes to instrument and/or select from sets of classes/methods. 3) My vision is to create a viewer that could do arbitrary state over time, and use CTF extensions to feed this so that the implementation is entirely data driven. Basically any hierarchy of parent-child entries with state under them. This particular one is, like the LTTng Control Flow View, hard coded to the event schema right now, but I can see how we can make it more general. I should say that the guys that wrote the framework did a good job of making it useable for different things (nice work guys!) Note that you could in fact use it for instrumenting native applications as well of course. The "DynamoRIO" project in particular does the same sort of thing as In Trace does (only more efficiently) so I think this is quite viable as a collection mechanism. cheers! Aaron Spear ----- Original Message ----- > From: "Erik Ostermueller" > To: "Aaron Spear" > Cc: lttng-dev at lists.lttng.org, "Alexandre Montplaisir" > > Sent: Wednesday, January 23, 2013 11:03:15 AM > Subject: RE: [lttng-dev] tracing of non-JNI java in IBM jvm > > Aaron, > > Sorry to have disappeared from this discussion. > What if we went is a slightly different direction. > > The InTrace tool > (https://urldefense.proofpoint.com/v1/url?u=http://mchr3k.github.com/o > rg.intrace/&k=%2FbkpAUdJWZuiTILCq%2FFnQg%3D%3D%0A&r=k0mtagpeWG6phJwAIzKq%2B4lTFA1JCM2OiWhVYmwwWeM%3D%0A&m=lFXy7dQ3u8Zg1jElCpolYCb7TruJrJgRwBFE22Y6%2BmY%3D%0A&s=96ea6ae0f26bd65195aad3b74892a253c5f364ba26e802b78e04d40b04f6ea10) will log start/stop times of dynamically instrumented methods to a text file (proprietary format). > What if we simply wrote a process to convert that log to CTF, and view > the trace with the lttng eclipse plug-in, unmodified. > > The idea would be to, at first, just support these two views: > https://urldefense.proofpoint.com/v1/url?u=http://wiki.eclipse.org/Lin > ux_Tools_Project/LTTng/User_Guide%23Control_Flow_View&k=%2FbkpAUdJWZui > TILCq%2FFnQg%3D%3D%0A&r=k0mtagpeWG6phJwAIzKq%2B4lTFA1JCM2OiWhVYmwwWeM% > 3D%0A&m=lFXy7dQ3u8Zg1jElCpolYCb7TruJrJgRwBFE22Y6%2BmY%3D%0A&s=912d647a > 2e19035e7ceb23bfbb7ca8b2e4217d47037a04c3e4ec65862ceae233 > https://urldefense.proofpoint.com/v1/url?u=http://wiki.eclipse.org/Lin > ux_Tools_Project/LTTng/User_Guide%23Statistics_View&k=%2FbkpAUdJWZuiTI > LCq%2FFnQg%3D%3D%0A&r=k0mtagpeWG6phJwAIzKq%2B4lTFA1JCM2OiWhVYmwwWeM%3D > %0A&m=lFXy7dQ3u8Zg1jElCpolYCb7TruJrJgRwBFE22Y6%2BmY%3D%0A&s=b8aa3bbc7e > 1bd3611941f0be18ced0000cd89295515ff32346c71549cc49ea26 > > --Erik > > > > -----Original Message----- > From: Aaron Spear [mailto:aspear at vmware.com] > Sent: Friday, January 11, 2013 12:56 PM > To: Ostermueller, Erik > Cc: lttng-dev at lists.lttng.org; Alexandre Montplaisir > Subject: Re: [lttng-dev] tracing of non-JNI java in IBM jvm > > > ----- Original Message ----- > > From: "Erik Ostermueller" > > To: "Alexandre Montplaisir" > > Cc: lttng-dev at lists.lttng.org > > Sent: Friday, January 11, 2013 9:26:51 AM > > Subject: Re: [lttng-dev] tracing of non-JNI java in IBM jvm > > > > Thanks Alex for the quick reply....now I get it. > > I'll jump in on that other thread you mentioned. > > > > There is a tool called InTrace that does some of this work. > > Perhaps some design ideas or even code could be stolen from here: > > > > https://urldefense.proofpoint.com/v1/url?u=http://mchr3k.github.com/ > > org.intrace/&k=%2FbkpAUdJWZuiTILCq%2FFnQg%3D%3D%0A&r=k0mtagpeWG6phJw > > AIzKq%2B4lTFA1JCM2OiWhVYmwwWeM%3D%0A&m=lFXy7dQ3u8Zg1jElCpolYCb7TruJr > > JgRwBFE22Y6%2BmY%3D%0A&s=96ea6ae0f26bd65195aad3b74892a253c5f364ba26e > > 802b78e04d40b04f6ea10 > > This project: > > * implements the java.lang.instrumentation api, which can be used to > > plug a tracing tool into an already-running JVM. > > * allows you to instrument/de-instrument various classes without > > restarting the JVM. > > * Uses > > https://urldefense.proofpoint.com/v1/url?u=http://asm.ow2.org/&k=%2F > > bkpAUdJWZuiTILCq%2FFnQg%3D%3D%0A&r=k0mtagpeWG6phJwAIzKq%2B4lTFA1JCM2OiWhVYmwwWeM%3D%0A&m=lFXy7dQ3u8Zg1jElCpolYCb7TruJrJgRwBFE22Y6%2BmY%3D%0A&s=e3bd826c82ea04de7f36936be65be723da73938e69695a85c5dcc17b05bc8caf to inject byte code for entry/exit tracing methods. > > * stores thread id (good) but does nothing to sort/organize activity > > by thread id into a session(bad) > > * no graphing/aggregating of performance metrics...just displays > > entry/exit times, method parameters, etc... > > Hi Erik, > > I think that what you are mentioning is certainly one thing that is > needed. To me I see a couple of different components here: > 1) implementation of java.util.logging interfaces as well as SLF4J > interfaces, as well as a dedicated LTTng java API for registering > custom event typess. This would be used for static, compile time > instrumentation of java apps. > 2) an implementation that uses the tooling you mention above for > dynamic instrumentation of any running java app. You basically would > define trace and install trace points on the fly. This would be > really, really powerful. > > The implementations of the above would have to be quite different from > the way that things are done currently with UST. Currently UST uses > macros in C files to define the various tracepoints statically. > We would need to have API's that could be called dynamically to > define tracepoints, so that the java code could do this. I have not > actually looked under the hood with the current UST implementation to > see what the implications are for this. > > It seems to me that we would want to have a Java API usage similar to > what you can do with SLF4J: > > class MyClass { > private static final Tracer tracer = > LTTngFactory.getTracer("MyComponentName"); > private static final String MY_TRACEPOINT = > "MyTracepointWithIntegerStringAndLong"; > > static { > // register a tracepoint. this goes through JNI and > creates a tracepoint > // in UST that has the given name and the specified objects > tracer.registerTracepoint(MY_TRACEPOINT, > new > Object[]{Integer.class,String.class,Long.class}); > } > > public void someMethod() { > Integer someInteger = 123456; > String someString = "this is the string"; > Long someLong = 56789; > > tracer.trace(MY_TRACEPOINT,someInteger,someString,someLong); > } > } > > Then over the top of this you have implementations of SLF4J, > java.util.logging, whatever. The infrastructure required in the JNI > side for this would be the same implementation needed by the binding > to the InTrace technology to dynamically create tracepoints. > > I need all of this right now, and am willing to spend time in the next > few months to implement it. > > cheers, > Aaron Spear, Staff Engineer, VMware Inc > > _____________ > The information contained in this message is proprietary and/or > confidential. If you are not the intended recipient, please: (i) > delete the message and all copies; (ii) do not disclose, distribute or > use the message in any manner; and (iii) notify the sender > immediately. In addition, please be aware that any message addressed > to our domain is subject to archiving and review by persons other than > the intended recipient. Thank you > _____________ The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you. From namei.unix at gmail.com Thu Jan 24 00:22:13 2013 From: namei.unix at gmail.com (Liu Yuan) Date: Thu, 24 Jan 2013 13:22:13 +0800 Subject: [lttng-dev] Query on the rculist In-Reply-To: <50FEA109.6060404@gmail.com> References: <50FCA183.8030201@gmail.com> <20130121141645.GB31140@Krystal> <50FEA109.6060404@gmail.com> Message-ID: <5100C505.6080505@gmail.com> On 01/22/2013 10:24 PM, Lai Jiangshan wrote: > Add a trivial comment. > > There is no list_del_init_rcu(), "init" hurts "rcu". > If you need a re-initialized object after deletion, you should use > synchronzie_rcu(): > > list_del_rcu(); > synchronize_rcu(); > CDS_INIT_LIST_HEAD(); Thanks, note taken. Mathieu, could you add this as comment for rculist.h? It will save people from finding list_dei_init_rcu(). Yuan From mathieu.desnoyers at efficios.com Thu Jan 24 12:04:35 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 24 Jan 2013 12:04:35 -0500 Subject: [lttng-dev] Query on the rculist In-Reply-To: <5100C505.6080505@gmail.com> References: <50FCA183.8030201@gmail.com> <20130121141645.GB31140@Krystal> <50FEA109.6060404@gmail.com> <5100C505.6080505@gmail.com> Message-ID: <20130124170435.GA1677@Krystal> * Liu Yuan (namei.unix at gmail.com) wrote: > On 01/22/2013 10:24 PM, Lai Jiangshan wrote: > > Add a trivial comment. > > > > There is no list_del_init_rcu(), "init" hurts "rcu". > > If you need a re-initialized object after deletion, you should use > > synchronzie_rcu(): > > > > list_del_rcu(); > > synchronize_rcu(); > > CDS_INIT_LIST_HEAD(); > > Thanks, note taken. Mathieu, could you add this as comment for > rculist.h? It will save people from finding list_dei_init_rcu(). Sure, done. Here is the updated proposed patch: commit 82bffe25ba06e2ab8c872640efdf40d1f17f0e85 Author: Mathieu Desnoyers Date: Mon Jan 21 15:53:41 2013 -0500 expand and cleanup list.h and rculist.h Cleanup urcu/list.h and urcu/rculist.h: adopt Userspace RCU project coding style, comment each function thoroughly. Add the following API members: - cds_list_for_each_safe() - cds_list_for_each_entry_reverse_safe() - cds_list_add_tail_rcu() Document that cds_list_empty() can be used on RCU lists without protection. Signed-off-by: Mathieu Desnoyers CC: Liu Yuan CC: Lai Jiangshan CC: Paul E. McKenney diff --git a/urcu/list.h b/urcu/list.h index 5d04394..61e3298 100644 --- a/urcu/list.h +++ b/urcu/list.h @@ -5,7 +5,7 @@ * * Copyright (C) 2009 Pierre-Marc Fournier * Conversion to RCU list. - * Copyright (C) 2010 Mathieu Desnoyers + * Copyright (C) 2010-2013 Mathieu Desnoyers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,86 +25,124 @@ #ifndef _CDS_LIST_H #define _CDS_LIST_H 1 -/* The definitions of this file are adopted from those which can be - found in the Linux kernel headers to enable people familiar with - the latter find their way in these sources as well. */ - +/* + * The definitions of this file are adopted from those which can be + * found in the Linux kernel headers to enable people familiar with the + * latter find their way in these sources as well. + */ -/* Basic type for the double-link list. */ -struct cds_list_head -{ - struct cds_list_head *next; - struct cds_list_head *prev; +/* Basic type for the double-link list. */ +struct cds_list_head { + struct cds_list_head *next; + struct cds_list_head *prev; }; +/* Define a variable with the head and tail of the list. */ +#define CDS_LIST_HEAD(name) \ + struct cds_list_head name = CDS_LIST_HEAD_INIT(name) -/* Define a variable with the head and tail of the list. */ -#define CDS_LIST_HEAD(name) \ - struct cds_list_head name = { &(name), &(name) } - -/* Initialize a new list head. */ -#define CDS_INIT_LIST_HEAD(ptr) \ - (ptr)->next = (ptr)->prev = (ptr) - -#define CDS_LIST_HEAD_INIT(name) { .prev = &(name), .next = &(name) } +#define CDS_LIST_HEAD_INIT(name) { .prev = &(name), .next = &(name) } -/* Add new element at the head of the list. */ -static inline void -cds_list_add (struct cds_list_head *newp, struct cds_list_head *head) +/* + * @CSD_INIT_LIST_HEAD: Initialize a new list head. + * @head: head of list to initialize. + */ +static inline +void CDS_INIT_LIST_HEAD(struct cds_list_head *head) { - head->next->prev = newp; - newp->next = head->next; - newp->prev = head; - head->next = newp; + head->next = head; + head->prev = head; } - -/* Add new element at the tail of the list. */ -static inline void -cds_list_add_tail (struct cds_list_head *newp, struct cds_list_head *head) +/* + * cds_list_add: Add new element at the head of the list. + * @newp: new element. + * @head: list head. + * + * Mutual exclusion against other updates and reads to list is required. + */ +static inline +void cds_list_add(struct cds_list_head *newp, struct cds_list_head *head) { - head->prev->next = newp; - newp->next = head; - newp->prev = head->prev; - head->prev = newp; + head->next->prev = newp; + newp->next = head->next; + newp->prev = head; + head->next = newp; } +/* + * cds_list_add_tail: Add new element at the tail of the list. + * @newp: new element. + * @head: list head. + * + * Mutual exclusion against other updates and reads to list is required. + */ +static inline +void cds_list_add_tail(struct cds_list_head *newp, struct cds_list_head *head) +{ + head->prev->next = newp; + newp->next = head; + newp->prev = head->prev; + head->prev = newp; +} -/* Remove element from list. */ -static inline void -__cds_list_del (struct cds_list_head *prev, struct cds_list_head *next) +static inline +void __cds_list_del(struct cds_list_head *prev, struct cds_list_head *next) { - next->prev = prev; - prev->next = next; + next->prev = prev; + prev->next = next; } -/* Remove element from list. */ -static inline void -cds_list_del (struct cds_list_head *elem) +/* + * cds_list_del: Remove element from list. + * @elem: element to remove. + * + * Mutual exclusion against other updates and reads to list is required. + */ +static inline +void cds_list_del(struct cds_list_head *elem) { - __cds_list_del (elem->prev, elem->next); + __cds_list_del(elem->prev, elem->next); } -/* Remove element from list, initializing the element's list pointers. */ -static inline void -cds_list_del_init (struct cds_list_head *elem) +/* + * cds_list_del_init: Remove element from list, init element. + * @elem: element to remove. + * + * Remove element from list, initializing the element's list pointers. + * Mutual exclusion against other updates and reads to list is required. + */ +static inline +void cds_list_del_init(struct cds_list_head *elem) { cds_list_del(elem); CDS_INIT_LIST_HEAD(elem); } -/* delete from list, add to another list as head */ -static inline void -cds_list_move (struct cds_list_head *elem, struct cds_list_head *head) +/* + * cds_list_move: Delete from list, add to another list as head. + * @elem: element to move. + * @head: head of list to move into. + * + * Mutual exclusion against other updates and reads to both lists is + * required. + */ +static inline +void cds_list_move(struct cds_list_head *elem, struct cds_list_head *head) { - __cds_list_del (elem->prev, elem->next); - cds_list_add (elem, head); + __cds_list_del(elem->prev, elem->next); + cds_list_add(elem, head); } -/* replace an old entry. +/* + * cds_list_replace: replace an old entry. + * @old: old entry. + * @_new: new entry. + * + * Mutual exclusion against other updates and reads to list is required. */ -static inline void -cds_list_replace(struct cds_list_head *old, struct cds_list_head *_new) +static inline +void cds_list_replace(struct cds_list_head *old, struct cds_list_head *_new) { _new->next = old->next; _new->prev = old->prev; @@ -112,75 +150,191 @@ cds_list_replace(struct cds_list_head *old, struct cds_list_head *_new) _new->next->prev = _new; } -/* Join two lists. */ -static inline void -cds_list_splice (struct cds_list_head *add, struct cds_list_head *head) +/* + * cds_list_empty: returns whether list is empty + * + * Return nonzero if list is empty, zero otherwise. + * cds_list_empty() can be used on RCU lists. RCU read-side lock is not + * required. + */ +static inline +int cds_list_empty(struct cds_list_head *head) { - /* Do nothing if the list which gets added is empty. */ - if (add != add->next) - { - add->next->prev = head; - add->prev->next = head->next; - head->next->prev = add->prev; - head->next = add->next; - } + return head == head->next; } -/* Get typed element from list at a given position. */ -#define cds_list_entry(ptr, type, member) \ - ((type *) ((char *) (ptr) - (unsigned long) (&((type *) 0)->member))) - +/* + * cds_list_splice: Join two lists. + * @add: head of list to merge into @head. + * @head: head of list to be merged into. + * + * Merge @add into @head. + * Mutual exclusion against other updates and reads to both lists is + * required. + */ +static inline +void cds_list_splice(struct cds_list_head *add, struct cds_list_head *head) +{ + if (cds_list_empty(add)) + return; + add->next->prev = head; + add->prev->next = head->next; + head->next->prev = add->prev; + head->next = add->next; +} -/* Get first entry from a list. */ -#define cds_list_first_entry(ptr, type, member) \ - cds_list_entry((ptr)->next, type, member) +/* + * cds_list_replace_init: replace old entry by new one, init new entry. + * @old: old entry to replace. + * @_new: new entry to replace with. + * + * Mutual exclusion against other updates and reads to list is required. + */ +static inline +void cds_list_replace_init(struct cds_list_head *old, + struct cds_list_head *_new) +{ + struct cds_list_head *head = old->next; + cds_list_del(old); + cds_list_add_tail(_new, head); + CDS_INIT_LIST_HEAD(old); +} +/* + * cds_list_entry: Get typed element from list at a given position. + * @ptr: node pointer (struct cds_list_head *). + * @type: type containing the list node field. + * @member: field name of list node within containing type. + */ +#define cds_list_entry(ptr, type, member) \ + ((type *) ((char *) (ptr) - (unsigned long) (&((type *) 0)->member))) -/* Iterate forward over the elements of the list. */ -#define cds_list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) +/* + * cds_list_first_entry: Get first entry from a list. + * @head: list head (struct cds_list_head *). + * @type: type containing the list node field. + * @member: field name of list node within containing type. + * + * This should *not* be used on an empty list. Test for list emptiness + * before using @cds_list_first_entry. + */ +#define cds_list_first_entry(head, type, member) \ + cds_list_entry((head)->next, type, member) +/* + * cds_list_for_each: Iterate forward over the elements of the list. + * @pos: pointer to use as iterator (struct cds_list_head *). + * @head: list head (struct cds_list_head *). + * + * Mutual exclusion against updates to list is required. + * It is not safe to remove elements within loop iteration. + */ +#define cds_list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); pos = pos->next) -/* Iterate backward over the elements of the list. */ -#define cds_list_for_each_prev(pos, head) \ - for (pos = (head)->prev; pos != (head); pos = pos->prev) +/* + * cds_list_for_each_safe: Iterate forward, safe against removal. + * @pos: pointer to use as iterator (struct cds_list_head *). + * @p: temporary pointer to store @pos copy (struct cds_list_head *). + * @head: list head (struct cds_list_head *). + * + * Mutual exclusion against updates to list is required. + * The list elements can be removed from the list within loop iteration. + */ +#define cds_list_for_each_safe(pos, p, head) \ + for (pos = (head)->next, p = pos->next; \ + pos != (head); \ + pos = p; p = pos->next) +/* + * cds_list_for_each_prev: Iterate backward over the elements of the list. + * @pos: pointer to use as iterator (struct cds_list_head *). + * @head: list head (struct cds_list_head *). + * + * Mutual exclusion against updates to list is required. + * It is not safe to remove elements within loop iteration. + */ +#define cds_list_for_each_prev(pos, head) \ + for (pos = (head)->prev; pos != (head); pos = pos->prev) -/* Iterate backwards over the elements list. The list elements can be - removed from the list while doing this. */ -#define cds_list_for_each_prev_safe(pos, p, head) \ - for (pos = (head)->prev, p = pos->prev; \ - pos != (head); \ - pos = p, p = pos->prev) +/* + * cds_list_for_each_prev_safe: Iterate backwards, safe against removal. + * @pos: pointer to use as iterator (struct cds_list_head *). + * @p: temporary pointer to store @pos copy (struct cds_list_head *). + * @head: list head (struct cds_list_head *). + * + * Mutual exclusion against updates to list is required. + * The list elements can be removed from the list within loop iteration. + */ +#define cds_list_for_each_prev_safe(pos, p, head) \ + for (pos = (head)->prev, p = pos->prev; \ + pos != (head); \ + pos = p, p = pos->prev) -#define cds_list_for_each_entry(pos, head, member) \ +/* + * cds_list_for_each_entry: Iterate forward over entries of the list. + * @pos: pointer to use as iterator (type of list node container). + * @head: list head (struct cds_list_head *). + * @member: field name of list node field within container type. + * + * Mutual exclusion against updates to list is required. + * It is not safe to remove elements within loop iteration. + */ +#define cds_list_for_each_entry(pos, head, member) \ for (pos = cds_list_entry((head)->next, __typeof__(*pos), member); \ - &pos->member != (head); \ - pos = cds_list_entry(pos->member.next, __typeof__(*pos), member)) + &pos->member != (head); \ + pos = cds_list_entry(pos->member.next, \ + __typeof__(*pos), member)) -#define cds_list_for_each_entry_reverse(pos, head, member) \ +/* + * cds_list_for_each_entry_reverse: Iterate backwards over entries of the list. + * @pos: pointer to use as iterator (type of list node container). + * @head: list head (struct cds_list_head *). + * @member: field name of list node field within container type. + * + * Mutual exclusion against updates to list is required. + * It is not safe to remove elements within loop iteration. + */ +#define cds_list_for_each_entry_reverse(pos, head, member) \ for (pos = cds_list_entry((head)->prev, __typeof__(*pos), member); \ - &pos->member != (head); \ - pos = cds_list_entry(pos->member.prev, __typeof__(*pos), member)) + &pos->member != (head); \ + pos = cds_list_entry(pos->member.prev, \ + __typeof__(*pos), member)) -#define cds_list_for_each_entry_safe(pos, p, head, member) \ +/* + * cds_list_for_each_entry_safe: Iterate forward, safe against removal. + * @pos: pointer to use as iterator (pointer to list node container). + * @p: temporary pointer to store @pos copy (pointer to list node container). + * @head: list head (struct cds_list_head *). + * @member: field name of list node field within container type. + * + * Mutual exclusion against updates to list is required. + * The list elements can be removed from the list within loop iteration. + */ +#define cds_list_for_each_entry_safe(pos, p, head, member) \ for (pos = cds_list_entry((head)->next, __typeof__(*pos), member), \ - p = cds_list_entry(pos->member.next, __typeof__(*pos), member); \ - &pos->member != (head); \ - pos = p, p = cds_list_entry(pos->member.next, __typeof__(*pos), member)) + p = cds_list_entry(pos->member.next, \ + __typeof__(*pos), member); \ + &pos->member != (head); \ + pos = p, p = cds_list_entry(pos->member.next, \ + __typeof__(*pos), member)) -static inline int cds_list_empty(struct cds_list_head *head) -{ - return head == head->next; -} - -static inline void cds_list_replace_init(struct cds_list_head *old, - struct cds_list_head *_new) -{ - struct cds_list_head *head = old->next; - cds_list_del(old); - cds_list_add_tail(_new, head); - CDS_INIT_LIST_HEAD(old); -} +/* + * cds_list_for_each_entry_reverse_safe: Iterate backwards, safe for removal. + * @pos: pointer to use as iterator (pointer to list node container). + * @p: temporary pointer to store @pos copy (pointer to list node container). + * @head: list head (struct cds_list_head *). + * @member: field name of list node field within container type. + * + * Mutual exclusion against updates to list is required. + * The list elements can be removed from the list within loop iteration. + */ +#define cds_list_for_each_entry_reverse_safe(pos, p, head, member) \ + for (pos = cds_list_entry((head)->prev, __typeof__(*pos), member), \ + p = cds_list_entry(pos->member.prev, \ + __typeof__(*pos), member); \ + &pos->member != (head); \ + pos = p, p = cds_list_entry(pos->member.prev, \ + __typeof__(*pos), member)) #endif /* _CDS_LIST_H */ diff --git a/urcu/rculist.h b/urcu/rculist.h index 3604a96..cca64e5 100644 --- a/urcu/rculist.h +++ b/urcu/rculist.h @@ -5,7 +5,7 @@ * * Copyright (C) 2009 Pierre-Marc Fournier * Conversion to RCU list. - * Copyright (C) 2010 Mathieu Desnoyers + * Copyright (C) 2010-2013 Mathieu Desnoyers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,9 +29,31 @@ #include #include -/* Add new element at the head of the list. +/* + * This header contains a RCU-safe list API. It uses the urcu/list.h + * struct cds_list_head, but note that unless explicitly stated here, + * none of the urcu/list.h API members should be considered safe to use + * concurrently with RCU traversals. In addition to the explanation + * provided for each API member below, clarifications about relationship + * to some urcu/list.h API members follow. + * + * cds_list_empty() from urcu/list.h can be used on RCU lists. RCU + * read-side lock is not required. + * + * There is no list_del_init_rcu(), since there would need to be a + * grace-period between the "del" operation and the "init" operation. + */ + +/* + * cds_list_add_rcu: Add new element at the head of the list. + * @newp: new element. + * @head: list head. + * + * Mutual exclusion against other updates to the list is required. + * RCU-safe for concurrent traversals. */ -static inline void cds_list_add_rcu(struct cds_list_head *newp, struct cds_list_head *head) +static inline +void cds_list_add_rcu(struct cds_list_head *newp, struct cds_list_head *head) { newp->next = head->next; newp->prev = head; @@ -40,9 +62,36 @@ static inline void cds_list_add_rcu(struct cds_list_head *newp, struct cds_list_ head->next = newp; } -/* replace an old entry atomically. +/* + * cds_list_add_tail_rcu: Add new element at the tail of the list. + * @newp: new element. + * @head: list head. + * + * Mutual exclusion against other updates to the list is required. + * RCU-safe for concurrent traversals. + */ +static inline +void cds_list_add_tail_rcu(struct cds_list_head *newp, + struct cds_list_head *head) +{ + newp->next = head; + newp->prev = head->prev; + cmm_smp_wmb(); + head->prev = newp; + head->prev->next = newp; +} + +/* + * cds_list_replace_rcu: replace an old entry atomically. + * @old: old entry. + * @_new: new entry. + * + * Replace old entry atomically with respect to concurrent readers. + * Mutual exclusion against other updates to the list is required. + * RCU-safe for concurrent traversals. */ -static inline void cds_list_replace_rcu(struct cds_list_head *old, struct cds_list_head *_new) +static inline +void cds_list_replace_rcu(struct cds_list_head *old, struct cds_list_head *_new) { _new->next = old->next; _new->prev = old->prev; @@ -50,29 +99,48 @@ static inline void cds_list_replace_rcu(struct cds_list_head *old, struct cds_li _new->next->prev = _new; } -/* Remove element from list. */ -static inline void cds_list_del_rcu(struct cds_list_head *elem) +/* + * cds_list_del_rcu: Remove element from list. + * @elem: new element. + * + * Mutual exclusion against other updates to the list is required. + * RCU-safe for concurrent traversals. + */ +static inline +void cds_list_del_rcu(struct cds_list_head *elem) { elem->next->prev = elem->prev; elem->prev->next = elem->next; } /* - * Iteration through all elements of the list must be done while rcu_read_lock() - * is held. + * cds_list_for_each_rcu: RCU-safe iteration over the elements of the list. + * @pos: iteration position (struct cds_list_head *). + * @head: list head (struct cds_list_head *). + * + * Iteration direction: forward. + * Iteration through all elements of the list must be done while + * rcu_read_lock() is held. */ +#define cds_list_for_each_rcu(pos, head) \ + for (pos = rcu_dereference((head)->next); pos != (head); \ + pos = rcu_dereference(pos->next)) -/* Iterate forward over the elements of the list. */ -#define cds_list_for_each_rcu(pos, head) \ - for (pos = rcu_dereference((head)->next); pos != (head); \ - pos = rcu_dereference(pos->next)) - - -/* Iterate through elements of the list. +/* + * cds_list_for_each_entry_rcu: RCU-safe iteration over entries of the list. + * @pos: iteration position (pointer to entry type). + * @head: list head (struct cds_list_head *). + * @member: field name of the list node within entry type. + * + * Iteration direction: forward. + * Iteration through all elements of the list must be done while + * rcu_read_lock() is held. */ -#define cds_list_for_each_entry_rcu(pos, head, member) \ - for (pos = cds_list_entry(rcu_dereference((head)->next), __typeof__(*pos), member); \ +#define cds_list_for_each_entry_rcu(pos, head, member) \ + for (pos = cds_list_entry(rcu_dereference((head)->next), \ + __typeof__(*pos), member); \ &pos->member != (head); \ - pos = cds_list_entry(rcu_dereference(pos->member.next), __typeof__(*pos), member)) + pos = cds_list_entry(rcu_dereference(pos->member.next), \ + __typeof__(*pos), member)) #endif /* _URCU_RCULIST_H */ -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Thu Jan 24 12:14:04 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 24 Jan 2013 12:14:04 -0500 Subject: [lttng-dev] [RELEASE] Babeltrace 1.0.3 Message-ID: <20130124171404.GB1677@Krystal> The Babeltrace project provides trace read and write libraries, as well as a trace converter. Plugins can be created for any trace format to allow its conversion to/from another trace format. The main format expected to be converted to/from is the Common Trace Format (CTF). The default input format of the "babeltrace" command is CTF, and its default output format is a human-readable text log. The "babeltrace-log" command converts from a text log to a CTF trace. Important note: we discovered some unplanned symbol clash in exported shared objects, and namespace clashes for 3 structure declarations in the headers: struct definition, struct declaration and struct stream_pos. In order to not introduce API changes within the 1.0.x series, fixing these issues will require us to release a 1.1.0. Therefore, Babeltrace 1.0.3 will likely be the last of the 1.0.x series, moving to 1.1.x afterward. Changelog: 2012-01-24 Babeltrace 1.0.3 * Fix: Double free when calling bt_context_remove_trace() * Add missing runall.sh to dist packaging * Fix: alignment of compound types containing array field Project website: http://www.efficios.com/babeltrace Download link: http://www.efficios.com/files/babeltrace/ CTF specification: http://www.efficios.com/ctf -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From jdesfossez at efficios.com Thu Jan 24 12:43:19 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 12:43:19 -0500 Subject: [lttng-dev] [BABELTRACE PATCH] Namespace the lookup_enum function In-Reply-To: <20130113175754.GA3917@Krystal> References: <20130107211855.GB3678@Krystal> <1357760893-11961-1-git-send-email-jdesfossez@efficios.com> <20130113175754.GA3917@Krystal> Message-ID: <510172B7.1090908@efficios.com> For info, this patch was merged in Babeltrace master, see commit 9e3274b092343c999fcde33854d2df37b3702496 Thanks, Julien On 13/01/13 12:57 PM, Mathieu Desnoyers wrote: > * Julien Desfossez (jdesfossez at efficios.com) wrote: >> This patch namespaces the lookup_enum function because it causes problem >> with the integration in gdb even though it is not exported. >> Hui, can you try this patch and confirm it solves the current problem ? >> After that we will continue the internal namespacing. > > Hi Julien, > > Since we know these changes are needed, can you provide patches with > proper changelogs, and I'll pull them. > > Thanks, > > Mathieu > >> >> Thanks, >> >> Julien >> --- >> formats/ctf/ctf.c | 2 +- >> include/babeltrace/types.h | 2 +- >> types/types.c | 2 +- >> 3 files changed, 3 insertions(+), 3 deletions(-) >> >> diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c >> index 18a5601..a8f8408 100644 >> --- a/formats/ctf/ctf.c >> +++ b/formats/ctf/ctf.c >> @@ -431,7 +431,7 @@ int ctf_read_event(struct stream_pos *ppos, struct ctf_stream_definition *stream >> } else { >> struct definition_enum *enum_definition; >> >> - enum_definition = lookup_enum(&stream->stream_event_header->p, "id", FALSE); >> + enum_definition = bt_lookup_enum(&stream->stream_event_header->p, "id", FALSE); >> if (enum_definition) { >> id = enum_definition->integer->value._unsigned; >> } >> diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h >> index b42ba03..00c928b 100644 >> --- a/include/babeltrace/types.h >> +++ b/include/babeltrace/types.h >> @@ -521,7 +521,7 @@ struct definition *lookup_definition(const struct definition *definition, >> struct definition_integer *lookup_integer(const struct definition *definition, >> const char *field_name, >> int signedness); >> -struct definition_enum *lookup_enum(const struct definition *definition, >> +struct definition_enum *bt_lookup_enum(const struct definition *definition, >> const char *field_name, >> int signedness); >> struct definition *lookup_variant(const struct definition *definition, >> diff --git a/types/types.c b/types/types.c >> index 5599027..139e318 100644 >> --- a/types/types.c >> +++ b/types/types.c >> @@ -642,7 +642,7 @@ struct definition_integer *lookup_integer(const struct definition *definition, >> return lookup_integer; >> } >> >> -struct definition_enum *lookup_enum(const struct definition *definition, >> +struct definition_enum *bt_lookup_enum(const struct definition *definition, >> const char *field_name, >> int signedness) >> { >> -- >> 1.7.10.4 >> > From simon.marchi at polymtl.ca Thu Jan 24 13:42:02 2013 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Thu, 24 Jan 2013 13:42:02 -0500 Subject: [lttng-dev] [PATCH v2 urcu] Add compilation support for the TileGX architecture Message-ID: <1359052922-24335-1-git-send-email-simon.marchi@polymtl.ca> This patch adds compilation support for the TileGx architecture. Since the tests were not ran on other architectures of the Tile family (Tile64, TIlepro), errors are triggered during compilation if the architecture is another Tile arch. Signed-off-by: Simon Marchi --- configure.ac | 1 + urcu/arch/tile.h | 30 ++++++++++++++++++++++++++++++ urcu/uatomic/tile.h | 28 ++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 0 deletions(-) create mode 100644 urcu/arch/tile.h create mode 100644 urcu/uatomic/tile.h diff --git a/configure.ac b/configure.ac index 1d04062..d064a13 100644 --- a/configure.ac +++ b/configure.ac @@ -77,6 +77,7 @@ AS_CASE([$host_cpu], [ia64], [ARCHTYPE="gcc"], [arm*], [ARCHTYPE="arm"], [mips*], [ARCHTYPE="mips"], + [tile*], [ARCHTYPE="tile"], [ARCHTYPE="unknown"] ) diff --git a/urcu/arch/tile.h b/urcu/arch/tile.h new file mode 100644 index 0000000..f1283af --- /dev/null +++ b/urcu/arch/tile.h @@ -0,0 +1,30 @@ +#ifndef _URCU_ARCH_TILE_H +#define _URCU_ARCH_TILE_H + +/* + * arch_tile.h: trivial definitions for the Tile architecture + * + * Copyright (c) 2013 Simon Marchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef __tilegx__ +#include +#else +#error "URCU has only been tested on the TileGx architecture. For other Tile* architectures, please run the tests first and report the results to the maintainer so that proper support can be added." +#endif + +#endif /* _URCU_ARCH_TILE_H */ diff --git a/urcu/uatomic/tile.h b/urcu/uatomic/tile.h new file mode 100644 index 0000000..b15f885 --- /dev/null +++ b/urcu/uatomic/tile.h @@ -0,0 +1,28 @@ +#ifndef _URCU_ARCH_UATOMIC_TILE_H +#define _URCU_ARCH_UATOMIC_TILE_H + +/* + * Copyright (c) 2013 Simon Marchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef __tilegx__ +#include +#else +#error "URCU has only been tested on the TileGx architecture. For other Tile* architectures, please run the tests first and report the results to the maintainer so that proper support can be added." +#endif + +#endif /* _URCU_ARCH_UATOMIC_TILE_H */ -- 1.7.1 From simon.marchi at polymtl.ca Thu Jan 24 14:18:33 2013 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Thu, 24 Jan 2013 14:18:33 -0500 Subject: [lttng-dev] [PATCH v2 ust] Add compilation support for Tile architectures Message-ID: <1359055113-25549-1-git-send-email-simon.marchi@polymtl.ca> Also add missing space on the mips line for OCD purposes. Signed-off-by: Simon Marchi --- configure.ac | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/configure.ac b/configure.ac index c4377a5..919b742 100644 --- a/configure.ac +++ b/configure.ac @@ -189,7 +189,8 @@ changequote([,])dnl s390) NO_UNALIGNED_ACCESS=1 ;; s390x) NO_UNALIGNED_ACCESS=1 ;; arm*) NO_UNALIGNED_ACCESS=1 ;; - mips*) NO_UNALIGNED_ACCESS=1;; + mips*) NO_UNALIGNED_ACCESS=1 ;; + tile*) NO_UNALIGNED_ACCESS=1 ;; *) AC_MSG_ERROR([unable to detect alignment requirements (unsupported architecture ($host_cpu)?)]) ;; esac -- 1.7.1 From mathieu.desnoyers at efficios.com Thu Jan 24 15:42:05 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 24 Jan 2013 15:42:05 -0500 Subject: [lttng-dev] [PATCH v2 urcu] Add compilation support for the TileGX architecture In-Reply-To: <1359052922-24335-1-git-send-email-simon.marchi@polymtl.ca> References: <1359052922-24335-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <20130124204205.GA9009@Krystal> * Simon Marchi (simon.marchi at polymtl.ca) wrote: > This patch adds compilation support for the TileGx architecture. Since > the tests were not ran on other architectures of the Tile family > (Tile64, TIlepro), errors are triggered during compilation if the > architecture is another Tile arch. > > Signed-off-by: Simon Marchi Patch merged, thanks ! Mathieu > --- > configure.ac | 1 + > urcu/arch/tile.h | 30 ++++++++++++++++++++++++++++++ > urcu/uatomic/tile.h | 28 ++++++++++++++++++++++++++++ > 3 files changed, 59 insertions(+), 0 deletions(-) > create mode 100644 urcu/arch/tile.h > create mode 100644 urcu/uatomic/tile.h > > diff --git a/configure.ac b/configure.ac > index 1d04062..d064a13 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -77,6 +77,7 @@ AS_CASE([$host_cpu], > [ia64], [ARCHTYPE="gcc"], > [arm*], [ARCHTYPE="arm"], > [mips*], [ARCHTYPE="mips"], > + [tile*], [ARCHTYPE="tile"], > [ARCHTYPE="unknown"] > ) > > diff --git a/urcu/arch/tile.h b/urcu/arch/tile.h > new file mode 100644 > index 0000000..f1283af > --- /dev/null > +++ b/urcu/arch/tile.h > @@ -0,0 +1,30 @@ > +#ifndef _URCU_ARCH_TILE_H > +#define _URCU_ARCH_TILE_H > + > +/* > + * arch_tile.h: trivial definitions for the Tile architecture > + * > + * Copyright (c) 2013 Simon Marchi > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * This library 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 > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#ifdef __tilegx__ > +#include > +#else > +#error "URCU has only been tested on the TileGx architecture. For other Tile* architectures, please run the tests first and report the results to the maintainer so that proper support can be added." > +#endif > + > +#endif /* _URCU_ARCH_TILE_H */ > diff --git a/urcu/uatomic/tile.h b/urcu/uatomic/tile.h > new file mode 100644 > index 0000000..b15f885 > --- /dev/null > +++ b/urcu/uatomic/tile.h > @@ -0,0 +1,28 @@ > +#ifndef _URCU_ARCH_UATOMIC_TILE_H > +#define _URCU_ARCH_UATOMIC_TILE_H > + > +/* > + * Copyright (c) 2013 Simon Marchi > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * This library 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 > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#ifdef __tilegx__ > +#include > +#else > +#error "URCU has only been tested on the TileGx architecture. For other Tile* architectures, please run the tests first and report the results to the maintainer so that proper support can be added." > +#endif > + > +#endif /* _URCU_ARCH_UATOMIC_TILE_H */ > -- > 1.7.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Thu Jan 24 15:43:17 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 24 Jan 2013 15:43:17 -0500 Subject: [lttng-dev] [PATCH v2 ust] Add compilation support for Tile architectures In-Reply-To: <1359055113-25549-1-git-send-email-simon.marchi@polymtl.ca> References: <1359055113-25549-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <20130124204317.GB9009@Krystal> * Simon Marchi (simon.marchi at polymtl.ca) wrote: > Also add missing space on the mips line for OCD purposes. Merged, thanks! Mathieu > > Signed-off-by: Simon Marchi > --- > configure.ac | 3 ++- > 1 files changed, 2 insertions(+), 1 deletions(-) > > diff --git a/configure.ac b/configure.ac > index c4377a5..919b742 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -189,7 +189,8 @@ changequote([,])dnl > s390) NO_UNALIGNED_ACCESS=1 ;; > s390x) NO_UNALIGNED_ACCESS=1 ;; > arm*) NO_UNALIGNED_ACCESS=1 ;; > - mips*) NO_UNALIGNED_ACCESS=1;; > + mips*) NO_UNALIGNED_ACCESS=1 ;; > + tile*) NO_UNALIGNED_ACCESS=1 ;; > *) AC_MSG_ERROR([unable to detect alignment requirements (unsupported architecture ($host_cpu)?)]) ;; > esac > > -- > 1.7.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From jdesfossez at efficios.com Thu Jan 24 16:21:33 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 16:21:33 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 01/18] BT_HIDDEN macro Message-ID: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> This macro will be used across the codebase to set the visibility of a function to hidden. Updated also the functions that were setting the attribute manually. Signed-off-by: Julien Desfossez --- formats/ctf/metadata/ctf-lexer.l | 2 +- formats/ctf/metadata/ctf-parser.y | 22 +++++++++++----------- formats/ctf/metadata/ctf-scanner.h | 2 +- include/babeltrace/babeltrace-internal.h | 5 +++++ 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/formats/ctf/metadata/ctf-lexer.l b/formats/ctf/metadata/ctf-lexer.l index 26aa1bc..2209a86 100644 --- a/formats/ctf/metadata/ctf-lexer.l +++ b/formats/ctf/metadata/ctf-lexer.l @@ -31,7 +31,7 @@ #include "ctf-parser.h" #include "ctf-ast.h" -__attribute__((visibility("hidden"))) +BT_HIDDEN void setstring(struct ctf_scanner *scanner, YYSTYPE *lvalp, const char *src); static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner) diff --git a/formats/ctf/metadata/ctf-parser.y b/formats/ctf/metadata/ctf-parser.y index e7dfd80..72b0978 100644 --- a/formats/ctf/metadata/ctf-parser.y +++ b/formats/ctf/metadata/ctf-parser.y @@ -39,7 +39,7 @@ #include "ctf-parser.h" #include "ctf-ast.h" -__attribute__((visibility("hidden"))) +BT_HIDDEN int yydebug; /* Join two lists, put "add" at the end of "head". */ @@ -55,15 +55,15 @@ _bt_list_splice_tail (struct bt_list_head *add, struct bt_list_head *head) } } -__attribute__((visibility("hidden"))) +BT_HIDDEN int yyparse(struct ctf_scanner *scanner); -__attribute__((visibility("hidden"))) +BT_HIDDEN int yylex(union YYSTYPE *yyval, struct ctf_scanner *scanner); -__attribute__((visibility("hidden"))) +BT_HIDDEN int yylex_init_extra(struct ctf_scanner *scanner, yyscan_t * ptr_yy_globals); -__attribute__((visibility("hidden"))) +BT_HIDDEN int yylex_destroy(yyscan_t yyscanner); -__attribute__((visibility("hidden"))) +BT_HIDDEN void yyrestart(FILE * in_str, yyscan_t scanner); struct gc_string { @@ -101,7 +101,7 @@ static const char *node_type_to_str[] = { [ NODE_STRUCT ] = "NODE_STRUCT", }; -__attribute__((visibility("hidden"))) +BT_HIDDEN const char *node_type(struct ctf_node *node) { if (node->type < NR_NODE_TYPES) @@ -132,7 +132,7 @@ static struct gc_string *gc_string_alloc(struct ctf_scanner *scanner, * gsrc will be garbage collected immediately, and gstr might be. * Should only be used to append characters to a string literal or constant. */ -__attribute__((visibility("hidden"))) +BT_HIDDEN struct gc_string *gc_string_append(struct ctf_scanner *scanner, struct gc_string *gstr, struct gc_string *gsrc) @@ -211,7 +211,7 @@ static int lookup_type(struct ctf_scanner_scope *s, const char *id) return ret; } -__attribute__((visibility("hidden"))) +BT_HIDDEN int is_type(struct ctf_scanner *scanner, const char *id) { struct ctf_scanner_scope *it; @@ -815,13 +815,13 @@ static int set_parent_node(struct ctf_node *node, return 0; } -__attribute__((visibility("hidden"))) +BT_HIDDEN void yyerror(struct ctf_scanner *scanner, const char *str) { fprintf(stderr, "error %s\n", str); } -__attribute__((visibility("hidden"))) +BT_HIDDEN int yywrap(void) { return 1; diff --git a/formats/ctf/metadata/ctf-scanner.h b/formats/ctf/metadata/ctf-scanner.h index d5650d0..21010fd 100644 --- a/formats/ctf/metadata/ctf-scanner.h +++ b/formats/ctf/metadata/ctf-scanner.h @@ -49,7 +49,7 @@ struct ctf_ast *ctf_scanner_get_ast(struct ctf_scanner *scanner) return scanner->ast; } -__attribute__((visibility("hidden"))) +BT_HIDDEN int is_type(struct ctf_scanner *scanner, const char *id); #endif /* _CTF_SCANNER_H */ diff --git a/include/babeltrace/babeltrace-internal.h b/include/babeltrace/babeltrace-internal.h index c567d39..6b6fcec 100644 --- a/include/babeltrace/babeltrace-internal.h +++ b/include/babeltrace/babeltrace-internal.h @@ -45,6 +45,11 @@ extern int babeltrace_verbose, babeltrace_debug; #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) +/* + * BT_HIDDEN: set the hidden attribute for internal functions + */ +#define BT_HIDDEN __attribute__((visibility("hidden"))) + struct trace_descriptor; struct trace_collection { GPtrArray *array; /* struct trace_descriptor */ -- 1.7.10.4 From jdesfossez at efficios.com Thu Jan 24 16:21:34 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 16:21:34 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 02/18] Hide internal functions of ctf-text In-Reply-To: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> Message-ID: <1359062510-7557-2-git-send-email-jdesfossez@efficios.com> Signed-off-by: Julien Desfossez --- include/babeltrace/ctf-text/types.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/babeltrace/ctf-text/types.h b/include/babeltrace/ctf-text/types.h index d69af90..debecfe 100644 --- a/include/babeltrace/ctf-text/types.h +++ b/include/babeltrace/ctf-text/types.h @@ -61,13 +61,21 @@ struct ctf_text_stream_pos *ctf_text_pos(struct stream_pos *pos) /* * Write only is supported for now. */ +BT_HIDDEN int ctf_text_integer_write(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_text_float_write(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_text_string_write(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_text_enum_write(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_text_struct_write(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_text_variant_write(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_text_array_write(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_text_sequence_write(struct stream_pos *pos, struct definition *definition); static inline @@ -82,6 +90,7 @@ void print_pos_tabs(struct ctf_text_stream_pos *pos) /* * Check if the field must be printed. */ +BT_HIDDEN int print_field(struct definition *definition); #endif /* _BABELTRACE_CTF_TEXT_TYPES_H */ -- 1.7.10.4 From jdesfossez at efficios.com Thu Jan 24 16:21:35 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 16:21:35 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 03/18] Hide internal functions of libbabeltrace-ctf In-Reply-To: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> Message-ID: <1359062510-7557-3-git-send-email-jdesfossez@efficios.com> Signed-off-by: Julien Desfossez --- formats/ctf/ctf.c | 5 ++++- formats/ctf/metadata/ctf-ast.h | 5 +++++ formats/ctf/types/float.c | 4 +++- include/babeltrace/ctf/callbacks-internal.h | 1 + include/babeltrace/ctf/callbacks.h | 1 + include/babeltrace/ctf/types.h | 14 ++++++++++++++ 6 files changed, 28 insertions(+), 2 deletions(-) diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index a8f8408..a55f5e4 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -307,6 +307,7 @@ void ctf_update_timestamp(struct ctf_stream_definition *stream, * Print timestamp, rescaling clock frequency to nanoseconds and * applying offsets as needed (unix time). */ +static void ctf_print_timestamp_real(FILE *fp, struct ctf_stream_definition *stream, uint64_t timestamp) @@ -371,6 +372,7 @@ end: /* * Print timestamp, in cycles */ +static void ctf_print_timestamp_cycles(FILE *fp, struct ctf_stream_definition *stream, uint64_t timestamp) @@ -1724,7 +1726,7 @@ error: return NULL; } - +static void ctf_init_mmap_pos(struct ctf_stream_pos *pos, struct mmap_stream *mmap_info) { @@ -1815,6 +1817,7 @@ error_def: return ret; } +static int ctf_open_mmap_trace_read(struct ctf_trace *td, struct mmap_stream_list *mmap_list, void (*packet_seek)(struct stream_pos *pos, size_t index, diff --git a/formats/ctf/metadata/ctf-ast.h b/formats/ctf/metadata/ctf-ast.h index d5a0544..1368627 100644 --- a/formats/ctf/metadata/ctf-ast.h +++ b/formats/ctf/metadata/ctf-ast.h @@ -302,11 +302,16 @@ const char *node_type(struct ctf_node *node); struct ctf_trace; +BT_HIDDEN int ctf_visitor_print_xml(FILE *fd, int depth, struct ctf_node *node); +BT_HIDDEN int ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node); +BT_HIDDEN int ctf_visitor_parent_links(FILE *fd, int depth, struct ctf_node *node); +BT_HIDDEN int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace, int byte_order); +BT_HIDDEN int ctf_destroy_metadata(struct ctf_trace *trace); #endif /* _CTF_AST_H */ diff --git a/formats/ctf/types/float.c b/formats/ctf/types/float.c index 0cf9cae..054e262 100644 --- a/formats/ctf/types/float.c +++ b/formats/ctf/types/float.c @@ -96,7 +96,7 @@ static void float_unlock(void) assert(!ret); } -int _ctf_float_copy(struct stream_pos *destp, +static int _ctf_float_copy(struct stream_pos *destp, struct definition_float *dest_definition, struct stream_pos *srcp, const struct definition_float *src_definition) @@ -278,6 +278,7 @@ end: return ret; } +static void __attribute__((constructor)) ctf_float_init(void) { static_float_declaration = @@ -292,6 +293,7 @@ void __attribute__((constructor)) ctf_float_init(void) __alignof__(double)); } +static void __attribute__((destructor)) ctf_float_fini(void) { declaration_unref(&static_float_declaration->p); diff --git a/include/babeltrace/ctf/callbacks-internal.h b/include/babeltrace/ctf/callbacks-internal.h index 0390b9a..41bc846 100644 --- a/include/babeltrace/ctf/callbacks-internal.h +++ b/include/babeltrace/ctf/callbacks-internal.h @@ -60,6 +60,7 @@ struct bt_dependencies { int refcount; /* free when decremented to 0 */ }; +BT_HIDDEN void process_callbacks(struct bt_ctf_iter *iter, struct ctf_stream_definition *stream); #endif /* _BABELTRACE_CALLBACKS_INTERNAL_H */ diff --git a/include/babeltrace/ctf/callbacks.h b/include/babeltrace/ctf/callbacks.h index c178767..8d25741 100644 --- a/include/babeltrace/ctf/callbacks.h +++ b/include/babeltrace/ctf/callbacks.h @@ -51,6 +51,7 @@ enum bt_cb_ret { /* * Receives a variable number of strings as parameter, ended with NULL. */ +BT_HIDDEN struct bt_dependencies *babeltrace_dependencies_create(const char *first, ...); /* diff --git a/include/babeltrace/ctf/types.h b/include/babeltrace/ctf/types.h index 6b8752e..8bd0102 100644 --- a/include/babeltrace/ctf/types.h +++ b/include/babeltrace/ctf/types.h @@ -90,19 +90,33 @@ struct ctf_stream_pos *ctf_pos(struct stream_pos *pos) return container_of(pos, struct ctf_stream_pos, parent); } +BT_HIDDEN int ctf_integer_read(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_integer_write(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_float_read(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_float_write(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_string_read(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_string_write(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_enum_read(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_enum_write(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_struct_rw(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_variant_rw(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_array_read(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_array_write(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_sequence_read(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_sequence_write(struct stream_pos *pos, struct definition *definition); void ctf_packet_seek(struct stream_pos *pos, size_t index, int whence); -- 1.7.10.4 From jdesfossez at efficios.com Thu Jan 24 16:21:36 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 16:21:36 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 04/18] namespace the scope_path functions In-Reply-To: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> Message-ID: <1359062510-7557-4-git-send-email-jdesfossez@efficios.com> Signed-off-by: Julien Desfossez --- include/babeltrace/types.h | 2 +- types/sequence.c | 2 +- types/types.c | 4 ++-- types/variant.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index 00c928b..772abb2 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -511,7 +511,7 @@ int sequence_rw(struct stream_pos *pos, struct definition *definition); /* * in: path (dot separated), out: q (GArray of GQuark) */ -void append_scope_path(const char *path, GArray *q); +void bt_append_scope_path(const char *path, GArray *q); /* * Lookup helpers. diff --git a/types/sequence.c b/types/sequence.c index 0e84b1d..3967f97 100644 --- a/types/sequence.c +++ b/types/sequence.c @@ -111,7 +111,7 @@ struct declaration_sequence * declaration = &sequence_declaration->p; sequence_declaration->length_name = g_array_new(FALSE, TRUE, sizeof(GQuark)); - append_scope_path(length, sequence_declaration->length_name); + bt_append_scope_path(length, sequence_declaration->length_name); declaration_ref(elem_declaration); sequence_declaration->elem = elem_declaration; diff --git a/types/types.c b/types/types.c index 139e318..9c5cfca 100644 --- a/types/types.c +++ b/types/types.c @@ -547,7 +547,7 @@ struct definition_scope * if (root_name) { scope = _new_definition_scope(parent_scope, 0); - append_scope_path(root_name, scope->scope_path); + bt_append_scope_path(root_name, scope->scope_path); } else { int scope_path_len = 1; @@ -574,7 +574,7 @@ struct definition_scope * /* * in: path (dot separated), out: q (GArray of GQuark) */ -void append_scope_path(const char *path, GArray *q) +void bt_append_scope_path(const char *path, GArray *q) { const char *ptrbegin, *ptrend = path; GQuark quark; diff --git a/types/variant.c b/types/variant.c index 55b4b1f..4f1e524 100644 --- a/types/variant.c +++ b/types/variant.c @@ -114,7 +114,7 @@ struct declaration_variant * variant_declaration->untagged_variant = untagged_variant; declaration_ref(&untagged_variant->p); variant_declaration->tag_name = g_array_new(FALSE, TRUE, sizeof(GQuark)); - append_scope_path(tag, variant_declaration->tag_name); + bt_append_scope_path(tag, variant_declaration->tag_name); declaration->id = CTF_TYPE_VARIANT; declaration->alignment = 1; declaration->declaration_free = _variant_declaration_free; -- 1.7.10.4 From jdesfossez at efficios.com Thu Jan 24 16:21:37 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 16:21:37 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 05/18] namespace the array functions In-Reply-To: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> Message-ID: <1359062510-7557-5-git-send-email-jdesfossez@efficios.com> Signed-off-by: Julien Desfossez --- formats/ctf-text/types/array.c | 4 ++-- formats/ctf/ctf.c | 4 ++-- formats/ctf/events.c | 4 ++-- formats/ctf/metadata/ctf-visitor-generate-io-struct.c | 2 +- formats/ctf/types/array.c | 4 ++-- include/babeltrace/types.h | 12 ++++++------ types/array.c | 12 ++++++------ 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/formats/ctf-text/types/array.c b/formats/ctf-text/types/array.c index 97b557f..e2ed7b3 100644 --- a/formats/ctf-text/types/array.c +++ b/formats/ctf-text/types/array.c @@ -63,7 +63,7 @@ int ctf_text_array_write(struct stream_pos *ppos, struct definition *definition) && integer_declaration->p.alignment == CHAR_BIT)) { pos->string = array_definition->string; g_string_assign(array_definition->string, ""); - ret = array_rw(ppos, definition); + ret = bt_array_rw(ppos, definition); pos->string = NULL; } fprintf(pos->fp, "\"%s\"", array_definition->string->str); @@ -77,7 +77,7 @@ int ctf_text_array_write(struct stream_pos *ppos, struct definition *definition) } field_nr_saved = pos->field_nr; pos->field_nr = 0; - ret = array_rw(ppos, definition); + ret = bt_array_rw(ppos, definition); if (!pos->dummy) { pos->depth--; fprintf(pos->fp, " ]"); diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index a55f5e4..e18fffb 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -1338,12 +1338,12 @@ int create_stream_packet_index(struct ctf_trace *td, field = struct_definition_get_field_from_index(file_stream->parent.trace_packet_header, len_index); assert(field->declaration->id == CTF_TYPE_ARRAY); defarray = container_of(field, struct definition_array, p); - assert(array_len(defarray) == BABELTRACE_UUID_LEN); + assert(bt_array_len(defarray) == BABELTRACE_UUID_LEN); for (i = 0; i < BABELTRACE_UUID_LEN; i++) { struct definition *elem; - elem = array_index(defarray, i); + elem = bt_array_index(defarray, i); uuidval[i] = get_unsigned_int(elem); } ret = babeltrace_uuid_compare(td->uuid, uuidval); diff --git a/formats/ctf/events.c b/formats/ctf/events.c index ac7dce4..b530cd5 100644 --- a/formats/ctf/events.c +++ b/formats/ctf/events.c @@ -140,7 +140,7 @@ const struct definition *bt_ctf_get_index(const struct bt_ctf_event *ctf_event, struct definition_array *array_definition; array_definition = container_of(field, struct definition_array, p); - ret = array_index(array_definition, index); + ret = bt_array_index(array_definition, index); } else if (bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_SEQUENCE) { struct definition_sequence *sequence_definition; sequence_definition = container_of(field, @@ -584,7 +584,7 @@ char *bt_ctf_get_char_array(const struct definition *field) GString *char_array; if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_ARRAY) { - char_array = get_char_array(field); + char_array = bt_get_char_array(field); if (char_array) { ret = char_array->str; goto end; diff --git a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c index c32aa99..97d15e7 100644 --- a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c +++ b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c @@ -509,7 +509,7 @@ struct declaration *ctf_type_declarator_visit(FILE *fd, int depth, size_t len; len = first->u.unary_expression.u.unsigned_constant; - array_declaration = array_declaration_new(len, nested_declaration, + array_declaration = bt_array_declaration_new(len, nested_declaration, declaration_scope); if (!array_declaration) { diff --git a/formats/ctf/types/array.c b/formats/ctf/types/array.c index d5b6ed4..006f0ce 100644 --- a/formats/ctf/types/array.c +++ b/formats/ctf/types/array.c @@ -61,7 +61,7 @@ int ctf_array_read(struct stream_pos *ppos, struct definition *definition) } } } - return array_rw(ppos, definition); + return bt_array_rw(ppos, definition); } int ctf_array_write(struct stream_pos *ppos, struct definition *definition) @@ -96,5 +96,5 @@ int ctf_array_write(struct stream_pos *ppos, struct definition *definition) } } } - return array_rw(ppos, definition); + return bt_array_rw(ppos, definition); } diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index 772abb2..3b45fd5 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -488,13 +488,13 @@ int variant_rw(struct stream_pos *pos, struct definition *definition); * array. */ struct declaration_array * - array_declaration_new(size_t len, struct declaration *elem_declaration, + bt_array_declaration_new(size_t len, struct declaration *elem_declaration, struct declaration_scope *parent_scope); -uint64_t array_len(struct definition_array *array); -struct definition *array_index(struct definition_array *array, uint64_t i); -int array_rw(struct stream_pos *pos, struct definition *definition); -GString *get_char_array(const struct definition *field); -int get_array_len(const struct definition *field); +uint64_t bt_array_len(struct definition_array *array); +struct definition *bt_array_index(struct definition_array *array, uint64_t i); +int bt_array_rw(struct stream_pos *pos, struct definition *definition); +GString *bt_get_char_array(const struct definition *field); +int bt_get_array_len(const struct definition *field); /* * int_declaration and elem_declaration passed as parameter now belong diff --git a/types/array.c b/types/array.c index 4942108..d2db46f 100644 --- a/types/array.c +++ b/types/array.c @@ -38,7 +38,7 @@ struct definition *_array_definition_new(struct declaration *declaration, static void _array_definition_free(struct definition *definition); -int array_rw(struct stream_pos *pos, struct definition *definition) +int bt_array_rw(struct stream_pos *pos, struct definition *definition) { struct definition_array *array_definition = container_of(definition, struct definition_array, p); @@ -70,7 +70,7 @@ void _array_declaration_free(struct declaration *declaration) } struct declaration_array * - array_declaration_new(size_t len, + bt_array_declaration_new(size_t len, struct declaration *elem_declaration, struct declaration_scope *parent_scope) { @@ -198,14 +198,14 @@ void _array_definition_free(struct definition *definition) g_free(array); } -uint64_t array_len(struct definition_array *array) +uint64_t bt_array_len(struct definition_array *array) { if (!array->elems) return array->string->len; return array->elems->len; } -struct definition *array_index(struct definition_array *array, uint64_t i) +struct definition *bt_array_index(struct definition_array *array, uint64_t i) { if (!array->elems) return NULL; @@ -214,7 +214,7 @@ struct definition *array_index(struct definition_array *array, uint64_t i) return g_ptr_array_index(array->elems, i); } -int get_array_len(const struct definition *field) +int bt_get_array_len(const struct definition *field) { struct definition_array *array_definition; struct declaration_array *array_declaration; @@ -225,7 +225,7 @@ int get_array_len(const struct definition *field) return array_declaration->len; } -GString *get_char_array(const struct definition *field) +GString *bt_get_char_array(const struct definition *field) { struct definition_array *array_definition; struct declaration_array *array_declaration; -- 1.7.10.4 From jdesfossez at efficios.com Thu Jan 24 16:21:38 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 16:21:38 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 06/18] namespace declaration_ref and declaration_unref In-Reply-To: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> Message-ID: <1359062510-7557-6-git-send-email-jdesfossez@efficios.com> Signed-off-by: Julien Desfossez --- .../ctf/metadata/ctf-visitor-generate-io-struct.c | 56 ++++++++++---------- formats/ctf/types/float.c | 4 +- include/babeltrace/types.h | 4 +- types/array.c | 10 ++-- types/enum.c | 8 +-- types/float.c | 10 ++-- types/integer.c | 4 +- types/sequence.c | 10 ++-- types/string.c | 4 +- types/struct.c | 10 ++-- types/types.c | 20 +++---- types/variant.c | 14 ++--- 12 files changed, 77 insertions(+), 77 deletions(-) diff --git a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c index 97d15e7..9693345 100644 --- a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c +++ b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c @@ -516,7 +516,7 @@ struct declaration *ctf_type_declarator_visit(FILE *fd, int depth, fprintf(fd, "[error] %s: cannot create array declaration.\n", __func__); return NULL; } - declaration_unref(nested_declaration); + bt_declaration_unref(nested_declaration); declaration = &array_declaration->p; break; } @@ -532,7 +532,7 @@ struct declaration *ctf_type_declarator_visit(FILE *fd, int depth, g_free(length_name); return NULL; } - declaration_unref(nested_declaration); + bt_declaration_unref(nested_declaration); declaration = &sequence_declaration->p; g_free(length_name); break; @@ -583,7 +583,7 @@ int ctf_struct_type_declarators_visit(FILE *fd, int depth, struct_declaration_add_field(struct_declaration, g_quark_to_string(field_name), field_declaration); - declaration_unref(field_declaration); + bt_declaration_unref(field_declaration); } return 0; } @@ -620,7 +620,7 @@ int ctf_variant_type_declarators_visit(FILE *fd, int depth, untagged_variant_declaration_add_field(untagged_variant_declaration, g_quark_to_string(field_name), field_declaration); - declaration_unref(field_declaration); + bt_declaration_unref(field_declaration); } return 0; } @@ -652,7 +652,7 @@ int ctf_typedef_visit(FILE *fd, int depth, struct declaration_scope *scope, */ if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) { fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__); - declaration_unref(type_declaration); + bt_declaration_unref(type_declaration); return -EPERM; } ret = register_declaration(identifier, type_declaration, scope); @@ -660,7 +660,7 @@ int ctf_typedef_visit(FILE *fd, int depth, struct declaration_scope *scope, type_declaration->declaration_free(type_declaration); return ret; } - declaration_unref(type_declaration); + bt_declaration_unref(type_declaration); } return 0; } @@ -702,7 +702,7 @@ int ctf_typealias_visit(FILE *fd, int depth, struct declaration_scope *scope, */ if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) { fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__); - declaration_unref(type_declaration); + bt_declaration_unref(type_declaration); return -EPERM; } /* @@ -725,7 +725,7 @@ int ctf_typealias_visit(FILE *fd, int depth, struct declaration_scope *scope, err = register_declaration(alias_q, type_declaration, scope); if (err) goto error; - declaration_unref(type_declaration); + bt_declaration_unref(type_declaration); return 0; error: @@ -842,7 +842,7 @@ struct declaration *ctf_declaration_struct_visit(FILE *fd, struct_declaration = lookup_struct_declaration(g_quark_from_string(name), declaration_scope); - declaration_ref(&struct_declaration->p); + bt_declaration_ref(&struct_declaration->p); return &struct_declaration->p; } else { uint64_t min_align_value = 0; @@ -914,7 +914,7 @@ struct declaration *ctf_declaration_variant_visit(FILE *fd, untagged_variant_declaration = lookup_variant_declaration(g_quark_from_string(name), declaration_scope); - declaration_ref(&untagged_variant_declaration->p); + bt_declaration_ref(&untagged_variant_declaration->p); } else { /* For unnamed variant, create type */ /* For named variant (with body), create type and add to declaration scope */ @@ -954,7 +954,7 @@ struct declaration *ctf_declaration_variant_visit(FILE *fd, variant_declaration = variant_declaration_new(untagged_variant_declaration, choice); if (!variant_declaration) goto error; - declaration_unref(&untagged_variant_declaration->p); + bt_declaration_unref(&untagged_variant_declaration->p); return &variant_declaration->p; } error: @@ -1078,7 +1078,7 @@ struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth, enum_declaration = lookup_enum_declaration(g_quark_from_string(name), declaration_scope); - declaration_ref(&enum_declaration->p); + bt_declaration_ref(&enum_declaration->p); return &enum_declaration->p; } else { /* For unnamed enum, create type */ @@ -1115,7 +1115,7 @@ struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth, } integer_declaration = container_of(declaration, struct declaration_integer, p); enum_declaration = enum_declaration_new(integer_declaration); - declaration_unref(&integer_declaration->p); /* leave ref to enum */ + bt_declaration_unref(&integer_declaration->p); /* leave ref to enum */ if (enum_declaration->integer_declaration->signedness) { last_value.u.s = 0; } else { @@ -1136,7 +1136,7 @@ struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth, enum_declaration, declaration_scope); assert(!ret); - declaration_unref(&enum_declaration->p); + bt_declaration_unref(&enum_declaration->p); } return &enum_declaration->p; } @@ -1164,7 +1164,7 @@ struct declaration *ctf_declaration_type_specifier_visit(FILE *fd, int depth, id_q = g_quark_from_string(str_c); g_free(str_c); declaration = lookup_declaration(id_q, declaration_scope); - declaration_ref(declaration); + bt_declaration_ref(declaration); return declaration; } @@ -1864,9 +1864,9 @@ int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node, error: if (event->fields_decl) - declaration_unref(&event->fields_decl->p); + bt_declaration_unref(&event->fields_decl->p); if (event->context_decl) - declaration_unref(&event->context_decl->p); + bt_declaration_unref(&event->context_decl->p); free_declaration_scope(event->declaration_scope); g_free(event_decl); return ret; @@ -2040,11 +2040,11 @@ int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node, error: if (stream->event_header_decl) - declaration_unref(&stream->event_header_decl->p); + bt_declaration_unref(&stream->event_header_decl->p); if (stream->event_context_decl) - declaration_unref(&stream->event_context_decl->p); + bt_declaration_unref(&stream->event_context_decl->p); if (stream->packet_context_decl) - declaration_unref(&stream->packet_context_decl->p); + bt_declaration_unref(&stream->packet_context_decl->p); g_ptr_array_free(stream->streams, TRUE); g_ptr_array_free(stream->events_by_id, TRUE); g_hash_table_destroy(stream->event_quark_to_id); @@ -2236,7 +2236,7 @@ int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace error: if (trace->packet_header_decl) { - declaration_unref(&trace->packet_header_decl->p); + bt_declaration_unref(&trace->packet_header_decl->p); trace->packet_header_decl = NULL; } g_ptr_array_free(trace->streams, TRUE); @@ -2851,7 +2851,7 @@ int ctf_root_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struc node, trace->root_declaration_scope, trace); if (!declaration) return -ENOMEM; - declaration_unref(declaration); + bt_declaration_unref(declaration); break; } default: @@ -3021,11 +3021,11 @@ int ctf_destroy_metadata(struct ctf_trace *trace) g_free(stream_def); } if (stream->event_header_decl) - declaration_unref(&stream->event_header_decl->p); + bt_declaration_unref(&stream->event_header_decl->p); if (stream->event_context_decl) - declaration_unref(&stream->event_context_decl->p); + bt_declaration_unref(&stream->event_context_decl->p); if (stream->packet_context_decl) - declaration_unref(&stream->packet_context_decl->p); + bt_declaration_unref(&stream->packet_context_decl->p); g_ptr_array_free(stream->streams, TRUE); g_ptr_array_free(stream->events_by_id, TRUE); g_hash_table_destroy(stream->event_quark_to_id); @@ -3056,9 +3056,9 @@ int ctf_destroy_metadata(struct ctf_trace *trace) event = &event_decl->parent; if (event->fields_decl) - declaration_unref(&event->fields_decl->p); + bt_declaration_unref(&event->fields_decl->p); if (event->context_decl) - declaration_unref(&event->context_decl->p); + bt_declaration_unref(&event->context_decl->p); free_declaration_scope(event->declaration_scope); g_free(event); @@ -3066,7 +3066,7 @@ int ctf_destroy_metadata(struct ctf_trace *trace) g_ptr_array_free(trace->event_declarations, TRUE); } if (trace->packet_header_decl) - declaration_unref(&trace->packet_header_decl->p); + bt_declaration_unref(&trace->packet_header_decl->p); free_declaration_scope(trace->root_declaration_scope); free_declaration_scope(trace->declaration_scope); diff --git a/formats/ctf/types/float.c b/formats/ctf/types/float.c index 054e262..d77cff5 100644 --- a/formats/ctf/types/float.c +++ b/formats/ctf/types/float.c @@ -296,6 +296,6 @@ void __attribute__((constructor)) ctf_float_init(void) static void __attribute__((destructor)) ctf_float_fini(void) { - declaration_unref(&static_float_declaration->p); - declaration_unref(&static_double_declaration->p); + bt_declaration_unref(&static_float_declaration->p); + bt_declaration_unref(&static_double_declaration->p); } diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index 3b45fd5..2348823 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -364,8 +364,8 @@ int compare_definition_path(struct definition *definition, GQuark path) return definition->path == path; } -void declaration_ref(struct declaration *declaration); -void declaration_unref(struct declaration *declaration); +void bt_declaration_ref(struct declaration *declaration); +void bt_declaration_unref(struct declaration *declaration); void definition_ref(struct definition *definition); void definition_unref(struct definition *definition); diff --git a/types/array.c b/types/array.c index d2db46f..cc9a600 100644 --- a/types/array.c +++ b/types/array.c @@ -65,7 +65,7 @@ void _array_declaration_free(struct declaration *declaration) container_of(declaration, struct declaration_array, p); free_declaration_scope(array_declaration->scope); - declaration_unref(array_declaration->elem); + bt_declaration_unref(array_declaration->elem); g_free(array_declaration); } @@ -80,7 +80,7 @@ struct declaration_array * array_declaration = g_new(struct declaration_array, 1); declaration = &array_declaration->p; array_declaration->len = len; - declaration_ref(elem_declaration); + bt_declaration_ref(elem_declaration); array_declaration->elem = elem_declaration; array_declaration->scope = new_declaration_scope(parent_scope); declaration->id = CTF_TYPE_ARRAY; @@ -105,7 +105,7 @@ struct definition * int i; array = g_new(struct definition_array, 1); - declaration_ref(&array_declaration->p); + bt_declaration_ref(&array_declaration->p); array->p.declaration = declaration; array->declaration = array_declaration; array->p.ref = 1; @@ -170,7 +170,7 @@ error: } (void) g_ptr_array_free(array->elems, TRUE); free_definition_scope(array->p.scope); - declaration_unref(array->p.declaration); + bt_declaration_unref(array->p.declaration); g_free(array); return NULL; } @@ -194,7 +194,7 @@ void _array_definition_free(struct definition *definition) (void) g_ptr_array_free(array->elems, TRUE); } free_definition_scope(array->p.scope); - declaration_unref(array->p.declaration); + bt_declaration_unref(array->p.declaration); g_free(array); } diff --git a/types/enum.c b/types/enum.c index ca0143d..2ea40ba 100644 --- a/types/enum.c +++ b/types/enum.c @@ -386,7 +386,7 @@ void _enum_declaration_free(struct declaration *declaration) g_free(iter); } g_hash_table_destroy(enum_declaration->table.quark_to_range_set); - declaration_unref(&enum_declaration->integer_declaration->p); + bt_declaration_unref(&enum_declaration->integer_declaration->p); g_free(enum_declaration); } @@ -405,7 +405,7 @@ struct declaration_enum * enum_declaration->table.quark_to_range_set = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, enum_range_set_free); - declaration_ref(&integer_declaration->p); + bt_declaration_ref(&integer_declaration->p); enum_declaration->integer_declaration = integer_declaration; enum_declaration->p.id = CTF_TYPE_ENUM; enum_declaration->p.alignment = 1; @@ -430,7 +430,7 @@ struct definition * int ret; _enum = g_new(struct definition_enum, 1); - declaration_ref(&enum_declaration->p); + bt_declaration_ref(&enum_declaration->p); _enum->p.declaration = declaration; _enum->declaration = enum_declaration; _enum->p.ref = 1; @@ -463,7 +463,7 @@ void _enum_definition_free(struct definition *definition) definition_unref(&_enum->integer->p); free_definition_scope(_enum->p.scope); - declaration_unref(_enum->p.declaration); + bt_declaration_unref(_enum->p.declaration); if (_enum->value) g_array_unref(_enum->value); g_free(_enum); diff --git a/types/float.c b/types/float.c index 028749b..5c80312 100644 --- a/types/float.c +++ b/types/float.c @@ -45,9 +45,9 @@ void _float_declaration_free(struct declaration *declaration) struct declaration_float *float_declaration = container_of(declaration, struct declaration_float, p); - declaration_unref(&float_declaration->exp->p); - declaration_unref(&float_declaration->mantissa->p); - declaration_unref(&float_declaration->sign->p); + bt_declaration_unref(&float_declaration->exp->p); + bt_declaration_unref(&float_declaration->mantissa->p); + bt_declaration_unref(&float_declaration->sign->p); g_free(float_declaration); } @@ -93,7 +93,7 @@ struct definition * struct definition *tmp; _float = g_new(struct definition_float, 1); - declaration_ref(&float_declaration->p); + bt_declaration_ref(&float_declaration->p); _float->p.declaration = declaration; _float->declaration = float_declaration; _float->p.scope = new_definition_scope(parent_scope, field_name, root_name); @@ -147,6 +147,6 @@ void _float_definition_free(struct definition *definition) definition_unref(&_float->exp->p); definition_unref(&_float->mantissa->p); free_definition_scope(_float->p.scope); - declaration_unref(_float->p.declaration); + bt_declaration_unref(_float->p.declaration); g_free(_float); } diff --git a/types/integer.c b/types/integer.c index 337641d..20e7688 100644 --- a/types/integer.c +++ b/types/integer.c @@ -85,7 +85,7 @@ struct definition * int ret; integer = g_new(struct definition_integer, 1); - declaration_ref(&integer_declaration->p); + bt_declaration_ref(&integer_declaration->p); integer->p.declaration = declaration; integer->declaration = integer_declaration; integer->p.ref = 1; @@ -111,7 +111,7 @@ void _integer_definition_free(struct definition *definition) struct definition_integer *integer = container_of(definition, struct definition_integer, p); - declaration_unref(integer->p.declaration); + bt_declaration_unref(integer->p.declaration); g_free(integer); } diff --git a/types/sequence.c b/types/sequence.c index 3967f97..18d7e35 100644 --- a/types/sequence.c +++ b/types/sequence.c @@ -95,7 +95,7 @@ void _sequence_declaration_free(struct declaration *declaration) free_declaration_scope(sequence_declaration->scope); g_array_free(sequence_declaration->length_name, TRUE); - declaration_unref(sequence_declaration->elem); + bt_declaration_unref(sequence_declaration->elem); g_free(sequence_declaration); } @@ -113,7 +113,7 @@ struct declaration_sequence * sequence_declaration->length_name = g_array_new(FALSE, TRUE, sizeof(GQuark)); bt_append_scope_path(length, sequence_declaration->length_name); - declaration_ref(elem_declaration); + bt_declaration_ref(elem_declaration); sequence_declaration->elem = elem_declaration; sequence_declaration->scope = new_declaration_scope(parent_scope); declaration->id = CTF_TYPE_SEQUENCE; @@ -138,7 +138,7 @@ struct definition *_sequence_definition_new(struct declaration *declaration, int ret; sequence = g_new(struct definition_sequence, 1); - declaration_ref(&sequence_declaration->p); + bt_declaration_ref(&sequence_declaration->p); sequence->p.declaration = declaration; sequence->declaration = sequence_declaration; sequence->p.ref = 1; @@ -192,7 +192,7 @@ struct definition *_sequence_definition_new(struct declaration *declaration, error: free_definition_scope(sequence->p.scope); - declaration_unref(&sequence_declaration->p); + bt_declaration_unref(&sequence_declaration->p); g_free(sequence); return NULL; } @@ -218,7 +218,7 @@ void _sequence_definition_free(struct definition *definition) } definition_unref(len_definition); free_definition_scope(sequence->p.scope); - declaration_unref(sequence->p.declaration); + bt_declaration_unref(sequence->p.declaration); g_free(sequence); } diff --git a/types/string.c b/types/string.c index 4860740..cebce12 100644 --- a/types/string.c +++ b/types/string.c @@ -76,7 +76,7 @@ struct definition * int ret; string = g_new(struct definition_string, 1); - declaration_ref(&string_declaration->p); + bt_declaration_ref(&string_declaration->p); string->p.declaration = declaration; string->declaration = string_declaration; string->p.ref = 1; @@ -104,7 +104,7 @@ void _string_definition_free(struct definition *definition) struct definition_string *string = container_of(definition, struct definition_string, p); - declaration_unref(string->p.declaration); + bt_declaration_unref(string->p.declaration); g_free(string->value); g_free(string); } diff --git a/types/struct.c b/types/struct.c index 138da16..5cc0849 100644 --- a/types/struct.c +++ b/types/struct.c @@ -74,7 +74,7 @@ void _struct_declaration_free(struct declaration *declaration) struct declaration_field *declaration_field = &g_array_index(struct_declaration->fields, struct declaration_field, i); - declaration_unref(declaration_field->declaration); + bt_declaration_unref(declaration_field->declaration); } g_array_free(struct_declaration->fields, true); g_free(struct_declaration); @@ -118,7 +118,7 @@ struct definition * int ret; _struct = g_new(struct definition_struct, 1); - declaration_ref(&struct_declaration->p); + bt_declaration_ref(&struct_declaration->p); _struct->p.declaration = declaration; _struct->declaration = struct_declaration; _struct->p.ref = 1; @@ -158,7 +158,7 @@ error: definition_unref(field); } free_definition_scope(_struct->p.scope); - declaration_unref(&struct_declaration->p); + bt_declaration_unref(&struct_declaration->p); g_free(_struct); return NULL; } @@ -176,7 +176,7 @@ void _struct_definition_free(struct definition *definition) definition_unref(field); } free_definition_scope(_struct->p.scope); - declaration_unref(_struct->p.declaration); + bt_declaration_unref(_struct->p.declaration); g_ptr_array_free(_struct->fields, TRUE); g_free(_struct); } @@ -192,7 +192,7 @@ void struct_declaration_add_field(struct declaration_struct *struct_declaration, index = struct_declaration->fields->len - 1; /* last field (new) */ field = &g_array_index(struct_declaration->fields, struct declaration_field, index); field->name = g_quark_from_string(field_name); - declaration_ref(field_declaration); + bt_declaration_ref(field_declaration); field->declaration = field_declaration; /* Keep index in hash rather than pointer, because array can relocate */ g_hash_table_insert(struct_declaration->fields_by_name, diff --git a/types/types.c b/types/types.c index 9c5cfca..5bb051f 100644 --- a/types/types.c +++ b/types/types.c @@ -87,7 +87,7 @@ int register_declaration(GQuark name, struct declaration *declaration, g_hash_table_insert(scope->typedef_declarations, (gpointer) (unsigned long) name, declaration); - declaration_ref(declaration); + bt_declaration_ref(declaration); return 0; } @@ -279,12 +279,12 @@ int register_field_definition(GQuark field_name, struct definition *definition, return 0; } -void declaration_ref(struct declaration *declaration) +void bt_declaration_ref(struct declaration *declaration) { declaration->ref++; } -void declaration_unref(struct declaration *declaration) +void bt_declaration_unref(struct declaration *declaration) { if (!declaration) return; @@ -312,16 +312,16 @@ struct declaration_scope * scope->typedef_declarations = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, - (GDestroyNotify) declaration_unref); + (GDestroyNotify) bt_declaration_unref); scope->struct_declarations = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, - (GDestroyNotify) declaration_unref); + (GDestroyNotify) bt_declaration_unref); scope->variant_declarations = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, - (GDestroyNotify) declaration_unref); + (GDestroyNotify) bt_declaration_unref); scope->enum_declarations = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, - (GDestroyNotify) declaration_unref); + (GDestroyNotify) bt_declaration_unref); scope->parent_scope = parent_scope; return scope; } @@ -374,7 +374,7 @@ int register_struct_declaration(GQuark struct_name, g_hash_table_insert(scope->struct_declarations, (gpointer) (unsigned long) struct_name, struct_declaration); - declaration_ref(&struct_declaration->p); + bt_declaration_ref(&struct_declaration->p); /* Also add in typedef/typealias scopes */ prefix_name = prefix_quark("struct ", struct_name); @@ -424,7 +424,7 @@ int register_variant_declaration(GQuark variant_name, g_hash_table_insert(scope->variant_declarations, (gpointer) (unsigned long) variant_name, untagged_variant_declaration); - declaration_ref(&untagged_variant_declaration->p); + bt_declaration_ref(&untagged_variant_declaration->p); /* Also add in typedef/typealias scopes */ prefix_name = prefix_quark("variant ", variant_name); @@ -475,7 +475,7 @@ int register_enum_declaration(GQuark enum_name, g_hash_table_insert(scope->enum_declarations, (gpointer) (unsigned long) enum_name, enum_declaration); - declaration_ref(&enum_declaration->p); + bt_declaration_ref(&enum_declaration->p); /* Also add in typedef/typealias scopes */ prefix_name = prefix_quark("enum ", enum_name); diff --git a/types/variant.c b/types/variant.c index 4f1e524..4d00a3b 100644 --- a/types/variant.c +++ b/types/variant.c @@ -63,7 +63,7 @@ void _untagged_variant_declaration_free(struct declaration *declaration) struct declaration_field *declaration_field = &g_array_index(untagged_variant_declaration->fields, struct declaration_field, i); - declaration_unref(declaration_field->declaration); + bt_declaration_unref(declaration_field->declaration); } g_array_free(untagged_variant_declaration->fields, true); g_free(untagged_variant_declaration); @@ -98,7 +98,7 @@ void _variant_declaration_free(struct declaration *declaration) struct declaration_variant *variant_declaration = container_of(declaration, struct declaration_variant, p); - declaration_unref(&variant_declaration->untagged_variant->p); + bt_declaration_unref(&variant_declaration->untagged_variant->p); g_array_free(variant_declaration->tag_name, TRUE); g_free(variant_declaration); } @@ -112,7 +112,7 @@ struct declaration_variant * variant_declaration = g_new(struct declaration_variant, 1); declaration = &variant_declaration->p; variant_declaration->untagged_variant = untagged_variant; - declaration_ref(&untagged_variant->p); + bt_declaration_ref(&untagged_variant->p); variant_declaration->tag_name = g_array_new(FALSE, TRUE, sizeof(GQuark)); bt_append_scope_path(tag, variant_declaration->tag_name); declaration->id = CTF_TYPE_VARIANT; @@ -185,7 +185,7 @@ struct definition * int ret; variant = g_new(struct definition_variant, 1); - declaration_ref(&variant_declaration->p); + bt_declaration_ref(&variant_declaration->p); variant->p.declaration = declaration; variant->declaration = variant_declaration; variant->p.ref = 1; @@ -233,7 +233,7 @@ struct definition * return &variant->p; error: free_definition_scope(variant->p.scope); - declaration_unref(&variant_declaration->p); + bt_declaration_unref(&variant_declaration->p); g_free(variant); return NULL; } @@ -252,7 +252,7 @@ void _variant_definition_free(struct definition *definition) } definition_unref(variant->enum_tag); free_definition_scope(variant->p.scope); - declaration_unref(variant->p.declaration); + bt_declaration_unref(variant->p.declaration); g_ptr_array_free(variant->fields, TRUE); g_free(variant); } @@ -268,7 +268,7 @@ void untagged_variant_declaration_add_field(struct declaration_untagged_variant index = untagged_variant_declaration->fields->len - 1; /* last field (new) */ field = &g_array_index(untagged_variant_declaration->fields, struct declaration_field, index); field->name = g_quark_from_string(field_name); - declaration_ref(field_declaration); + bt_declaration_ref(field_declaration); field->declaration = field_declaration; /* Keep index in hash rather than pointer, because array can relocate */ g_hash_table_insert(untagged_variant_declaration->fields_by_tag, -- 1.7.10.4 From jdesfossez at efficios.com Thu Jan 24 16:21:39 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 16:21:39 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 07/18] namespace definition_ref and definition_unref In-Reply-To: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> Message-ID: <1359062510-7557-7-git-send-email-jdesfossez@efficios.com> Signed-off-by: Julien Desfossez --- formats/ctf/ctf.c | 14 +++++++------- formats/ctf/metadata/ctf-visitor-generate-io-struct.c | 12 ++++++------ formats/ctf/types/float.c | 4 ++-- include/babeltrace/types.h | 4 ++-- types/enum.c | 2 +- types/float.c | 6 +++--- types/sequence.c | 4 ++-- types/struct.c | 4 ++-- types/types.c | 4 ++-- types/variant.c | 6 +++--- 10 files changed, 30 insertions(+), 30 deletions(-) diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index e18fffb..6a24087 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -1168,9 +1168,9 @@ struct ctf_event_definition *create_event_definitions(struct ctf_trace *td, error: if (stream_event->event_fields) - definition_unref(&stream_event->event_fields->p); + bt_definition_unref(&stream_event->event_fields->p); if (stream_event->event_context) - definition_unref(&stream_event->event_context->p); + bt_definition_unref(&stream_event->event_context->p); return NULL; } @@ -1246,11 +1246,11 @@ error_event: g_ptr_array_free(stream->events_by_id, TRUE); error: if (stream->stream_event_context) - definition_unref(&stream->stream_event_context->p); + bt_definition_unref(&stream->stream_event_context->p); if (stream->stream_event_header) - definition_unref(&stream->stream_event_header->p); + bt_definition_unref(&stream->stream_event_header->p); if (stream->stream_packet_context) - definition_unref(&stream->stream_packet_context->p); + bt_definition_unref(&stream->stream_packet_context->p); return ret; } @@ -1572,7 +1572,7 @@ int ctf_open_file_stream_read(struct ctf_trace *td, const char *path, int flags, error_index: if (file_stream->parent.trace_packet_header) - definition_unref(&file_stream->parent.trace_packet_header->p); + bt_definition_unref(&file_stream->parent.trace_packet_header->p); error_def: closeret = ctf_fini_pos(&file_stream->pos); if (closeret) { @@ -1811,7 +1811,7 @@ int ctf_open_mmap_stream_read(struct ctf_trace *td, error_index: if (file_stream->parent.trace_packet_header) - definition_unref(&file_stream->parent.trace_packet_header->p); + bt_definition_unref(&file_stream->parent.trace_packet_header->p); error_def: g_free(file_stream); return ret; diff --git a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c index 9693345..9ade8c4 100644 --- a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c +++ b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c @@ -3004,19 +3004,19 @@ int ctf_destroy_metadata(struct ctf_trace *trace) if (!event) continue; if (&event->event_fields->p) - definition_unref(&event->event_fields->p); + bt_definition_unref(&event->event_fields->p); if (&event->event_context->p) - definition_unref(&event->event_context->p); + bt_definition_unref(&event->event_context->p); g_free(event); } if (&stream_def->trace_packet_header->p) - definition_unref(&stream_def->trace_packet_header->p); + bt_definition_unref(&stream_def->trace_packet_header->p); if (&stream_def->stream_event_header->p) - definition_unref(&stream_def->stream_event_header->p); + bt_definition_unref(&stream_def->stream_event_header->p); if (&stream_def->stream_packet_context->p) - definition_unref(&stream_def->stream_packet_context->p); + bt_definition_unref(&stream_def->stream_packet_context->p); if (&stream_def->stream_event_context->p) - definition_unref(&stream_def->stream_event_context->p); + bt_definition_unref(&stream_def->stream_event_context->p); g_ptr_array_free(stream_def->events_by_id, TRUE); g_free(stream_def); } diff --git a/formats/ctf/types/float.c b/formats/ctf/types/float.c index d77cff5..fc7c39c 100644 --- a/formats/ctf/types/float.c +++ b/formats/ctf/types/float.c @@ -216,7 +216,7 @@ int ctf_float_read(struct stream_pos *ppos, struct definition *definition) } end_unref: - definition_unref(tmpdef); + bt_definition_unref(tmpdef); end: float_unlock(); return ret; @@ -272,7 +272,7 @@ int ctf_float_write(struct stream_pos *ppos, struct definition *definition) ret = _ctf_float_copy(ppos, float_definition, &srcp.parent, tmpfloat); end_unref: - definition_unref(tmpdef); + bt_definition_unref(tmpdef); end: float_unlock(); return ret; diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index 2348823..1b0cd2b 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -367,8 +367,8 @@ int compare_definition_path(struct definition *definition, GQuark path) void bt_declaration_ref(struct declaration *declaration); void bt_declaration_unref(struct declaration *declaration); -void definition_ref(struct definition *definition); -void definition_unref(struct definition *definition); +void bt_definition_ref(struct definition *definition); +void bt_definition_unref(struct definition *definition); struct declaration_integer *integer_declaration_new(size_t len, int byte_order, int signedness, size_t alignment, diff --git a/types/enum.c b/types/enum.c index 2ea40ba..43df4eb 100644 --- a/types/enum.c +++ b/types/enum.c @@ -461,7 +461,7 @@ void _enum_definition_free(struct definition *definition) struct definition_enum *_enum = container_of(definition, struct definition_enum, p); - definition_unref(&_enum->integer->p); + bt_definition_unref(&_enum->integer->p); free_definition_scope(_enum->p.scope); bt_declaration_unref(_enum->p.declaration); if (_enum->value) diff --git a/types/float.c b/types/float.c index 5c80312..0fc137f 100644 --- a/types/float.c +++ b/types/float.c @@ -143,9 +143,9 @@ void _float_definition_free(struct definition *definition) struct definition_float *_float = container_of(definition, struct definition_float, p); - definition_unref(&_float->sign->p); - definition_unref(&_float->exp->p); - definition_unref(&_float->mantissa->p); + bt_definition_unref(&_float->sign->p); + bt_definition_unref(&_float->exp->p); + bt_definition_unref(&_float->mantissa->p); free_definition_scope(_float->p.scope); bt_declaration_unref(_float->p.declaration); g_free(_float); diff --git a/types/sequence.c b/types/sequence.c index 18d7e35..736e866 100644 --- a/types/sequence.c +++ b/types/sequence.c @@ -166,7 +166,7 @@ struct definition *_sequence_definition_new(struct declaration *declaration, printf("[error] Sequence length field should be unsigned.\n"); goto error; } - definition_ref(len_parent); + bt_definition_ref(len_parent); sequence->string = NULL; sequence->elems = NULL; @@ -216,7 +216,7 @@ void _sequence_definition_free(struct definition *definition) } (void) g_ptr_array_free(sequence->elems, TRUE); } - definition_unref(len_definition); + bt_definition_unref(len_definition); free_definition_scope(sequence->p.scope); bt_declaration_unref(sequence->p.declaration); g_free(sequence); diff --git a/types/struct.c b/types/struct.c index 5cc0849..cf8fef6 100644 --- a/types/struct.c +++ b/types/struct.c @@ -155,7 +155,7 @@ struct definition * error: for (i--; i >= 0; i--) { struct definition *field = g_ptr_array_index(_struct->fields, i); - definition_unref(field); + bt_definition_unref(field); } free_definition_scope(_struct->p.scope); bt_declaration_unref(&struct_declaration->p); @@ -173,7 +173,7 @@ void _struct_definition_free(struct definition *definition) assert(_struct->fields->len == _struct->declaration->fields->len); for (i = 0; i < _struct->fields->len; i++) { struct definition *field = g_ptr_array_index(_struct->fields, i); - definition_unref(field); + bt_definition_unref(field); } free_definition_scope(_struct->p.scope); bt_declaration_unref(_struct->p.declaration); diff --git a/types/types.c b/types/types.c index 5bb051f..a6c8abe 100644 --- a/types/types.c +++ b/types/types.c @@ -292,12 +292,12 @@ void bt_declaration_unref(struct declaration *declaration) declaration->declaration_free(declaration); } -void definition_ref(struct definition *definition) +void bt_definition_ref(struct definition *definition) { definition->ref++; } -void definition_unref(struct definition *definition) +void bt_definition_unref(struct definition *definition) { if (!definition) return; diff --git a/types/variant.c b/types/variant.c index 4d00a3b..a58c17f 100644 --- a/types/variant.c +++ b/types/variant.c @@ -209,7 +209,7 @@ struct definition * if (!variant->enum_tag || check_enum_tag(variant, variant->enum_tag) < 0) goto error; - definition_ref(variant->enum_tag); + bt_definition_ref(variant->enum_tag); variant->fields = g_ptr_array_sized_new(variant_declaration->untagged_variant->fields->len); g_ptr_array_set_size(variant->fields, variant_declaration->untagged_variant->fields->len); for (i = 0; i < variant_declaration->untagged_variant->fields->len; i++) { @@ -248,9 +248,9 @@ void _variant_definition_free(struct definition *definition) assert(variant->fields->len == variant->declaration->untagged_variant->fields->len); for (i = 0; i < variant->fields->len; i++) { struct definition *field = g_ptr_array_index(variant->fields, i); - definition_unref(field); + bt_definition_unref(field); } - definition_unref(variant->enum_tag); + bt_definition_unref(variant->enum_tag); free_definition_scope(variant->p.scope); bt_declaration_unref(variant->p.declaration); g_ptr_array_free(variant->fields, TRUE); -- 1.7.10.4 From jdesfossez at efficios.com Thu Jan 24 16:21:40 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 16:21:40 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 08/18] namespace the enum functions In-Reply-To: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> Message-ID: <1359062510-7557-8-git-send-email-jdesfossez@efficios.com> Signed-off-by: Julien Desfossez --- formats/ctf/events.c | 4 +-- .../ctf/metadata/ctf-visitor-generate-io-struct.c | 6 ++-- formats/ctf/types/enum.c | 4 +-- include/babeltrace/types.h | 14 ++++----- types/enum.c | 30 ++++++++++---------- types/variant.c | 4 +-- 6 files changed, 31 insertions(+), 31 deletions(-) diff --git a/formats/ctf/events.c b/formats/ctf/events.c index b530cd5..1d1ef6f 100644 --- a/formats/ctf/events.c +++ b/formats/ctf/events.c @@ -463,10 +463,10 @@ const char *bt_ctf_get_enum_str(const struct definition *field) def_enum = container_of(field, const struct definition_enum, p); decl_enum = def_enum->declaration; if (get_int_signedness(&def_enum->integer->p)) { - array = enum_int_to_quark_set(decl_enum, + array = bt_enum_int_to_quark_set(decl_enum, get_signed_int(&def_enum->integer->p)); } else { - array = enum_uint_to_quark_set(decl_enum, + array = bt_enum_uint_to_quark_set(decl_enum, get_unsigned_int(&def_enum->integer->p)); } if (!array) { diff --git a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c index 9ade8c4..928262f 100644 --- a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c +++ b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c @@ -1007,7 +1007,7 @@ int ctf_enumerator_list_visit(FILE *fd, int depth, if (nr_vals <= 1) end = start; last->u.s = end + 1; - enum_signed_insert(enum_declaration, start, end, q); + bt_enum_signed_insert(enum_declaration, start, end, q); } else { uint64_t start, end; int nr_vals = 0; @@ -1047,7 +1047,7 @@ int ctf_enumerator_list_visit(FILE *fd, int depth, if (nr_vals <= 1) end = start; last->u.u = end + 1; - enum_unsigned_insert(enum_declaration, start, end, q); + bt_enum_unsigned_insert(enum_declaration, start, end, q); } return 0; } @@ -1114,7 +1114,7 @@ struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth, return NULL; } integer_declaration = container_of(declaration, struct declaration_integer, p); - enum_declaration = enum_declaration_new(integer_declaration); + enum_declaration = bt_enum_declaration_new(integer_declaration); bt_declaration_unref(&integer_declaration->p); /* leave ref to enum */ if (enum_declaration->integer_declaration->signedness) { last_value.u.s = 0; diff --git a/formats/ctf/types/enum.c b/formats/ctf/types/enum.c index e4e7ac8..1891175 100644 --- a/formats/ctf/types/enum.c +++ b/formats/ctf/types/enum.c @@ -48,14 +48,14 @@ int ctf_enum_read(struct stream_pos *ppos, struct definition *definition) if (ret) return ret; if (!integer_declaration->signedness) { - qs = enum_uint_to_quark_set(enum_declaration, + qs = bt_enum_uint_to_quark_set(enum_declaration, integer_definition->value._unsigned); if (!qs) { fprintf(stderr, "[warning] Unknown value %" PRIu64 " in enum.\n", integer_definition->value._unsigned); } } else { - qs = enum_int_to_quark_set(enum_declaration, + qs = bt_enum_int_to_quark_set(enum_declaration, integer_definition->value._signed); if (!qs) { fprintf(stderr, "[warning] Unknown value %" PRId64 " in enum.\n", diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index 1b0cd2b..15bbef3 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -399,14 +399,14 @@ struct declaration_float *float_declaration_new(size_t mantissa_len, * Returns a GArray of GQuark or NULL. * Caller must release the GArray with g_array_unref(). */ -GArray *enum_uint_to_quark_set(const struct declaration_enum *enum_declaration, +GArray *bt_enum_uint_to_quark_set(const struct declaration_enum *enum_declaration, uint64_t v); /* * Returns a GArray of GQuark or NULL. * Caller must release the GArray with g_array_unref(). */ -GArray *enum_int_to_quark_set(const struct declaration_enum *enum_declaration, +GArray *bt_enum_int_to_quark_set(const struct declaration_enum *enum_declaration, int64_t v); /* @@ -414,16 +414,16 @@ GArray *enum_int_to_quark_set(const struct declaration_enum *enum_declaration, * Callers do _not_ own the returned GArray (and therefore _don't_ need to * release it). */ -GArray *enum_quark_to_range_set(const struct declaration_enum *enum_declaration, +GArray *bt_enum_quark_to_range_set(const struct declaration_enum *enum_declaration, GQuark q); -void enum_signed_insert(struct declaration_enum *enum_declaration, +void bt_enum_signed_insert(struct declaration_enum *enum_declaration, int64_t start, int64_t end, GQuark q); -void enum_unsigned_insert(struct declaration_enum *enum_declaration, +void bt_enum_unsigned_insert(struct declaration_enum *enum_declaration, uint64_t start, uint64_t end, GQuark q); -size_t enum_get_nr_enumerators(struct declaration_enum *enum_declaration); +size_t bt_enum_get_nr_enumerators(struct declaration_enum *enum_declaration); struct declaration_enum * - enum_declaration_new(struct declaration_integer *integer_declaration); + bt_enum_declaration_new(struct declaration_integer *integer_declaration); struct declaration_string * string_declaration_new(enum ctf_string_encoding encoding); diff --git a/types/enum.c b/types/enum.c index 43df4eb..6d33713 100644 --- a/types/enum.c +++ b/types/enum.c @@ -124,7 +124,7 @@ void enum_val_free(void *ptr) * Returns a GArray or NULL. * Caller must release the GArray with g_array_unref(). */ -GArray *enum_uint_to_quark_set(const struct declaration_enum *enum_declaration, +GArray *bt_enum_uint_to_quark_set(const struct declaration_enum *enum_declaration, uint64_t v) { struct enum_range_to_quark *iter; @@ -171,7 +171,7 @@ GArray *enum_uint_to_quark_set(const struct declaration_enum *enum_declaration, * Returns a GArray or NULL. * Caller must release the GArray with g_array_unref(). */ -GArray *enum_int_to_quark_set(const struct declaration_enum *enum_declaration, +GArray *bt_enum_int_to_quark_set(const struct declaration_enum *enum_declaration, int64_t v) { struct enum_range_to_quark *iter; @@ -215,7 +215,7 @@ GArray *enum_int_to_quark_set(const struct declaration_enum *enum_declaration, } static -void enum_unsigned_insert_value_to_quark_set(struct declaration_enum *enum_declaration, +void bt_enum_unsigned_insert_value_to_quark_set(struct declaration_enum *enum_declaration, uint64_t v, GQuark q) { uint64_t *valuep; @@ -241,7 +241,7 @@ void enum_unsigned_insert_value_to_quark_set(struct declaration_enum *enum_decla } static -void enum_signed_insert_value_to_quark_set(struct declaration_enum *enum_declaration, +void bt_enum_signed_insert_value_to_quark_set(struct declaration_enum *enum_declaration, int64_t v, GQuark q) { int64_t *valuep; @@ -266,7 +266,7 @@ void enum_signed_insert_value_to_quark_set(struct declaration_enum *enum_declara } } -GArray *enum_quark_to_range_set(const struct declaration_enum *enum_declaration, +GArray *bt_enum_quark_to_range_set(const struct declaration_enum *enum_declaration, GQuark q) { return g_hash_table_lookup(enum_declaration->table.quark_to_range_set, @@ -274,7 +274,7 @@ GArray *enum_quark_to_range_set(const struct declaration_enum *enum_declaration, } static -void enum_signed_insert_range_to_quark(struct declaration_enum *enum_declaration, +void bt_enum_signed_insert_range_to_quark(struct declaration_enum *enum_declaration, int64_t start, int64_t end, GQuark q) { struct enum_range_to_quark *rtoq; @@ -287,7 +287,7 @@ void enum_signed_insert_range_to_quark(struct declaration_enum *enum_declaration } static -void enum_unsigned_insert_range_to_quark(struct declaration_enum *enum_declaration, +void bt_enum_unsigned_insert_range_to_quark(struct declaration_enum *enum_declaration, uint64_t start, uint64_t end, GQuark q) { struct enum_range_to_quark *rtoq; @@ -299,14 +299,14 @@ void enum_unsigned_insert_range_to_quark(struct declaration_enum *enum_declarati rtoq->quark = q; } -void enum_signed_insert(struct declaration_enum *enum_declaration, +void bt_enum_signed_insert(struct declaration_enum *enum_declaration, int64_t start, int64_t end, GQuark q) { GArray *array; struct enum_range *range; if (start == end) { - enum_signed_insert_value_to_quark_set(enum_declaration, start, q); + bt_enum_signed_insert_value_to_quark_set(enum_declaration, start, q); } else { if (start > end) { uint64_t tmp; @@ -315,7 +315,7 @@ void enum_signed_insert(struct declaration_enum *enum_declaration, start = end; end = tmp; } - enum_signed_insert_range_to_quark(enum_declaration, start, end, q); + bt_enum_signed_insert_range_to_quark(enum_declaration, start, end, q); } array = g_hash_table_lookup(enum_declaration->table.quark_to_range_set, @@ -333,7 +333,7 @@ void enum_signed_insert(struct declaration_enum *enum_declaration, range->end._signed = end; } -void enum_unsigned_insert(struct declaration_enum *enum_declaration, +void bt_enum_unsigned_insert(struct declaration_enum *enum_declaration, uint64_t start, uint64_t end, GQuark q) { GArray *array; @@ -341,7 +341,7 @@ void enum_unsigned_insert(struct declaration_enum *enum_declaration, if (start == end) { - enum_unsigned_insert_value_to_quark_set(enum_declaration, start, q); + bt_enum_unsigned_insert_value_to_quark_set(enum_declaration, start, q); } else { if (start > end) { uint64_t tmp; @@ -350,7 +350,7 @@ void enum_unsigned_insert(struct declaration_enum *enum_declaration, start = end; end = tmp; } - enum_unsigned_insert_range_to_quark(enum_declaration, start, end, q); + bt_enum_unsigned_insert_range_to_quark(enum_declaration, start, end, q); } array = g_hash_table_lookup(enum_declaration->table.quark_to_range_set, @@ -368,7 +368,7 @@ void enum_unsigned_insert(struct declaration_enum *enum_declaration, range->end._unsigned = end; } -size_t enum_get_nr_enumerators(struct declaration_enum *enum_declaration) +size_t bt_enum_get_nr_enumerators(struct declaration_enum *enum_declaration) { return g_hash_table_size(enum_declaration->table.quark_to_range_set); } @@ -391,7 +391,7 @@ void _enum_declaration_free(struct declaration *declaration) } struct declaration_enum * - enum_declaration_new(struct declaration_integer *integer_declaration) + bt_enum_declaration_new(struct declaration_integer *integer_declaration) { struct declaration_enum *enum_declaration; diff --git a/types/variant.c b/types/variant.c index a58c17f..47c821e 100644 --- a/types/variant.c +++ b/types/variant.c @@ -144,14 +144,14 @@ int check_enum_tag(struct definition_variant *variant, * variant choice map to an enumerator too. We then validate that the * number of enumerators equals the number of variant choices. */ - if (variant->declaration->untagged_variant->fields->len != enum_get_nr_enumerators(enum_declaration)) + if (variant->declaration->untagged_variant->fields->len != bt_enum_get_nr_enumerators(enum_declaration)) return -EPERM; for (i = 0; i < variant->declaration->untagged_variant->fields->len; i++) { struct declaration_field *field_declaration = &g_array_index(variant->declaration->untagged_variant->fields, struct declaration_field, i); - if (!enum_quark_to_range_set(enum_declaration, field_declaration->name)) { + if (!bt_enum_quark_to_range_set(enum_declaration, field_declaration->name)) { missing_field = 1; break; } -- 1.7.10.4 From jdesfossez at efficios.com Thu Jan 24 16:21:41 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 16:21:41 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 09/18] namespace the int functions In-Reply-To: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> Message-ID: <1359062510-7557-9-git-send-email-jdesfossez@efficios.com> Signed-off-by: Julien Desfossez --- formats/ctf/ctf.c | 18 +++++++++--------- formats/ctf/events.c | 10 +++++----- include/babeltrace/types.h | 14 +++++++------- types/integer.c | 14 +++++++------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index 6a24087..45ab65e 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -1317,7 +1317,7 @@ int create_stream_packet_index(struct ctf_trace *td, uint64_t magic; field = struct_definition_get_field_from_index(file_stream->parent.trace_packet_header, len_index); - magic = get_unsigned_int(field); + magic = bt_get_unsigned_int(field); if (magic != CTF_MAGIC) { fprintf(stderr, "[error] Invalid magic number 0x%" PRIX64 " at packet %u (file offset %zd).\n", magic, @@ -1344,7 +1344,7 @@ int create_stream_packet_index(struct ctf_trace *td, struct definition *elem; elem = bt_array_index(defarray, i); - uuidval[i] = get_unsigned_int(elem); + uuidval[i] = bt_get_unsigned_int(elem); } ret = babeltrace_uuid_compare(td->uuid, uuidval); if (ret) { @@ -1359,7 +1359,7 @@ int create_stream_packet_index(struct ctf_trace *td, struct definition *field; field = struct_definition_get_field_from_index(file_stream->parent.trace_packet_header, len_index); - stream_id = get_unsigned_int(field); + stream_id = bt_get_unsigned_int(field); } } @@ -1396,7 +1396,7 @@ int create_stream_packet_index(struct ctf_trace *td, struct definition *field; field = struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index); - packet_index.content_size = get_unsigned_int(field); + packet_index.content_size = bt_get_unsigned_int(field); } else { /* Use file size for packet size */ packet_index.content_size = filestats.st_size * CHAR_BIT; @@ -1408,7 +1408,7 @@ int create_stream_packet_index(struct ctf_trace *td, struct definition *field; field = struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index); - packet_index.packet_size = get_unsigned_int(field); + packet_index.packet_size = bt_get_unsigned_int(field); } else { /* Use content size if non-zero, else file size */ packet_index.packet_size = packet_index.content_size ? : filestats.st_size * CHAR_BIT; @@ -1420,7 +1420,7 @@ int create_stream_packet_index(struct ctf_trace *td, struct definition *field; field = struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index); - packet_index.timestamp_begin = get_unsigned_int(field); + packet_index.timestamp_begin = bt_get_unsigned_int(field); if (file_stream->parent.stream_class->trace->collection) { packet_index.timestamp_begin = ctf_get_real_timestamp( @@ -1435,7 +1435,7 @@ int create_stream_packet_index(struct ctf_trace *td, struct definition *field; field = struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index); - packet_index.timestamp_end = get_unsigned_int(field); + packet_index.timestamp_end = bt_get_unsigned_int(field); if (file_stream->parent.stream_class->trace->collection) { packet_index.timestamp_end = ctf_get_real_timestamp( @@ -1450,8 +1450,8 @@ int create_stream_packet_index(struct ctf_trace *td, struct definition *field; field = struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index); - packet_index.events_discarded = get_unsigned_int(field); - packet_index.events_discarded_len = get_int_len(field); + packet_index.events_discarded = bt_get_unsigned_int(field); + packet_index.events_discarded_len = bt_get_int_len(field); } } else { /* Use file size for packet size */ diff --git a/formats/ctf/events.c b/formats/ctf/events.c index 1d1ef6f..372fdd1 100644 --- a/formats/ctf/events.c +++ b/formats/ctf/events.c @@ -462,12 +462,12 @@ const char *bt_ctf_get_enum_str(const struct definition *field) } def_enum = container_of(field, const struct definition_enum, p); decl_enum = def_enum->declaration; - if (get_int_signedness(&def_enum->integer->p)) { + if (bt_get_int_signedness(&def_enum->integer->p)) { array = bt_enum_int_to_quark_set(decl_enum, - get_signed_int(&def_enum->integer->p)); + bt_get_signed_int(&def_enum->integer->p)); } else { array = bt_enum_uint_to_quark_set(decl_enum, - get_unsigned_int(&def_enum->integer->p)); + bt_get_unsigned_int(&def_enum->integer->p)); } if (!array) { bt_ctf_field_set_error(-ENOENT); @@ -559,7 +559,7 @@ uint64_t bt_ctf_get_uint64(const struct definition *field) uint64_t ret = 0; if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_INTEGER) - ret = get_unsigned_int(field); + ret = bt_get_unsigned_int(field); else bt_ctf_field_set_error(-EINVAL); @@ -571,7 +571,7 @@ int64_t bt_ctf_get_int64(const struct definition *field) int64_t ret = 0; if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_INTEGER) - ret = get_signed_int(field); + ret = bt_get_signed_int(field); else bt_ctf_field_set_error(-EINVAL); diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index 15bbef3..7b3485d 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -374,13 +374,13 @@ struct declaration_integer *integer_declaration_new(size_t len, int byte_order, int signedness, size_t alignment, int base, enum ctf_string_encoding encoding, struct ctf_clock *clock); -uint64_t get_unsigned_int(const struct definition *field); -int64_t get_signed_int(const struct definition *field); -int get_int_signedness(const struct definition *field); -int get_int_byte_order(const struct definition *field); -int get_int_base(const struct definition *field); -size_t get_int_len(const struct definition *field); /* in bits */ -enum ctf_string_encoding get_int_encoding(const struct definition *field); +uint64_t bt_get_unsigned_int(const struct definition *field); +int64_t bt_get_signed_int(const struct definition *field); +int bt_get_int_signedness(const struct definition *field); +int bt_get_int_byte_order(const struct definition *field); +int bt_get_int_base(const struct definition *field); +size_t bt_get_int_len(const struct definition *field); /* in bits */ +enum ctf_string_encoding bt_get_int_encoding(const struct definition *field); /* * mantissa_len is the length of the number of bytes represented by the mantissa diff --git a/types/integer.c b/types/integer.c index 20e7688..58b6104 100644 --- a/types/integer.c +++ b/types/integer.c @@ -115,7 +115,7 @@ void _integer_definition_free(struct definition *definition) g_free(integer); } -enum ctf_string_encoding get_int_encoding(const struct definition *field) +enum ctf_string_encoding bt_get_int_encoding(const struct definition *field) { struct definition_integer *integer_definition; const struct declaration_integer *integer_declaration; @@ -126,7 +126,7 @@ enum ctf_string_encoding get_int_encoding(const struct definition *field) return integer_declaration->encoding; } -int get_int_base(const struct definition *field) +int bt_get_int_base(const struct definition *field) { struct definition_integer *integer_definition; const struct declaration_integer *integer_declaration; @@ -137,7 +137,7 @@ int get_int_base(const struct definition *field) return integer_declaration->base; } -size_t get_int_len(const struct definition *field) +size_t bt_get_int_len(const struct definition *field) { struct definition_integer *integer_definition; const struct declaration_integer *integer_declaration; @@ -148,7 +148,7 @@ size_t get_int_len(const struct definition *field) return integer_declaration->len; } -int get_int_byte_order(const struct definition *field) +int bt_get_int_byte_order(const struct definition *field) { struct definition_integer *integer_definition; const struct declaration_integer *integer_declaration; @@ -159,7 +159,7 @@ int get_int_byte_order(const struct definition *field) return integer_declaration->byte_order; } -int get_int_signedness(const struct definition *field) +int bt_get_int_signedness(const struct definition *field) { struct definition_integer *integer_definition; const struct declaration_integer *integer_declaration; @@ -170,7 +170,7 @@ int get_int_signedness(const struct definition *field) return integer_declaration->signedness; } -uint64_t get_unsigned_int(const struct definition *field) +uint64_t bt_get_unsigned_int(const struct definition *field) { struct definition_integer *integer_definition; const struct declaration_integer *integer_declaration; @@ -186,7 +186,7 @@ uint64_t get_unsigned_int(const struct definition *field) return (uint64_t)integer_definition->value._signed; } -int64_t get_signed_int(const struct definition *field) +int64_t bt_get_signed_int(const struct definition *field) { struct definition_integer *integer_definition; const struct declaration_integer *integer_declaration; -- 1.7.10.4 From jdesfossez at efficios.com Thu Jan 24 16:21:43 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 16:21:43 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 11/18] namespace the string functions In-Reply-To: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> Message-ID: <1359062510-7557-11-git-send-email-jdesfossez@efficios.com> Signed-off-by: Julien Desfossez --- formats/ctf/events.c | 2 +- formats/ctf/metadata/ctf-visitor-generate-io-struct.c | 2 +- include/babeltrace/types.h | 6 +++--- types/string.c | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/formats/ctf/events.c b/formats/ctf/events.c index 036ce46..3660c04 100644 --- a/formats/ctf/events.c +++ b/formats/ctf/events.c @@ -601,7 +601,7 @@ char *bt_ctf_get_string(const struct definition *field) char *ret = NULL; if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_STRING) - ret = get_string(field); + ret = bt_get_string(field); else bt_ctf_field_set_error(-EINVAL); diff --git a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c index 94dd0c8..bdb9f5f 100644 --- a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c +++ b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c @@ -1558,7 +1558,7 @@ struct declaration *ctf_declaration_string_visit(FILE *fd, int depth, } if (encoding_c && !strcmp(encoding_c, "ASCII")) encoding = CTF_STRING_ASCII; - string_declaration = string_declaration_new(encoding); + string_declaration = bt_string_declaration_new(encoding); return &string_declaration->p; } diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index a0c5467..da69b91 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -426,9 +426,9 @@ struct declaration_enum * bt_enum_declaration_new(struct declaration_integer *integer_declaration); struct declaration_string * - string_declaration_new(enum ctf_string_encoding encoding); -char *get_string(const struct definition *field); -enum ctf_string_encoding get_string_encoding(const struct definition *field); + bt_string_declaration_new(enum ctf_string_encoding encoding); +char *bt_get_string(const struct definition *field); +enum ctf_string_encoding bt_get_string_encoding(const struct definition *field); struct declaration_struct * struct_declaration_new(struct declaration_scope *parent_scope, diff --git a/types/string.c b/types/string.c index cebce12..255388f 100644 --- a/types/string.c +++ b/types/string.c @@ -48,7 +48,7 @@ void _string_declaration_free(struct declaration *declaration) } struct declaration_string * - string_declaration_new(enum ctf_string_encoding encoding) + bt_string_declaration_new(enum ctf_string_encoding encoding) { struct declaration_string *string_declaration; @@ -109,7 +109,7 @@ void _string_definition_free(struct definition *definition) g_free(string); } -enum ctf_string_encoding get_string_encoding(const struct definition *field) +enum ctf_string_encoding bt_get_string_encoding(const struct definition *field) { struct definition_string *string_definition; const struct declaration_string *string_declaration; @@ -120,7 +120,7 @@ enum ctf_string_encoding get_string_encoding(const struct definition *field) return string_declaration->encoding; } -char *get_string(const struct definition *field) +char *bt_get_string(const struct definition *field) { struct definition_string *string_definition = container_of(field, struct definition_string, p); -- 1.7.10.4 From jdesfossez at efficios.com Thu Jan 24 16:21:42 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 16:21:42 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 10/18] namespace the sequence functions In-Reply-To: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> Message-ID: <1359062510-7557-10-git-send-email-jdesfossez@efficios.com> Signed-off-by: Julien Desfossez --- formats/ctf-text/types/sequence.c | 4 ++-- formats/ctf/events.c | 2 +- formats/ctf/metadata/ctf-visitor-generate-io-struct.c | 2 +- formats/ctf/types/sequence.c | 8 ++++---- include/babeltrace/types.h | 8 ++++---- types/sequence.c | 8 ++++---- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/formats/ctf-text/types/sequence.c b/formats/ctf-text/types/sequence.c index 20345cc..12574ee 100644 --- a/formats/ctf-text/types/sequence.c +++ b/formats/ctf-text/types/sequence.c @@ -63,7 +63,7 @@ int ctf_text_sequence_write(struct stream_pos *ppos, struct definition *definiti && integer_declaration->p.alignment == CHAR_BIT)) { pos->string = sequence_definition->string; g_string_assign(sequence_definition->string, ""); - ret = sequence_rw(ppos, definition); + ret = bt_sequence_rw(ppos, definition); pos->string = NULL; } fprintf(pos->fp, "\"%s\"", sequence_definition->string->str); @@ -77,7 +77,7 @@ int ctf_text_sequence_write(struct stream_pos *ppos, struct definition *definiti } field_nr_saved = pos->field_nr; pos->field_nr = 0; - ret = sequence_rw(ppos, definition); + ret = bt_sequence_rw(ppos, definition); if (!pos->dummy) { pos->depth--; fprintf(pos->fp, " ]"); diff --git a/formats/ctf/events.c b/formats/ctf/events.c index 372fdd1..036ce46 100644 --- a/formats/ctf/events.c +++ b/formats/ctf/events.c @@ -145,7 +145,7 @@ const struct definition *bt_ctf_get_index(const struct bt_ctf_event *ctf_event, struct definition_sequence *sequence_definition; sequence_definition = container_of(field, struct definition_sequence, p); - ret = sequence_index(sequence_definition, index); + ret = bt_sequence_index(sequence_definition, index); } return ret; } diff --git a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c index 928262f..94dd0c8 100644 --- a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c +++ b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c @@ -526,7 +526,7 @@ struct declaration *ctf_type_declarator_visit(FILE *fd, int depth, char *length_name = concatenate_unary_strings(&node_type_declarator->u.type_declarator.u.nested.length); struct declaration_sequence *sequence_declaration; - sequence_declaration = sequence_declaration_new(length_name, nested_declaration, declaration_scope); + sequence_declaration = bt_sequence_declaration_new(length_name, nested_declaration, declaration_scope); if (!sequence_declaration) { fprintf(fd, "[error] %s: cannot create sequence declaration.\n", __func__); g_free(length_name); diff --git a/formats/ctf/types/sequence.c b/formats/ctf/types/sequence.c index 7f12bbc..2ff31b7 100644 --- a/formats/ctf/types/sequence.c +++ b/formats/ctf/types/sequence.c @@ -46,7 +46,7 @@ int ctf_sequence_read(struct stream_pos *ppos, struct definition *definition) if (integer_declaration->len == CHAR_BIT && integer_declaration->p.alignment == CHAR_BIT) { - uint64_t len = sequence_len(sequence_definition); + uint64_t len = bt_sequence_len(sequence_definition); ctf_align_pos(pos, integer_declaration->p.alignment); if (!ctf_pos_access_ok(pos, len * CHAR_BIT)) @@ -60,7 +60,7 @@ int ctf_sequence_read(struct stream_pos *ppos, struct definition *definition) } } } - return sequence_rw(ppos, definition); + return bt_sequence_rw(ppos, definition); } int ctf_sequence_write(struct stream_pos *ppos, struct definition *definition) @@ -81,7 +81,7 @@ int ctf_sequence_write(struct stream_pos *ppos, struct definition *definition) if (integer_declaration->len == CHAR_BIT && integer_declaration->p.alignment == CHAR_BIT) { - uint64_t len = sequence_len(sequence_definition); + uint64_t len = bt_sequence_len(sequence_definition); ctf_align_pos(pos, integer_declaration->p.alignment); if (!ctf_pos_access_ok(pos, len * CHAR_BIT)) @@ -94,5 +94,5 @@ int ctf_sequence_write(struct stream_pos *ppos, struct definition *definition) } } } - return sequence_rw(ppos, definition); + return bt_sequence_rw(ppos, definition); } diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index 7b3485d..a0c5467 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -501,12 +501,12 @@ int bt_get_array_len(const struct definition *field); * to the sequence. No need to free them explicitly. */ struct declaration_sequence * - sequence_declaration_new(const char *length_name, + bt_sequence_declaration_new(const char *length_name, struct declaration *elem_declaration, struct declaration_scope *parent_scope); -uint64_t sequence_len(struct definition_sequence *sequence); -struct definition *sequence_index(struct definition_sequence *sequence, uint64_t i); -int sequence_rw(struct stream_pos *pos, struct definition *definition); +uint64_t bt_sequence_len(struct definition_sequence *sequence); +struct definition *bt_sequence_index(struct definition_sequence *sequence, uint64_t i); +int bt_sequence_rw(struct stream_pos *pos, struct definition *definition); /* * in: path (dot separated), out: q (GArray of GQuark) diff --git a/types/sequence.c b/types/sequence.c index 736e866..6ed168c 100644 --- a/types/sequence.c +++ b/types/sequence.c @@ -39,7 +39,7 @@ struct definition *_sequence_definition_new(struct declaration *declaration, static void _sequence_definition_free(struct definition *definition); -int sequence_rw(struct stream_pos *pos, struct definition *definition) +int bt_sequence_rw(struct stream_pos *pos, struct definition *definition) { struct definition_sequence *sequence_definition = container_of(definition, struct definition_sequence, p); @@ -100,7 +100,7 @@ void _sequence_declaration_free(struct declaration *declaration) } struct declaration_sequence * - sequence_declaration_new(const char *length, + bt_sequence_declaration_new(const char *length, struct declaration *elem_declaration, struct declaration_scope *parent_scope) { @@ -222,12 +222,12 @@ void _sequence_definition_free(struct definition *definition) g_free(sequence); } -uint64_t sequence_len(struct definition_sequence *sequence) +uint64_t bt_sequence_len(struct definition_sequence *sequence) { return sequence->length->value._unsigned; } -struct definition *sequence_index(struct definition_sequence *sequence, uint64_t i) +struct definition *bt_sequence_index(struct definition_sequence *sequence, uint64_t i) { if (!sequence->elems) return NULL; -- 1.7.10.4 From jdesfossez at efficios.com Thu Jan 24 16:21:44 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 16:21:44 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 12/18] namespace the struct functions In-Reply-To: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> Message-ID: <1359062510-7557-12-git-send-email-jdesfossez@efficios.com> Signed-off-by: Julien Desfossez --- formats/ctf-text/types/struct.c | 4 +-- formats/ctf/ctf.c | 32 ++++++++++---------- .../ctf/metadata/ctf-visitor-generate-io-struct.c | 16 +++++----- formats/ctf/types/struct.c | 2 +- include/babeltrace/types.h | 18 +++++------ types/struct.c | 16 +++++----- types/types.c | 10 +++--- 7 files changed, 49 insertions(+), 49 deletions(-) diff --git a/formats/ctf-text/types/struct.c b/formats/ctf-text/types/struct.c index 8a9344e..e9365af 100644 --- a/formats/ctf-text/types/struct.c +++ b/formats/ctf-text/types/struct.c @@ -35,7 +35,7 @@ int ctf_text_struct_write(struct stream_pos *ppos, struct definition *definition struct declaration_struct *struct_declaration = container_of(declaration, struct declaration_struct, p); struct ctf_text_stream_pos *pos = ctf_text_pos(ppos); - uint64_t len = struct_declaration_len(struct_declaration); + uint64_t len = bt_struct_declaration_len(struct_declaration); int field_nr_saved; int ret; @@ -58,7 +58,7 @@ int ctf_text_struct_write(struct stream_pos *ppos, struct definition *definition } field_nr_saved = pos->field_nr; pos->field_nr = 0; - ret = struct_rw(ppos, definition); + ret = bt_struct_rw(ppos, definition); if (!pos->dummy) { pos->depth--; if (pos->depth >= 0 && (pos->print_names || len > 1)) { diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index 45ab65e..e2a109b 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -1311,12 +1311,12 @@ int create_stream_packet_index(struct ctf_trace *td, ret = generic_rw(&pos->parent, &file_stream->parent.trace_packet_header->p); if (ret) return ret; - len_index = struct_declaration_lookup_field_index(file_stream->parent.trace_packet_header->declaration, g_quark_from_static_string("magic")); + len_index = bt_struct_declaration_lookup_field_index(file_stream->parent.trace_packet_header->declaration, g_quark_from_static_string("magic")); if (len_index >= 0) { struct definition *field; uint64_t magic; - field = struct_definition_get_field_from_index(file_stream->parent.trace_packet_header, len_index); + field = bt_struct_definition_get_field_from_index(file_stream->parent.trace_packet_header, len_index); magic = bt_get_unsigned_int(field); if (magic != CTF_MAGIC) { fprintf(stderr, "[error] Invalid magic number 0x%" PRIX64 " at packet %u (file offset %zd).\n", @@ -1328,14 +1328,14 @@ int create_stream_packet_index(struct ctf_trace *td, } /* check uuid */ - len_index = struct_declaration_lookup_field_index(file_stream->parent.trace_packet_header->declaration, g_quark_from_static_string("uuid")); + len_index = bt_struct_declaration_lookup_field_index(file_stream->parent.trace_packet_header->declaration, g_quark_from_static_string("uuid")); if (len_index >= 0) { struct definition_array *defarray; struct definition *field; uint64_t i; uint8_t uuidval[BABELTRACE_UUID_LEN]; - field = struct_definition_get_field_from_index(file_stream->parent.trace_packet_header, len_index); + field = bt_struct_definition_get_field_from_index(file_stream->parent.trace_packet_header, len_index); assert(field->declaration->id == CTF_TYPE_ARRAY); defarray = container_of(field, struct definition_array, p); assert(bt_array_len(defarray) == BABELTRACE_UUID_LEN); @@ -1354,11 +1354,11 @@ int create_stream_packet_index(struct ctf_trace *td, } - len_index = struct_declaration_lookup_field_index(file_stream->parent.trace_packet_header->declaration, g_quark_from_static_string("stream_id")); + len_index = bt_struct_declaration_lookup_field_index(file_stream->parent.trace_packet_header->declaration, g_quark_from_static_string("stream_id")); if (len_index >= 0) { struct definition *field; - field = struct_definition_get_field_from_index(file_stream->parent.trace_packet_header, len_index); + field = bt_struct_definition_get_field_from_index(file_stream->parent.trace_packet_header, len_index); stream_id = bt_get_unsigned_int(field); } } @@ -1391,11 +1391,11 @@ int create_stream_packet_index(struct ctf_trace *td, if (ret) return ret; /* read content size from header */ - len_index = struct_declaration_lookup_field_index(file_stream->parent.stream_packet_context->declaration, g_quark_from_static_string("content_size")); + len_index = bt_struct_declaration_lookup_field_index(file_stream->parent.stream_packet_context->declaration, g_quark_from_static_string("content_size")); if (len_index >= 0) { struct definition *field; - field = struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index); + field = bt_struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index); packet_index.content_size = bt_get_unsigned_int(field); } else { /* Use file size for packet size */ @@ -1403,11 +1403,11 @@ int create_stream_packet_index(struct ctf_trace *td, } /* read packet size from header */ - len_index = struct_declaration_lookup_field_index(file_stream->parent.stream_packet_context->declaration, g_quark_from_static_string("packet_size")); + len_index = bt_struct_declaration_lookup_field_index(file_stream->parent.stream_packet_context->declaration, g_quark_from_static_string("packet_size")); if (len_index >= 0) { struct definition *field; - field = struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index); + field = bt_struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index); packet_index.packet_size = bt_get_unsigned_int(field); } else { /* Use content size if non-zero, else file size */ @@ -1415,11 +1415,11 @@ int create_stream_packet_index(struct ctf_trace *td, } /* read timestamp begin from header */ - len_index = struct_declaration_lookup_field_index(file_stream->parent.stream_packet_context->declaration, g_quark_from_static_string("timestamp_begin")); + len_index = bt_struct_declaration_lookup_field_index(file_stream->parent.stream_packet_context->declaration, g_quark_from_static_string("timestamp_begin")); if (len_index >= 0) { struct definition *field; - field = struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index); + field = bt_struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index); packet_index.timestamp_begin = bt_get_unsigned_int(field); if (file_stream->parent.stream_class->trace->collection) { packet_index.timestamp_begin = @@ -1430,11 +1430,11 @@ int create_stream_packet_index(struct ctf_trace *td, } /* read timestamp end from header */ - len_index = struct_declaration_lookup_field_index(file_stream->parent.stream_packet_context->declaration, g_quark_from_static_string("timestamp_end")); + len_index = bt_struct_declaration_lookup_field_index(file_stream->parent.stream_packet_context->declaration, g_quark_from_static_string("timestamp_end")); if (len_index >= 0) { struct definition *field; - field = struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index); + field = bt_struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index); packet_index.timestamp_end = bt_get_unsigned_int(field); if (file_stream->parent.stream_class->trace->collection) { packet_index.timestamp_end = @@ -1445,11 +1445,11 @@ int create_stream_packet_index(struct ctf_trace *td, } /* read events discarded from header */ - len_index = struct_declaration_lookup_field_index(file_stream->parent.stream_packet_context->declaration, g_quark_from_static_string("events_discarded")); + len_index = bt_struct_declaration_lookup_field_index(file_stream->parent.stream_packet_context->declaration, g_quark_from_static_string("events_discarded")); if (len_index >= 0) { struct definition *field; - field = struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index); + field = bt_struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index); packet_index.events_discarded = bt_get_unsigned_int(field); packet_index.events_discarded_len = bt_get_int_len(field); } diff --git a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c index bdb9f5f..9c5aeb1 100644 --- a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c +++ b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c @@ -575,12 +575,12 @@ int ctf_struct_type_declarators_visit(FILE *fd, int depth, } /* Check if field with same name already exists */ - if (struct_declaration_lookup_field_index(struct_declaration, field_name) >= 0) { + if (bt_struct_declaration_lookup_field_index(struct_declaration, field_name) >= 0) { fprintf(fd, "[error] %s: duplicate field %s in struct\n", __func__, g_quark_to_string(field_name)); return -EINVAL; } - struct_declaration_add_field(struct_declaration, + bt_struct_declaration_add_field(struct_declaration, g_quark_to_string(field_name), field_declaration); bt_declaration_unref(field_declaration); @@ -840,7 +840,7 @@ struct declaration *ctf_declaration_struct_visit(FILE *fd, if (!has_body) { assert(name); struct_declaration = - lookup_struct_declaration(g_quark_from_string(name), + bt_lookup_struct_declaration(g_quark_from_string(name), declaration_scope); bt_declaration_ref(&struct_declaration->p); return &struct_declaration->p; @@ -850,7 +850,7 @@ struct declaration *ctf_declaration_struct_visit(FILE *fd, /* For unnamed struct, create type */ /* For named struct (with body), create type and add to declaration scope */ if (name) { - if (lookup_struct_declaration(g_quark_from_string(name), + if (bt_lookup_struct_declaration(g_quark_from_string(name), declaration_scope)) { fprintf(fd, "[error] %s: struct %s already declared in scope\n", __func__, name); @@ -867,7 +867,7 @@ struct declaration *ctf_declaration_struct_visit(FILE *fd, goto error; } } - struct_declaration = struct_declaration_new(declaration_scope, + struct_declaration = bt_struct_declaration_new(declaration_scope, min_align_value); bt_list_for_each_entry(iter, declaration_list, siblings) { int ret; @@ -880,7 +880,7 @@ struct declaration *ctf_declaration_struct_visit(FILE *fd, if (name) { int ret; - ret = register_struct_declaration(g_quark_from_string(name), + ret = bt_register_struct_declaration(g_quark_from_string(name), struct_declaration, declaration_scope); assert(!ret); @@ -2017,7 +2017,7 @@ int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node, if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) { /* check that packet header has stream_id field. */ if (!trace->packet_header_decl - || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("stream_id")) < 0) { + || bt_struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("stream_id")) < 0) { ret = -EPERM; fprintf(fd, "[error] %s: missing stream_id field in packet header declaration, but stream_id attribute is declared for stream.\n", __func__); goto error; @@ -2226,7 +2226,7 @@ int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) { /* check that the packet header contains a "magic" field */ if (!trace->packet_header_decl - || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("magic")) < 0) { + || bt_struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("magic")) < 0) { ret = -EPERM; fprintf(fd, "[error] %s: missing both byte_order and packet header magic number in trace declaration\n", __func__); goto error; diff --git a/formats/ctf/types/struct.c b/formats/ctf/types/struct.c index 21ce96f..b0d9e4a 100644 --- a/formats/ctf/types/struct.c +++ b/formats/ctf/types/struct.c @@ -34,5 +34,5 @@ int ctf_struct_rw(struct stream_pos *ppos, struct definition *definition) struct ctf_stream_pos *pos = ctf_pos(ppos); ctf_align_pos(pos, declaration->alignment); - return struct_rw(ppos, definition); + return bt_struct_rw(ppos, definition); } diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index da69b91..a3d9788 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -317,11 +317,11 @@ struct declaration *lookup_declaration(GQuark declaration_name, * that a named variant can be declared without specifying its target * "choice" tag field immediately. */ -int register_struct_declaration(GQuark struct_name, +int bt_register_struct_declaration(GQuark struct_name, struct declaration_struct *struct_declaration, struct declaration_scope *scope); struct declaration_struct * - lookup_struct_declaration(GQuark struct_name, + bt_lookup_struct_declaration(GQuark struct_name, struct declaration_scope *scope); int register_variant_declaration(GQuark variant_name, struct declaration_untagged_variant *untagged_variant_declaration, @@ -431,27 +431,27 @@ char *bt_get_string(const struct definition *field); enum ctf_string_encoding bt_get_string_encoding(const struct definition *field); struct declaration_struct * - struct_declaration_new(struct declaration_scope *parent_scope, + bt_struct_declaration_new(struct declaration_scope *parent_scope, uint64_t min_align); -void struct_declaration_add_field(struct declaration_struct *struct_declaration, +void bt_struct_declaration_add_field(struct declaration_struct *struct_declaration, const char *field_name, struct declaration *field_declaration); /* * Returns the index of a field within a structure. */ -int struct_declaration_lookup_field_index(struct declaration_struct *struct_declaration, +int bt_struct_declaration_lookup_field_index(struct declaration_struct *struct_declaration, GQuark field_name); /* * field returned only valid as long as the field structure is not appended to. */ struct declaration_field * -struct_declaration_get_field_from_index(struct declaration_struct *struct_declaration, +bt_struct_declaration_get_field_from_index(struct declaration_struct *struct_declaration, int index); struct definition * -struct_definition_get_field_from_index(struct definition_struct *struct_definition, +bt_struct_definition_get_field_from_index(struct definition_struct *struct_definition, int index); -int struct_rw(struct stream_pos *pos, struct definition *definition); -uint64_t struct_declaration_len(struct declaration_struct *struct_declaration); +int bt_struct_rw(struct stream_pos *pos, struct definition *definition); +uint64_t bt_struct_declaration_len(struct declaration_struct *struct_declaration); /* * The tag enumeration is validated to ensure that it contains only mappings diff --git a/types/struct.c b/types/struct.c index cf8fef6..f065dbc 100644 --- a/types/struct.c +++ b/types/struct.c @@ -43,7 +43,7 @@ struct definition *_struct_definition_new(struct declaration *declaration, static void _struct_definition_free(struct definition *definition); -int struct_rw(struct stream_pos *ppos, struct definition *definition) +int bt_struct_rw(struct stream_pos *ppos, struct definition *definition) { struct definition_struct *struct_definition = container_of(definition, struct definition_struct, p); @@ -81,7 +81,7 @@ void _struct_declaration_free(struct declaration *declaration) } struct declaration_struct * - struct_declaration_new(struct declaration_scope *parent_scope, + bt_struct_declaration_new(struct declaration_scope *parent_scope, uint64_t min_align) { struct declaration_struct *struct_declaration; @@ -181,7 +181,7 @@ void _struct_definition_free(struct definition *definition) g_free(_struct); } -void struct_declaration_add_field(struct declaration_struct *struct_declaration, +void bt_struct_declaration_add_field(struct declaration_struct *struct_declaration, const char *field_name, struct declaration *field_declaration) { @@ -207,12 +207,12 @@ void struct_declaration_add_field(struct declaration_struct *struct_declaration, } /* - * struct_declaration_lookup_field_index - returns field index + * bt_struct_declaration_lookup_field_index - returns field index * * Returns the index of a field in a structure, or -1 if it does not * exist. */ -int struct_declaration_lookup_field_index(struct declaration_struct *struct_declaration, +int bt_struct_declaration_lookup_field_index(struct declaration_struct *struct_declaration, GQuark field_name) { gpointer index; @@ -230,7 +230,7 @@ int struct_declaration_lookup_field_index(struct declaration_struct *struct_decl * field returned only valid as long as the field structure is not appended to. */ struct declaration_field * - struct_declaration_get_field_from_index(struct declaration_struct *struct_declaration, + bt_struct_declaration_get_field_from_index(struct declaration_struct *struct_declaration, int index) { if (index < 0) @@ -242,7 +242,7 @@ struct declaration_field * * field returned only valid as long as the field structure is not appended to. */ struct definition * -struct_definition_get_field_from_index(struct definition_struct *_struct, +bt_struct_definition_get_field_from_index(struct definition_struct *_struct, int index) { if (index < 0) @@ -250,7 +250,7 @@ struct_definition_get_field_from_index(struct definition_struct *_struct, return g_ptr_array_index(_struct->fields, index); } -uint64_t struct_declaration_len(struct declaration_struct *struct_declaration) +uint64_t bt_struct_declaration_len(struct declaration_struct *struct_declaration) { return struct_declaration->fields->len; } diff --git a/types/types.c b/types/types.c index a6c8abe..615ab70 100644 --- a/types/types.c +++ b/types/types.c @@ -336,20 +336,20 @@ void free_declaration_scope(struct declaration_scope *scope) } static -struct declaration_struct *lookup_struct_declaration_scope(GQuark struct_name, +struct declaration_struct *bt_lookup_struct_declaration_scope(GQuark struct_name, struct declaration_scope *scope) { return g_hash_table_lookup(scope->struct_declarations, (gconstpointer) (unsigned long) struct_name); } -struct declaration_struct *lookup_struct_declaration(GQuark struct_name, +struct declaration_struct *bt_lookup_struct_declaration(GQuark struct_name, struct declaration_scope *scope) { struct declaration_struct *declaration; while (scope) { - declaration = lookup_struct_declaration_scope(struct_name, scope); + declaration = bt_lookup_struct_declaration_scope(struct_name, scope); if (declaration) return declaration; scope = scope->parent_scope; @@ -357,7 +357,7 @@ struct declaration_struct *lookup_struct_declaration(GQuark struct_name, return NULL; } -int register_struct_declaration(GQuark struct_name, +int bt_register_struct_declaration(GQuark struct_name, struct declaration_struct *struct_declaration, struct declaration_scope *scope) { @@ -368,7 +368,7 @@ int register_struct_declaration(GQuark struct_name, return -EPERM; /* Only lookup in local scope */ - if (lookup_struct_declaration_scope(struct_name, scope)) + if (bt_lookup_struct_declaration_scope(struct_name, scope)) return -EEXIST; g_hash_table_insert(scope->struct_declarations, -- 1.7.10.4 From jdesfossez at efficios.com Thu Jan 24 16:21:45 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 16:21:45 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 13/18] namespace the heap functions In-Reply-To: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> Message-ID: <1359062510-7557-13-git-send-email-jdesfossez@efficios.com> Signed-off-by: Julien Desfossez --- formats/ctf/iterator.c | 2 +- include/babeltrace/prio_heap.h | 34 ++++++++++++------------- lib/iterator.c | 54 ++++++++++++++++++++-------------------- lib/prio_heap/prio_heap.c | 20 +++++++-------- 4 files changed, 55 insertions(+), 55 deletions(-) diff --git a/formats/ctf/iterator.c b/formats/ctf/iterator.c index 0534d01..d2cd914 100644 --- a/formats/ctf/iterator.c +++ b/formats/ctf/iterator.c @@ -120,7 +120,7 @@ struct bt_ctf_event *bt_ctf_iter_read_event_flags(struct bt_ctf_iter *iter, assert(iter); ret = &iter->current_ctf_event; - file_stream = heap_maximum(iter->parent.stream_heap); + file_stream = bt_heap_maximum(iter->parent.stream_heap); if (!file_stream) { /* end of file for all streams */ goto stop; diff --git a/include/babeltrace/prio_heap.h b/include/babeltrace/prio_heap.h index 90aec8f..52de47c 100644 --- a/include/babeltrace/prio_heap.h +++ b/include/babeltrace/prio_heap.h @@ -47,38 +47,38 @@ void check_heap(const struct ptr_heap *heap) #endif /** - * heap_maximum - return the largest element in the heap + * bt_heap_maximum - return the largest element in the heap * @heap: the heap to be operated on * * Returns the largest element in the heap, without performing any modification * to the heap structure. Returns NULL if the heap is empty. */ -static inline void *heap_maximum(const struct ptr_heap *heap) +static inline void *bt_heap_maximum(const struct ptr_heap *heap) { check_heap(heap); return likely(heap->len) ? heap->ptrs[0] : NULL; } /** - * heap_init - initialize the heap + * bt_heap_init - initialize the heap * @heap: the heap to initialize * @alloc_len: number of elements initially allocated * @gt: function to compare the elements * * Returns -ENOMEM if out of memory. */ -extern int heap_init(struct ptr_heap *heap, +extern int bt_heap_init(struct ptr_heap *heap, size_t alloc_len, int gt(void *a, void *b)); /** - * heap_free - free the heap + * bt_heap_free - free the heap * @heap: the heap to free */ -extern void heap_free(struct ptr_heap *heap); +extern void bt_heap_free(struct ptr_heap *heap); /** - * heap_insert - insert an element into the heap + * bt_heap_insert - insert an element into the heap * @heap: the heap to be operated on * @p: the element to add * @@ -86,19 +86,19 @@ extern void heap_free(struct ptr_heap *heap); * * Returns -ENOMEM if out of memory. */ -extern int heap_insert(struct ptr_heap *heap, void *p); +extern int bt_heap_insert(struct ptr_heap *heap, void *p); /** - * heap_remove - remove the largest element from the heap + * bt_heap_remove - remove the largest element from the heap * @heap: the heap to be operated on * * Returns the largest element in the heap. It removes this element from the * heap. Returns NULL if the heap is empty. */ -extern void *heap_remove(struct ptr_heap *heap); +extern void *bt_heap_remove(struct ptr_heap *heap); /** - * heap_cherrypick - remove a given element from the heap + * bt_heap_cherrypick - remove a given element from the heap * @heap: the heap to be operated on * @p: the element * @@ -106,10 +106,10 @@ extern void *heap_remove(struct ptr_heap *heap); * return NULL. This algorithm has a complexity of O(n), which is higher than * O(log(n)) provided by the rest of this API. */ -extern void *heap_cherrypick(struct ptr_heap *heap, void *p); +extern void *bt_heap_cherrypick(struct ptr_heap *heap, void *p); /** - * heap_replace_max - replace the the largest element from the heap + * bt_heap_replace_max - replace the the largest element from the heap * @heap: the heap to be operated on * @p: the pointer to be inserted as topmost element replacement * @@ -117,18 +117,18 @@ extern void *heap_cherrypick(struct ptr_heap *heap, void *p); * heap. The heap is rebalanced only once after the insertion. Returns NULL if * the heap is empty. * - * This is the equivalent of calling heap_remove() and then heap_insert(), but + * This is the equivalent of calling bt_heap_remove() and then bt_heap_insert(), but * it only rebalances the heap once. It never allocates memory. */ -extern void *heap_replace_max(struct ptr_heap *heap, void *p); +extern void *bt_heap_replace_max(struct ptr_heap *heap, void *p); /** - * heap_copy - copy a heap + * bt_heap_copy - copy a heap * @dst: the destination heap (must be allocated) * @src: the source heap * * Returns -ENOMEM if out of memory. */ -extern int heap_copy(struct ptr_heap *dst, struct ptr_heap *src); +extern int bt_heap_copy(struct ptr_heap *dst, struct ptr_heap *src); #endif /* _BABELTRACE_PRIO_HEAP_H */ diff --git a/lib/iterator.c b/lib/iterator.c index 41a4602..dc12a2f 100644 --- a/lib/iterator.c +++ b/lib/iterator.c @@ -180,7 +180,7 @@ static int seek_ctf_trace_by_timestamp(struct ctf_trace *tin, ret = seek_file_stream_by_timestamp(cfs, timestamp); if (ret == 0) { /* Add to heap */ - ret = heap_insert(stream_heap, cfs); + ret = bt_heap_insert(stream_heap, cfs); if (ret) { /* Return positive error. */ return -ret; @@ -358,8 +358,8 @@ int bt_iter_set_pos(struct bt_iter *iter, const struct bt_iter_pos *iter_pos) if (!iter_pos->u.restore) return -EINVAL; - heap_free(iter->stream_heap); - ret = heap_init(iter->stream_heap, 0, stream_compare); + bt_heap_free(iter->stream_heap); + ret = bt_heap_init(iter->stream_heap, 0, stream_compare); if (ret < 0) goto error_heap_init; @@ -404,7 +404,7 @@ int bt_iter_set_pos(struct bt_iter *iter, const struct bt_iter_pos *iter_pos) } /* Add to heap */ - ret = heap_insert(iter->stream_heap, + ret = bt_heap_insert(iter->stream_heap, saved_pos->file_stream); if (ret) goto error; @@ -413,8 +413,8 @@ int bt_iter_set_pos(struct bt_iter *iter, const struct bt_iter_pos *iter_pos) case BT_SEEK_TIME: tc = iter->ctx->tc; - heap_free(iter->stream_heap); - ret = heap_init(iter->stream_heap, 0, stream_compare); + bt_heap_free(iter->stream_heap); + ret = bt_heap_init(iter->stream_heap, 0, stream_compare); if (ret < 0) goto error_heap_init; @@ -444,8 +444,8 @@ int bt_iter_set_pos(struct bt_iter *iter, const struct bt_iter_pos *iter_pos) return 0; case BT_SEEK_BEGIN: tc = iter->ctx->tc; - heap_free(iter->stream_heap); - ret = heap_init(iter->stream_heap, 0, stream_compare); + bt_heap_free(iter->stream_heap); + ret = bt_heap_init(iter->stream_heap, 0, stream_compare); if (ret < 0) goto error_heap_init; @@ -487,7 +487,7 @@ int bt_iter_set_pos(struct bt_iter *iter, const struct bt_iter_pos *iter_pos) /* Do not add EOF streams */ continue; } - ret = heap_insert(iter->stream_heap, file_stream); + ret = bt_heap_insert(iter->stream_heap, file_stream); if (ret) goto error; } @@ -503,13 +503,13 @@ int bt_iter_set_pos(struct bt_iter *iter, const struct bt_iter_pos *iter_pos) if (ret != 0 || !cfs) goto error; /* remove all streams from the heap */ - heap_free(iter->stream_heap); + bt_heap_free(iter->stream_heap); /* Create a new empty heap */ - ret = heap_init(iter->stream_heap, 0, stream_compare); + ret = bt_heap_init(iter->stream_heap, 0, stream_compare); if (ret < 0) goto error; /* Insert the stream that contains the last event */ - ret = heap_insert(iter->stream_heap, cfs); + ret = bt_heap_insert(iter->stream_heap, cfs); if (ret) goto error; break; @@ -522,10 +522,10 @@ int bt_iter_set_pos(struct bt_iter *iter, const struct bt_iter_pos *iter_pos) return 0; error: - heap_free(iter->stream_heap); + bt_heap_free(iter->stream_heap); error_heap_init: - if (heap_init(iter->stream_heap, 0, stream_compare) < 0) { - heap_free(iter->stream_heap); + if (bt_heap_init(iter->stream_heap, 0, stream_compare) < 0) { + bt_heap_free(iter->stream_heap); g_free(iter->stream_heap); iter->stream_heap = NULL; ret = -ENOMEM; @@ -555,12 +555,12 @@ struct bt_iter_pos *bt_iter_get_pos(struct bt_iter *iter) if (!pos->u.restore->stream_saved_pos) goto error; - ret = heap_copy(&iter_heap_copy, iter->stream_heap); + ret = bt_heap_copy(&iter_heap_copy, iter->stream_heap); if (ret < 0) goto error_heap; /* iterate over each stream in the heap */ - file_stream = heap_maximum(&iter_heap_copy); + file_stream = bt_heap_maximum(&iter_heap_copy); while (file_stream != NULL) { struct stream_saved_pos saved_pos; @@ -584,12 +584,12 @@ struct bt_iter_pos *bt_iter_get_pos(struct bt_iter *iter) saved_pos.current_real_timestamp); /* remove the stream from the heap copy */ - removed = heap_remove(&iter_heap_copy); + removed = bt_heap_remove(&iter_heap_copy); assert(removed == file_stream); - file_stream = heap_maximum(&iter_heap_copy); + file_stream = bt_heap_maximum(&iter_heap_copy); } - heap_free(&iter_heap_copy); + bt_heap_free(&iter_heap_copy); return pos; error_heap: @@ -669,7 +669,7 @@ int bt_iter_init(struct bt_iter *iter, bt_context_get(ctx); iter->ctx = ctx; - ret = heap_init(iter->stream_heap, 0, stream_compare); + ret = bt_heap_init(iter->stream_heap, 0, stream_compare); if (ret < 0) goto error_heap_init; @@ -718,7 +718,7 @@ int bt_iter_init(struct bt_iter *iter, goto error; } /* Add to heap */ - ret = heap_insert(iter->stream_heap, file_stream); + ret = bt_heap_insert(iter->stream_heap, file_stream); if (ret) goto error; } @@ -729,7 +729,7 @@ int bt_iter_init(struct bt_iter *iter, return 0; error: - heap_free(iter->stream_heap); + bt_heap_free(iter->stream_heap); error_heap_init: g_free(iter->stream_heap); iter->stream_heap = NULL; @@ -760,7 +760,7 @@ void bt_iter_fini(struct bt_iter *iter) { assert(iter); if (iter->stream_heap) { - heap_free(iter->stream_heap); + bt_heap_free(iter->stream_heap); g_free(iter->stream_heap); } iter->ctx->current_iterator = NULL; @@ -782,7 +782,7 @@ int bt_iter_next(struct bt_iter *iter) if (!iter) return -EINVAL; - file_stream = heap_maximum(iter->stream_heap); + file_stream = bt_heap_maximum(iter->stream_heap); if (!file_stream) { /* end of file for all streams */ ret = 0; @@ -791,7 +791,7 @@ int bt_iter_next(struct bt_iter *iter) ret = stream_read_event(file_stream); if (ret == EOF) { - removed = heap_remove(iter->stream_heap); + removed = bt_heap_remove(iter->stream_heap); assert(removed == file_stream); ret = 0; goto end; @@ -799,7 +799,7 @@ int bt_iter_next(struct bt_iter *iter) goto end; } /* Reinsert the file stream into the heap, and rebalance. */ - removed = heap_replace_max(iter->stream_heap, file_stream); + removed = bt_heap_replace_max(iter->stream_heap, file_stream); assert(removed == file_stream); end: diff --git a/lib/prio_heap/prio_heap.c b/lib/prio_heap/prio_heap.c index 43b4e8a..8942a11 100644 --- a/lib/prio_heap/prio_heap.c +++ b/lib/prio_heap/prio_heap.c @@ -102,7 +102,7 @@ int heap_set_len(struct ptr_heap *heap, size_t new_len) return 0; } -int heap_init(struct ptr_heap *heap, size_t alloc_len, +int bt_heap_init(struct ptr_heap *heap, size_t alloc_len, int gt(void *a, void *b)) { heap->ptrs = NULL; @@ -111,12 +111,12 @@ int heap_init(struct ptr_heap *heap, size_t alloc_len, heap->gt = gt; /* * Minimum size allocated is 1 entry to ensure memory allocation - * never fails within heap_replace_max. + * never fails within bt_heap_replace_max. */ return heap_grow(heap, max_t(size_t, 1, alloc_len)); } -void heap_free(struct ptr_heap *heap) +void bt_heap_free(struct ptr_heap *heap) { free(heap->ptrs); } @@ -147,7 +147,7 @@ static void heapify(struct ptr_heap *heap, size_t i) check_heap(heap); } -void *heap_replace_max(struct ptr_heap *heap, void *p) +void *bt_heap_replace_max(struct ptr_heap *heap, void *p) { void *res; @@ -165,7 +165,7 @@ void *heap_replace_max(struct ptr_heap *heap, void *p) return res; } -int heap_insert(struct ptr_heap *heap, void *p) +int bt_heap_insert(struct ptr_heap *heap, void *p) { void **ptrs; size_t pos; @@ -186,7 +186,7 @@ int heap_insert(struct ptr_heap *heap, void *p) return 0; } -void *heap_remove(struct ptr_heap *heap) +void *bt_heap_remove(struct ptr_heap *heap) { switch (heap->len) { case 0: @@ -198,10 +198,10 @@ void *heap_remove(struct ptr_heap *heap) /* Shrink, replace the current max by previous last entry and heapify */ heap_set_len(heap, heap->len - 1); /* len changed. previous last entry is at heap->len */ - return heap_replace_max(heap, heap->ptrs[heap->len]); + return bt_heap_replace_max(heap, heap->ptrs[heap->len]); } -void *heap_cherrypick(struct ptr_heap *heap, void *p) +void *bt_heap_cherrypick(struct ptr_heap *heap, void *p) { size_t pos, len = heap->len; @@ -223,11 +223,11 @@ found: return p; } -int heap_copy(struct ptr_heap *dst, struct ptr_heap *src) +int bt_heap_copy(struct ptr_heap *dst, struct ptr_heap *src) { int ret; - ret = heap_init(dst, src->alloc_len, src->gt); + ret = bt_heap_init(dst, src->alloc_len, src->gt); if (ret < 0) goto end; -- 1.7.10.4 From jdesfossez at efficios.com Thu Jan 24 16:21:46 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 16:21:46 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 14/18] namespace the collection functions In-Reply-To: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> Message-ID: <1359062510-7557-14-git-send-email-jdesfossez@efficios.com> Signed-off-by: Julien Desfossez --- include/babeltrace/trace-collection.h | 8 ++++---- lib/context.c | 8 ++++---- lib/trace-collection.c | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/babeltrace/trace-collection.h b/include/babeltrace/trace-collection.h index 2ac9ba6..e65654f 100644 --- a/include/babeltrace/trace-collection.h +++ b/include/babeltrace/trace-collection.h @@ -35,11 +35,11 @@ extern "C" { struct trace_collection; -void init_trace_collection(struct trace_collection *tc); -void finalize_trace_collection(struct trace_collection *tc); -int trace_collection_add(struct trace_collection *tc, +void bt_init_trace_collection(struct trace_collection *tc); +void bt_finalize_trace_collection(struct trace_collection *tc); +int bt_trace_collection_add(struct trace_collection *tc, struct trace_descriptor *td); -int trace_collection_remove(struct trace_collection *tc, +int bt_trace_collection_remove(struct trace_collection *tc, struct trace_descriptor *td); #ifdef __cplusplus diff --git a/lib/context.c b/lib/context.c index 5516e49..d067422 100644 --- a/lib/context.c +++ b/lib/context.c @@ -60,7 +60,7 @@ struct bt_context *bt_context_create(void) ctx->current_iterator = NULL; ctx->tc = g_new0(struct trace_collection, 1); - init_trace_collection(ctx->tc); + bt_init_trace_collection(ctx->tc); return ctx; } @@ -129,7 +129,7 @@ int bt_context_add_trace(struct bt_context *ctx, const char *path, g_hash_table_insert(ctx->trace_handles, (gpointer) (unsigned long) handle->id, handle); - ret = trace_collection_add(ctx->tc, td); + ret = bt_trace_collection_add(ctx->tc, td); if (ret != 0) goto error; @@ -167,7 +167,7 @@ int bt_context_remove_trace(struct bt_context *ctx, int handle_id) return -ENOENT; /* Remove from containers */ - trace_collection_remove(ctx->tc, handle->td); + bt_trace_collection_remove(ctx->tc, handle->td); /* Close the trace */ ret = handle->format->close_trace(handle->td); if (ret) { @@ -184,7 +184,7 @@ static void bt_context_destroy(struct bt_context *ctx) { assert(ctx); - finalize_trace_collection(ctx->tc); + bt_finalize_trace_collection(ctx->tc); /* * Remove all traces. The g_hash_table_destroy will call diff --git a/lib/trace-collection.c b/lib/trace-collection.c index 4f1379c..fc06dcd 100644 --- a/lib/trace-collection.c +++ b/lib/trace-collection.c @@ -155,7 +155,7 @@ static void clock_add(gpointer key, gpointer value, gpointer user_data) * correlate this trace with at least one other clock in the trace and * convert the index from cycles to real time. */ -int trace_collection_add(struct trace_collection *tc, +int bt_trace_collection_add(struct trace_collection *tc, struct trace_descriptor *td) { struct ctf_trace *trace; @@ -208,7 +208,7 @@ error: return -EPERM; } -int trace_collection_remove(struct trace_collection *tc, +int bt_trace_collection_remove(struct trace_collection *tc, struct trace_descriptor *td) { if (!tc || !td) @@ -222,7 +222,7 @@ int trace_collection_remove(struct trace_collection *tc, } -void init_trace_collection(struct trace_collection *tc) +void bt_init_trace_collection(struct trace_collection *tc) { assert(tc); tc->array = g_ptr_array_new(); @@ -234,10 +234,10 @@ void init_trace_collection(struct trace_collection *tc) } /* - * finalize_trace_collection() closes the opened traces for read + * bt_finalize_trace_collection() closes the opened traces for read * and free the memory allocated for trace collection */ -void finalize_trace_collection(struct trace_collection *tc) +void bt_finalize_trace_collection(struct trace_collection *tc) { assert(tc); g_ptr_array_free(tc->array, TRUE); -- 1.7.10.4 From jdesfossez at efficios.com Thu Jan 24 16:21:48 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 16:21:48 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 16/18] namespace the variant functions In-Reply-To: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> Message-ID: <1359062510-7557-16-git-send-email-jdesfossez@efficios.com> Signed-off-by: Julien Desfossez --- formats/ctf-text/types/variant.c | 2 +- formats/ctf/ctf.c | 2 +- formats/ctf/types/variant.c | 2 +- include/babeltrace/types.h | 6 +++--- types/types.c | 8 ++++---- types/variant.c | 6 +++--- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/formats/ctf-text/types/variant.c b/formats/ctf-text/types/variant.c index 89d518a..e7e50ac 100644 --- a/formats/ctf-text/types/variant.c +++ b/formats/ctf-text/types/variant.c @@ -52,7 +52,7 @@ int ctf_text_variant_write(struct stream_pos *ppos, struct definition *definitio } field_nr_saved = pos->field_nr; pos->field_nr = 0; - ret = variant_rw(ppos, definition); + ret = bt_variant_rw(ppos, definition); if (!pos->dummy) { pos->depth--; if (pos->depth >= 0) { diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index e2a109b..ba403aa 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -439,7 +439,7 @@ int ctf_read_event(struct stream_pos *ppos, struct ctf_stream_definition *stream } } - variant = lookup_variant(&stream->stream_event_header->p, "v"); + variant = bt_lookup_variant(&stream->stream_event_header->p, "v"); if (variant) { integer_definition = lookup_integer(variant, "id", FALSE); if (integer_definition) { diff --git a/formats/ctf/types/variant.c b/formats/ctf/types/variant.c index 297f26f..f3559f5 100644 --- a/formats/ctf/types/variant.c +++ b/formats/ctf/types/variant.c @@ -34,5 +34,5 @@ int ctf_variant_rw(struct stream_pos *ppos, struct definition *definition) struct ctf_stream_pos *pos = ctf_pos(ppos); ctf_align_pos(pos, declaration->alignment); - return variant_rw(ppos, definition); + return bt_variant_rw(ppos, definition); } diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index 84d0c95..60bd4fd 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -479,8 +479,8 @@ int variant_definition_set_tag(struct definition_variant *variant, * field returned only valid as long as the variant structure is not appended * to. */ -struct definition *variant_get_current_field(struct definition_variant *variant); -int variant_rw(struct stream_pos *pos, struct definition *definition); +struct definition *bt_variant_get_current_field(struct definition_variant *variant); +int bt_variant_rw(struct stream_pos *pos, struct definition *definition); /* * elem_declaration passed as parameter now belongs to the array. No @@ -524,7 +524,7 @@ struct definition_integer *lookup_integer(const struct definition *definition, struct definition_enum *bt_lookup_enum(const struct definition *definition, const char *field_name, int signedness); -struct definition *lookup_variant(const struct definition *definition, +struct definition *bt_lookup_variant(const struct definition *definition, const char *field_name); static inline diff --git a/types/types.c b/types/types.c index 912c8d5..d60e577 100644 --- a/types/types.c +++ b/types/types.c @@ -660,19 +660,19 @@ struct definition_enum *bt_lookup_enum(const struct definition *definition, return lookup_enum; } -struct definition *lookup_variant(const struct definition *definition, +struct definition *bt_lookup_variant(const struct definition *definition, const char *field_name) { struct definition *lookup; - struct definition_variant *lookup_variant; + struct definition_variant *bt_lookup_variant; lookup = lookup_definition(definition, field_name); if (!lookup) return NULL; if (lookup->declaration->id != CTF_TYPE_VARIANT) return NULL; - lookup_variant = container_of(lookup, struct definition_variant, p); - lookup = variant_get_current_field(lookup_variant); + bt_lookup_variant = container_of(lookup, struct definition_variant, p); + lookup = bt_variant_get_current_field(bt_lookup_variant); assert(lookup); return lookup; } diff --git a/types/variant.c b/types/variant.c index ba4179d..837875c 100644 --- a/types/variant.c +++ b/types/variant.c @@ -39,13 +39,13 @@ struct definition *_variant_definition_new(struct declaration *declaration, static void _variant_definition_free(struct definition *definition); -int variant_rw(struct stream_pos *ppos, struct definition *definition) +int bt_variant_rw(struct stream_pos *ppos, struct definition *definition) { struct definition_variant *variant_definition = container_of(definition, struct definition_variant, p); struct definition *field; - field = variant_get_current_field(variant_definition); + field = bt_variant_get_current_field(variant_definition); return generic_rw(ppos, field); } @@ -301,7 +301,7 @@ bt_untagged_variant_declaration_get_field_from_tag(struct declaration_untagged_v /* * field returned only valid as long as the field structure is not appended to. */ -struct definition *variant_get_current_field(struct definition_variant *variant) +struct definition *bt_variant_get_current_field(struct definition_variant *variant) { struct definition_enum *_enum = container_of(variant->enum_tag, struct definition_enum, p); -- 1.7.10.4 From jdesfossez at efficios.com Thu Jan 24 16:21:47 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 16:21:47 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 15/18] namespace the declaration functions In-Reply-To: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> Message-ID: <1359062510-7557-15-git-send-email-jdesfossez@efficios.com> Signed-off-by: Julien Desfossez --- .../ctf/metadata/ctf-visitor-generate-io-struct.c | 62 ++++++++++---------- formats/ctf/types/float.c | 4 +- include/babeltrace/types.h | 28 ++++----- types/array.c | 4 +- types/float.c | 8 +-- types/integer.c | 2 +- types/sequence.c | 4 +- types/struct.c | 4 +- types/types.c | 40 ++++++------- types/variant.c | 12 ++-- 10 files changed, 84 insertions(+), 84 deletions(-) diff --git a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c index 9c5aeb1..d1b453e 100644 --- a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c +++ b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c @@ -445,7 +445,7 @@ struct declaration *ctf_type_declarator_visit(FILE *fd, int depth, */ alias_q = create_typealias_identifier(fd, depth, type_specifier_list, node_type_declarator); - nested_declaration = lookup_declaration(alias_q, declaration_scope); + nested_declaration = bt_lookup_declaration(alias_q, declaration_scope); if (!nested_declaration) { fprintf(fd, "[error] %s: cannot find typealias \"%s\".\n", __func__, g_quark_to_string(alias_q)); return NULL; @@ -460,7 +460,7 @@ struct declaration *ctf_type_declarator_visit(FILE *fd, int depth, * integer declaration to modify it. There could be other references to * it. */ - integer_declaration = integer_declaration_new(integer_declaration->len, + integer_declaration = bt_integer_declaration_new(integer_declaration->len, integer_declaration->byte_order, integer_declaration->signedness, integer_declaration->p.alignment, 16, integer_declaration->encoding, integer_declaration->clock); @@ -612,12 +612,12 @@ int ctf_variant_type_declarators_visit(FILE *fd, int depth, return -EINVAL; } - if (untagged_variant_declaration_get_field_from_tag(untagged_variant_declaration, field_name) != NULL) { + if (bt_untagged_variant_declaration_get_field_from_tag(untagged_variant_declaration, field_name) != NULL) { fprintf(fd, "[error] %s: duplicate field %s in variant\n", __func__, g_quark_to_string(field_name)); return -EINVAL; } - untagged_variant_declaration_add_field(untagged_variant_declaration, + bt_untagged_variant_declaration_add_field(untagged_variant_declaration, g_quark_to_string(field_name), field_declaration); bt_declaration_unref(field_declaration); @@ -655,7 +655,7 @@ int ctf_typedef_visit(FILE *fd, int depth, struct declaration_scope *scope, bt_declaration_unref(type_declaration); return -EPERM; } - ret = register_declaration(identifier, type_declaration, scope); + ret = bt_register_declaration(identifier, type_declaration, scope); if (ret) { type_declaration->declaration_free(type_declaration); return ret; @@ -722,7 +722,7 @@ int ctf_typealias_visit(FILE *fd, int depth, struct declaration_scope *scope, struct ctf_node, siblings); alias_q = create_typealias_identifier(fd, depth, alias->u.typealias_alias.type_specifier_list, node); - err = register_declaration(alias_q, type_declaration, scope); + err = bt_register_declaration(alias_q, type_declaration, scope); if (err) goto error; bt_declaration_unref(type_declaration); @@ -912,21 +912,21 @@ struct declaration *ctf_declaration_variant_visit(FILE *fd, if (!has_body) { assert(name); untagged_variant_declaration = - lookup_variant_declaration(g_quark_from_string(name), + bt_lookup_variant_declaration(g_quark_from_string(name), declaration_scope); bt_declaration_ref(&untagged_variant_declaration->p); } else { /* For unnamed variant, create type */ /* For named variant (with body), create type and add to declaration scope */ if (name) { - if (lookup_variant_declaration(g_quark_from_string(name), + if (bt_lookup_variant_declaration(g_quark_from_string(name), declaration_scope)) { fprintf(fd, "[error] %s: variant %s already declared in scope\n", __func__, name); return NULL; } } - untagged_variant_declaration = untagged_variant_declaration_new(declaration_scope); + untagged_variant_declaration = bt_untagged_bt_variant_declaration_new(declaration_scope); bt_list_for_each_entry(iter, declaration_list, siblings) { int ret; @@ -938,7 +938,7 @@ struct declaration *ctf_declaration_variant_visit(FILE *fd, if (name) { int ret; - ret = register_variant_declaration(g_quark_from_string(name), + ret = bt_register_variant_declaration(g_quark_from_string(name), untagged_variant_declaration, declaration_scope); assert(!ret); @@ -951,7 +951,7 @@ struct declaration *ctf_declaration_variant_visit(FILE *fd, if (!choice) { return &untagged_variant_declaration->p; } else { - variant_declaration = variant_declaration_new(untagged_variant_declaration, choice); + variant_declaration = bt_variant_declaration_new(untagged_variant_declaration, choice); if (!variant_declaration) goto error; bt_declaration_unref(&untagged_variant_declaration->p); @@ -1076,7 +1076,7 @@ struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth, if (!has_body) { assert(name); enum_declaration = - lookup_enum_declaration(g_quark_from_string(name), + bt_lookup_enum_declaration(g_quark_from_string(name), declaration_scope); bt_declaration_ref(&enum_declaration->p); return &enum_declaration->p; @@ -1084,7 +1084,7 @@ struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth, /* For unnamed enum, create type */ /* For named enum (with body), create type and add to declaration scope */ if (name) { - if (lookup_enum_declaration(g_quark_from_string(name), + if (bt_lookup_enum_declaration(g_quark_from_string(name), declaration_scope)) { fprintf(fd, "[error] %s: enum %s already declared in scope\n", __func__, name); @@ -1092,7 +1092,7 @@ struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth, } } if (!container_type) { - declaration = lookup_declaration(g_quark_from_static_string("int"), + declaration = bt_lookup_declaration(g_quark_from_static_string("int"), declaration_scope); if (!declaration) { fprintf(fd, "[error] %s: \"int\" type declaration missing for enumeration\n", __func__); @@ -1132,7 +1132,7 @@ struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth, if (name) { int ret; - ret = register_enum_declaration(g_quark_from_string(name), + ret = bt_register_enum_declaration(g_quark_from_string(name), enum_declaration, declaration_scope); assert(!ret); @@ -1163,7 +1163,7 @@ struct declaration *ctf_declaration_type_specifier_visit(FILE *fd, int depth, str_c = g_string_free(str, FALSE); id_q = g_quark_from_string(str_c); g_free(str_c); - declaration = lookup_declaration(id_q, declaration_scope); + declaration = bt_lookup_declaration(id_q, declaration_scope); bt_declaration_ref(declaration); return declaration; } @@ -1442,7 +1442,7 @@ struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth, alignment = CHAR_BIT; } } - integer_declaration = integer_declaration_new(size, + integer_declaration = bt_integer_declaration_new(size, byte_order, signedness, alignment, base, encoding, clock); return &integer_declaration->p; @@ -1522,7 +1522,7 @@ struct declaration *ctf_declaration_floating_point_visit(FILE *fd, int depth, alignment = CHAR_BIT; } } - float_declaration = float_declaration_new(mant_dig, exp_dig, + float_declaration = bt_float_declaration_new(mant_dig, exp_dig, byte_order, alignment); return &float_declaration->p; } @@ -1816,7 +1816,7 @@ int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node, event_decl = g_new0(struct bt_ctf_event_decl, 1); event = &event_decl->parent; - event->declaration_scope = new_declaration_scope(parent_declaration_scope); + event->declaration_scope = bt_new_declaration_scope(parent_declaration_scope); event->loglevel = -1; bt_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) { ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace); @@ -1867,7 +1867,7 @@ error: bt_declaration_unref(&event->fields_decl->p); if (event->context_decl) bt_declaration_unref(&event->context_decl->p); - free_declaration_scope(event->declaration_scope); + bt_free_declaration_scope(event->declaration_scope); g_free(event_decl); return ret; } @@ -2003,7 +2003,7 @@ int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream_declaration *stream; stream = g_new0(struct ctf_stream_declaration, 1); - stream->declaration_scope = new_declaration_scope(parent_declaration_scope); + stream->declaration_scope = bt_new_declaration_scope(parent_declaration_scope); stream->events_by_id = g_ptr_array_new(); stream->event_quark_to_id = g_hash_table_new(g_direct_hash, g_direct_equal); stream->streams = g_ptr_array_new(); @@ -2048,7 +2048,7 @@ error: g_ptr_array_free(stream->streams, TRUE); g_ptr_array_free(stream->events_by_id, TRUE); g_hash_table_destroy(stream->event_quark_to_id); - free_declaration_scope(stream->declaration_scope); + bt_free_declaration_scope(stream->declaration_scope); g_free(stream); return ret; } @@ -2199,7 +2199,7 @@ int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace if (trace->declaration_scope) return -EEXIST; - trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope); + trace->declaration_scope = bt_new_declaration_scope(trace->root_declaration_scope); trace->streams = g_ptr_array_new(); trace->event_declarations = g_ptr_array_new(); bt_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) { @@ -2241,7 +2241,7 @@ error: } g_ptr_array_free(trace->streams, TRUE); g_ptr_array_free(trace->event_declarations, TRUE); - free_declaration_scope(trace->declaration_scope); + bt_free_declaration_scope(trace->declaration_scope); trace->declaration_scope = NULL; return ret; } @@ -2876,7 +2876,7 @@ int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node, NULL, callsite_free); retry: - trace->root_declaration_scope = new_declaration_scope(NULL); + trace->root_declaration_scope = bt_new_declaration_scope(NULL); switch (node->type) { case NODE_ROOT: @@ -2910,7 +2910,7 @@ retry: bt_list_for_each_entry(iter, &node->u.root.trace, siblings) { ret = ctf_trace_visit(fd, depth + 1, iter, trace); if (ret == -EINTR) { - free_declaration_scope(trace->root_declaration_scope); + bt_free_declaration_scope(trace->root_declaration_scope); /* * Need to restart creation of type * definitions, aliases and @@ -2971,7 +2971,7 @@ retry: return ret; error: - free_declaration_scope(trace->root_declaration_scope); + bt_free_declaration_scope(trace->root_declaration_scope); g_hash_table_destroy(trace->callsites); g_hash_table_destroy(trace->clocks); return ret; @@ -3029,7 +3029,7 @@ int ctf_destroy_metadata(struct ctf_trace *trace) g_ptr_array_free(stream->streams, TRUE); g_ptr_array_free(stream->events_by_id, TRUE); g_hash_table_destroy(stream->event_quark_to_id); - free_declaration_scope(stream->declaration_scope); + bt_free_declaration_scope(stream->declaration_scope); g_free(stream); } g_ptr_array_free(trace->streams, TRUE); @@ -3059,7 +3059,7 @@ int ctf_destroy_metadata(struct ctf_trace *trace) bt_declaration_unref(&event->fields_decl->p); if (event->context_decl) bt_declaration_unref(&event->context_decl->p); - free_declaration_scope(event->declaration_scope); + bt_free_declaration_scope(event->declaration_scope); g_free(event); } @@ -3068,8 +3068,8 @@ int ctf_destroy_metadata(struct ctf_trace *trace) if (trace->packet_header_decl) bt_declaration_unref(&trace->packet_header_decl->p); - free_declaration_scope(trace->root_declaration_scope); - free_declaration_scope(trace->declaration_scope); + bt_free_declaration_scope(trace->root_declaration_scope); + bt_free_declaration_scope(trace->declaration_scope); g_hash_table_destroy(trace->callsites); g_hash_table_destroy(trace->clocks); diff --git a/formats/ctf/types/float.c b/formats/ctf/types/float.c index fc7c39c..2dfef86 100644 --- a/formats/ctf/types/float.c +++ b/formats/ctf/types/float.c @@ -282,12 +282,12 @@ static void __attribute__((constructor)) ctf_float_init(void) { static_float_declaration = - float_declaration_new(FLT_MANT_DIG, + bt_float_declaration_new(FLT_MANT_DIG, sizeof(float) * CHAR_BIT - FLT_MANT_DIG, BYTE_ORDER, __alignof__(float)); static_double_declaration = - float_declaration_new(DBL_MANT_DIG, + bt_float_declaration_new(DBL_MANT_DIG, sizeof(double) * CHAR_BIT - DBL_MANT_DIG, BYTE_ORDER, __alignof__(double)); diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index a3d9788..84d0c95 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -305,10 +305,10 @@ struct definition_sequence { GString *string; /* String for encoded integer children */ }; -int register_declaration(GQuark declaration_name, +int bt_register_declaration(GQuark declaration_name, struct declaration *declaration, struct declaration_scope *scope); -struct declaration *lookup_declaration(GQuark declaration_name, +struct declaration *bt_lookup_declaration(GQuark declaration_name, struct declaration_scope *scope); /* @@ -323,21 +323,21 @@ int bt_register_struct_declaration(GQuark struct_name, struct declaration_struct * bt_lookup_struct_declaration(GQuark struct_name, struct declaration_scope *scope); -int register_variant_declaration(GQuark variant_name, +int bt_register_variant_declaration(GQuark variant_name, struct declaration_untagged_variant *untagged_variant_declaration, struct declaration_scope *scope); -struct declaration_untagged_variant *lookup_variant_declaration(GQuark variant_name, +struct declaration_untagged_variant *bt_lookup_variant_declaration(GQuark variant_name, struct declaration_scope *scope); -int register_enum_declaration(GQuark enum_name, +int bt_register_enum_declaration(GQuark enum_name, struct declaration_enum *enum_declaration, struct declaration_scope *scope); struct declaration_enum * - lookup_enum_declaration(GQuark enum_name, + bt_lookup_enum_declaration(GQuark enum_name, struct declaration_scope *scope); struct declaration_scope * - new_declaration_scope(struct declaration_scope *parent_scope); -void free_declaration_scope(struct declaration_scope *scope); + bt_new_declaration_scope(struct declaration_scope *parent_scope); +void bt_free_declaration_scope(struct declaration_scope *scope); /* * field_definition is for field definitions. They are registered into @@ -370,7 +370,7 @@ void bt_declaration_unref(struct declaration *declaration); void bt_definition_ref(struct definition *definition); void bt_definition_unref(struct definition *definition); -struct declaration_integer *integer_declaration_new(size_t len, int byte_order, +struct declaration_integer *bt_integer_declaration_new(size_t len, int byte_order, int signedness, size_t alignment, int base, enum ctf_string_encoding encoding, struct ctf_clock *clock); @@ -386,7 +386,7 @@ enum ctf_string_encoding bt_get_int_encoding(const struct definition *field); * mantissa_len is the length of the number of bytes represented by the mantissa * (e.g. result of DBL_MANT_DIG). It includes the leading 1. */ -struct declaration_float *float_declaration_new(size_t mantissa_len, +struct declaration_float *bt_float_declaration_new(size_t mantissa_len, size_t exp_len, int byte_order, size_t alignment); @@ -458,16 +458,16 @@ uint64_t bt_struct_declaration_len(struct declaration_struct *struct_declaration * from numeric values to a single tag. Overlapping tag value ranges are * therefore forbidden. */ -struct declaration_untagged_variant *untagged_variant_declaration_new( +struct declaration_untagged_variant *bt_untagged_bt_variant_declaration_new( struct declaration_scope *parent_scope); -struct declaration_variant *variant_declaration_new(struct declaration_untagged_variant *untagged_variant, +struct declaration_variant *bt_variant_declaration_new(struct declaration_untagged_variant *untagged_variant, const char *tag); -void untagged_variant_declaration_add_field(struct declaration_untagged_variant *untagged_variant_declaration, +void bt_untagged_variant_declaration_add_field(struct declaration_untagged_variant *untagged_variant_declaration, const char *field_name, struct declaration *field_declaration); struct declaration_field * - untagged_variant_declaration_get_field_from_tag(struct declaration_untagged_variant *untagged_variant_declaration, + bt_untagged_variant_declaration_get_field_from_tag(struct declaration_untagged_variant *untagged_variant_declaration, GQuark tag); /* * Returns 0 on success, -EPERM on error. diff --git a/types/array.c b/types/array.c index cc9a600..7f82167 100644 --- a/types/array.c +++ b/types/array.c @@ -64,7 +64,7 @@ void _array_declaration_free(struct declaration *declaration) struct declaration_array *array_declaration = container_of(declaration, struct declaration_array, p); - free_declaration_scope(array_declaration->scope); + bt_free_declaration_scope(array_declaration->scope); bt_declaration_unref(array_declaration->elem); g_free(array_declaration); } @@ -82,7 +82,7 @@ struct declaration_array * array_declaration->len = len; bt_declaration_ref(elem_declaration); array_declaration->elem = elem_declaration; - array_declaration->scope = new_declaration_scope(parent_scope); + array_declaration->scope = bt_new_declaration_scope(parent_scope); declaration->id = CTF_TYPE_ARRAY; declaration->alignment = elem_declaration->alignment; declaration->declaration_free = _array_declaration_free; diff --git a/types/float.c b/types/float.c index 0fc137f..7b89a89 100644 --- a/types/float.c +++ b/types/float.c @@ -52,7 +52,7 @@ void _float_declaration_free(struct declaration *declaration) } struct declaration_float * - float_declaration_new(size_t mantissa_len, + bt_float_declaration_new(size_t mantissa_len, size_t exp_len, int byte_order, size_t alignment) { struct declaration_float *float_declaration; @@ -68,13 +68,13 @@ struct declaration_float * declaration->ref = 1; float_declaration->byte_order = byte_order; - float_declaration->sign = integer_declaration_new(1, + float_declaration->sign = bt_integer_declaration_new(1, byte_order, false, 1, 2, CTF_STRING_NONE, NULL); - float_declaration->mantissa = integer_declaration_new(mantissa_len - 1, + float_declaration->mantissa = bt_integer_declaration_new(mantissa_len - 1, byte_order, false, 1, 10, CTF_STRING_NONE, NULL); - float_declaration->exp = integer_declaration_new(exp_len, + float_declaration->exp = bt_integer_declaration_new(exp_len, byte_order, true, 1, 10, CTF_STRING_NONE, NULL); return float_declaration; diff --git a/types/integer.c b/types/integer.c index 58b6104..936453a 100644 --- a/types/integer.c +++ b/types/integer.c @@ -49,7 +49,7 @@ void _integer_declaration_free(struct declaration *declaration) } struct declaration_integer * - integer_declaration_new(size_t len, int byte_order, + bt_integer_declaration_new(size_t len, int byte_order, int signedness, size_t alignment, int base, enum ctf_string_encoding encoding, struct ctf_clock *clock) diff --git a/types/sequence.c b/types/sequence.c index 6ed168c..1795ae4 100644 --- a/types/sequence.c +++ b/types/sequence.c @@ -93,7 +93,7 @@ void _sequence_declaration_free(struct declaration *declaration) struct declaration_sequence *sequence_declaration = container_of(declaration, struct declaration_sequence, p); - free_declaration_scope(sequence_declaration->scope); + bt_free_declaration_scope(sequence_declaration->scope); g_array_free(sequence_declaration->length_name, TRUE); bt_declaration_unref(sequence_declaration->elem); g_free(sequence_declaration); @@ -115,7 +115,7 @@ struct declaration_sequence * bt_declaration_ref(elem_declaration); sequence_declaration->elem = elem_declaration; - sequence_declaration->scope = new_declaration_scope(parent_scope); + sequence_declaration->scope = bt_new_declaration_scope(parent_scope); declaration->id = CTF_TYPE_SEQUENCE; declaration->alignment = elem_declaration->alignment; declaration->declaration_free = _sequence_declaration_free; diff --git a/types/struct.c b/types/struct.c index f065dbc..76b82d2 100644 --- a/types/struct.c +++ b/types/struct.c @@ -67,7 +67,7 @@ void _struct_declaration_free(struct declaration *declaration) container_of(declaration, struct declaration_struct, p); unsigned long i; - free_declaration_scope(struct_declaration->scope); + bt_free_declaration_scope(struct_declaration->scope); g_hash_table_destroy(struct_declaration->fields_by_name); for (i = 0; i < struct_declaration->fields->len; i++) { @@ -94,7 +94,7 @@ struct declaration_struct * struct_declaration->fields = g_array_sized_new(FALSE, TRUE, sizeof(struct declaration_field), DEFAULT_NR_STRUCT_FIELDS); - struct_declaration->scope = new_declaration_scope(parent_scope); + struct_declaration->scope = bt_new_declaration_scope(parent_scope); declaration->id = CTF_TYPE_STRUCT; declaration->alignment = max(1, min_align); declaration->declaration_free = _struct_declaration_free; diff --git a/types/types.c b/types/types.c index 615ab70..912c8d5 100644 --- a/types/types.c +++ b/types/types.c @@ -52,20 +52,20 @@ GQuark prefix_quark(const char *prefix, GQuark quark) static struct declaration * - lookup_declaration_scope(GQuark declaration_name, + bt_lookup_declaration_scope(GQuark declaration_name, struct declaration_scope *scope) { return g_hash_table_lookup(scope->typedef_declarations, (gconstpointer) (unsigned long) declaration_name); } -struct declaration *lookup_declaration(GQuark declaration_name, +struct declaration *bt_lookup_declaration(GQuark declaration_name, struct declaration_scope *scope) { struct declaration *declaration; while (scope) { - declaration = lookup_declaration_scope(declaration_name, + declaration = bt_lookup_declaration_scope(declaration_name, scope); if (declaration) return declaration; @@ -74,14 +74,14 @@ struct declaration *lookup_declaration(GQuark declaration_name, return NULL; } -int register_declaration(GQuark name, struct declaration *declaration, +int bt_register_declaration(GQuark name, struct declaration *declaration, struct declaration_scope *scope) { if (!name) return -EPERM; /* Only lookup in local scope */ - if (lookup_declaration_scope(name, scope)) + if (bt_lookup_declaration_scope(name, scope)) return -EEXIST; g_hash_table_insert(scope->typedef_declarations, @@ -306,7 +306,7 @@ void bt_definition_unref(struct definition *definition) } struct declaration_scope * - new_declaration_scope(struct declaration_scope *parent_scope) + bt_new_declaration_scope(struct declaration_scope *parent_scope) { struct declaration_scope *scope = g_new(struct declaration_scope, 1); @@ -326,7 +326,7 @@ struct declaration_scope * return scope; } -void free_declaration_scope(struct declaration_scope *scope) +void bt_free_declaration_scope(struct declaration_scope *scope) { g_hash_table_destroy(scope->enum_declarations); g_hash_table_destroy(scope->variant_declarations); @@ -378,14 +378,14 @@ int bt_register_struct_declaration(GQuark struct_name, /* Also add in typedef/typealias scopes */ prefix_name = prefix_quark("struct ", struct_name); - ret = register_declaration(prefix_name, &struct_declaration->p, scope); + ret = bt_register_declaration(prefix_name, &struct_declaration->p, scope); assert(!ret); return 0; } static struct declaration_untagged_variant * - lookup_variant_declaration_scope(GQuark variant_name, + bt_lookup_variant_declaration_scope(GQuark variant_name, struct declaration_scope *scope) { return g_hash_table_lookup(scope->variant_declarations, @@ -393,13 +393,13 @@ struct declaration_untagged_variant * } struct declaration_untagged_variant * - lookup_variant_declaration(GQuark variant_name, + bt_lookup_variant_declaration(GQuark variant_name, struct declaration_scope *scope) { struct declaration_untagged_variant *declaration; while (scope) { - declaration = lookup_variant_declaration_scope(variant_name, scope); + declaration = bt_lookup_variant_declaration_scope(variant_name, scope); if (declaration) return declaration; scope = scope->parent_scope; @@ -407,7 +407,7 @@ struct declaration_untagged_variant * return NULL; } -int register_variant_declaration(GQuark variant_name, +int bt_register_variant_declaration(GQuark variant_name, struct declaration_untagged_variant *untagged_variant_declaration, struct declaration_scope *scope) { @@ -418,7 +418,7 @@ int register_variant_declaration(GQuark variant_name, return -EPERM; /* Only lookup in local scope */ - if (lookup_variant_declaration_scope(variant_name, scope)) + if (bt_lookup_variant_declaration_scope(variant_name, scope)) return -EEXIST; g_hash_table_insert(scope->variant_declarations, @@ -428,7 +428,7 @@ int register_variant_declaration(GQuark variant_name, /* Also add in typedef/typealias scopes */ prefix_name = prefix_quark("variant ", variant_name); - ret = register_declaration(prefix_name, + ret = bt_register_declaration(prefix_name, &untagged_variant_declaration->p, scope); assert(!ret); return 0; @@ -436,7 +436,7 @@ int register_variant_declaration(GQuark variant_name, static struct declaration_enum * - lookup_enum_declaration_scope(GQuark enum_name, + bt_lookup_enum_declaration_scope(GQuark enum_name, struct declaration_scope *scope) { return g_hash_table_lookup(scope->enum_declarations, @@ -444,13 +444,13 @@ struct declaration_enum * } struct declaration_enum * - lookup_enum_declaration(GQuark enum_name, + bt_lookup_enum_declaration(GQuark enum_name, struct declaration_scope *scope) { struct declaration_enum *declaration; while (scope) { - declaration = lookup_enum_declaration_scope(enum_name, scope); + declaration = bt_lookup_enum_declaration_scope(enum_name, scope); if (declaration) return declaration; scope = scope->parent_scope; @@ -458,7 +458,7 @@ struct declaration_enum * return NULL; } -int register_enum_declaration(GQuark enum_name, +int bt_register_enum_declaration(GQuark enum_name, struct declaration_enum *enum_declaration, struct declaration_scope *scope) { @@ -469,7 +469,7 @@ int register_enum_declaration(GQuark enum_name, return -EPERM; /* Only lookup in local scope */ - if (lookup_enum_declaration_scope(enum_name, scope)) + if (bt_lookup_enum_declaration_scope(enum_name, scope)) return -EEXIST; g_hash_table_insert(scope->enum_declarations, @@ -479,7 +479,7 @@ int register_enum_declaration(GQuark enum_name, /* Also add in typedef/typealias scopes */ prefix_name = prefix_quark("enum ", enum_name); - ret = register_declaration(prefix_name, &enum_declaration->p, scope); + ret = bt_register_declaration(prefix_name, &enum_declaration->p, scope); assert(!ret); return 0; } diff --git a/types/variant.c b/types/variant.c index 47c821e..ba4179d 100644 --- a/types/variant.c +++ b/types/variant.c @@ -56,7 +56,7 @@ void _untagged_variant_declaration_free(struct declaration *declaration) container_of(declaration, struct declaration_untagged_variant, p); unsigned long i; - free_declaration_scope(untagged_variant_declaration->scope); + bt_free_declaration_scope(untagged_variant_declaration->scope); g_hash_table_destroy(untagged_variant_declaration->fields_by_tag); for (i = 0; i < untagged_variant_declaration->fields->len; i++) { @@ -69,7 +69,7 @@ void _untagged_variant_declaration_free(struct declaration *declaration) g_free(untagged_variant_declaration); } -struct declaration_untagged_variant *untagged_variant_declaration_new( +struct declaration_untagged_variant *bt_untagged_bt_variant_declaration_new( struct declaration_scope *parent_scope) { struct declaration_untagged_variant *untagged_variant_declaration; @@ -82,7 +82,7 @@ struct declaration_untagged_variant *untagged_variant_declaration_new( untagged_variant_declaration->fields = g_array_sized_new(FALSE, TRUE, sizeof(struct declaration_field), DEFAULT_NR_STRUCT_FIELDS); - untagged_variant_declaration->scope = new_declaration_scope(parent_scope); + untagged_variant_declaration->scope = bt_new_declaration_scope(parent_scope); declaration->id = CTF_TYPE_UNTAGGED_VARIANT; declaration->alignment = 1; declaration->declaration_free = _untagged_variant_declaration_free; @@ -104,7 +104,7 @@ void _variant_declaration_free(struct declaration *declaration) } struct declaration_variant * - variant_declaration_new(struct declaration_untagged_variant *untagged_variant, const char *tag) + bt_variant_declaration_new(struct declaration_untagged_variant *untagged_variant, const char *tag) { struct declaration_variant *variant_declaration; struct declaration *declaration; @@ -257,7 +257,7 @@ void _variant_definition_free(struct definition *definition) g_free(variant); } -void untagged_variant_declaration_add_field(struct declaration_untagged_variant *untagged_variant_declaration, +void bt_untagged_variant_declaration_add_field(struct declaration_untagged_variant *untagged_variant_declaration, const char *field_name, struct declaration *field_declaration) { @@ -282,7 +282,7 @@ void untagged_variant_declaration_add_field(struct declaration_untagged_variant } struct declaration_field * -untagged_variant_declaration_get_field_from_tag(struct declaration_untagged_variant *untagged_variant_declaration, GQuark tag) +bt_untagged_variant_declaration_get_field_from_tag(struct declaration_untagged_variant *untagged_variant_declaration, GQuark tag) { gpointer index; gboolean found; -- 1.7.10.4 From jdesfossez at efficios.com Thu Jan 24 16:21:49 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 16:21:49 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 17/18] namespace the definition functions In-Reply-To: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> Message-ID: <1359062510-7557-17-git-send-email-jdesfossez@efficios.com> Signed-off-by: Julien Desfossez --- formats/ctf/events.c | 4 ++-- include/babeltrace/types.h | 12 ++++++------ types/array.c | 10 +++++----- types/enum.c | 8 ++++---- types/float.c | 8 ++++---- types/integer.c | 4 ++-- types/sequence.c | 12 ++++++------ types/string.c | 4 ++-- types/struct.c | 10 +++++----- types/types.c | 24 ++++++++++++------------ types/variant.c | 12 ++++++------ 11 files changed, 54 insertions(+), 54 deletions(-) diff --git a/formats/ctf/events.c b/formats/ctf/events.c index 3660c04..5a6f625 100644 --- a/formats/ctf/events.c +++ b/formats/ctf/events.c @@ -106,7 +106,7 @@ const struct definition *bt_ctf_get_field(const struct bt_ctf_event *ctf_event, if (!ctf_event || !scope || !field) return NULL; - def = lookup_definition(scope, field); + def = bt_lookup_definition(scope, field); /* * optionally a field can have an underscore prefix, try * to lookup the field with this prefix if it failed @@ -115,7 +115,7 @@ const struct definition *bt_ctf_get_field(const struct bt_ctf_event *ctf_event, field_underscore = g_new(char, strlen(field) + 2); field_underscore[0] = '_'; strcpy(&field_underscore[1], field); - def = lookup_definition(scope, field_underscore); + def = bt_lookup_definition(scope, field_underscore); g_free(field_underscore); } if (bt_ctf_field_type(bt_ctf_get_decl_from_def(def)) == CTF_TYPE_VARIANT) { diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index 60bd4fd..f01a11c 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -344,18 +344,18 @@ void bt_free_declaration_scope(struct declaration_scope *scope); * definition scopes. */ struct definition * - lookup_path_definition(GArray *cur_path, /* array of GQuark */ + bt_lookup_path_definition(GArray *cur_path, /* array of GQuark */ GArray *lookup_path, /* array of GQuark */ struct definition_scope *scope); -int register_field_definition(GQuark field_name, +int bt_register_field_definition(GQuark field_name, struct definition *definition, struct definition_scope *scope); struct definition_scope * - new_definition_scope(struct definition_scope *parent_scope, + bt_new_definition_scope(struct definition_scope *parent_scope, GQuark field_name, const char *root_name); -void free_definition_scope(struct definition_scope *scope); +void bt_free_definition_scope(struct definition_scope *scope); -GQuark new_definition_path(struct definition_scope *parent_scope, +GQuark bt_new_definition_path(struct definition_scope *parent_scope, GQuark field_name, const char *root_name); static inline @@ -516,7 +516,7 @@ void bt_append_scope_path(const char *path, GArray *q); /* * Lookup helpers. */ -struct definition *lookup_definition(const struct definition *definition, +struct definition *bt_lookup_definition(const struct definition *definition, const char *field_name); struct definition_integer *lookup_integer(const struct definition *definition, const char *field_name, diff --git a/types/array.c b/types/array.c index 7f82167..30699b1 100644 --- a/types/array.c +++ b/types/array.c @@ -115,9 +115,9 @@ struct definition * */ array->p.index = root_name ? INT_MAX : index; array->p.name = field_name; - array->p.path = new_definition_path(parent_scope, field_name, root_name); - array->p.scope = new_definition_scope(parent_scope, field_name, root_name); - ret = register_field_definition(field_name, &array->p, + array->p.path = bt_new_definition_path(parent_scope, field_name, root_name); + array->p.scope = bt_new_definition_scope(parent_scope, field_name, root_name); + ret = bt_register_field_definition(field_name, &array->p, parent_scope); assert(!ret); array->string = NULL; @@ -169,7 +169,7 @@ error: field->declaration->definition_free(field); } (void) g_ptr_array_free(array->elems, TRUE); - free_definition_scope(array->p.scope); + bt_free_definition_scope(array->p.scope); bt_declaration_unref(array->p.declaration); g_free(array); return NULL; @@ -193,7 +193,7 @@ void _array_definition_free(struct definition *definition) } (void) g_ptr_array_free(array->elems, TRUE); } - free_definition_scope(array->p.scope); + bt_free_definition_scope(array->p.scope); bt_declaration_unref(array->p.declaration); g_free(array); } diff --git a/types/enum.c b/types/enum.c index 6d33713..2c0cfe8 100644 --- a/types/enum.c +++ b/types/enum.c @@ -440,10 +440,10 @@ struct definition * */ _enum->p.index = root_name ? INT_MAX : index; _enum->p.name = field_name; - _enum->p.path = new_definition_path(parent_scope, field_name, root_name); - _enum->p.scope = new_definition_scope(parent_scope, field_name, root_name); + _enum->p.path = bt_new_definition_path(parent_scope, field_name, root_name); + _enum->p.scope = bt_new_definition_scope(parent_scope, field_name, root_name); _enum->value = NULL; - ret = register_field_definition(field_name, &_enum->p, + ret = bt_register_field_definition(field_name, &_enum->p, parent_scope); assert(!ret); definition_integer_parent = @@ -462,7 +462,7 @@ void _enum_definition_free(struct definition *definition) container_of(definition, struct definition_enum, p); bt_definition_unref(&_enum->integer->p); - free_definition_scope(_enum->p.scope); + bt_free_definition_scope(_enum->p.scope); bt_declaration_unref(_enum->p.declaration); if (_enum->value) g_array_unref(_enum->value); diff --git a/types/float.c b/types/float.c index 7b89a89..16d4352 100644 --- a/types/float.c +++ b/types/float.c @@ -96,8 +96,8 @@ struct definition * bt_declaration_ref(&float_declaration->p); _float->p.declaration = declaration; _float->declaration = float_declaration; - _float->p.scope = new_definition_scope(parent_scope, field_name, root_name); - _float->p.path = new_definition_path(parent_scope, field_name, root_name); + _float->p.scope = bt_new_definition_scope(parent_scope, field_name, root_name); + _float->p.path = bt_new_definition_path(parent_scope, field_name, root_name); if (float_declaration->byte_order == LITTLE_ENDIAN) { tmp = float_declaration->mantissa->p.definition_new(&float_declaration->mantissa->p, _float->p.scope, g_quark_from_static_string("mantissa"), 0, NULL); @@ -130,7 +130,7 @@ struct definition * if (parent_scope) { int ret; - ret = register_field_definition(field_name, &_float->p, + ret = bt_register_field_definition(field_name, &_float->p, parent_scope); assert(!ret); } @@ -146,7 +146,7 @@ void _float_definition_free(struct definition *definition) bt_definition_unref(&_float->sign->p); bt_definition_unref(&_float->exp->p); bt_definition_unref(&_float->mantissa->p); - free_definition_scope(_float->p.scope); + bt_free_definition_scope(_float->p.scope); bt_declaration_unref(_float->p.declaration); g_free(_float); } diff --git a/types/integer.c b/types/integer.c index 936453a..47f23eb 100644 --- a/types/integer.c +++ b/types/integer.c @@ -95,11 +95,11 @@ struct definition * */ integer->p.index = root_name ? INT_MAX : index; integer->p.name = field_name; - integer->p.path = new_definition_path(parent_scope, field_name, + integer->p.path = bt_new_definition_path(parent_scope, field_name, root_name); integer->p.scope = NULL; integer->value._unsigned = 0; - ret = register_field_definition(field_name, &integer->p, + ret = bt_register_field_definition(field_name, &integer->p, parent_scope); assert(!ret); return &integer->p; diff --git a/types/sequence.c b/types/sequence.c index 1795ae4..2646cef 100644 --- a/types/sequence.c +++ b/types/sequence.c @@ -148,12 +148,12 @@ struct definition *_sequence_definition_new(struct declaration *declaration, */ sequence->p.index = root_name ? INT_MAX : index; sequence->p.name = field_name; - sequence->p.path = new_definition_path(parent_scope, field_name, root_name); - sequence->p.scope = new_definition_scope(parent_scope, field_name, root_name); - ret = register_field_definition(field_name, &sequence->p, + sequence->p.path = bt_new_definition_path(parent_scope, field_name, root_name); + sequence->p.scope = bt_new_definition_scope(parent_scope, field_name, root_name); + ret = bt_register_field_definition(field_name, &sequence->p, parent_scope); assert(!ret); - len_parent = lookup_path_definition(sequence->p.scope->scope_path, + len_parent = bt_lookup_path_definition(sequence->p.scope->scope_path, sequence_declaration->length_name, parent_scope); if (!len_parent) { @@ -191,7 +191,7 @@ struct definition *_sequence_definition_new(struct declaration *declaration, return &sequence->p; error: - free_definition_scope(sequence->p.scope); + bt_free_definition_scope(sequence->p.scope); bt_declaration_unref(&sequence_declaration->p); g_free(sequence); return NULL; @@ -217,7 +217,7 @@ void _sequence_definition_free(struct definition *definition) (void) g_ptr_array_free(sequence->elems, TRUE); } bt_definition_unref(len_definition); - free_definition_scope(sequence->p.scope); + bt_free_definition_scope(sequence->p.scope); bt_declaration_unref(sequence->p.declaration); g_free(sequence); } diff --git a/types/string.c b/types/string.c index 255388f..dff27ee 100644 --- a/types/string.c +++ b/types/string.c @@ -86,13 +86,13 @@ struct definition * */ string->p.index = root_name ? INT_MAX : index; string->p.name = field_name; - string->p.path = new_definition_path(parent_scope, field_name, + string->p.path = bt_new_definition_path(parent_scope, field_name, root_name); string->p.scope = NULL; string->value = NULL; string->len = 0; string->alloc_len = 0; - ret = register_field_definition(field_name, &string->p, + ret = bt_register_field_definition(field_name, &string->p, parent_scope); assert(!ret); return &string->p; diff --git a/types/struct.c b/types/struct.c index 76b82d2..5da9033 100644 --- a/types/struct.c +++ b/types/struct.c @@ -128,10 +128,10 @@ struct definition * */ _struct->p.index = root_name ? INT_MAX : index; _struct->p.name = field_name; - _struct->p.path = new_definition_path(parent_scope, field_name, root_name); - _struct->p.scope = new_definition_scope(parent_scope, field_name, root_name); + _struct->p.path = bt_new_definition_path(parent_scope, field_name, root_name); + _struct->p.scope = bt_new_definition_scope(parent_scope, field_name, root_name); - ret = register_field_definition(field_name, &_struct->p, + ret = bt_register_field_definition(field_name, &_struct->p, parent_scope); assert(!ret || ret == -EPERM); @@ -157,7 +157,7 @@ error: struct definition *field = g_ptr_array_index(_struct->fields, i); bt_definition_unref(field); } - free_definition_scope(_struct->p.scope); + bt_free_definition_scope(_struct->p.scope); bt_declaration_unref(&struct_declaration->p); g_free(_struct); return NULL; @@ -175,7 +175,7 @@ void _struct_definition_free(struct definition *definition) struct definition *field = g_ptr_array_index(_struct->fields, i); bt_definition_unref(field); } - free_definition_scope(_struct->p.scope); + bt_free_definition_scope(_struct->p.scope); bt_declaration_unref(_struct->p.declaration); g_ptr_array_free(_struct->fields, TRUE); g_free(_struct); diff --git a/types/types.c b/types/types.c index d60e577..25ce715 100644 --- a/types/types.c +++ b/types/types.c @@ -184,7 +184,7 @@ static struct definition_scope * * scope: the definition scope containing the variant definition. */ struct definition * - lookup_path_definition(GArray *cur_path, + bt_lookup_path_definition(GArray *cur_path, GArray *lookup_path, struct definition_scope *scope) { @@ -262,7 +262,7 @@ lookup: return NULL; } -int register_field_definition(GQuark field_name, struct definition *definition, +int bt_register_field_definition(GQuark field_name, struct definition *definition, struct definition_scope *scope) { if (!scope || !field_name) @@ -485,7 +485,7 @@ int bt_register_enum_declaration(GQuark enum_name, } static struct definition_scope * - _new_definition_scope(struct definition_scope *parent_scope, + _bt_new_definition_scope(struct definition_scope *parent_scope, int scope_path_len) { struct definition_scope *scope = g_new(struct definition_scope, 1); @@ -499,7 +499,7 @@ static struct definition_scope * return scope; } -GQuark new_definition_path(struct definition_scope *parent_scope, +GQuark bt_new_definition_path(struct definition_scope *parent_scope, GQuark field_name, const char *root_name) { GQuark path; @@ -540,20 +540,20 @@ GQuark new_definition_path(struct definition_scope *parent_scope, } struct definition_scope * - new_definition_scope(struct definition_scope *parent_scope, + bt_new_definition_scope(struct definition_scope *parent_scope, GQuark field_name, const char *root_name) { struct definition_scope *scope; if (root_name) { - scope = _new_definition_scope(parent_scope, 0); + scope = _bt_new_definition_scope(parent_scope, 0); bt_append_scope_path(root_name, scope->scope_path); } else { int scope_path_len = 1; assert(parent_scope); scope_path_len += parent_scope->scope_path->len; - scope = _new_definition_scope(parent_scope, scope_path_len); + scope = _bt_new_definition_scope(parent_scope, scope_path_len); memcpy(scope->scope_path->data, parent_scope->scope_path->data, sizeof(GQuark) * (scope_path_len - 1)); g_array_index(scope->scope_path, GQuark, scope_path_len - 1) = @@ -605,14 +605,14 @@ void bt_append_scope_path(const char *path, GArray *q) } } -void free_definition_scope(struct definition_scope *scope) +void bt_free_definition_scope(struct definition_scope *scope) { g_array_free(scope->scope_path, TRUE); g_hash_table_destroy(scope->definitions); g_free(scope); } -struct definition *lookup_definition(const struct definition *definition, +struct definition *bt_lookup_definition(const struct definition *definition, const char *field_name) { struct definition_scope *scope = get_definition_scope(definition); @@ -631,7 +631,7 @@ struct definition_integer *lookup_integer(const struct definition *definition, struct definition *lookup; struct definition_integer *lookup_integer; - lookup = lookup_definition(definition, field_name); + lookup = bt_lookup_definition(definition, field_name); if (!lookup) return NULL; if (lookup->declaration->id != CTF_TYPE_INTEGER) @@ -649,7 +649,7 @@ struct definition_enum *bt_lookup_enum(const struct definition *definition, struct definition *lookup; struct definition_enum *lookup_enum; - lookup = lookup_definition(definition, field_name); + lookup = bt_lookup_definition(definition, field_name); if (!lookup) return NULL; if (lookup->declaration->id != CTF_TYPE_ENUM) @@ -666,7 +666,7 @@ struct definition *bt_lookup_variant(const struct definition *definition, struct definition *lookup; struct definition_variant *bt_lookup_variant; - lookup = lookup_definition(definition, field_name); + lookup = bt_lookup_definition(definition, field_name); if (!lookup) return NULL; if (lookup->declaration->id != CTF_TYPE_VARIANT) diff --git a/types/variant.c b/types/variant.c index 837875c..ebaf43c 100644 --- a/types/variant.c +++ b/types/variant.c @@ -195,14 +195,14 @@ struct definition * */ variant->p.index = root_name ? INT_MAX : index; variant->p.name = field_name; - variant->p.path = new_definition_path(parent_scope, field_name, root_name); - variant->p.scope = new_definition_scope(parent_scope, field_name, root_name); + variant->p.path = bt_new_definition_path(parent_scope, field_name, root_name); + variant->p.scope = bt_new_definition_scope(parent_scope, field_name, root_name); - ret = register_field_definition(field_name, &variant->p, + ret = bt_register_field_definition(field_name, &variant->p, parent_scope); assert(!ret); - variant->enum_tag = lookup_path_definition(variant->p.scope->scope_path, + variant->enum_tag = bt_lookup_path_definition(variant->p.scope->scope_path, variant_declaration->tag_name, parent_scope); @@ -232,7 +232,7 @@ struct definition * variant->current_field = NULL; return &variant->p; error: - free_definition_scope(variant->p.scope); + bt_free_definition_scope(variant->p.scope); bt_declaration_unref(&variant_declaration->p); g_free(variant); return NULL; @@ -251,7 +251,7 @@ void _variant_definition_free(struct definition *definition) bt_definition_unref(field); } bt_definition_unref(variant->enum_tag); - free_definition_scope(variant->p.scope); + bt_free_definition_scope(variant->p.scope); bt_declaration_unref(variant->p.declaration); g_ptr_array_free(variant->fields, TRUE); g_free(variant); -- 1.7.10.4 From jdesfossez at efficios.com Thu Jan 24 16:21:50 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 16:21:50 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 18/18] namespace the lookup_integer function In-Reply-To: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> Message-ID: <1359062510-7557-18-git-send-email-jdesfossez@efficios.com> Signed-off-by: Julien Desfossez --- formats/ctf/ctf.c | 8 ++++---- include/babeltrace/types.h | 2 +- types/types.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index ba403aa..deb9a66 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -427,7 +427,7 @@ int ctf_read_event(struct stream_pos *ppos, struct ctf_stream_definition *stream if (unlikely(ret)) goto error; /* lookup event id */ - integer_definition = lookup_integer(&stream->stream_event_header->p, "id", FALSE); + integer_definition = bt_lookup_integer(&stream->stream_event_header->p, "id", FALSE); if (integer_definition) { id = integer_definition->value._unsigned; } else { @@ -441,7 +441,7 @@ int ctf_read_event(struct stream_pos *ppos, struct ctf_stream_definition *stream variant = bt_lookup_variant(&stream->stream_event_header->p, "v"); if (variant) { - integer_definition = lookup_integer(variant, "id", FALSE); + integer_definition = bt_lookup_integer(variant, "id", FALSE); if (integer_definition) { id = integer_definition->value._unsigned; } @@ -450,13 +450,13 @@ int ctf_read_event(struct stream_pos *ppos, struct ctf_stream_definition *stream /* lookup timestamp */ stream->has_timestamp = 0; - integer_definition = lookup_integer(&stream->stream_event_header->p, "timestamp", FALSE); + integer_definition = bt_lookup_integer(&stream->stream_event_header->p, "timestamp", FALSE); if (integer_definition) { ctf_update_timestamp(stream, integer_definition); stream->has_timestamp = 1; } else { if (variant) { - integer_definition = lookup_integer(variant, "timestamp", FALSE); + integer_definition = bt_lookup_integer(variant, "timestamp", FALSE); if (integer_definition) { ctf_update_timestamp(stream, integer_definition); stream->has_timestamp = 1; diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index f01a11c..d742b40 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -518,7 +518,7 @@ void bt_append_scope_path(const char *path, GArray *q); */ struct definition *bt_lookup_definition(const struct definition *definition, const char *field_name); -struct definition_integer *lookup_integer(const struct definition *definition, +struct definition_integer *bt_lookup_integer(const struct definition *definition, const char *field_name, int signedness); struct definition_enum *bt_lookup_enum(const struct definition *definition, diff --git a/types/types.c b/types/types.c index 25ce715..3e20dfe 100644 --- a/types/types.c +++ b/types/types.c @@ -624,7 +624,7 @@ struct definition *bt_lookup_definition(const struct definition *definition, scope); } -struct definition_integer *lookup_integer(const struct definition *definition, +struct definition_integer *bt_lookup_integer(const struct definition *definition, const char *field_name, int signedness) { -- 1.7.10.4 From julien.desfossez at polymtl.ca Thu Jan 24 16:26:37 2013 From: julien.desfossez at polymtl.ca (Julien Desfossez) Date: Thu, 24 Jan 2013 16:26:37 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 03/18] Hide internal functions of libbabeltrace-ctf In-Reply-To: <1359062510-7557-3-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-1-git-send-email-jdesfossez@efficios.com> <1359062510-7557-3-git-send-email-jdesfossez@efficios.com> Message-ID: <5101A70D.10607@polymtl.ca> On 24/01/13 04:21 PM, Julien Desfossez wrote: > Signed-off-by: Julien Desfossez > --- > formats/ctf/ctf.c | 5 ++++- > formats/ctf/metadata/ctf-ast.h | 5 +++++ > formats/ctf/types/float.c | 4 +++- > include/babeltrace/ctf/callbacks-internal.h | 1 + > include/babeltrace/ctf/callbacks.h | 1 + > include/babeltrace/ctf/types.h | 14 ++++++++++++++ > 6 files changed, 28 insertions(+), 2 deletions(-) > > diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c > index a8f8408..a55f5e4 100644 > --- a/formats/ctf/ctf.c > +++ b/formats/ctf/ctf.c > @@ -307,6 +307,7 @@ void ctf_update_timestamp(struct ctf_stream_definition *stream, > * Print timestamp, rescaling clock frequency to nanoseconds and > * applying offsets as needed (unix time). > */ > +static > void ctf_print_timestamp_real(FILE *fp, > struct ctf_stream_definition *stream, > uint64_t timestamp) > @@ -371,6 +372,7 @@ end: > /* > * Print timestamp, in cycles > */ > +static > void ctf_print_timestamp_cycles(FILE *fp, > struct ctf_stream_definition *stream, > uint64_t timestamp) > @@ -1724,7 +1726,7 @@ error: > return NULL; > } > > - > +static > void ctf_init_mmap_pos(struct ctf_stream_pos *pos, > struct mmap_stream *mmap_info) > { > @@ -1815,6 +1817,7 @@ error_def: > return ret; > } > > +static > int ctf_open_mmap_trace_read(struct ctf_trace *td, > struct mmap_stream_list *mmap_list, > void (*packet_seek)(struct stream_pos *pos, size_t index, > diff --git a/formats/ctf/metadata/ctf-ast.h b/formats/ctf/metadata/ctf-ast.h > index d5a0544..1368627 100644 > --- a/formats/ctf/metadata/ctf-ast.h > +++ b/formats/ctf/metadata/ctf-ast.h > @@ -302,11 +302,16 @@ const char *node_type(struct ctf_node *node); > > struct ctf_trace; > > +BT_HIDDEN > int ctf_visitor_print_xml(FILE *fd, int depth, struct ctf_node *node); > +BT_HIDDEN > int ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node); > +BT_HIDDEN > int ctf_visitor_parent_links(FILE *fd, int depth, struct ctf_node *node); > +BT_HIDDEN > int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node, > struct ctf_trace *trace, int byte_order); > +BT_HIDDEN > int ctf_destroy_metadata(struct ctf_trace *trace); > > #endif /* _CTF_AST_H */ > diff --git a/formats/ctf/types/float.c b/formats/ctf/types/float.c > index 0cf9cae..054e262 100644 > --- a/formats/ctf/types/float.c > +++ b/formats/ctf/types/float.c > @@ -96,7 +96,7 @@ static void float_unlock(void) > assert(!ret); > } > > -int _ctf_float_copy(struct stream_pos *destp, > +static int _ctf_float_copy(struct stream_pos *destp, > struct definition_float *dest_definition, > struct stream_pos *srcp, > const struct definition_float *src_definition) > @@ -278,6 +278,7 @@ end: > return ret; > } > > +static > void __attribute__((constructor)) ctf_float_init(void) > { > static_float_declaration = > @@ -292,6 +293,7 @@ void __attribute__((constructor)) ctf_float_init(void) > __alignof__(double)); > } > > +static > void __attribute__((destructor)) ctf_float_fini(void) > { > declaration_unref(&static_float_declaration->p); > diff --git a/include/babeltrace/ctf/callbacks-internal.h b/include/babeltrace/ctf/callbacks-internal.h > index 0390b9a..41bc846 100644 > --- a/include/babeltrace/ctf/callbacks-internal.h > +++ b/include/babeltrace/ctf/callbacks-internal.h > @@ -60,6 +60,7 @@ struct bt_dependencies { > int refcount; /* free when decremented to 0 */ > }; > > +BT_HIDDEN > void process_callbacks(struct bt_ctf_iter *iter, struct ctf_stream_definition *stream); > > #endif /* _BABELTRACE_CALLBACKS_INTERNAL_H */ > diff --git a/include/babeltrace/ctf/callbacks.h b/include/babeltrace/ctf/callbacks.h > index c178767..8d25741 100644 > --- a/include/babeltrace/ctf/callbacks.h > +++ b/include/babeltrace/ctf/callbacks.h > @@ -51,6 +51,7 @@ enum bt_cb_ret { > /* > * Receives a variable number of strings as parameter, ended with NULL. > */ > +BT_HIDDEN > struct bt_dependencies *babeltrace_dependencies_create(const char *first, ...); this last modif will be removed, this is part of the exposed API, sorry. Julien > > /* > diff --git a/include/babeltrace/ctf/types.h b/include/babeltrace/ctf/types.h > index 6b8752e..8bd0102 100644 > --- a/include/babeltrace/ctf/types.h > +++ b/include/babeltrace/ctf/types.h > @@ -90,19 +90,33 @@ struct ctf_stream_pos *ctf_pos(struct stream_pos *pos) > return container_of(pos, struct ctf_stream_pos, parent); > } > > +BT_HIDDEN > int ctf_integer_read(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_integer_write(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_float_read(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_float_write(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_string_read(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_string_write(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_enum_read(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_enum_write(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_struct_rw(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_variant_rw(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_array_read(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_array_write(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_sequence_read(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_sequence_write(struct stream_pos *pos, struct definition *definition); > > void ctf_packet_seek(struct stream_pos *pos, size_t index, int whence); From jdesfossez at efficios.com Thu Jan 24 17:08:35 2013 From: jdesfossez at efficios.com (Julien Desfossez) Date: Thu, 24 Jan 2013 17:08:35 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 03/18] Hide internal functions of libbabeltrace-ctf In-Reply-To: <1359062510-7557-3-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-3-git-send-email-jdesfossez@efficios.com> Message-ID: <1359065315-17252-1-git-send-email-jdesfossez@efficios.com> Signed-off-by: Julien Desfossez --- formats/ctf/ctf.c | 5 ++++- formats/ctf/metadata/ctf-ast.h | 5 +++++ formats/ctf/types/float.c | 4 +++- include/babeltrace/ctf/callbacks-internal.h | 1 + include/babeltrace/ctf/types.h | 14 ++++++++++++++ 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index a8f8408..a55f5e4 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -307,6 +307,7 @@ void ctf_update_timestamp(struct ctf_stream_definition *stream, * Print timestamp, rescaling clock frequency to nanoseconds and * applying offsets as needed (unix time). */ +static void ctf_print_timestamp_real(FILE *fp, struct ctf_stream_definition *stream, uint64_t timestamp) @@ -371,6 +372,7 @@ end: /* * Print timestamp, in cycles */ +static void ctf_print_timestamp_cycles(FILE *fp, struct ctf_stream_definition *stream, uint64_t timestamp) @@ -1724,7 +1726,7 @@ error: return NULL; } - +static void ctf_init_mmap_pos(struct ctf_stream_pos *pos, struct mmap_stream *mmap_info) { @@ -1815,6 +1817,7 @@ error_def: return ret; } +static int ctf_open_mmap_trace_read(struct ctf_trace *td, struct mmap_stream_list *mmap_list, void (*packet_seek)(struct stream_pos *pos, size_t index, diff --git a/formats/ctf/metadata/ctf-ast.h b/formats/ctf/metadata/ctf-ast.h index d5a0544..1368627 100644 --- a/formats/ctf/metadata/ctf-ast.h +++ b/formats/ctf/metadata/ctf-ast.h @@ -302,11 +302,16 @@ const char *node_type(struct ctf_node *node); struct ctf_trace; +BT_HIDDEN int ctf_visitor_print_xml(FILE *fd, int depth, struct ctf_node *node); +BT_HIDDEN int ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node); +BT_HIDDEN int ctf_visitor_parent_links(FILE *fd, int depth, struct ctf_node *node); +BT_HIDDEN int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace, int byte_order); +BT_HIDDEN int ctf_destroy_metadata(struct ctf_trace *trace); #endif /* _CTF_AST_H */ diff --git a/formats/ctf/types/float.c b/formats/ctf/types/float.c index 0cf9cae..054e262 100644 --- a/formats/ctf/types/float.c +++ b/formats/ctf/types/float.c @@ -96,7 +96,7 @@ static void float_unlock(void) assert(!ret); } -int _ctf_float_copy(struct stream_pos *destp, +static int _ctf_float_copy(struct stream_pos *destp, struct definition_float *dest_definition, struct stream_pos *srcp, const struct definition_float *src_definition) @@ -278,6 +278,7 @@ end: return ret; } +static void __attribute__((constructor)) ctf_float_init(void) { static_float_declaration = @@ -292,6 +293,7 @@ void __attribute__((constructor)) ctf_float_init(void) __alignof__(double)); } +static void __attribute__((destructor)) ctf_float_fini(void) { declaration_unref(&static_float_declaration->p); diff --git a/include/babeltrace/ctf/callbacks-internal.h b/include/babeltrace/ctf/callbacks-internal.h index 0390b9a..41bc846 100644 --- a/include/babeltrace/ctf/callbacks-internal.h +++ b/include/babeltrace/ctf/callbacks-internal.h @@ -60,6 +60,7 @@ struct bt_dependencies { int refcount; /* free when decremented to 0 */ }; +BT_HIDDEN void process_callbacks(struct bt_ctf_iter *iter, struct ctf_stream_definition *stream); #endif /* _BABELTRACE_CALLBACKS_INTERNAL_H */ diff --git a/include/babeltrace/ctf/types.h b/include/babeltrace/ctf/types.h index 6b8752e..8bd0102 100644 --- a/include/babeltrace/ctf/types.h +++ b/include/babeltrace/ctf/types.h @@ -90,19 +90,33 @@ struct ctf_stream_pos *ctf_pos(struct stream_pos *pos) return container_of(pos, struct ctf_stream_pos, parent); } +BT_HIDDEN int ctf_integer_read(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_integer_write(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_float_read(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_float_write(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_string_read(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_string_write(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_enum_read(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_enum_write(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_struct_rw(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_variant_rw(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_array_read(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_array_write(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_sequence_read(struct stream_pos *pos, struct definition *definition); +BT_HIDDEN int ctf_sequence_write(struct stream_pos *pos, struct definition *definition); void ctf_packet_seek(struct stream_pos *pos, size_t index, int whence); -- 1.7.10.4 From mathieu.desnoyers at efficios.com Thu Jan 24 17:27:32 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 24 Jan 2013 17:27:32 -0500 Subject: [lttng-dev] [BABELTRACE PATCH 03/18] Hide internal functions of libbabeltrace-ctf In-Reply-To: <1359065315-17252-1-git-send-email-jdesfossez@efficios.com> References: <1359062510-7557-3-git-send-email-jdesfossez@efficios.com> <1359065315-17252-1-git-send-email-jdesfossez@efficios.com> Message-ID: <20130124222732.GA12113@Krystal> * Julien Desfossez (jdesfossez at efficios.com) wrote: > Signed-off-by: Julien Desfossez All 18 patches merged, including this updated version for 03. This opens the road towards babeltrace 1.1. Thanks! Mathieu > --- > formats/ctf/ctf.c | 5 ++++- > formats/ctf/metadata/ctf-ast.h | 5 +++++ > formats/ctf/types/float.c | 4 +++- > include/babeltrace/ctf/callbacks-internal.h | 1 + > include/babeltrace/ctf/types.h | 14 ++++++++++++++ > 5 files changed, 27 insertions(+), 2 deletions(-) > > diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c > index a8f8408..a55f5e4 100644 > --- a/formats/ctf/ctf.c > +++ b/formats/ctf/ctf.c > @@ -307,6 +307,7 @@ void ctf_update_timestamp(struct ctf_stream_definition *stream, > * Print timestamp, rescaling clock frequency to nanoseconds and > * applying offsets as needed (unix time). > */ > +static > void ctf_print_timestamp_real(FILE *fp, > struct ctf_stream_definition *stream, > uint64_t timestamp) > @@ -371,6 +372,7 @@ end: > /* > * Print timestamp, in cycles > */ > +static > void ctf_print_timestamp_cycles(FILE *fp, > struct ctf_stream_definition *stream, > uint64_t timestamp) > @@ -1724,7 +1726,7 @@ error: > return NULL; > } > > - > +static > void ctf_init_mmap_pos(struct ctf_stream_pos *pos, > struct mmap_stream *mmap_info) > { > @@ -1815,6 +1817,7 @@ error_def: > return ret; > } > > +static > int ctf_open_mmap_trace_read(struct ctf_trace *td, > struct mmap_stream_list *mmap_list, > void (*packet_seek)(struct stream_pos *pos, size_t index, > diff --git a/formats/ctf/metadata/ctf-ast.h b/formats/ctf/metadata/ctf-ast.h > index d5a0544..1368627 100644 > --- a/formats/ctf/metadata/ctf-ast.h > +++ b/formats/ctf/metadata/ctf-ast.h > @@ -302,11 +302,16 @@ const char *node_type(struct ctf_node *node); > > struct ctf_trace; > > +BT_HIDDEN > int ctf_visitor_print_xml(FILE *fd, int depth, struct ctf_node *node); > +BT_HIDDEN > int ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node); > +BT_HIDDEN > int ctf_visitor_parent_links(FILE *fd, int depth, struct ctf_node *node); > +BT_HIDDEN > int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node, > struct ctf_trace *trace, int byte_order); > +BT_HIDDEN > int ctf_destroy_metadata(struct ctf_trace *trace); > > #endif /* _CTF_AST_H */ > diff --git a/formats/ctf/types/float.c b/formats/ctf/types/float.c > index 0cf9cae..054e262 100644 > --- a/formats/ctf/types/float.c > +++ b/formats/ctf/types/float.c > @@ -96,7 +96,7 @@ static void float_unlock(void) > assert(!ret); > } > > -int _ctf_float_copy(struct stream_pos *destp, > +static int _ctf_float_copy(struct stream_pos *destp, > struct definition_float *dest_definition, > struct stream_pos *srcp, > const struct definition_float *src_definition) > @@ -278,6 +278,7 @@ end: > return ret; > } > > +static > void __attribute__((constructor)) ctf_float_init(void) > { > static_float_declaration = > @@ -292,6 +293,7 @@ void __attribute__((constructor)) ctf_float_init(void) > __alignof__(double)); > } > > +static > void __attribute__((destructor)) ctf_float_fini(void) > { > declaration_unref(&static_float_declaration->p); > diff --git a/include/babeltrace/ctf/callbacks-internal.h b/include/babeltrace/ctf/callbacks-internal.h > index 0390b9a..41bc846 100644 > --- a/include/babeltrace/ctf/callbacks-internal.h > +++ b/include/babeltrace/ctf/callbacks-internal.h > @@ -60,6 +60,7 @@ struct bt_dependencies { > int refcount; /* free when decremented to 0 */ > }; > > +BT_HIDDEN > void process_callbacks(struct bt_ctf_iter *iter, struct ctf_stream_definition *stream); > > #endif /* _BABELTRACE_CALLBACKS_INTERNAL_H */ > diff --git a/include/babeltrace/ctf/types.h b/include/babeltrace/ctf/types.h > index 6b8752e..8bd0102 100644 > --- a/include/babeltrace/ctf/types.h > +++ b/include/babeltrace/ctf/types.h > @@ -90,19 +90,33 @@ struct ctf_stream_pos *ctf_pos(struct stream_pos *pos) > return container_of(pos, struct ctf_stream_pos, parent); > } > > +BT_HIDDEN > int ctf_integer_read(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_integer_write(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_float_read(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_float_write(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_string_read(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_string_write(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_enum_read(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_enum_write(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_struct_rw(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_variant_rw(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_array_read(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_array_write(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_sequence_read(struct stream_pos *pos, struct definition *definition); > +BT_HIDDEN > int ctf_sequence_write(struct stream_pos *pos, struct definition *definition); > > void ctf_packet_seek(struct stream_pos *pos, size_t index, int whence); > -- > 1.7.10.4 > -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Thu Jan 24 18:47:32 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 24 Jan 2013 18:47:32 -0500 Subject: [lttng-dev] [PULL REQUEST lttng-tools] please pull for compudj-pull Message-ID: <20130124234731.GA16402@Krystal> Hi David, Please pull from my pull branch at: git://git.dorsal.polymtl.ca/~compudj/lttng-tools branch: compudj-pull It contains the following useful commits: commit 9d623b7096efbd378f566c39e4c9ab91e21fb656 Author: Mathieu Desnoyers Date: Thu Jan 24 18:43:48 2013 -0500 symbol prefixing: in-house copy of hash table Will ensure we don't clash with the real version in liburcu cds. It's especially important since those symbols are exported globally by liblttng-ctl. Signed-off-by: Mathieu Desnoyers commit ec1406acb4af789da299b4e81b3b7f5cc0057714 Author: Mathieu Desnoyers Date: Thu Jan 24 18:34:44 2013 -0500 Fix: add missing unistd.h include for fdatasync in compat-fcntl.c Signed-off-by: Mathieu Desnoyers commit 73f94c074aa293f09e526c01ed262a1751e10523 Author: Mathieu Desnoyers Date: Thu Jan 24 18:33:41 2013 -0500 namespace lttngctl filter flex/bison symbols Signed-off-by: Mathieu Desnoyers Thanks, Mathieu -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From yangw.wang5 at unb.ca Thu Jan 24 19:48:08 2013 From: yangw.wang5 at unb.ca (Yang Wang) Date: Fri, 25 Jan 2013 00:48:08 +0000 Subject: [lttng-dev] How to debug the CTF struct problem? Message-ID: <8E0A14A4C9B95B459AE214584119C1EB3BC90A1E@Hal.ad.unb.ca> Hello Could anybody know what causes the following problem? How to debug it? I guess somewhere a tracepoint is wrong, but I don't know which one as I have tons of tracepoints automatically generated and scattered in all the system files. yang at yang-OptiPlex-990:~/j9home/home/yangwang/benchmarks$ lttng view Trace directory: /home/yang/lttng-traces/auto-20130124-190929 [error] ctf_struct_type_declarators_visit: duplicate field _string in struct [error] ctf_visitor_construct_metadata: event declaration error [error] Error in CTF metadata constructor -1 [warning] Unable to open trace metadata for path "/home/yang/lttng-traces/auto-20130124-190929/ust/java-7907-20130124-190951". [warning] [Context] Cannot open_trace of the format /home/yang/lttng-traces/auto-20130124-190929/ust/java-7907-20130124-190951 . Thanks in advance Yang -------------- next part -------------- An HTML attachment was scrubbed... URL: From mathieu.desnoyers at efficios.com Thu Jan 24 20:58:21 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 24 Jan 2013 20:58:21 -0500 Subject: [lttng-dev] How to debug the CTF struct problem? In-Reply-To: <8E0A14A4C9B95B459AE214584119C1EB3BC90A1E@Hal.ad.unb.ca> References: <8E0A14A4C9B95B459AE214584119C1EB3BC90A1E@Hal.ad.unb.ca> Message-ID: <20130125015821.GA19436@Krystal> * Yang Wang (yangw.wang5 at unb.ca) wrote: > Hello > > Could anybody know what causes the following problem? How to debug it? > I guess somewhere a tracepoint is wrong, but I don't know which one as > I have tons of tracepoints automatically generated and scattered in > all the system files. can you show us the content of: /home/yang/lttng-traces/auto-20130124-190929/metadata please ? Also the output of babeltrace -d -v might help. Thanks, Mathieu > > yang at yang-OptiPlex-990:~/j9home/home/yangwang/benchmarks$ lttng view > Trace directory: /home/yang/lttng-traces/auto-20130124-190929 > > [error] ctf_struct_type_declarators_visit: duplicate field _string in struct > [error] ctf_visitor_construct_metadata: event declaration error > [error] Error in CTF metadata constructor -1 > [warning] Unable to open trace metadata for path "/home/yang/lttng-traces/auto-20130124-190929/ust/java-7907-20130124-190951". > [warning] [Context] Cannot open_trace of the format /home/yang/lttng-traces/auto-20130124-190929/ust/java-7907-20130124-190951 . > > Thanks in advance > > Yang > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From teawater at gmail.com Fri Jan 25 06:16:00 2013 From: teawater at gmail.com (Hui Zhu) Date: Fri, 25 Jan 2013 19:16:00 +0800 Subject: [lttng-dev] [BABELTRACE PATCH] Namespace the lookup_enum function In-Reply-To: <510172B7.1090908@efficios.com> References: <20130107211855.GB3678@Krystal> <1357760893-11961-1-git-send-email-jdesfossez@efficios.com> <20130113175754.GA3917@Krystal> <510172B7.1090908@efficios.com> Message-ID: Hi Julien and Mathieu, I just tried it with GDB ctf patches. It works very good. Thanks for your help. Best, Hui On Fri, Jan 25, 2013 at 1:43 AM, Julien Desfossez wrote: > For info, this patch was merged in Babeltrace master, see commit > 9e3274b092343c999fcde33854d2df37b3702496 > > Thanks, > > Julien > > On 13/01/13 12:57 PM, Mathieu Desnoyers wrote: >> * Julien Desfossez (jdesfossez at efficios.com) wrote: >>> This patch namespaces the lookup_enum function because it causes problem >>> with the integration in gdb even though it is not exported. >>> Hui, can you try this patch and confirm it solves the current problem ? >>> After that we will continue the internal namespacing. >> >> Hi Julien, >> >> Since we know these changes are needed, can you provide patches with >> proper changelogs, and I'll pull them. >> >> Thanks, >> >> Mathieu >> >>> >>> Thanks, >>> >>> Julien >>> --- >>> formats/ctf/ctf.c | 2 +- >>> include/babeltrace/types.h | 2 +- >>> types/types.c | 2 +- >>> 3 files changed, 3 insertions(+), 3 deletions(-) >>> >>> diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c >>> index 18a5601..a8f8408 100644 >>> --- a/formats/ctf/ctf.c >>> +++ b/formats/ctf/ctf.c >>> @@ -431,7 +431,7 @@ int ctf_read_event(struct stream_pos *ppos, struct ctf_stream_definition *stream >>> } else { >>> struct definition_enum *enum_definition; >>> >>> - enum_definition = lookup_enum(&stream->stream_event_header->p, "id", FALSE); >>> + enum_definition = bt_lookup_enum(&stream->stream_event_header->p, "id", FALSE); >>> if (enum_definition) { >>> id = enum_definition->integer->value._unsigned; >>> } >>> diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h >>> index b42ba03..00c928b 100644 >>> --- a/include/babeltrace/types.h >>> +++ b/include/babeltrace/types.h >>> @@ -521,7 +521,7 @@ struct definition *lookup_definition(const struct definition *definition, >>> struct definition_integer *lookup_integer(const struct definition *definition, >>> const char *field_name, >>> int signedness); >>> -struct definition_enum *lookup_enum(const struct definition *definition, >>> +struct definition_enum *bt_lookup_enum(const struct definition *definition, >>> const char *field_name, >>> int signedness); >>> struct definition *lookup_variant(const struct definition *definition, >>> diff --git a/types/types.c b/types/types.c >>> index 5599027..139e318 100644 >>> --- a/types/types.c >>> +++ b/types/types.c >>> @@ -642,7 +642,7 @@ struct definition_integer *lookup_integer(const struct definition *definition, >>> return lookup_integer; >>> } >>> >>> -struct definition_enum *lookup_enum(const struct definition *definition, >>> +struct definition_enum *bt_lookup_enum(const struct definition *definition, >>> const char *field_name, >>> int signedness) >>> { >>> -- >>> 1.7.10.4 >>> >> > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev From paulmck at linux.vnet.ibm.com Fri Jan 25 08:53:24 2013 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Fri, 25 Jan 2013 05:53:24 -0800 Subject: [lttng-dev] [PATCH] Add ACCESS_ONCE() to avoid compiler splitting assignments In-Reply-To: <20130120205131.GB19512@Krystal> References: <20130115181936.GA30319@linux.vnet.ibm.com> <20130115235642.GA31367@Krystal> <20130116125054.GA9734@Krystal> <20130119191752.GA3159@linux.vnet.ibm.com> <20130120205131.GB19512@Krystal> Message-ID: <20130125135324.GP6395@linux.vnet.ibm.com> On Sun, Jan 20, 2013 at 03:51:31PM -0500, Mathieu Desnoyers wrote: > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > On Wed, Jan 16, 2013 at 07:50:54AM -0500, Mathieu Desnoyers wrote: > > > * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > As noted by Konstantin Khlebnikov, gcc can split assignment of > > > > > constants to long variables (https://lkml.org/lkml/2013/1/15/141), > > > > > though assignment of NULL (0) is OK. Assuming that a gcc bug is > > > > > fixed (http://gcc.gnu.org/bugzilla/attachment.cgi?id=29169&action=diff > > > > > has a patch), making the store be volatile keeps gcc from splitting. > > > > > > > > > > This commit therefore applies ACCESS_ONCE() to CMM_STORE_SHARED(), > > > > > which is the underlying primitive used by rcu_assign_pointer(). > > > > > > > > Hi Paul, > > > > > > > > I recognise that this is an issue in the Linux kernel, since a simple > > > > store is used and expected to be performed atomically when aligned. > > > > However, I think this does not affect liburcu, see below: > > > > > > Side question: what gcc versions may issue non-atomic volatile stores ? > > > I think we should at least document those. Bug > > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55981 seems to target gcc > > > 4.7.2, but I wonder when this issue first appeared on x86 and x86-64 > > > (and if it affects other architectures as well). > > > > I have no idea which versions are affected. The bug is in the x86 > > backend, so is specific to x86, but there might well be similar bugs > > in other architectures. > > Results for my quick tests so far: > > gcc version 4.4.7 (Debian 4.4.7-2) > gcc version 4.6.3 (Debian 4.6.3-11) > gcc version 4.7.2 (Debian 4.7.2-5) > > for x86-64 are affected (all gcc installed currently on my Debian > laptop). I made a simpler test case than the one shown on the bugzilla, > which triggers the issue with -O0 and -O1 (-O2 and -Os optimisations > seems not to show this issue with the simpler test case). So far, it > seems to only affect stores from immediate value operands (and only some > patterns). Good to know! And more widespread than I would have guessed... For whatever it is worth, there is an alleged patch here: http://gcc.gnu.org/ml/gcc-patches/2013-01/msg01119.html > Debian clang version 3.0-6 (tags/RELEASE_30/final) (based on LLVM 3.0) > is not affected for x86-64. Heh! Good to know as well. ;-) Thanx, Paul > My test case looks like this: > > * non-atomic-pointer.c: > > volatile void *var; > > void fct(void) > { > asm volatile ("/* test_begin */" : : : "memory"); > var = (void *) 0x100000002; > var = (void *) 0x300000004; > asm volatile ("/* test_end */" : : : "memory"); > } > > > * build.sh: > > #!/bin/bash > > FLAGS="-S ${*}" > > function do_build > { > $1 ${FLAGS} -o non-atomic-pointer-$1.S.output non-atomic-pointer.c > } > > do_build gcc-4.4 > do_build gcc-4.6 > do_build gcc-4.7 > do_build gcc-4.7 > do_build g++-4.6 > do_build g++-4.7 > do_build clang > > > * check.py (might need adaptation for each architecture and O2, Os): > > #!/usr/bin/env python > > import sys, string, os, re > > # count the number of lines with "mov*" instructions between test_begin > # and test_end. Should be 2. Report error if not. > > f = open (sys.argv[1], "r") > > lines = f.readlines() > > within_range = 0 > mov_count = 0 > error = 0 > > re_mov = re.compile(' mov.*') > re_begin = re.compile('.*test_begin.*') > re_end = re.compile('.*test_end.*') > > output = "" > > for line in lines: > if re_begin.match(line): > within_range = 1 > elif re_end.match(line): > within_range = 0 > elif (within_range and re_mov.match(line)): > output += line > mov_count += 1 > > if mov_count > 2: > error = 1 > > f.close() > > if error > 0: > print "[Error] expect 2 mov, found " + str(mov_count) > print output > 1 > else: > 0 > > > > > > Thanks, > > > > > > Mathieu > > > > > > > > > > > > > > > > > Signed-off-by: Paul E. McKenney > > > > > > > > > > diff --git a/urcu/system.h b/urcu/system.h > > > > > index 2a45f22..7a1887e 100644 > > > > > --- a/urcu/system.h > > > > > +++ b/urcu/system.h > > > > > @@ -49,7 +49,7 @@ > > > > > */ > > > > > #define CMM_STORE_SHARED(x, v) \ > > > > > ({ \ > > > > > - __typeof__(x) _v = _CMM_STORE_SHARED(x, v); \ > > > > > + __typeof__(x) CMM_ACCESS_ONCE(_v) = _CMM_STORE_SHARED(x, v); \ > > > > > > > > Here, the macro "_CMM_STORE_SHARED(x, v)" is doing the actual store. > > > > It stores v into "x". So adding a CMM_ACCESS_ONCE(_v), as you propose > > > > here, is really only making sure the return value (usually unused), > > > > located on the stack, is accessed with a volatile access, which does not > > > > make much sense. > > > > > > > > What really matters is the _CMM_STORE_SHARED() macro: > > > > > > > > #define _CMM_STORE_SHARED(x, v) ({ CMM_ACCESS_ONCE(x) = (v); }) > > > > > > > > which already uses a volatile access for the store. So this seems to be > > > > a case where our preemptive use of volatile for stores in addition to > > > > loads made us bug-free for a gcc behavior unexpected at the time we > > > > implemented this macro. Just a touch of paranoia seems to be a good > > > > thing sometimes. ;-) > > > > > > > > Thoughts ? > > > > Here is my thought: You should ignore my "fix". Please accept my > > apologies for my confusion! > > No worries! Thanks for bringing this issue to my attention. > > I'm thinking we might want to create a test throwing code with random > immediate values into my python checker script, for various > architectures for a couple of weeks, and see what breaks. > > Also, it might be good to test whether some register inputs can generate > code that write into an unsigned long non-atomically. This would be even > more worrying. > > Thanks, > > Mathieu > > > > > Thanx, Paul > > > > > > Thanks, > > > > > > > > Mathieu > > > > > > > > > cmm_smp_wmc(); \ > > > > > _v; \ > > > > > }) > > > > > > > > > > > > > > > _______________________________________________ > > > > > lttng-dev mailing list > > > > > lttng-dev at lists.lttng.org > > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > > > -- > > > > Mathieu Desnoyers > > > > EfficiOS Inc. > > > > http://www.efficios.com > > > > > > > > _______________________________________________ > > > > lttng-dev mailing list > > > > lttng-dev at lists.lttng.org > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > -- > > > Mathieu Desnoyers > > > EfficiOS Inc. > > > http://www.efficios.com > > > > > > > -- > Mathieu Desnoyers > EfficiOS Inc. > http://www.efficios.com > From dgoulet at efficios.com Fri Jan 25 10:48:50 2013 From: dgoulet at efficios.com (David Goulet) Date: Fri, 25 Jan 2013 10:48:50 -0500 Subject: [lttng-dev] [PULL REQUEST lttng-tools] please pull for compudj-pull In-Reply-To: <20130124234731.GA16402@Krystal> References: <20130124234731.GA16402@Krystal> Message-ID: <5102A962.4010105@efficios.com> Merged! Note that commit ec1406acb4af789da299b4e81b3b7f5cc0057714 has been backported to stable-2.1. Thanks! Mathieu Desnoyers: > Hi David, > > Please pull from my pull branch at: > > git://git.dorsal.polymtl.ca/~compudj/lttng-tools > branch: compudj-pull > > It contains the following useful commits: > > commit 9d623b7096efbd378f566c39e4c9ab91e21fb656 > Author: Mathieu Desnoyers > Date: Thu Jan 24 18:43:48 2013 -0500 > > symbol prefixing: in-house copy of hash table > > Will ensure we don't clash with the real version in liburcu cds. It's > especially important since those symbols are exported globally by > liblttng-ctl. > > Signed-off-by: Mathieu Desnoyers > > commit ec1406acb4af789da299b4e81b3b7f5cc0057714 > Author: Mathieu Desnoyers > Date: Thu Jan 24 18:34:44 2013 -0500 > > Fix: add missing unistd.h include for fdatasync in compat-fcntl.c > > Signed-off-by: Mathieu Desnoyers > > commit 73f94c074aa293f09e526c01ed262a1751e10523 > Author: Mathieu Desnoyers > Date: Thu Jan 24 18:33:41 2013 -0500 > > namespace lttngctl filter flex/bison symbols > > Signed-off-by: Mathieu Desnoyers > > Thanks, > > Mathieu > From jeremie.galarneau at efficios.com Fri Jan 25 11:03:12 2013 From: jeremie.galarneau at efficios.com (=?ISO-8859-1?Q?J=E9r=E9mie_Galarneau?=) Date: Fri, 25 Jan 2013 16:03:12 +0000 Subject: [lttng-dev] [PATCH babeltrace 1/2] Add missing shebangs to Python examples. In-Reply-To: References: <1358898446-1622-1-git-send-email-jeremie.galarneau@efficios.com> <20130123144550.GA3952@Krystal> Message-ID: Looks like this patch will require more work since it was decided we only want to explicitly support Python3. I'll have to look into the examples and see what can be ported and fixed. I'll also work on having a more comprehensive test suite in preparation for an eventual merge into master. However, please note that the second patch from this series - [PATCH babeltrace 2/2] Fix: Unified types expected by the Definition Python interface. - will remain unchanged and should be pulled as it fixes a bug that prevented the Python iterator tests from passing. Regards, J?r?mie On Wed, Jan 23, 2013 at 5:21 PM, J?r?mie Galarneau wrote: >> I would recommend using "#!/usr/bin/env python" so it will default to >> the Python interpreter available on the machine. Take note that we >> might have issues with Python 3 interpreters if the scripts are not >> fully compliant. > > It does seem like some of the example scripts are not Python 3 > compatible. However, forcing the use of Python 2 on distros wich use > Python 3 as the default interpreter is far from ideal... I'll see if I > can make them version agnostic before resubmitting. > > Thanks, > J?r?mie From mathieu.desnoyers at efficios.com Fri Jan 25 11:39:22 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 25 Jan 2013 11:39:22 -0500 Subject: [lttng-dev] [PATCH babeltrace 2/2] Fix: Unified types expected by the Definition Python interface. In-Reply-To: <1358898446-1622-2-git-send-email-jeremie.galarneau@efficios.com> References: <1358898446-1622-1-git-send-email-jeremie.galarneau@efficios.com> <1358898446-1622-2-git-send-email-jeremie.galarneau@efficios.com> Message-ID: <20130125163922.GA32661@Krystal> * J?r?mie Galarneau (jeremie.galarneau at efficios.com) wrote: > This change makes the Python iterator test case execute successfully. merged, thanks! Mathieu > > Signed-off-by: J?r?mie Galarneau > --- > bindings/python/babeltrace.i.in | 23 +++++++++++++---------- > 1 file changed, 13 insertions(+), 10 deletions(-) > > diff --git a/bindings/python/babeltrace.i.in b/bindings/python/babeltrace.i.in > index dd49ba5..a5426c8 100644 > --- a/bindings/python/babeltrace.i.in > +++ b/bindings/python/babeltrace.i.in > @@ -553,8 +553,8 @@ struct bt_ctf_event *bt_ctf_iter_read_event(struct bt_ctf_iter *iter); > const struct definition *scope, const char *field); > %rename("_bt_ctf_get_index") bt_ctf_get_index(const struct bt_ctf_event *ctf_event, > const struct definition *field, unsigned int index); > -%rename("_bt_ctf_field_name") bt_ctf_field_name(const struct definition *def); > -%rename("_bt_ctf_field_type") bt_ctf_field_type(const struct declaration *def); > +%rename("_bt_ctf_field_name") bt_ctf_field_name(const struct definition *field); > +%rename("_bt_ctf_field_type") bt_ctf_field_type(const struct declaration *field); > %rename("_bt_ctf_get_int_signedness") bt_ctf_get_int_signedness( > const struct declaration *field); > %rename("_bt_ctf_get_int_base") bt_ctf_get_int_base(const struct declaration *field); > @@ -572,6 +572,8 @@ struct bt_ctf_event *bt_ctf_iter_read_event(struct bt_ctf_iter *iter); > bt_ctf_event_decl *event); > %rename("_bt_ctf_get_decl_field_name") bt_ctf_get_decl_field_name( > const struct bt_ctf_field_decl *field); > +%rename("_bt_ctf_get_decl_from_def") bt_ctf_get_decl_from_def( > + const struct definition *field); > > const struct definition *bt_ctf_get_top_level_scope(const struct bt_ctf_event *ctf_event, > enum bt_ctf_scope scope); > @@ -584,8 +586,8 @@ const struct definition *bt_ctf_get_field(const struct bt_ctf_event *ctf_event, > const struct definition *bt_ctf_get_index(const struct bt_ctf_event *ctf_event, > const struct definition *field, > unsigned int index); > -const char *bt_ctf_field_name(const struct definition *def); > -enum ctf_type_id bt_ctf_field_type(const struct declaration *def); > +const char *bt_ctf_field_name(const struct definition *field); > +enum ctf_type_id bt_ctf_field_type(const struct declaration *field); > int bt_ctf_get_int_signedness(const struct declaration *field); > int bt_ctf_get_int_base(const struct declaration *field); > int bt_ctf_get_int_byte_order(const struct declaration *field); > @@ -599,6 +601,7 @@ char *bt_ctf_get_string(const struct definition *field); > int bt_ctf_field_get_error(void); > const char *bt_ctf_get_decl_event_name(const struct bt_ctf_event_decl *event); > const char *bt_ctf_get_decl_field_name(const struct bt_ctf_field_decl *field); > +const struct declaration *bt_ctf_get_decl_from_def(const struct definition *field); > > %pythoncode%{ > > @@ -839,25 +842,25 @@ class ctf: > > def field_type(self): > """Return the type of a field or -1 if unknown.""" > - return _bt_ctf_field_type(self._d) > + return _bt_ctf_field_type(_bt_ctf_get_decl_from_def(self._d)) > > def get_int_signedness(self): > """ > Return the signedness of an integer: > 0 if unsigned; 1 if signed; -1 on error. > """ > - return _bt_ctf_get_int_signedness(self._d) > + return _bt_ctf_get_int_signedness(_bt_ctf_get_decl_from_def(self._d)) > > def get_int_base(self): > """Return the base of an int or a negative value on error.""" > - return _bt_ctf_get_int_base(self._d) > + return _bt_ctf_get_int_base(_bt_ctf_get_decl_from_def(self._d)) > > def get_int_byte_order(self): > """ > Return the byte order of an int or a negative > value on error. > """ > - return _bt_ctf_get_int_byte_order(self._d) > + return _bt_ctf_get_int_byte_order(_bt_ctf_get_decl_from_def(self._d)) > > def get_int_len(self): > """ > @@ -871,14 +874,14 @@ class ctf: > Return the encoding of an int or a string. > Return a negative value on error. > """ > - return _bt_ctf_get_encoding(self._d) > + return _bt_ctf_get_encoding(_bt_ctf_get_decl_from_def(self._d)) > > def get_array_len(self): > """ > Return the len of an array or a negative > value on error. > """ > - return _bt_ctf_get_array_len(self._d) > + return _bt_ctf_get_array_len(_bt_ctf_get_decl_from_def(self._d)) > > def get_uint64(self): > """ > -- > 1.8.1.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Fri Jan 25 12:24:48 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 25 Jan 2013 12:24:48 -0500 Subject: [lttng-dev] LTTng: global_dirty_limit symbol lookup failed Message-ID: <20130125172448.GA694@Krystal> Hi Andrew, Commit: commit b87700e318c27267890cbd6fb5e50b687279131b Author: Andrew Gabbasov Date: Mon Dec 10 11:14:52 2012 -0500 Add new kernel probes instrumentation Add kernel probes for btrfs, compaction, ext4, printk, random, rcu, regmap, rpm, sunrpc, workqueue, writeback. Signed-off-by: Andrew Gabbasov Signed-off-by: Mathieu Desnoyers has 2 issues: 1) it implements a wrapper around global_dirty_limit() in probes/. All wrappers should be in /wrapper/, without exception, otherwise the code will quickly become unmaintainable (we need to know what wrappers we can eventually remove if we remove support for older kernels in the future, and we need to be aware of those wrappers for complete testing coverage). I have no problem with having a probes/Makefile using a relative path (e.g. ../wrapper/somefile.o) as input if needed. 2) It fills my dmesg log output with: "LTTng: global_dirty_limit symbol lookup failed." messages. .config follows. Can you look into those issues ? Thanks, Mathieu A Debian kernel: Linux thinkos 3.5-trunk-amd64 #1 SMP Mon Aug 20 04:17:46 UTC 2012 x86_64 GNU/Linux Here is its .config: # # Automatically generated file; DO NOT EDIT. # Linux/x86 3.5.2 Kernel Configuration # CONFIG_64BIT=y # CONFIG_X86_32 is not set CONFIG_X86_64=y CONFIG_X86=y CONFIG_INSTRUCTION_DECODER=y CONFIG_OUTPUT_FORMAT="elf64-x86-64" CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig" CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_MMU=y CONFIG_NEED_DMA_MAP_STATE=y CONFIG_NEED_SG_DMA_LENGTH=y CONFIG_GENERIC_ISA_DMA=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_GPIO=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y # CONFIG_RWSEM_GENERIC_SPINLOCK is not set CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_ARCH_HAS_CPU_RELAX=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y CONFIG_ARCH_HAS_CPU_AUTOPROBE=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ZONE_DMA32=y CONFIG_AUDIT_ARCH=y CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y CONFIG_HAVE_INTEL_TXT=y CONFIG_X86_64_SMP=y CONFIG_X86_HT=y CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" CONFIG_ARCH_CPU_PROBE_RELEASE=y CONFIG_ARCH_SUPPORTS_UPROBES=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_HAVE_IRQ_WORK=y CONFIG_IRQ_WORK=y CONFIG_BUILDTIME_EXTABLE_SORT=y # # General setup # CONFIG_EXPERIMENTAL=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_CROSS_COMPILE="" CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y CONFIG_HAVE_KERNEL_XZ=y CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set # CONFIG_KERNEL_XZ is not set # CONFIG_KERNEL_LZO is not set CONFIG_DEFAULT_HOSTNAME="(none)" CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_FHANDLE=y CONFIG_TASKSTATS=y CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y CONFIG_AUDIT=y CONFIG_AUDITSYSCALL=y CONFIG_AUDIT_WATCH=y CONFIG_AUDIT_TREE=y # CONFIG_AUDIT_LOGINUID_IMMUTABLE is not set CONFIG_HAVE_GENERIC_HARDIRQS=y # # IRQ subsystem # CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_IRQ_SHOW=y CONFIG_GENERIC_PENDING_IRQ=y CONFIG_GENERIC_IRQ_CHIP=y CONFIG_IRQ_FORCED_THREADING=y CONFIG_SPARSE_IRQ=y CONFIG_CLOCKSOURCE_WATCHDOG=y CONFIG_ARCH_CLOCKSOURCE_DATA=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CLOCKEVENTS_BUILD=y CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y CONFIG_GENERIC_CMOS_UPDATE=y # # Timers subsystem # CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y # # RCU Subsystem # CONFIG_TREE_RCU=y # CONFIG_PREEMPT_RCU is not set CONFIG_RCU_FANOUT=64 CONFIG_RCU_FANOUT_LEAF=16 # CONFIG_RCU_FANOUT_EXACT is not set CONFIG_RCU_FAST_NO_HZ=y # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=17 CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y CONFIG_CGROUPS=y # CONFIG_CGROUP_DEBUG is not set CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_DEVICE=y CONFIG_CPUSETS=y CONFIG_PROC_PID_CPUSET=y CONFIG_CGROUP_CPUACCT=y CONFIG_RESOURCE_COUNTERS=y CONFIG_CGROUP_MEM_RES_CTLR=y CONFIG_CGROUP_MEM_RES_CTLR_DISABLED=y CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y # CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED is not set # CONFIG_CGROUP_MEM_RES_CTLR_KMEM is not set CONFIG_CGROUP_PERF=y CONFIG_CGROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y # CONFIG_CFS_BANDWIDTH is not set # CONFIG_RT_GROUP_SCHED is not set CONFIG_BLK_CGROUP=y # CONFIG_DEBUG_BLK_CGROUP is not set # CONFIG_CHECKPOINT_RESTORE is not set CONFIG_NAMESPACES=y CONFIG_UTS_NS=y CONFIG_IPC_NS=y CONFIG_PID_NS=y CONFIG_NET_NS=y CONFIG_SCHED_AUTOGROUP=y CONFIG_MM_OWNER=y # CONFIG_SYSFS_DEPRECATED is not set CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y CONFIG_RD_BZIP2=y CONFIG_RD_LZMA=y CONFIG_RD_XZ=y CONFIG_RD_LZO=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y # CONFIG_EXPERT is not set CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_PCSPKR_PLATFORM=y CONFIG_HAVE_PCSPKR_PLATFORM=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y # CONFIG_EMBEDDED is not set CONFIG_HAVE_PERF_EVENTS=y # # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y # CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y # CONFIG_COMPAT_BRK is not set CONFIG_SLAB=y # CONFIG_SLUB is not set CONFIG_PROFILING=y CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=m # CONFIG_OPROFILE_EVENT_MULTIPLEX is not set CONFIG_HAVE_OPROFILE=y CONFIG_OPROFILE_NMI_TIMER=y CONFIG_KPROBES=y # CONFIG_JUMP_LABEL is not set CONFIG_OPTPROBES=y CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y CONFIG_KRETPROBES=y CONFIG_USER_RETURN_NOTIFIER=y CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_OPTPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_USE_GENERIC_SMP_HELPERS=y CONFIG_GENERIC_SMP_IDLE_THREAD=y CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y CONFIG_HAVE_DMA_API_DEBUG=y CONFIG_HAVE_HW_BREAKPOINT=y CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y CONFIG_HAVE_USER_RETURN_NOTIFIER=y CONFIG_HAVE_PERF_EVENTS_NMI=y CONFIG_HAVE_ARCH_JUMP_LABEL=y CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y CONFIG_HAVE_CMPXCHG_LOCAL=y CONFIG_HAVE_CMPXCHG_DOUBLE=y CONFIG_ARCH_WANT_OLD_COMPAT_IPC=y CONFIG_HAVE_ARCH_SECCOMP_FILTER=y CONFIG_SECCOMP_FILTER=y # # GCOV-based kernel profiling # # CONFIG_GCOV_KERNEL is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_FORCE_LOAD=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_STOP_MACHINE=y CONFIG_BLOCK=y CONFIG_BLK_DEV_BSG=y CONFIG_BLK_DEV_BSGLIB=y CONFIG_BLK_DEV_INTEGRITY=y # CONFIG_BLK_DEV_THROTTLING is not set # # Partition Types # CONFIG_PARTITION_ADVANCED=y CONFIG_ACORN_PARTITION=y # CONFIG_ACORN_PARTITION_CUMANA is not set # CONFIG_ACORN_PARTITION_EESOX is not set CONFIG_ACORN_PARTITION_ICS=y # CONFIG_ACORN_PARTITION_ADFS is not set # CONFIG_ACORN_PARTITION_POWERTEC is not set CONFIG_ACORN_PARTITION_RISCIX=y CONFIG_OSF_PARTITION=y CONFIG_AMIGA_PARTITION=y CONFIG_ATARI_PARTITION=y CONFIG_MAC_PARTITION=y CONFIG_MSDOS_PARTITION=y CONFIG_BSD_DISKLABEL=y CONFIG_MINIX_SUBPARTITION=y CONFIG_SOLARIS_X86_PARTITION=y CONFIG_UNIXWARE_DISKLABEL=y CONFIG_LDM_PARTITION=y # CONFIG_LDM_DEBUG is not set CONFIG_SGI_PARTITION=y CONFIG_ULTRIX_PARTITION=y CONFIG_SUN_PARTITION=y CONFIG_KARMA_PARTITION=y CONFIG_EFI_PARTITION=y # CONFIG_SYSV68_PARTITION is not set CONFIG_BLOCK_COMPAT=y # # IO Schedulers # CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y CONFIG_CFQ_GROUP_IOSCHED=y # CONFIG_DEFAULT_DEADLINE is not set CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" CONFIG_PREEMPT_NOTIFIERS=y CONFIG_PADATA=y # CONFIG_INLINE_SPIN_TRYLOCK is not set # CONFIG_INLINE_SPIN_TRYLOCK_BH is not set # CONFIG_INLINE_SPIN_LOCK is not set # CONFIG_INLINE_SPIN_LOCK_BH is not set # CONFIG_INLINE_SPIN_LOCK_IRQ is not set # CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set # CONFIG_INLINE_SPIN_UNLOCK_BH is not set CONFIG_INLINE_SPIN_UNLOCK_IRQ=y # CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set # CONFIG_INLINE_READ_TRYLOCK is not set # CONFIG_INLINE_READ_LOCK is not set # CONFIG_INLINE_READ_LOCK_BH is not set # CONFIG_INLINE_READ_LOCK_IRQ is not set # CONFIG_INLINE_READ_LOCK_IRQSAVE is not set CONFIG_INLINE_READ_UNLOCK=y # CONFIG_INLINE_READ_UNLOCK_BH is not set CONFIG_INLINE_READ_UNLOCK_IRQ=y # CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set # CONFIG_INLINE_WRITE_TRYLOCK is not set # CONFIG_INLINE_WRITE_LOCK is not set # CONFIG_INLINE_WRITE_LOCK_BH is not set # CONFIG_INLINE_WRITE_LOCK_IRQ is not set # CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set CONFIG_INLINE_WRITE_UNLOCK=y # CONFIG_INLINE_WRITE_UNLOCK_BH is not set CONFIG_INLINE_WRITE_UNLOCK_IRQ=y # CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set CONFIG_MUTEX_SPIN_ON_OWNER=y CONFIG_FREEZER=y # # Processor type and features # CONFIG_ZONE_DMA=y CONFIG_SMP=y CONFIG_X86_X2APIC=y CONFIG_X86_MPPARSE=y # CONFIG_X86_EXTENDED_PLATFORM is not set CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y CONFIG_SCHED_OMIT_FRAME_POINTER=y CONFIG_PARAVIRT_GUEST=y # CONFIG_PARAVIRT_TIME_ACCOUNTING is not set CONFIG_XEN=y CONFIG_XEN_DOM0=y CONFIG_XEN_PRIVILEGED_GUEST=y CONFIG_XEN_PVHVM=y CONFIG_XEN_MAX_DOMAIN_MEMORY=500 CONFIG_XEN_SAVE_RESTORE=y # CONFIG_XEN_DEBUG_FS is not set CONFIG_KVM_CLOCK=y CONFIG_KVM_GUEST=y CONFIG_PARAVIRT=y # CONFIG_PARAVIRT_SPINLOCKS is not set CONFIG_PARAVIRT_CLOCK=y # CONFIG_PARAVIRT_DEBUG is not set CONFIG_NO_BOOTMEM=y CONFIG_MEMTEST=y # CONFIG_MK8 is not set # CONFIG_MPSC is not set # CONFIG_MCORE2 is not set # CONFIG_MATOM is not set CONFIG_GENERIC_CPU=y CONFIG_X86_INTERNODE_CACHE_SHIFT=6 CONFIG_X86_CMPXCHG=y CONFIG_X86_L1_CACHE_SHIFT=6 CONFIG_X86_XADD=y CONFIG_X86_WP_WORKS_OK=y CONFIG_X86_TSC=y CONFIG_X86_CMPXCHG64=y CONFIG_X86_CMOV=y CONFIG_X86_MINIMUM_CPU_FAMILY=64 CONFIG_X86_DEBUGCTLMSR=y CONFIG_CPU_SUP_INTEL=y CONFIG_CPU_SUP_AMD=y CONFIG_CPU_SUP_CENTAUR=y CONFIG_HPET_TIMER=y CONFIG_HPET_EMULATE_RTC=y CONFIG_DMI=y CONFIG_GART_IOMMU=y CONFIG_CALGARY_IOMMU=y CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y CONFIG_SWIOTLB=y CONFIG_IOMMU_HELPER=y # CONFIG_MAXSMP is not set CONFIG_NR_CPUS=512 CONFIG_SCHED_SMT=y CONFIG_SCHED_MC=y # CONFIG_IRQ_TIME_ACCOUNTING is not set # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y CONFIG_X86_MCE=y CONFIG_X86_MCE_INTEL=y CONFIG_X86_MCE_AMD=y CONFIG_X86_MCE_THRESHOLD=y CONFIG_X86_MCE_INJECT=m CONFIG_X86_THERMAL_VECTOR=y CONFIG_I8K=m CONFIG_MICROCODE=m CONFIG_MICROCODE_INTEL=y CONFIG_MICROCODE_AMD=y CONFIG_MICROCODE_OLD_INTERFACE=y CONFIG_X86_MSR=m CONFIG_X86_CPUID=m CONFIG_ARCH_PHYS_ADDR_T_64BIT=y CONFIG_ARCH_DMA_ADDR_T_64BIT=y CONFIG_DIRECT_GBPAGES=y CONFIG_NUMA=y CONFIG_AMD_NUMA=y CONFIG_X86_64_ACPI_NUMA=y CONFIG_NODES_SPAN_OTHER_NODES=y CONFIG_NUMA_EMU=y CONFIG_NODES_SHIFT=6 CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_MEMORY_PROBE=y CONFIG_ARCH_PROC_KCORE_TEXT=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_SELECT_MEMORY_MODEL=y CONFIG_SPARSEMEM_MANUAL=y CONFIG_SPARSEMEM=y CONFIG_NEED_MULTIPLE_NODES=y CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y CONFIG_SPARSEMEM_VMEMMAP=y CONFIG_HAVE_MEMBLOCK=y CONFIG_HAVE_MEMBLOCK_NODE_MAP=y CONFIG_ARCH_DISCARD_MEMBLOCK=y CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTPLUG_SPARSE=y CONFIG_MEMORY_HOTREMOVE=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_COMPACTION=y CONFIG_MIGRATION=y CONFIG_PHYS_ADDR_T_64BIT=y CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y CONFIG_MMU_NOTIFIER=y CONFIG_KSM=y CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y CONFIG_MEMORY_FAILURE=y CONFIG_HWPOISON_INJECT=m CONFIG_TRANSPARENT_HUGEPAGE=y # CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS is not set CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y CONFIG_CROSS_MEMORY_ATTACH=y # CONFIG_CLEANCACHE is not set # CONFIG_FRONTSWAP is not set # CONFIG_X86_CHECK_BIOS_CORRUPTION is not set CONFIG_X86_RESERVE_LOW=64 CONFIG_MTRR=y CONFIG_MTRR_SANITIZER=y CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0 CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1 CONFIG_X86_PAT=y CONFIG_ARCH_USES_PG_UNCACHED=y CONFIG_ARCH_RANDOM=y CONFIG_EFI=y CONFIG_EFI_STUB=y CONFIG_SECCOMP=y CONFIG_CC_STACKPROTECTOR=y # CONFIG_HZ_100 is not set CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 CONFIG_SCHED_HRTICK=y CONFIG_KEXEC=y CONFIG_CRASH_DUMP=y # CONFIG_KEXEC_JUMP is not set CONFIG_PHYSICAL_START=0x1000000 CONFIG_RELOCATABLE=y CONFIG_PHYSICAL_ALIGN=0x1000000 CONFIG_HOTPLUG_CPU=y # CONFIG_COMPAT_VDSO is not set # CONFIG_CMDLINE_BOOL is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_USE_PERCPU_NUMA_NODE_ID=y # # Power management and ACPI options # CONFIG_ARCH_HIBERNATION_HEADER=y CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y CONFIG_HIBERNATE_CALLBACKS=y CONFIG_HIBERNATION=y CONFIG_PM_STD_PARTITION="" CONFIG_PM_SLEEP=y CONFIG_PM_SLEEP_SMP=y # CONFIG_PM_AUTOSLEEP is not set # CONFIG_PM_WAKELOCKS is not set CONFIG_PM_RUNTIME=y CONFIG_PM=y CONFIG_PM_DEBUG=y CONFIG_PM_ADVANCED_DEBUG=y # CONFIG_PM_TEST_SUSPEND is not set CONFIG_CAN_PM_TRACE=y # CONFIG_PM_TRACE_RTC is not set CONFIG_ACPI=y CONFIG_ACPI_SLEEP=y # CONFIG_ACPI_PROCFS is not set # CONFIG_ACPI_PROCFS_POWER is not set # CONFIG_ACPI_EC_DEBUGFS is not set # CONFIG_ACPI_PROC_EVENT is not set CONFIG_ACPI_AC=m CONFIG_ACPI_BATTERY=m CONFIG_ACPI_BUTTON=m CONFIG_ACPI_VIDEO=m CONFIG_ACPI_FAN=m CONFIG_ACPI_DOCK=y CONFIG_ACPI_PROCESSOR=m CONFIG_ACPI_IPMI=m CONFIG_ACPI_HOTPLUG_CPU=y CONFIG_ACPI_PROCESSOR_AGGREGATOR=m CONFIG_ACPI_THERMAL=m CONFIG_ACPI_NUMA=y # CONFIG_ACPI_CUSTOM_DSDT is not set CONFIG_ACPI_BLACKLIST_YEAR=0 # CONFIG_ACPI_DEBUG is not set CONFIG_ACPI_PCI_SLOT=m CONFIG_X86_PM_TIMER=y CONFIG_ACPI_CONTAINER=m CONFIG_ACPI_HOTPLUG_MEMORY=m CONFIG_ACPI_SBS=m CONFIG_ACPI_HED=y # CONFIG_ACPI_CUSTOM_METHOD is not set # CONFIG_ACPI_BGRT is not set CONFIG_ACPI_APEI=y CONFIG_ACPI_APEI_GHES=y CONFIG_ACPI_APEI_PCIEAER=y CONFIG_ACPI_APEI_MEMORY_FAILURE=y # CONFIG_ACPI_APEI_EINJ is not set # CONFIG_ACPI_APEI_ERST_DEBUG is not set CONFIG_SFI=y # # CPU Frequency scaling # CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_TABLE=y CONFIG_CPU_FREQ_STAT=m # CONFIG_CPU_FREQ_STAT_DETAILS is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=m CONFIG_CPU_FREQ_GOV_USERSPACE=m CONFIG_CPU_FREQ_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m # # x86 CPU frequency scaling drivers # CONFIG_X86_PCC_CPUFREQ=m CONFIG_X86_ACPI_CPUFREQ=m CONFIG_X86_POWERNOW_K8=m CONFIG_X86_SPEEDSTEP_CENTRINO=m CONFIG_X86_P4_CLOCKMOD=m # # shared options # CONFIG_X86_SPEEDSTEP_LIB=m CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE_GOV_LADDER=y CONFIG_CPU_IDLE_GOV_MENU=y CONFIG_INTEL_IDLE=y # # Memory power savings # CONFIG_I7300_IDLE_IOAT_CHANNEL=y CONFIG_I7300_IDLE=m # # Bus options (PCI etc.) # CONFIG_PCI=y CONFIG_PCI_DIRECT=y CONFIG_PCI_MMCONFIG=y CONFIG_PCI_XEN=y CONFIG_PCI_DOMAINS=y # CONFIG_PCI_CNB20LE_QUIRK is not set CONFIG_PCIEPORTBUS=y CONFIG_HOTPLUG_PCI_PCIE=y CONFIG_PCIEAER=y # CONFIG_PCIE_ECRC is not set CONFIG_PCIEAER_INJECT=m CONFIG_PCIEASPM=y # CONFIG_PCIEASPM_DEBUG is not set CONFIG_PCIEASPM_DEFAULT=y # CONFIG_PCIEASPM_POWERSAVE is not set # CONFIG_PCIEASPM_PERFORMANCE is not set CONFIG_PCIE_PME=y CONFIG_ARCH_SUPPORTS_MSI=y CONFIG_PCI_MSI=y # CONFIG_PCI_DEBUG is not set # CONFIG_PCI_REALLOC_ENABLE_AUTO is not set CONFIG_PCI_STUB=m CONFIG_XEN_PCIDEV_FRONTEND=m CONFIG_HT_IRQ=y CONFIG_PCI_ATS=y CONFIG_PCI_IOV=y CONFIG_PCI_PRI=y CONFIG_PCI_PASID=y # CONFIG_PCI_IOAPIC is not set CONFIG_PCI_LABEL=y CONFIG_ISA_DMA_API=y CONFIG_AMD_NB=y CONFIG_PCCARD=m CONFIG_PCMCIA=m CONFIG_PCMCIA_LOAD_CIS=y CONFIG_CARDBUS=y # # PC-card bridges # CONFIG_YENTA=m CONFIG_YENTA_O2=y CONFIG_YENTA_RICOH=y CONFIG_YENTA_TI=y CONFIG_YENTA_ENE_TUNE=y CONFIG_YENTA_TOSHIBA=y CONFIG_PD6729=m CONFIG_I82092=m CONFIG_PCCARD_NONSTATIC=y CONFIG_HOTPLUG_PCI=y CONFIG_HOTPLUG_PCI_FAKE=m CONFIG_HOTPLUG_PCI_ACPI=y CONFIG_HOTPLUG_PCI_ACPI_IBM=m CONFIG_HOTPLUG_PCI_CPCI=y CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m CONFIG_HOTPLUG_PCI_SHPC=m # CONFIG_RAPIDIO is not set # # Executable file formats / Emulations # CONFIG_BINFMT_ELF=y CONFIG_COMPAT_BINFMT_ELF=y CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y # CONFIG_HAVE_AOUT is not set CONFIG_BINFMT_MISC=m CONFIG_IA32_EMULATION=y CONFIG_IA32_AOUT=y # CONFIG_X86_X32 is not set CONFIG_COMPAT=y CONFIG_COMPAT_FOR_U64_ALIGNMENT=y CONFIG_SYSVIPC_COMPAT=y CONFIG_KEYS_COMPAT=y CONFIG_HAVE_TEXT_POKE_SMP=y CONFIG_X86_DEV_DMA_OPS=y CONFIG_NET=y CONFIG_COMPAT_NETLINK_MESSAGES=y # # Networking options # CONFIG_PACKET=y CONFIG_UNIX=y # CONFIG_UNIX_DIAG is not set CONFIG_XFRM=y CONFIG_XFRM_ALGO=m CONFIG_XFRM_USER=m CONFIG_XFRM_SUB_POLICY=y CONFIG_XFRM_MIGRATE=y # CONFIG_XFRM_STATISTICS is not set CONFIG_XFRM_IPCOMP=m CONFIG_NET_KEY=m CONFIG_NET_KEY_MIGRATE=y CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_FIB_TRIE_STATS=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_MULTIPATH=y CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_ROUTE_CLASSID=y # CONFIG_IP_PNP is not set CONFIG_NET_IPIP=m CONFIG_NET_IPGRE_DEMUX=m CONFIG_NET_IPGRE=m CONFIG_NET_IPGRE_BROADCAST=y CONFIG_IP_MROUTE=y CONFIG_IP_MROUTE_MULTIPLE_TABLES=y CONFIG_IP_PIMSM_V1=y CONFIG_IP_PIMSM_V2=y # CONFIG_ARPD is not set CONFIG_SYN_COOKIES=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_TUNNEL=m CONFIG_INET_TUNNEL=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m CONFIG_INET_LRO=m CONFIG_INET_DIAG=m CONFIG_INET_TCP_DIAG=m # CONFIG_INET_UDP_DIAG is not set CONFIG_TCP_CONG_ADVANCED=y CONFIG_TCP_CONG_BIC=m CONFIG_TCP_CONG_CUBIC=y CONFIG_TCP_CONG_WESTWOOD=m CONFIG_TCP_CONG_HTCP=m CONFIG_TCP_CONG_HSTCP=m CONFIG_TCP_CONG_HYBLA=m CONFIG_TCP_CONG_VEGAS=m CONFIG_TCP_CONG_SCALABLE=m CONFIG_TCP_CONG_LP=m CONFIG_TCP_CONG_VENO=m CONFIG_TCP_CONG_YEAH=m CONFIG_TCP_CONG_ILLINOIS=m CONFIG_DEFAULT_CUBIC=y # CONFIG_DEFAULT_RENO is not set CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_TCP_MD5SIG=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTE_INFO=y CONFIG_IPV6_OPTIMISTIC_DAD=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m CONFIG_IPV6_MIP6=y CONFIG_INET6_XFRM_TUNNEL=m CONFIG_INET6_TUNNEL=m CONFIG_INET6_XFRM_MODE_TRANSPORT=m CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y CONFIG_IPV6_PIMSM_V2=y # CONFIG_NETLABEL is not set CONFIG_NETWORK_SECMARK=y # CONFIG_NETWORK_PHY_TIMESTAMPING is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set CONFIG_NETFILTER_ADVANCED=y CONFIG_BRIDGE_NETFILTER=y # # Core Netfilter Configuration # CONFIG_NETFILTER_NETLINK=m CONFIG_NETFILTER_NETLINK_ACCT=m CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NETFILTER_NETLINK_LOG=m CONFIG_NF_CONNTRACK=m CONFIG_NF_CONNTRACK_MARK=y CONFIG_NF_CONNTRACK_SECMARK=y CONFIG_NF_CONNTRACK_ZONES=y CONFIG_NF_CONNTRACK_PROCFS=y CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CONNTRACK_TIMEOUT=y CONFIG_NF_CONNTRACK_TIMESTAMP=y CONFIG_NF_CT_PROTO_DCCP=m CONFIG_NF_CT_PROTO_GRE=m CONFIG_NF_CT_PROTO_SCTP=m CONFIG_NF_CT_PROTO_UDPLITE=m CONFIG_NF_CONNTRACK_AMANDA=m CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m CONFIG_NF_CONNTRACK_IRC=m CONFIG_NF_CONNTRACK_BROADCAST=m CONFIG_NF_CONNTRACK_NETBIOS_NS=m CONFIG_NF_CONNTRACK_SNMP=m CONFIG_NF_CONNTRACK_PPTP=m CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_CT_NETLINK=m CONFIG_NF_CT_NETLINK_TIMEOUT=m CONFIG_NETFILTER_TPROXY=m CONFIG_NETFILTER_XTABLES=m # # Xtables combined modules # CONFIG_NETFILTER_XT_MARK=m CONFIG_NETFILTER_XT_CONNMARK=m CONFIG_NETFILTER_XT_SET=m # # Xtables targets # CONFIG_NETFILTER_XT_TARGET_AUDIT=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m CONFIG_NETFILTER_XT_TARGET_CT=m CONFIG_NETFILTER_XT_TARGET_DSCP=m CONFIG_NETFILTER_XT_TARGET_HL=m # CONFIG_NETFILTER_XT_TARGET_HMARK is not set CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m CONFIG_NETFILTER_XT_TARGET_LED=m CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m CONFIG_NETFILTER_XT_TARGET_NOTRACK=m CONFIG_NETFILTER_XT_TARGET_RATEEST=m CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_SECMARK=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m # # Xtables matches # CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m CONFIG_NETFILTER_XT_MATCH_CLUSTER=m CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m CONFIG_NETFILTER_XT_MATCH_CPU=m CONFIG_NETFILTER_XT_MATCH_DCCP=m CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ECN=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m CONFIG_NETFILTER_XT_MATCH_HELPER=m CONFIG_NETFILTER_XT_MATCH_HL=m CONFIG_NETFILTER_XT_MATCH_IPRANGE=m CONFIG_NETFILTER_XT_MATCH_IPVS=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m CONFIG_NETFILTER_XT_MATCH_NFACCT=m CONFIG_NETFILTER_XT_MATCH_OSF=m CONFIG_NETFILTER_XT_MATCH_OWNER=m CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m CONFIG_NETFILTER_XT_MATCH_QUOTA=m CONFIG_NETFILTER_XT_MATCH_RATEEST=m CONFIG_NETFILTER_XT_MATCH_REALM=m CONFIG_NETFILTER_XT_MATCH_RECENT=m CONFIG_NETFILTER_XT_MATCH_SCTP=m CONFIG_NETFILTER_XT_MATCH_SOCKET=m CONFIG_NETFILTER_XT_MATCH_STATE=m CONFIG_NETFILTER_XT_MATCH_STATISTIC=m CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m CONFIG_IP_SET=m CONFIG_IP_SET_MAX=256 CONFIG_IP_SET_BITMAP_IP=m CONFIG_IP_SET_BITMAP_IPMAC=m CONFIG_IP_SET_BITMAP_PORT=m CONFIG_IP_SET_HASH_IP=m CONFIG_IP_SET_HASH_IPPORT=m CONFIG_IP_SET_HASH_IPPORTIP=m CONFIG_IP_SET_HASH_IPPORTNET=m CONFIG_IP_SET_HASH_NET=m CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_LIST_SET=m CONFIG_IP_VS=m CONFIG_IP_VS_IPV6=y # CONFIG_IP_VS_DEBUG is not set CONFIG_IP_VS_TAB_BITS=12 # # IPVS transport protocol load balancing support # CONFIG_IP_VS_PROTO_TCP=y CONFIG_IP_VS_PROTO_UDP=y CONFIG_IP_VS_PROTO_AH_ESP=y CONFIG_IP_VS_PROTO_ESP=y CONFIG_IP_VS_PROTO_AH=y CONFIG_IP_VS_PROTO_SCTP=y # # IPVS scheduler # CONFIG_IP_VS_RR=m CONFIG_IP_VS_WRR=m CONFIG_IP_VS_LC=m CONFIG_IP_VS_WLC=m CONFIG_IP_VS_LBLC=m CONFIG_IP_VS_LBLCR=m CONFIG_IP_VS_DH=m CONFIG_IP_VS_SH=m CONFIG_IP_VS_SED=m CONFIG_IP_VS_NQ=m # # IPVS SH scheduler # CONFIG_IP_VS_SH_TAB_BITS=8 # # IPVS application helper # CONFIG_IP_VS_FTP=m CONFIG_IP_VS_NFCT=y CONFIG_IP_VS_PE_SIP=m # # IP: Netfilter Configuration # CONFIG_NF_DEFRAG_IPV4=m CONFIG_NF_CONNTRACK_IPV4=m CONFIG_NF_CONNTRACK_PROC_COMPAT=y CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_RPFILTER=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_ULOG=m CONFIG_NF_NAT=m CONFIG_NF_NAT_NEEDED=y CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_NF_NAT_PROTO_DCCP=m CONFIG_NF_NAT_PROTO_GRE=m CONFIG_NF_NAT_PROTO_UDPLITE=m CONFIG_NF_NAT_PROTO_SCTP=m CONFIG_NF_NAT_FTP=m CONFIG_NF_NAT_IRC=m CONFIG_NF_NAT_TFTP=m CONFIG_NF_NAT_AMANDA=m CONFIG_NF_NAT_PPTP=m CONFIG_NF_NAT_H323=m CONFIG_NF_NAT_SIP=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m CONFIG_IP_NF_RAW=m CONFIG_IP_NF_SECURITY=m CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m # # IPv6: Netfilter Configuration # CONFIG_NF_DEFRAG_IPV6=m CONFIG_NF_CONNTRACK_IPV6=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m CONFIG_IP6_NF_MATCH_FRAG=m CONFIG_IP6_NF_MATCH_OPTS=m CONFIG_IP6_NF_MATCH_HL=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m CONFIG_IP6_NF_MATCH_MH=m CONFIG_IP6_NF_MATCH_RPFILTER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_TARGET_HL=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m CONFIG_IP6_NF_SECURITY=m # # DECnet: Netfilter Configuration # CONFIG_DECNET_NF_GRABULATOR=m CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m CONFIG_BRIDGE_EBT_T_FILTER=m CONFIG_BRIDGE_EBT_T_NAT=m CONFIG_BRIDGE_EBT_802_3=m CONFIG_BRIDGE_EBT_AMONG=m CONFIG_BRIDGE_EBT_ARP=m CONFIG_BRIDGE_EBT_IP=m CONFIG_BRIDGE_EBT_IP6=m CONFIG_BRIDGE_EBT_LIMIT=m CONFIG_BRIDGE_EBT_MARK=m CONFIG_BRIDGE_EBT_PKTTYPE=m CONFIG_BRIDGE_EBT_STP=m CONFIG_BRIDGE_EBT_VLAN=m CONFIG_BRIDGE_EBT_ARPREPLY=m CONFIG_BRIDGE_EBT_DNAT=m CONFIG_BRIDGE_EBT_MARK_T=m CONFIG_BRIDGE_EBT_REDIRECT=m CONFIG_BRIDGE_EBT_SNAT=m CONFIG_BRIDGE_EBT_LOG=m CONFIG_BRIDGE_EBT_ULOG=m CONFIG_BRIDGE_EBT_NFLOG=m CONFIG_IP_DCCP=m CONFIG_INET_DCCP_DIAG=m # # DCCP CCIDs Configuration (EXPERIMENTAL) # # CONFIG_IP_DCCP_CCID2_DEBUG is not set CONFIG_IP_DCCP_CCID3=y # CONFIG_IP_DCCP_CCID3_DEBUG is not set CONFIG_IP_DCCP_TFRC_LIB=y # # DCCP Kernel Hacking # # CONFIG_IP_DCCP_DEBUG is not set CONFIG_NET_DCCPPROBE=m CONFIG_IP_SCTP=m CONFIG_NET_SCTPPROBE=m # CONFIG_SCTP_DBG_MSG is not set # CONFIG_SCTP_DBG_OBJCNT is not set # CONFIG_SCTP_HMAC_NONE is not set # CONFIG_SCTP_HMAC_SHA1 is not set CONFIG_SCTP_HMAC_MD5=y CONFIG_RDS=m CONFIG_RDS_RDMA=m CONFIG_RDS_TCP=m # CONFIG_RDS_DEBUG is not set CONFIG_TIPC=m CONFIG_TIPC_ADVANCED=y CONFIG_TIPC_PORTS=8191 CONFIG_TIPC_LOG=0 # CONFIG_TIPC_DEBUG is not set CONFIG_ATM=m CONFIG_ATM_CLIP=m # CONFIG_ATM_CLIP_NO_ICMP is not set CONFIG_ATM_LANE=m CONFIG_ATM_MPOA=m CONFIG_ATM_BR2684=m # CONFIG_ATM_BR2684_IPFILTER is not set CONFIG_L2TP=m CONFIG_L2TP_DEBUGFS=m CONFIG_L2TP_V3=y CONFIG_L2TP_IP=m CONFIG_L2TP_ETH=m CONFIG_STP=m CONFIG_GARP=m CONFIG_BRIDGE=m CONFIG_BRIDGE_IGMP_SNOOPING=y # CONFIG_NET_DSA is not set CONFIG_VLAN_8021Q=m CONFIG_VLAN_8021Q_GVRP=y CONFIG_DECNET=m # CONFIG_DECNET_ROUTER is not set CONFIG_LLC=m CONFIG_LLC2=m CONFIG_IPX=m # CONFIG_IPX_INTERN is not set CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m CONFIG_IPDDP=m CONFIG_IPDDP_ENCAP=y CONFIG_IPDDP_DECAP=y # CONFIG_X25 is not set CONFIG_LAPB=m CONFIG_WAN_ROUTER=m CONFIG_PHONET=m CONFIG_IEEE802154=m CONFIG_IEEE802154_6LOWPAN=m # CONFIG_MAC802154 is not set CONFIG_NET_SCHED=y # # Queueing/Scheduling # CONFIG_NET_SCH_CBQ=m CONFIG_NET_SCH_HTB=m CONFIG_NET_SCH_HFSC=m CONFIG_NET_SCH_ATM=m CONFIG_NET_SCH_PRIO=m CONFIG_NET_SCH_MULTIQ=m CONFIG_NET_SCH_RED=m CONFIG_NET_SCH_SFB=m CONFIG_NET_SCH_SFQ=m CONFIG_NET_SCH_TEQL=m CONFIG_NET_SCH_TBF=m CONFIG_NET_SCH_GRED=m CONFIG_NET_SCH_DSMARK=m CONFIG_NET_SCH_NETEM=m CONFIG_NET_SCH_DRR=m CONFIG_NET_SCH_MQPRIO=m CONFIG_NET_SCH_CHOKE=m CONFIG_NET_SCH_QFQ=m CONFIG_NET_SCH_CODEL=m CONFIG_NET_SCH_FQ_CODEL=m CONFIG_NET_SCH_INGRESS=m CONFIG_NET_SCH_PLUG=m # # Classification # CONFIG_NET_CLS=y CONFIG_NET_CLS_BASIC=m CONFIG_NET_CLS_TCINDEX=m CONFIG_NET_CLS_ROUTE4=m CONFIG_NET_CLS_FW=m CONFIG_NET_CLS_U32=m CONFIG_CLS_U32_PERF=y CONFIG_CLS_U32_MARK=y CONFIG_NET_CLS_RSVP=m CONFIG_NET_CLS_RSVP6=m CONFIG_NET_CLS_FLOW=m CONFIG_NET_CLS_CGROUP=y CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_STACK=32 CONFIG_NET_EMATCH_CMP=m CONFIG_NET_EMATCH_NBYTE=m CONFIG_NET_EMATCH_U32=m CONFIG_NET_EMATCH_META=m CONFIG_NET_EMATCH_TEXT=m CONFIG_NET_CLS_ACT=y CONFIG_NET_ACT_POLICE=m CONFIG_NET_ACT_GACT=m CONFIG_GACT_PROB=y CONFIG_NET_ACT_MIRRED=m CONFIG_NET_ACT_IPT=m CONFIG_NET_ACT_NAT=m CONFIG_NET_ACT_PEDIT=m CONFIG_NET_ACT_SIMP=m CONFIG_NET_ACT_SKBEDIT=m CONFIG_NET_ACT_CSUM=m CONFIG_NET_CLS_IND=y CONFIG_NET_SCH_FIFO=y CONFIG_DCB=y CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m CONFIG_BATMAN_ADV_BLA=y # CONFIG_BATMAN_ADV_DEBUG is not set CONFIG_OPENVSWITCH=m CONFIG_RPS=y CONFIG_RFS_ACCEL=y CONFIG_XPS=y # CONFIG_NETPRIO_CGROUP is not set CONFIG_BQL=y CONFIG_BPF_JIT=y # # Network testing # CONFIG_NET_PKTGEN=m # CONFIG_NET_TCPPROBE is not set CONFIG_NET_DROP_MONITOR=y CONFIG_HAMRADIO=y # # Packet Radio protocols # CONFIG_AX25=m # CONFIG_AX25_DAMA_SLAVE is not set CONFIG_NETROM=m CONFIG_ROSE=m # # AX.25 network device drivers # CONFIG_MKISS=m CONFIG_6PACK=m CONFIG_BPQETHER=m CONFIG_BAYCOM_SER_FDX=m CONFIG_BAYCOM_SER_HDX=m CONFIG_BAYCOM_PAR=m CONFIG_YAM=m CONFIG_CAN=m CONFIG_CAN_RAW=m CONFIG_CAN_BCM=m CONFIG_CAN_GW=m # # CAN Device Drivers # CONFIG_CAN_VCAN=m CONFIG_CAN_SLCAN=m CONFIG_CAN_DEV=m CONFIG_CAN_CALC_BITTIMING=y CONFIG_CAN_MCP251X=m CONFIG_PCH_CAN=m CONFIG_CAN_SJA1000=m CONFIG_CAN_SJA1000_ISA=m # CONFIG_CAN_SJA1000_PLATFORM is not set CONFIG_CAN_EMS_PCMCIA=m CONFIG_CAN_EMS_PCI=m # CONFIG_CAN_PEAK_PCMCIA is not set CONFIG_CAN_PEAK_PCI=m CONFIG_CAN_PEAK_PCIEC=y CONFIG_CAN_KVASER_PCI=m CONFIG_CAN_PLX_PCI=m # CONFIG_CAN_C_CAN is not set # CONFIG_CAN_CC770 is not set # # CAN USB interfaces # CONFIG_CAN_EMS_USB=m CONFIG_CAN_ESD_USB2=m # CONFIG_CAN_PEAK_USB is not set CONFIG_CAN_SOFTING=m CONFIG_CAN_SOFTING_CS=m # CONFIG_CAN_DEBUG_DEVICES is not set CONFIG_IRDA=m # # IrDA protocols # CONFIG_IRLAN=m CONFIG_IRNET=m CONFIG_IRCOMM=m # CONFIG_IRDA_ULTRA is not set # # IrDA options # CONFIG_IRDA_CACHE_LAST_LSAP=y CONFIG_IRDA_FAST_RR=y # CONFIG_IRDA_DEBUG is not set # # Infrared-port device drivers # # # SIR device drivers # CONFIG_IRTTY_SIR=m # # Dongle support # CONFIG_DONGLE=y CONFIG_ESI_DONGLE=m CONFIG_ACTISYS_DONGLE=m CONFIG_TEKRAM_DONGLE=m CONFIG_TOIM3232_DONGLE=m CONFIG_LITELINK_DONGLE=m CONFIG_MA600_DONGLE=m CONFIG_GIRBIL_DONGLE=m CONFIG_MCP2120_DONGLE=m CONFIG_OLD_BELKIN_DONGLE=m CONFIG_ACT200L_DONGLE=m CONFIG_KINGSUN_DONGLE=m CONFIG_KSDAZZLE_DONGLE=m CONFIG_KS959_DONGLE=m # # FIR device drivers # CONFIG_USB_IRDA=m CONFIG_SIGMATEL_FIR=m CONFIG_NSC_FIR=m CONFIG_WINBOND_FIR=m CONFIG_SMC_IRCC_FIR=m CONFIG_ALI_FIR=m CONFIG_VLSI_FIR=m CONFIG_VIA_FIR=m CONFIG_MCS_FIR=m CONFIG_BT=m CONFIG_BT_RFCOMM=m CONFIG_BT_RFCOMM_TTY=y CONFIG_BT_BNEP=m CONFIG_BT_BNEP_MC_FILTER=y CONFIG_BT_BNEP_PROTO_FILTER=y CONFIG_BT_CMTP=m CONFIG_BT_HIDP=m # # Bluetooth device drivers # CONFIG_BT_HCIBTUSB=m CONFIG_BT_HCIBTSDIO=m CONFIG_BT_HCIUART=m CONFIG_BT_HCIUART_H4=y CONFIG_BT_HCIUART_BCSP=y CONFIG_BT_HCIUART_ATH3K=y CONFIG_BT_HCIUART_LL=y CONFIG_BT_HCIBCM203X=m CONFIG_BT_HCIBPA10X=m CONFIG_BT_HCIBFUSB=m CONFIG_BT_HCIDTL1=m CONFIG_BT_HCIBT3C=m CONFIG_BT_HCIBLUECARD=m CONFIG_BT_HCIBTUART=m CONFIG_BT_HCIVHCI=m CONFIG_BT_MRVL=m CONFIG_BT_MRVL_SDIO=m CONFIG_BT_ATH3K=m CONFIG_AF_RXRPC=m # CONFIG_AF_RXRPC_DEBUG is not set CONFIG_RXKAD=m CONFIG_FIB_RULES=y CONFIG_WIRELESS=y CONFIG_WIRELESS_EXT=y CONFIG_WEXT_CORE=y CONFIG_WEXT_PROC=y CONFIG_WEXT_SPY=y CONFIG_WEXT_PRIV=y CONFIG_CFG80211=m # CONFIG_NL80211_TESTMODE is not set # CONFIG_CFG80211_DEVELOPER_WARNINGS is not set # CONFIG_CFG80211_REG_DEBUG is not set CONFIG_CFG80211_DEFAULT_PS=y # CONFIG_CFG80211_DEBUGFS is not set # CONFIG_CFG80211_INTERNAL_REGDB is not set CONFIG_CFG80211_WEXT=y # CONFIG_WIRELESS_EXT_SYSFS is not set CONFIG_LIB80211=m CONFIG_LIB80211_CRYPT_WEP=m CONFIG_LIB80211_CRYPT_CCMP=m CONFIG_LIB80211_CRYPT_TKIP=m # CONFIG_LIB80211_DEBUG is not set CONFIG_MAC80211=m CONFIG_MAC80211_HAS_RC=y CONFIG_MAC80211_RC_MINSTREL=y CONFIG_MAC80211_RC_MINSTREL_HT=y CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" CONFIG_MAC80211_MESH=y CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_DEBUG_MENU is not set CONFIG_WIMAX=m CONFIG_WIMAX_DEBUG_LEVEL=8 CONFIG_RFKILL=m CONFIG_RFKILL_LEDS=y CONFIG_RFKILL_INPUT=y # CONFIG_RFKILL_REGULATOR is not set CONFIG_NET_9P=m CONFIG_NET_9P_VIRTIO=m CONFIG_NET_9P_RDMA=m # CONFIG_NET_9P_DEBUG is not set # CONFIG_CAIF is not set CONFIG_CEPH_LIB=m # CONFIG_CEPH_LIB_PRETTYDEBUG is not set # CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set CONFIG_NFC=m CONFIG_NFC_NCI=m # CONFIG_NFC_HCI is not set # CONFIG_NFC_LLCP is not set # # Near Field Communication (NFC) devices # # CONFIG_PN544_NFC is not set CONFIG_NFC_PN533=m CONFIG_HAVE_BPF_JIT=y # # Device Drivers # # # Generic Driver Options # CONFIG_UEVENT_HELPER_PATH="" CONFIG_DEVTMPFS=y # CONFIG_DEVTMPFS_MOUNT is not set CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # CONFIG_FIRMWARE_IN_KERNEL is not set CONFIG_EXTRA_FIRMWARE="" # CONFIG_DEBUG_DRIVER is not set # CONFIG_DEBUG_DEVRES is not set CONFIG_SYS_HYPERVISOR=y # CONFIG_GENERIC_CPU_DEVICES is not set CONFIG_REGMAP=y CONFIG_REGMAP_I2C=m CONFIG_DMA_SHARED_BUFFER=y CONFIG_CONNECTOR=m CONFIG_MTD=m # CONFIG_MTD_TESTS is not set CONFIG_MTD_REDBOOT_PARTS=m CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 # CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set # CONFIG_MTD_REDBOOT_PARTS_READONLY is not set CONFIG_MTD_AR7_PARTS=m # # User Modules And Translation Layers # CONFIG_MTD_CHAR=m CONFIG_MTD_BLKDEVS=m CONFIG_MTD_BLOCK=m CONFIG_MTD_BLOCK_RO=m CONFIG_FTL=m CONFIG_NFTL=m CONFIG_NFTL_RW=y CONFIG_INFTL=m CONFIG_RFD_FTL=m CONFIG_SSFDC=m # CONFIG_SM_FTL is not set CONFIG_MTD_OOPS=m CONFIG_MTD_SWAP=m # # RAM/ROM/Flash chip drivers # CONFIG_MTD_CFI=m CONFIG_MTD_JEDECPROBE=m CONFIG_MTD_GEN_PROBE=m # CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_MAP_BANK_WIDTH_1=y CONFIG_MTD_MAP_BANK_WIDTH_2=y CONFIG_MTD_MAP_BANK_WIDTH_4=y # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set CONFIG_MTD_CFI_I1=y CONFIG_MTD_CFI_I2=y # CONFIG_MTD_CFI_I4 is not set # CONFIG_MTD_CFI_I8 is not set CONFIG_MTD_CFI_INTELEXT=m CONFIG_MTD_CFI_AMDSTD=m CONFIG_MTD_CFI_STAA=m CONFIG_MTD_CFI_UTIL=m CONFIG_MTD_RAM=m CONFIG_MTD_ROM=m CONFIG_MTD_ABSENT=m # # Mapping drivers for chip access # CONFIG_MTD_COMPLEX_MAPPINGS=y CONFIG_MTD_PHYSMAP=m # CONFIG_MTD_PHYSMAP_COMPAT is not set CONFIG_MTD_SC520CDP=m CONFIG_MTD_NETSC520=m CONFIG_MTD_TS5500=m CONFIG_MTD_SBC_GXX=m # CONFIG_MTD_AMD76XROM is not set # CONFIG_MTD_ICHXROM is not set # CONFIG_MTD_ESB2ROM is not set # CONFIG_MTD_CK804XROM is not set # CONFIG_MTD_SCB2_FLASH is not set CONFIG_MTD_NETtel=m # CONFIG_MTD_L440GX is not set CONFIG_MTD_PCI=m CONFIG_MTD_PCMCIA=m # CONFIG_MTD_PCMCIA_ANONYMOUS is not set # CONFIG_MTD_GPIO_ADDR is not set CONFIG_MTD_INTEL_VR_NOR=m CONFIG_MTD_PLATRAM=m # CONFIG_MTD_LATCH_ADDR is not set # # Self-contained MTD device drivers # CONFIG_MTD_PMC551=m # CONFIG_MTD_PMC551_BUGFIX is not set # CONFIG_MTD_PMC551_DEBUG is not set CONFIG_MTD_DATAFLASH=m # CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set # CONFIG_MTD_DATAFLASH_OTP is not set CONFIG_MTD_M25P80=m CONFIG_M25PXX_USE_FAST_READ=y CONFIG_MTD_SST25L=m CONFIG_MTD_SLRAM=m CONFIG_MTD_PHRAM=m CONFIG_MTD_MTDRAM=m CONFIG_MTDRAM_TOTAL_SIZE=4096 CONFIG_MTDRAM_ERASE_SIZE=128 CONFIG_MTD_BLOCK2MTD=m # # Disk-On-Chip Device Drivers # CONFIG_MTD_DOC2000=m CONFIG_MTD_DOC2001=m CONFIG_MTD_DOC2001PLUS=m # CONFIG_MTD_DOCG3 is not set CONFIG_MTD_DOCPROBE=m CONFIG_MTD_DOCECC=m # CONFIG_MTD_DOCPROBE_ADVANCED is not set CONFIG_MTD_DOCPROBE_ADDRESS=0x0 CONFIG_MTD_NAND_ECC=m # CONFIG_MTD_NAND_ECC_SMC is not set CONFIG_MTD_NAND=m # CONFIG_MTD_NAND_VERIFY_WRITE is not set # CONFIG_MTD_NAND_ECC_BCH is not set CONFIG_MTD_SM_COMMON=m # CONFIG_MTD_NAND_MUSEUM_IDS is not set # CONFIG_MTD_NAND_DENALI is not set CONFIG_MTD_NAND_IDS=m CONFIG_MTD_NAND_RICOH=m CONFIG_MTD_NAND_DISKONCHIP=m # CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 # CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set # CONFIG_MTD_NAND_DOCG4 is not set CONFIG_MTD_NAND_CAFE=m CONFIG_MTD_NAND_NANDSIM=m CONFIG_MTD_NAND_PLATFORM=m CONFIG_MTD_ALAUDA=m CONFIG_MTD_ONENAND=m CONFIG_MTD_ONENAND_VERIFY_WRITE=y CONFIG_MTD_ONENAND_GENERIC=m # CONFIG_MTD_ONENAND_OTP is not set CONFIG_MTD_ONENAND_2X_PROGRAM=y CONFIG_MTD_ONENAND_SIM=m # # LPDDR flash memory drivers # CONFIG_MTD_LPDDR=m CONFIG_MTD_QINFO_PROBE=m CONFIG_MTD_UBI=m CONFIG_MTD_UBI_WL_THRESHOLD=4096 CONFIG_MTD_UBI_BEB_RESERVE=1 # CONFIG_MTD_UBI_GLUEBI is not set CONFIG_PARPORT=m CONFIG_PARPORT_PC=m CONFIG_PARPORT_SERIAL=m # CONFIG_PARPORT_PC_FIFO is not set # CONFIG_PARPORT_PC_SUPERIO is not set CONFIG_PARPORT_PC_PCMCIA=m # CONFIG_PARPORT_GSC is not set CONFIG_PARPORT_AX88796=m CONFIG_PARPORT_1284=y CONFIG_PARPORT_NOT_PC=y CONFIG_PNP=y # CONFIG_PNP_DEBUG_MESSAGES is not set # # Protocols # CONFIG_PNPACPI=y CONFIG_BLK_DEV=y CONFIG_BLK_DEV_FD=m CONFIG_PARIDE=m # # Parallel IDE high-level drivers # CONFIG_PARIDE_PD=m CONFIG_PARIDE_PCD=m CONFIG_PARIDE_PF=m CONFIG_PARIDE_PT=m CONFIG_PARIDE_PG=m # # Parallel IDE protocol modules # CONFIG_PARIDE_ATEN=m CONFIG_PARIDE_BPCK=m CONFIG_PARIDE_COMM=m CONFIG_PARIDE_DSTR=m CONFIG_PARIDE_FIT2=m CONFIG_PARIDE_FIT3=m CONFIG_PARIDE_EPAT=m # CONFIG_PARIDE_EPATC8 is not set CONFIG_PARIDE_EPIA=m CONFIG_PARIDE_FRIQ=m CONFIG_PARIDE_FRPW=m CONFIG_PARIDE_KBIC=m CONFIG_PARIDE_KTTI=m CONFIG_PARIDE_ON20=m CONFIG_PARIDE_ON26=m # CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set CONFIG_BLK_CPQ_DA=m CONFIG_BLK_CPQ_CISS_DA=m CONFIG_CISS_SCSI_TAPE=y CONFIG_BLK_DEV_DAC960=m CONFIG_BLK_DEV_UMEM=m # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 # CONFIG_BLK_DEV_CRYPTOLOOP is not set CONFIG_BLK_DEV_DRBD=m # CONFIG_DRBD_FAULT_INJECTION is not set CONFIG_BLK_DEV_NBD=m # CONFIG_BLK_DEV_NVME is not set CONFIG_BLK_DEV_OSD=m CONFIG_BLK_DEV_SX8=m # CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=m CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=65536 # CONFIG_BLK_DEV_XIP is not set CONFIG_CDROM_PKTCDVD=m CONFIG_CDROM_PKTCDVD_BUFFERS=8 # CONFIG_CDROM_PKTCDVD_WCACHE is not set CONFIG_ATA_OVER_ETH=m CONFIG_XEN_BLKDEV_FRONTEND=m CONFIG_XEN_BLKDEV_BACKEND=m CONFIG_VIRTIO_BLK=m # CONFIG_BLK_DEV_HD is not set CONFIG_BLK_DEV_RBD=m # # Misc devices # CONFIG_SENSORS_LIS3LV02D=m CONFIG_AD525X_DPOT=m CONFIG_AD525X_DPOT_I2C=m CONFIG_AD525X_DPOT_SPI=m CONFIG_IBM_ASM=m CONFIG_PHANTOM=m # CONFIG_INTEL_MID_PTI is not set CONFIG_SGI_IOC4=m CONFIG_TIFM_CORE=m CONFIG_TIFM_7XX1=m CONFIG_ICS932S401=m CONFIG_ENCLOSURE_SERVICES=m CONFIG_HP_ILO=m CONFIG_APDS9802ALS=m CONFIG_ISL29003=m CONFIG_ISL29020=m CONFIG_SENSORS_TSL2550=m CONFIG_SENSORS_BH1780=m CONFIG_SENSORS_BH1770=m CONFIG_SENSORS_APDS990X=m CONFIG_HMC6352=m CONFIG_DS1682=m CONFIG_TI_DAC7512=m CONFIG_VMWARE_BALLOON=m # CONFIG_BMP085_I2C is not set # CONFIG_BMP085_SPI is not set CONFIG_PCH_PHUB=m # CONFIG_USB_SWITCH_FSA9480 is not set CONFIG_C2PORT=m CONFIG_C2PORT_DURAMAR_2150=m # # EEPROM support # CONFIG_EEPROM_AT24=m CONFIG_EEPROM_AT25=m CONFIG_EEPROM_LEGACY=m CONFIG_EEPROM_MAX6875=m CONFIG_EEPROM_93CX6=m # CONFIG_EEPROM_93XX46 is not set CONFIG_CB710_CORE=m # CONFIG_CB710_DEBUG is not set CONFIG_CB710_DEBUG_ASSUMPTIONS=y CONFIG_IWMC3200TOP=m # CONFIG_IWMC3200TOP_DEBUG is not set # CONFIG_IWMC3200TOP_DEBUGFS is not set # # Texas Instruments shared transport line discipline # # CONFIG_TI_ST is not set CONFIG_SENSORS_LIS3_I2C=m # # Altera FPGA firmware download module # # CONFIG_ALTERA_STAPL is not set # CONFIG_INTEL_MEI is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # # SCSI device support # CONFIG_SCSI_MOD=m CONFIG_RAID_ATTRS=m CONFIG_SCSI=m CONFIG_SCSI_DMA=y CONFIG_SCSI_TGT=m CONFIG_SCSI_NETLINK=y # CONFIG_SCSI_PROC_FS is not set # # SCSI support type (disk, tape, CD-ROM) # CONFIG_BLK_DEV_SD=m CONFIG_CHR_DEV_ST=m CONFIG_CHR_DEV_OSST=m CONFIG_BLK_DEV_SR=m CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_CHR_DEV_SCH=m CONFIG_SCSI_ENCLOSURE=m CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_SCSI_WAIT_SCAN=m # # SCSI Transports # CONFIG_SCSI_SPI_ATTRS=m CONFIG_SCSI_FC_ATTRS=m CONFIG_SCSI_FC_TGT_ATTRS=y CONFIG_SCSI_ISCSI_ATTRS=m CONFIG_SCSI_SAS_ATTRS=m CONFIG_SCSI_SAS_LIBSAS=m CONFIG_SCSI_SAS_ATA=y CONFIG_SCSI_SAS_HOST_SMP=y CONFIG_SCSI_SRP_ATTRS=m CONFIG_SCSI_SRP_TGT_ATTRS=y CONFIG_SCSI_LOWLEVEL=y CONFIG_ISCSI_TCP=m CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_SCSI_CXGB3_ISCSI=m CONFIG_SCSI_CXGB4_ISCSI=m CONFIG_SCSI_BNX2_ISCSI=m CONFIG_SCSI_BNX2X_FCOE=m CONFIG_BE2ISCSI=m CONFIG_BLK_DEV_3W_XXXX_RAID=m CONFIG_SCSI_HPSA=m CONFIG_SCSI_3W_9XXX=m CONFIG_SCSI_3W_SAS=m CONFIG_SCSI_ACARD=m CONFIG_SCSI_AACRAID=m CONFIG_SCSI_AIC7XXX=m CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 CONFIG_AIC7XXX_RESET_DELAY_MS=15000 CONFIG_AIC7XXX_DEBUG_ENABLE=y CONFIG_AIC7XXX_DEBUG_MASK=0 CONFIG_AIC7XXX_REG_PRETTY_PRINT=y CONFIG_SCSI_AIC7XXX_OLD=m CONFIG_SCSI_AIC79XX=m CONFIG_AIC79XX_CMDS_PER_DEVICE=32 CONFIG_AIC79XX_RESET_DELAY_MS=15000 CONFIG_AIC79XX_DEBUG_ENABLE=y CONFIG_AIC79XX_DEBUG_MASK=0 CONFIG_AIC79XX_REG_PRETTY_PRINT=y CONFIG_SCSI_AIC94XX=m # CONFIG_AIC94XX_DEBUG is not set CONFIG_SCSI_MVSAS=m # CONFIG_SCSI_MVSAS_DEBUG is not set # CONFIG_SCSI_MVSAS_TASKLET is not set CONFIG_SCSI_MVUMI=m CONFIG_SCSI_DPT_I2O=m CONFIG_SCSI_ADVANSYS=m CONFIG_SCSI_ARCMSR=m CONFIG_MEGARAID_NEWGEN=y CONFIG_MEGARAID_MM=m CONFIG_MEGARAID_MAILBOX=m CONFIG_MEGARAID_LEGACY=m CONFIG_MEGARAID_SAS=m CONFIG_SCSI_MPT2SAS=m CONFIG_SCSI_MPT2SAS_MAX_SGE=128 # CONFIG_SCSI_MPT2SAS_LOGGING is not set CONFIG_SCSI_UFSHCD=m CONFIG_SCSI_HPTIOP=m CONFIG_SCSI_BUSLOGIC=m CONFIG_VMWARE_PVSCSI=m CONFIG_HYPERV_STORAGE=m CONFIG_LIBFC=m CONFIG_LIBFCOE=m CONFIG_FCOE=m CONFIG_FCOE_FNIC=m CONFIG_SCSI_DMX3191D=m CONFIG_SCSI_EATA=m CONFIG_SCSI_EATA_TAGGED_QUEUE=y CONFIG_SCSI_EATA_LINKED_COMMANDS=y CONFIG_SCSI_EATA_MAX_TAGS=16 CONFIG_SCSI_FUTURE_DOMAIN=m CONFIG_SCSI_GDTH=m CONFIG_SCSI_ISCI=m CONFIG_SCSI_IPS=m CONFIG_SCSI_INITIO=m CONFIG_SCSI_INIA100=m CONFIG_SCSI_PPA=m CONFIG_SCSI_IMM=m # CONFIG_SCSI_IZIP_EPP16 is not set # CONFIG_SCSI_IZIP_SLOW_CTR is not set CONFIG_SCSI_STEX=m CONFIG_SCSI_SYM53C8XX_2=m CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 CONFIG_SCSI_SYM53C8XX_MMIO=y CONFIG_SCSI_IPR=m # CONFIG_SCSI_IPR_TRACE is not set # CONFIG_SCSI_IPR_DUMP is not set CONFIG_SCSI_QLOGIC_1280=m CONFIG_SCSI_QLA_FC=m # CONFIG_TCM_QLA2XXX is not set CONFIG_SCSI_QLA_ISCSI=m CONFIG_SCSI_LPFC=m # CONFIG_SCSI_LPFC_DEBUG_FS is not set CONFIG_SCSI_DC395x=m CONFIG_SCSI_DC390T=m CONFIG_SCSI_DEBUG=m CONFIG_SCSI_PMCRAID=m CONFIG_SCSI_PM8001=m CONFIG_SCSI_SRP=m CONFIG_SCSI_BFA_FC=m CONFIG_SCSI_VIRTIO=m CONFIG_SCSI_LOWLEVEL_PCMCIA=y CONFIG_PCMCIA_AHA152X=m CONFIG_PCMCIA_FDOMAIN=m CONFIG_PCMCIA_QLOGIC=m CONFIG_PCMCIA_SYM53C500=m CONFIG_SCSI_DH=m CONFIG_SCSI_DH_RDAC=m CONFIG_SCSI_DH_HP_SW=m CONFIG_SCSI_DH_EMC=m CONFIG_SCSI_DH_ALUA=m CONFIG_SCSI_OSD_INITIATOR=m CONFIG_SCSI_OSD_ULD=m CONFIG_SCSI_OSD_DPRINT_SENSE=1 # CONFIG_SCSI_OSD_DEBUG is not set CONFIG_ATA=m # CONFIG_ATA_NONSTANDARD is not set CONFIG_ATA_VERBOSE_ERROR=y CONFIG_ATA_ACPI=y CONFIG_SATA_PMP=y # # Controllers with non-SFF native interface # CONFIG_SATA_AHCI=m # CONFIG_SATA_AHCI_PLATFORM is not set CONFIG_SATA_INIC162X=m CONFIG_SATA_ACARD_AHCI=m CONFIG_SATA_SIL24=m CONFIG_ATA_SFF=y # # SFF controllers with custom DMA interface # CONFIG_PDC_ADMA=m CONFIG_SATA_QSTOR=m CONFIG_SATA_SX4=m CONFIG_ATA_BMDMA=y # # SATA SFF controllers with BMDMA # CONFIG_ATA_PIIX=m CONFIG_SATA_MV=m CONFIG_SATA_NV=m CONFIG_SATA_PROMISE=m CONFIG_SATA_SIL=m CONFIG_SATA_SIS=m CONFIG_SATA_SVW=m CONFIG_SATA_ULI=m CONFIG_SATA_VIA=m CONFIG_SATA_VITESSE=m # # PATA SFF controllers with BMDMA # CONFIG_PATA_ALI=m CONFIG_PATA_AMD=m CONFIG_PATA_ARASAN_CF=m CONFIG_PATA_ARTOP=m CONFIG_PATA_ATIIXP=m CONFIG_PATA_ATP867X=m CONFIG_PATA_CMD64X=m CONFIG_PATA_CS5520=m CONFIG_PATA_CS5530=m # CONFIG_PATA_CS5536 is not set # CONFIG_PATA_CYPRESS is not set CONFIG_PATA_EFAR=m CONFIG_PATA_HPT366=m CONFIG_PATA_HPT37X=m # CONFIG_PATA_HPT3X2N is not set # CONFIG_PATA_HPT3X3 is not set CONFIG_PATA_IT8213=m CONFIG_PATA_IT821X=m CONFIG_PATA_JMICRON=m CONFIG_PATA_MARVELL=m CONFIG_PATA_NETCELL=m CONFIG_PATA_NINJA32=m CONFIG_PATA_NS87415=m CONFIG_PATA_OLDPIIX=m # CONFIG_PATA_OPTIDMA is not set CONFIG_PATA_PDC2027X=m CONFIG_PATA_PDC_OLD=m # CONFIG_PATA_RADISYS is not set CONFIG_PATA_RDC=m CONFIG_PATA_SC1200=m CONFIG_PATA_SCH=m CONFIG_PATA_SERVERWORKS=m CONFIG_PATA_SIL680=m CONFIG_PATA_SIS=m CONFIG_PATA_TOSHIBA=m CONFIG_PATA_TRIFLEX=m CONFIG_PATA_VIA=m # CONFIG_PATA_WINBOND is not set # # PIO-only SFF controllers # # CONFIG_PATA_CMD640_PCI is not set CONFIG_PATA_MPIIX=m CONFIG_PATA_NS87410=m # CONFIG_PATA_OPTI is not set CONFIG_PATA_PCMCIA=m CONFIG_PATA_RZ1000=m # # Generic fallback / legacy drivers # # CONFIG_PATA_ACPI is not set CONFIG_ATA_GENERIC=m # CONFIG_PATA_LEGACY is not set CONFIG_MD=y CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m CONFIG_MD_RAID1=m CONFIG_MD_RAID10=m CONFIG_MD_RAID456=m # CONFIG_MULTICORE_RAID456 is not set CONFIG_MD_MULTIPATH=m CONFIG_MD_FAULTY=m CONFIG_BLK_DEV_DM=m # CONFIG_DM_DEBUG is not set CONFIG_DM_BUFIO=m CONFIG_DM_PERSISTENT_DATA=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_THIN_PROVISIONING=m # CONFIG_DM_DEBUG_BLOCK_STACK_TRACING is not set # CONFIG_DM_DEBUG_SPACE_MAPS is not set CONFIG_DM_MIRROR=m CONFIG_DM_RAID=m CONFIG_DM_LOG_USERSPACE=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_MULTIPATH_QL=m CONFIG_DM_MULTIPATH_ST=m CONFIG_DM_DELAY=m CONFIG_DM_UEVENT=y CONFIG_DM_FLAKEY=m CONFIG_DM_VERITY=m CONFIG_TARGET_CORE=m CONFIG_TCM_IBLOCK=m CONFIG_TCM_FILEIO=m CONFIG_TCM_PSCSI=m CONFIG_LOOPBACK_TARGET=m CONFIG_TCM_FC=m CONFIG_ISCSI_TARGET=m # CONFIG_SBP_TARGET is not set CONFIG_FUSION=y CONFIG_FUSION_SPI=m CONFIG_FUSION_FC=m CONFIG_FUSION_SAS=m CONFIG_FUSION_MAX_SGE=128 CONFIG_FUSION_CTL=m CONFIG_FUSION_LAN=m # CONFIG_FUSION_LOGGING is not set # # IEEE 1394 (FireWire) support # CONFIG_FIREWIRE=m CONFIG_FIREWIRE_OHCI=m CONFIG_FIREWIRE_SBP2=m CONFIG_FIREWIRE_NET=m CONFIG_FIREWIRE_NOSY=m CONFIG_I2O=m CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y CONFIG_I2O_EXT_ADAPTEC=y CONFIG_I2O_EXT_ADAPTEC_DMA64=y CONFIG_I2O_CONFIG=m CONFIG_I2O_CONFIG_OLD_IOCTL=y CONFIG_I2O_BUS=m CONFIG_I2O_BLOCK=m CONFIG_I2O_SCSI=m CONFIG_I2O_PROC=m CONFIG_MACINTOSH_DRIVERS=y CONFIG_MAC_EMUMOUSEBTN=y CONFIG_NETDEVICES=y CONFIG_NET_CORE=y CONFIG_BONDING=m CONFIG_DUMMY=m CONFIG_EQUALIZER=m CONFIG_NET_FC=y CONFIG_MII=m CONFIG_IEEE802154_DRIVERS=m CONFIG_IEEE802154_FAKEHARD=m CONFIG_IFB=m CONFIG_NET_TEAM=m CONFIG_NET_TEAM_MODE_ROUNDROBIN=m CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m CONFIG_NET_TEAM_MODE_LOADBALANCE=m CONFIG_MACVLAN=m CONFIG_MACVTAP=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_NETPOLL=y # CONFIG_NETPOLL_TRAP is not set CONFIG_NET_POLL_CONTROLLER=y CONFIG_TUN=m CONFIG_VETH=m CONFIG_VIRTIO_NET=m CONFIG_SUNGEM_PHY=m CONFIG_ARCNET=m CONFIG_ARCNET_1201=m CONFIG_ARCNET_1051=m CONFIG_ARCNET_RAW=m CONFIG_ARCNET_CAP=m CONFIG_ARCNET_COM90xx=m CONFIG_ARCNET_COM90xxIO=m CONFIG_ARCNET_RIM_I=m CONFIG_ARCNET_COM20020=m CONFIG_ARCNET_COM20020_PCI=m CONFIG_ARCNET_COM20020_CS=m CONFIG_ATM_DRIVERS=y CONFIG_ATM_DUMMY=m CONFIG_ATM_TCP=m CONFIG_ATM_LANAI=m CONFIG_ATM_ENI=m # CONFIG_ATM_ENI_DEBUG is not set # CONFIG_ATM_ENI_TUNE_BURST is not set CONFIG_ATM_FIRESTREAM=m CONFIG_ATM_ZATM=m # CONFIG_ATM_ZATM_DEBUG is not set CONFIG_ATM_NICSTAR=m CONFIG_ATM_NICSTAR_USE_SUNI=y CONFIG_ATM_NICSTAR_USE_IDT77105=y CONFIG_ATM_IDT77252=m # CONFIG_ATM_IDT77252_DEBUG is not set # CONFIG_ATM_IDT77252_RCV_ALL is not set CONFIG_ATM_IDT77252_USE_SUNI=y CONFIG_ATM_AMBASSADOR=m # CONFIG_ATM_AMBASSADOR_DEBUG is not set CONFIG_ATM_HORIZON=m # CONFIG_ATM_HORIZON_DEBUG is not set CONFIG_ATM_IA=m # CONFIG_ATM_IA_DEBUG is not set CONFIG_ATM_FORE200E=m # CONFIG_ATM_FORE200E_USE_TASKLET is not set CONFIG_ATM_FORE200E_TX_RETRY=16 CONFIG_ATM_FORE200E_DEBUG=0 CONFIG_ATM_HE=m CONFIG_ATM_HE_USE_SUNI=y CONFIG_ATM_SOLOS=m # # CAIF transport drivers # CONFIG_ETHERNET=y CONFIG_MDIO=m CONFIG_NET_VENDOR_3COM=y CONFIG_PCMCIA_3C574=m CONFIG_PCMCIA_3C589=m CONFIG_VORTEX=m CONFIG_TYPHOON=m CONFIG_NET_VENDOR_ADAPTEC=y CONFIG_ADAPTEC_STARFIRE=m CONFIG_NET_VENDOR_ALTEON=y CONFIG_ACENIC=m # CONFIG_ACENIC_OMIT_TIGON_I is not set CONFIG_NET_VENDOR_AMD=y CONFIG_AMD8111_ETH=m CONFIG_PCNET32=m CONFIG_PCMCIA_NMCLAN=m CONFIG_NET_VENDOR_ATHEROS=y CONFIG_ATL2=m CONFIG_ATL1=m CONFIG_ATL1E=m CONFIG_ATL1C=m CONFIG_NET_VENDOR_BROADCOM=y CONFIG_B44=m CONFIG_B44_PCI_AUTOSELECT=y CONFIG_B44_PCICORE_AUTOSELECT=y CONFIG_B44_PCI=y CONFIG_BNX2=m CONFIG_CNIC=m CONFIG_TIGON3=m CONFIG_BNX2X=m CONFIG_NET_VENDOR_BROCADE=y CONFIG_BNA=m # CONFIG_NET_CALXEDA_XGMAC is not set CONFIG_NET_VENDOR_CHELSIO=y CONFIG_CHELSIO_T1=m CONFIG_CHELSIO_T1_1G=y CONFIG_CHELSIO_T3=m CONFIG_CHELSIO_T4=m CONFIG_CHELSIO_T4VF=m CONFIG_NET_VENDOR_CISCO=y CONFIG_ENIC=m CONFIG_DNET=m CONFIG_NET_VENDOR_DEC=y CONFIG_NET_TULIP=y CONFIG_DE2104X=m CONFIG_DE2104X_DSL=0 CONFIG_TULIP=m # CONFIG_TULIP_MWI is not set # CONFIG_TULIP_MMIO is not set CONFIG_TULIP_NAPI=y CONFIG_TULIP_NAPI_HW_MITIGATION=y # CONFIG_DE4X5 is not set CONFIG_WINBOND_840=m CONFIG_DM9102=m CONFIG_ULI526X=m CONFIG_PCMCIA_XIRCOM=m CONFIG_NET_VENDOR_DLINK=y CONFIG_DE600=m CONFIG_DE620=m CONFIG_DL2K=m CONFIG_SUNDANCE=m # CONFIG_SUNDANCE_MMIO is not set CONFIG_NET_VENDOR_EMULEX=y CONFIG_BE2NET=m CONFIG_NET_VENDOR_EXAR=y CONFIG_S2IO=m CONFIG_VXGE=m # CONFIG_VXGE_DEBUG_TRACE_ALL is not set CONFIG_NET_VENDOR_FUJITSU=y CONFIG_PCMCIA_FMVJ18X=m CONFIG_NET_VENDOR_HP=y CONFIG_HP100=m CONFIG_NET_VENDOR_INTEL=y CONFIG_E100=m CONFIG_E1000=m CONFIG_E1000E=m CONFIG_IGB=m CONFIG_IGB_DCA=y # CONFIG_IGB_PTP is not set CONFIG_IGBVF=m CONFIG_IXGB=m CONFIG_IXGBE=m CONFIG_IXGBE_HWMON=y CONFIG_IXGBE_DCA=y CONFIG_IXGBE_DCB=y # CONFIG_IXGBE_PTP is not set CONFIG_IXGBEVF=m CONFIG_NET_VENDOR_I825XX=y # CONFIG_ZNET is not set CONFIG_IP1000=m CONFIG_JME=m CONFIG_NET_VENDOR_MARVELL=y CONFIG_SKGE=m # CONFIG_SKGE_DEBUG is not set CONFIG_SKGE_GENESIS=y CONFIG_SKY2=m # CONFIG_SKY2_DEBUG is not set CONFIG_NET_VENDOR_MELLANOX=y CONFIG_MLX4_EN=m CONFIG_MLX4_EN_DCB=y CONFIG_MLX4_CORE=m CONFIG_MLX4_DEBUG=y CONFIG_NET_VENDOR_MICREL=y CONFIG_KS8842=m CONFIG_KS8851=m CONFIG_KS8851_MLL=m CONFIG_KSZ884X_PCI=m CONFIG_NET_VENDOR_MICROCHIP=y CONFIG_ENC28J60=m # CONFIG_ENC28J60_WRITEVERIFY is not set CONFIG_NET_VENDOR_MYRI=y CONFIG_MYRI10GE=m CONFIG_MYRI10GE_DCA=y CONFIG_FEALNX=m CONFIG_NET_VENDOR_NATSEMI=y CONFIG_NATSEMI=m CONFIG_NS83820=m CONFIG_NET_VENDOR_8390=y CONFIG_PCMCIA_AXNET=m CONFIG_NE2K_PCI=m CONFIG_PCMCIA_PCNET=m CONFIG_NET_VENDOR_NVIDIA=y CONFIG_FORCEDETH=m CONFIG_NET_VENDOR_OKI=y CONFIG_PCH_GBE=m CONFIG_ETHOC=m CONFIG_NET_PACKET_ENGINE=y CONFIG_HAMACHI=m CONFIG_YELLOWFIN=m CONFIG_NET_VENDOR_QLOGIC=y CONFIG_QLA3XXX=m CONFIG_QLCNIC=m CONFIG_QLGE=m CONFIG_NETXEN_NIC=m CONFIG_NET_VENDOR_REALTEK=y CONFIG_ATP=m CONFIG_8139CP=m CONFIG_8139TOO=m # CONFIG_8139TOO_PIO is not set CONFIG_8139TOO_TUNE_TWISTER=y CONFIG_8139TOO_8129=y # CONFIG_8139_OLD_RX_RESET is not set CONFIG_R8169=m CONFIG_NET_VENDOR_RDC=y CONFIG_R6040=m CONFIG_NET_VENDOR_SEEQ=y # CONFIG_SEEQ8005 is not set CONFIG_NET_VENDOR_SILAN=y CONFIG_SC92031=m CONFIG_NET_VENDOR_SIS=y CONFIG_SIS900=m CONFIG_SIS190=m CONFIG_SFC=m CONFIG_SFC_MTD=y CONFIG_SFC_MCDI_MON=y CONFIG_SFC_SRIOV=y CONFIG_NET_VENDOR_SMSC=y CONFIG_PCMCIA_SMC91C92=m CONFIG_EPIC100=m CONFIG_SMSC9420=m CONFIG_NET_VENDOR_STMICRO=y # CONFIG_STMMAC_ETH is not set CONFIG_NET_VENDOR_SUN=y CONFIG_HAPPYMEAL=m CONFIG_SUNGEM=m CONFIG_CASSINI=m CONFIG_NIU=m CONFIG_NET_VENDOR_TEHUTI=y CONFIG_TEHUTI=m CONFIG_NET_VENDOR_TI=y CONFIG_TLAN=m CONFIG_NET_VENDOR_VIA=y CONFIG_VIA_RHINE=m # CONFIG_VIA_RHINE_MMIO is not set CONFIG_VIA_VELOCITY=m CONFIG_NET_VENDOR_WIZNET=y # CONFIG_WIZNET_W5100 is not set # CONFIG_WIZNET_W5300 is not set CONFIG_NET_VENDOR_XIRCOM=y CONFIG_PCMCIA_XIRC2PS=m CONFIG_FDDI=y CONFIG_DEFXX=m # CONFIG_DEFXX_MMIO is not set CONFIG_SKFP=m CONFIG_HIPPI=y CONFIG_ROADRUNNER=m # CONFIG_ROADRUNNER_LARGE_RINGS is not set CONFIG_NET_SB1000=m CONFIG_PHYLIB=m # # MII PHY device drivers # # CONFIG_AMD_PHY is not set CONFIG_MARVELL_PHY=m CONFIG_DAVICOM_PHY=m CONFIG_QSEMI_PHY=m CONFIG_LXT_PHY=m CONFIG_CICADA_PHY=m CONFIG_VITESSE_PHY=m CONFIG_SMSC_PHY=m CONFIG_BROADCOM_PHY=m CONFIG_ICPLUS_PHY=m CONFIG_REALTEK_PHY=m CONFIG_NATIONAL_PHY=m CONFIG_STE10XP=m CONFIG_LSI_ET1011C_PHY=m CONFIG_MICREL_PHY=m CONFIG_MDIO_BITBANG=m # CONFIG_MDIO_GPIO is not set # CONFIG_MICREL_KS8995MA is not set CONFIG_PLIP=m CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=m CONFIG_PPP_MULTILINK=y CONFIG_PPPOATM=m CONFIG_PPPOE=m CONFIG_PPTP=m CONFIG_PPPOL2TP=m CONFIG_PPP_ASYNC=m CONFIG_PPP_SYNC_TTY=m CONFIG_SLIP=m CONFIG_SLHC=m CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y # # USB Network Adapters # CONFIG_USB_CATC=m CONFIG_USB_KAWETH=m CONFIG_USB_PEGASUS=m CONFIG_USB_RTL8150=m CONFIG_USB_USBNET=m CONFIG_USB_NET_AX8817X=m CONFIG_USB_NET_CDCETHER=m CONFIG_USB_NET_CDC_EEM=m CONFIG_USB_NET_CDC_NCM=m CONFIG_USB_NET_DM9601=m CONFIG_USB_NET_SMSC75XX=m CONFIG_USB_NET_SMSC95XX=m CONFIG_USB_NET_GL620A=m CONFIG_USB_NET_NET1080=m CONFIG_USB_NET_PLUSB=m CONFIG_USB_NET_MCS7830=m CONFIG_USB_NET_RNDIS_HOST=m CONFIG_USB_NET_CDC_SUBSET=m CONFIG_USB_ALI_M5632=y CONFIG_USB_AN2720=y CONFIG_USB_BELKIN=y CONFIG_USB_ARMLINUX=y CONFIG_USB_EPSON2888=y CONFIG_USB_KC2190=y CONFIG_USB_NET_ZAURUS=m CONFIG_USB_NET_CX82310_ETH=m CONFIG_USB_NET_KALMIA=m # CONFIG_USB_NET_QMI_WWAN is not set CONFIG_USB_HSO=m CONFIG_USB_NET_INT51X1=m CONFIG_USB_CDC_PHONET=m CONFIG_USB_IPHETH=m CONFIG_USB_SIERRA_NET=m CONFIG_USB_VL600=m CONFIG_WLAN=y CONFIG_PCMCIA_RAYCS=m CONFIG_LIBERTAS_THINFIRM=m # CONFIG_LIBERTAS_THINFIRM_DEBUG is not set CONFIG_LIBERTAS_THINFIRM_USB=m CONFIG_AIRO=m CONFIG_ATMEL=m CONFIG_PCI_ATMEL=m CONFIG_PCMCIA_ATMEL=m CONFIG_AT76C50X_USB=m CONFIG_AIRO_CS=m CONFIG_PCMCIA_WL3501=m # CONFIG_PRISM54 is not set CONFIG_USB_ZD1201=m CONFIG_USB_NET_RNDIS_WLAN=m CONFIG_RTL8180=m CONFIG_RTL8187=m CONFIG_RTL8187_LEDS=y CONFIG_ADM8211=m CONFIG_MAC80211_HWSIM=m CONFIG_MWL8K=m CONFIG_ATH_COMMON=m # CONFIG_ATH_DEBUG is not set CONFIG_ATH5K=m # CONFIG_ATH5K_DEBUG is not set # CONFIG_ATH5K_TRACER is not set CONFIG_ATH5K_PCI=y CONFIG_ATH9K_HW=m CONFIG_ATH9K_COMMON=m CONFIG_ATH9K_BTCOEX_SUPPORT=y CONFIG_ATH9K=m CONFIG_ATH9K_PCI=y # CONFIG_ATH9K_AHB is not set # CONFIG_ATH9K_DEBUGFS is not set CONFIG_ATH9K_RATE_CONTROL=y CONFIG_ATH9K_HTC=m # CONFIG_ATH9K_HTC_DEBUGFS is not set CONFIG_CARL9170=m CONFIG_CARL9170_LEDS=y CONFIG_CARL9170_WPC=y # CONFIG_CARL9170_HWRNG is not set CONFIG_ATH6KL=m # CONFIG_ATH6KL_SDIO is not set # CONFIG_ATH6KL_USB is not set # CONFIG_ATH6KL_DEBUG is not set CONFIG_B43=m CONFIG_B43_BCMA=y # CONFIG_B43_BCMA_EXTRA is not set CONFIG_B43_SSB=y CONFIG_B43_PCI_AUTOSELECT=y CONFIG_B43_PCICORE_AUTOSELECT=y CONFIG_B43_PCMCIA=y CONFIG_B43_SDIO=y CONFIG_B43_BCMA_PIO=y CONFIG_B43_PIO=y CONFIG_B43_PHY_N=y CONFIG_B43_PHY_LP=y CONFIG_B43_PHY_HT=y CONFIG_B43_LEDS=y CONFIG_B43_HWRNG=y # CONFIG_B43_DEBUG is not set CONFIG_B43LEGACY=m CONFIG_B43LEGACY_PCI_AUTOSELECT=y CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y CONFIG_B43LEGACY_LEDS=y CONFIG_B43LEGACY_HWRNG=y CONFIG_B43LEGACY_DEBUG=y CONFIG_B43LEGACY_DMA=y CONFIG_B43LEGACY_PIO=y CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y # CONFIG_B43LEGACY_DMA_MODE is not set # CONFIG_B43LEGACY_PIO_MODE is not set CONFIG_BRCMUTIL=m CONFIG_BRCMSMAC=m # CONFIG_BRCMFMAC is not set # CONFIG_BRCMDBG is not set CONFIG_HOSTAP=m CONFIG_HOSTAP_FIRMWARE=y # CONFIG_HOSTAP_FIRMWARE_NVRAM is not set CONFIG_HOSTAP_PLX=m CONFIG_HOSTAP_PCI=m CONFIG_HOSTAP_CS=m # CONFIG_IPW2100 is not set CONFIG_IPW2200=m CONFIG_IPW2200_MONITOR=y CONFIG_IPW2200_RADIOTAP=y CONFIG_IPW2200_PROMISCUOUS=y CONFIG_IPW2200_QOS=y # CONFIG_IPW2200_DEBUG is not set CONFIG_LIBIPW=m # CONFIG_LIBIPW_DEBUG is not set CONFIG_IWLWIFI=m # # Debugging Options # # CONFIG_IWLWIFI_DEBUG is not set # CONFIG_IWLWIFI_DEVICE_TRACING is not set CONFIG_IWLWIFI_P2P=y # CONFIG_IWLWIFI_EXPERIMENTAL_MFP is not set CONFIG_IWLEGACY=m CONFIG_IWL4965=m CONFIG_IWL3945=m # # iwl3945 / iwl4965 Debugging Options # # CONFIG_IWLEGACY_DEBUG is not set CONFIG_IWM=m # CONFIG_IWM_DEBUG is not set # CONFIG_IWM_TRACING is not set CONFIG_LIBERTAS=m CONFIG_LIBERTAS_USB=m CONFIG_LIBERTAS_CS=m CONFIG_LIBERTAS_SDIO=m CONFIG_LIBERTAS_SPI=m # CONFIG_LIBERTAS_DEBUG is not set CONFIG_LIBERTAS_MESH=y CONFIG_HERMES=m # CONFIG_HERMES_PRISM is not set CONFIG_HERMES_CACHE_FW_ON_INIT=y CONFIG_PLX_HERMES=m CONFIG_TMD_HERMES=m CONFIG_NORTEL_HERMES=m CONFIG_PCMCIA_HERMES=m CONFIG_PCMCIA_SPECTRUM=m CONFIG_ORINOCO_USB=m CONFIG_P54_COMMON=m CONFIG_P54_USB=m CONFIG_P54_PCI=m CONFIG_P54_SPI=m # CONFIG_P54_SPI_DEFAULT_EEPROM is not set CONFIG_P54_LEDS=y CONFIG_RT2X00=m CONFIG_RT2400PCI=m CONFIG_RT2500PCI=m CONFIG_RT61PCI=m CONFIG_RT2800PCI=m CONFIG_RT2800PCI_RT33XX=y CONFIG_RT2800PCI_RT35XX=y CONFIG_RT2800PCI_RT53XX=y CONFIG_RT2500USB=m CONFIG_RT73USB=m CONFIG_RT2800USB=m CONFIG_RT2800USB_RT33XX=y CONFIG_RT2800USB_RT35XX=y CONFIG_RT2800USB_RT53XX=y # CONFIG_RT2800USB_UNKNOWN is not set CONFIG_RT2800_LIB=m CONFIG_RT2X00_LIB_PCI=m CONFIG_RT2X00_LIB_USB=m CONFIG_RT2X00_LIB=m CONFIG_RT2X00_LIB_FIRMWARE=y CONFIG_RT2X00_LIB_CRYPTO=y CONFIG_RT2X00_LIB_LEDS=y # CONFIG_RT2X00_DEBUG is not set CONFIG_RTL8192CE=m CONFIG_RTL8192SE=m CONFIG_RTL8192DE=m CONFIG_RTL8192CU=m CONFIG_RTLWIFI=m CONFIG_RTLWIFI_DEBUG=y CONFIG_RTL8192C_COMMON=m # CONFIG_WL_TI is not set CONFIG_ZD1211RW=m # CONFIG_ZD1211RW_DEBUG is not set CONFIG_MWIFIEX=m CONFIG_MWIFIEX_SDIO=m CONFIG_MWIFIEX_PCIE=m # CONFIG_MWIFIEX_USB is not set # # WiMAX Wireless Broadband devices # CONFIG_WIMAX_I2400M=m CONFIG_WIMAX_I2400M_USB=m # CONFIG_WIMAX_I2400M_SDIO is not set CONFIG_WIMAX_I2400M_DEBUG_LEVEL=8 CONFIG_WAN=y CONFIG_LANMEDIA=m CONFIG_HDLC=m CONFIG_HDLC_RAW=m CONFIG_HDLC_RAW_ETH=m CONFIG_HDLC_CISCO=m CONFIG_HDLC_FR=m CONFIG_HDLC_PPP=m # CONFIG_HDLC_X25 is not set CONFIG_PCI200SYN=m CONFIG_WANXL=m # CONFIG_PC300TOO is not set CONFIG_FARSYNC=m CONFIG_DSCC4=m CONFIG_DSCC4_PCISYNC=y CONFIG_DSCC4_PCI_RST=y CONFIG_DLCI=m CONFIG_DLCI_MAX=8 CONFIG_WAN_ROUTER_DRIVERS=m CONFIG_CYCLADES_SYNC=m # CONFIG_CYCLOMX_X25 is not set CONFIG_SBNI=m # CONFIG_SBNI_MULTILINE is not set CONFIG_XEN_NETDEV_FRONTEND=m CONFIG_XEN_NETDEV_BACKEND=m CONFIG_VMXNET3=m CONFIG_HYPERV_NET=m CONFIG_ISDN=y # CONFIG_ISDN_I4L is not set CONFIG_ISDN_CAPI=m CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y CONFIG_CAPI_TRACE=y CONFIG_ISDN_CAPI_MIDDLEWARE=y CONFIG_ISDN_CAPI_CAPI20=m # # CAPI hardware drivers # CONFIG_CAPI_AVM=y CONFIG_ISDN_DRV_AVMB1_B1PCI=m CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m CONFIG_ISDN_DRV_AVMB1_AVM_CS=m CONFIG_ISDN_DRV_AVMB1_T1PCI=m CONFIG_ISDN_DRV_AVMB1_C4=m CONFIG_CAPI_EICON=y CONFIG_ISDN_DIVAS=m CONFIG_ISDN_DIVAS_BRIPCI=y CONFIG_ISDN_DIVAS_PRIPCI=y CONFIG_ISDN_DIVAS_DIVACAPI=m CONFIG_ISDN_DIVAS_USERIDI=m CONFIG_ISDN_DIVAS_MAINT=m CONFIG_ISDN_DRV_GIGASET=m CONFIG_GIGASET_CAPI=y # CONFIG_GIGASET_DUMMYLL is not set CONFIG_GIGASET_BASE=m CONFIG_GIGASET_M105=m CONFIG_GIGASET_M101=m # CONFIG_GIGASET_DEBUG is not set CONFIG_HYSDN=m CONFIG_HYSDN_CAPI=y CONFIG_MISDN=m CONFIG_MISDN_DSP=m CONFIG_MISDN_L1OIP=m # # mISDN hardware drivers # CONFIG_MISDN_HFCPCI=m CONFIG_MISDN_HFCMULTI=m CONFIG_MISDN_HFCUSB=m CONFIG_MISDN_AVMFRITZ=m CONFIG_MISDN_SPEEDFAX=m CONFIG_MISDN_INFINEON=m CONFIG_MISDN_W6692=m # CONFIG_MISDN_NETJET is not set CONFIG_MISDN_IPAC=m CONFIG_MISDN_ISAR=m # # Input device support # CONFIG_INPUT=y CONFIG_INPUT_FF_MEMLESS=m CONFIG_INPUT_POLLDEV=m CONFIG_INPUT_SPARSEKMAP=m # CONFIG_INPUT_MATRIXKMAP is not set # # Userland interfaces # CONFIG_INPUT_MOUSEDEV=y CONFIG_INPUT_MOUSEDEV_PSAUX=y CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 CONFIG_INPUT_JOYDEV=m CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_EVBUG is not set # # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y CONFIG_KEYBOARD_ADP5588=m # CONFIG_KEYBOARD_ADP5589 is not set CONFIG_KEYBOARD_ATKBD=y # CONFIG_KEYBOARD_QT1070 is not set CONFIG_KEYBOARD_QT2160=m CONFIG_KEYBOARD_LKKBD=m # CONFIG_KEYBOARD_GPIO is not set # CONFIG_KEYBOARD_GPIO_POLLED is not set # CONFIG_KEYBOARD_TCA6416 is not set # CONFIG_KEYBOARD_TCA8418 is not set # CONFIG_KEYBOARD_MATRIX is not set CONFIG_KEYBOARD_LM8323=m # CONFIG_KEYBOARD_LM8333 is not set CONFIG_KEYBOARD_MAX7359=m # CONFIG_KEYBOARD_MCS is not set # CONFIG_KEYBOARD_MPR121 is not set CONFIG_KEYBOARD_NEWTON=m CONFIG_KEYBOARD_OPENCORES=m CONFIG_KEYBOARD_STOWAWAY=m CONFIG_KEYBOARD_SUNKBD=m # CONFIG_KEYBOARD_OMAP4 is not set CONFIG_KEYBOARD_XTKBD=m CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=m CONFIG_MOUSE_PS2_ALPS=y CONFIG_MOUSE_PS2_LOGIPS2PP=y CONFIG_MOUSE_PS2_SYNAPTICS=y CONFIG_MOUSE_PS2_LIFEBOOK=y CONFIG_MOUSE_PS2_TRACKPOINT=y CONFIG_MOUSE_PS2_ELANTECH=y CONFIG_MOUSE_PS2_SENTELIC=y # CONFIG_MOUSE_PS2_TOUCHKIT is not set CONFIG_MOUSE_SERIAL=m CONFIG_MOUSE_APPLETOUCH=m CONFIG_MOUSE_BCM5974=m CONFIG_MOUSE_VSXXXAA=m # CONFIG_MOUSE_GPIO is not set CONFIG_MOUSE_SYNAPTICS_I2C=m CONFIG_MOUSE_SYNAPTICS_USB=m CONFIG_INPUT_JOYSTICK=y CONFIG_JOYSTICK_ANALOG=m CONFIG_JOYSTICK_A3D=m CONFIG_JOYSTICK_ADI=m CONFIG_JOYSTICK_COBRA=m CONFIG_JOYSTICK_GF2K=m CONFIG_JOYSTICK_GRIP=m CONFIG_JOYSTICK_GRIP_MP=m CONFIG_JOYSTICK_GUILLEMOT=m CONFIG_JOYSTICK_INTERACT=m CONFIG_JOYSTICK_SIDEWINDER=m CONFIG_JOYSTICK_TMDC=m CONFIG_JOYSTICK_IFORCE=m CONFIG_JOYSTICK_IFORCE_USB=y CONFIG_JOYSTICK_IFORCE_232=y CONFIG_JOYSTICK_WARRIOR=m CONFIG_JOYSTICK_MAGELLAN=m CONFIG_JOYSTICK_SPACEORB=m CONFIG_JOYSTICK_SPACEBALL=m CONFIG_JOYSTICK_STINGER=m CONFIG_JOYSTICK_TWIDJOY=m CONFIG_JOYSTICK_ZHENHUA=m CONFIG_JOYSTICK_DB9=m CONFIG_JOYSTICK_GAMECON=m CONFIG_JOYSTICK_TURBOGRAFX=m # CONFIG_JOYSTICK_AS5011 is not set CONFIG_JOYSTICK_JOYDUMP=m CONFIG_JOYSTICK_XPAD=m CONFIG_JOYSTICK_XPAD_FF=y CONFIG_JOYSTICK_XPAD_LEDS=y CONFIG_JOYSTICK_WALKERA0701=m CONFIG_INPUT_TABLET=y CONFIG_TABLET_USB_ACECAD=m CONFIG_TABLET_USB_AIPTEK=m CONFIG_TABLET_USB_GTCO=m CONFIG_TABLET_USB_HANWANG=m CONFIG_TABLET_USB_KBTAB=m CONFIG_TABLET_USB_WACOM=m CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_ADS7846=m CONFIG_TOUCHSCREEN_AD7877=m CONFIG_TOUCHSCREEN_AD7879=m CONFIG_TOUCHSCREEN_AD7879_I2C=m # CONFIG_TOUCHSCREEN_AD7879_SPI is not set # CONFIG_TOUCHSCREEN_ATMEL_MXT is not set # CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set # CONFIG_TOUCHSCREEN_BU21013 is not set # CONFIG_TOUCHSCREEN_CY8CTMG110 is not set # CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set CONFIG_TOUCHSCREEN_DYNAPRO=m CONFIG_TOUCHSCREEN_HAMPSHIRE=m CONFIG_TOUCHSCREEN_EETI=m # CONFIG_TOUCHSCREEN_EGALAX is not set CONFIG_TOUCHSCREEN_FUJITSU=m # CONFIG_TOUCHSCREEN_ILI210X is not set CONFIG_TOUCHSCREEN_GUNZE=m CONFIG_TOUCHSCREEN_ELO=m CONFIG_TOUCHSCREEN_WACOM_W8001=m # CONFIG_TOUCHSCREEN_WACOM_I2C is not set # CONFIG_TOUCHSCREEN_MAX11801 is not set CONFIG_TOUCHSCREEN_MCS5000=m CONFIG_TOUCHSCREEN_MTOUCH=m CONFIG_TOUCHSCREEN_INEXIO=m CONFIG_TOUCHSCREEN_MK712=m CONFIG_TOUCHSCREEN_PENMOUNT=m CONFIG_TOUCHSCREEN_TOUCHRIGHT=m CONFIG_TOUCHSCREEN_TOUCHWIN=m # CONFIG_TOUCHSCREEN_PIXCIR is not set CONFIG_TOUCHSCREEN_WM97XX=m CONFIG_TOUCHSCREEN_WM9705=y CONFIG_TOUCHSCREEN_WM9712=y CONFIG_TOUCHSCREEN_WM9713=y CONFIG_TOUCHSCREEN_USB_COMPOSITE=m CONFIG_TOUCHSCREEN_USB_EGALAX=y CONFIG_TOUCHSCREEN_USB_PANJIT=y CONFIG_TOUCHSCREEN_USB_3M=y CONFIG_TOUCHSCREEN_USB_ITM=y CONFIG_TOUCHSCREEN_USB_ETURBO=y CONFIG_TOUCHSCREEN_USB_GUNZE=y CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y CONFIG_TOUCHSCREEN_USB_IRTOUCH=y CONFIG_TOUCHSCREEN_USB_IDEALTEK=y CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y CONFIG_TOUCHSCREEN_USB_GOTOP=y CONFIG_TOUCHSCREEN_USB_JASTEC=y CONFIG_TOUCHSCREEN_USB_ELO=y CONFIG_TOUCHSCREEN_USB_E2I=y CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y CONFIG_TOUCHSCREEN_USB_NEXIO=y CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y CONFIG_TOUCHSCREEN_TOUCHIT213=m # CONFIG_TOUCHSCREEN_TSC_SERIO is not set # CONFIG_TOUCHSCREEN_TSC2005 is not set CONFIG_TOUCHSCREEN_TSC2007=m # CONFIG_TOUCHSCREEN_ST1232 is not set CONFIG_TOUCHSCREEN_TPS6507X=m CONFIG_INPUT_MISC=y # CONFIG_INPUT_AD714X is not set # CONFIG_INPUT_BMA150 is not set CONFIG_INPUT_PCSPKR=m # CONFIG_INPUT_MMA8450 is not set # CONFIG_INPUT_MPU3050 is not set CONFIG_INPUT_APANEL=m # CONFIG_INPUT_GP2A is not set # CONFIG_INPUT_GPIO_TILT_POLLED is not set CONFIG_INPUT_ATLAS_BTNS=m CONFIG_INPUT_ATI_REMOTE2=m CONFIG_INPUT_KEYSPAN_REMOTE=m # CONFIG_INPUT_KXTJ9 is not set CONFIG_INPUT_POWERMATE=m CONFIG_INPUT_YEALINK=m CONFIG_INPUT_CM109=m CONFIG_INPUT_UINPUT=m CONFIG_INPUT_PCF50633_PMU=m # CONFIG_INPUT_PCF8574 is not set # CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set # CONFIG_INPUT_ADXL34X is not set # CONFIG_INPUT_CMA3000 is not set CONFIG_INPUT_XEN_KBDDEV_FRONTEND=y # # Hardware I/O ports # CONFIG_SERIO=y CONFIG_SERIO_I8042=y CONFIG_SERIO_SERPORT=m CONFIG_SERIO_CT82C710=m CONFIG_SERIO_PARKBD=m CONFIG_SERIO_PCIPS2=m CONFIG_SERIO_LIBPS2=y CONFIG_SERIO_RAW=m CONFIG_SERIO_ALTERA_PS2=m # CONFIG_SERIO_PS2MULT is not set CONFIG_GAMEPORT=m CONFIG_GAMEPORT_NS558=m CONFIG_GAMEPORT_L4=m CONFIG_GAMEPORT_EMU10K1=m CONFIG_GAMEPORT_FM801=m # # Character devices # CONFIG_VT=y CONFIG_CONSOLE_TRANSLATIONS=y CONFIG_VT_CONSOLE=y CONFIG_VT_CONSOLE_SLEEP=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_UNIX98_PTYS=y CONFIG_DEVPTS_MULTIPLE_INSTANCES=y # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_NONSTANDARD=y CONFIG_ROCKETPORT=m CONFIG_CYCLADES=m # CONFIG_CYZ_INTR is not set CONFIG_MOXA_INTELLIO=m CONFIG_MOXA_SMARTIO=m CONFIG_SYNCLINK=m CONFIG_SYNCLINKMP=m CONFIG_SYNCLINK_GT=m CONFIG_NOZOMI=m CONFIG_ISI=m CONFIG_N_HDLC=m CONFIG_N_GSM=m # CONFIG_TRACE_SINK is not set # CONFIG_DEVKMEM is not set CONFIG_STALDRV=y # # Serial drivers # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_FIX_EARLYCON_MEM=y CONFIG_SERIAL_8250_PCI=y CONFIG_SERIAL_8250_PNP=y CONFIG_SERIAL_8250_CS=m CONFIG_SERIAL_8250_NR_UARTS=32 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set CONFIG_SERIAL_8250_RSA=y # # Non-8250 serial port support # CONFIG_SERIAL_MAX3100=m # CONFIG_SERIAL_MAX3107 is not set CONFIG_SERIAL_MFD_HSU=m CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_JSM=m # CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_SERIAL_ALTERA_JTAGUART is not set # CONFIG_SERIAL_ALTERA_UART is not set # CONFIG_SERIAL_IFX6X60 is not set CONFIG_SERIAL_PCH_UART=m # CONFIG_SERIAL_XILINX_PS_UART is not set CONFIG_PRINTER=m # CONFIG_LP_CONSOLE is not set CONFIG_PPDEV=m CONFIG_HVC_DRIVER=y CONFIG_HVC_IRQ=y CONFIG_HVC_XEN=y CONFIG_HVC_XEN_FRONTEND=y CONFIG_VIRTIO_CONSOLE=m CONFIG_IPMI_HANDLER=m # CONFIG_IPMI_PANIC_EVENT is not set CONFIG_IPMI_DEVICE_INTERFACE=m CONFIG_IPMI_SI=m CONFIG_IPMI_WATCHDOG=m CONFIG_IPMI_POWEROFF=m CONFIG_HW_RANDOM=m CONFIG_HW_RANDOM_TIMERIOMEM=m CONFIG_HW_RANDOM_INTEL=m CONFIG_HW_RANDOM_AMD=m CONFIG_HW_RANDOM_VIA=m CONFIG_HW_RANDOM_VIRTIO=m CONFIG_NVRAM=m CONFIG_R3964=m CONFIG_APPLICOM=m # # PCMCIA character devices # CONFIG_SYNCLINK_CS=m CONFIG_CARDMAN_4000=m CONFIG_CARDMAN_4040=m CONFIG_IPWIRELESS=m CONFIG_MWAVE=m CONFIG_RAW_DRIVER=m CONFIG_MAX_RAW_DEVS=256 CONFIG_HPET=y CONFIG_HPET_MMAP=y CONFIG_HANGCHECK_TIMER=m CONFIG_TCG_TPM=m CONFIG_TCG_TIS=m CONFIG_TCG_NSC=m CONFIG_TCG_ATMEL=m CONFIG_TCG_INFINEON=m CONFIG_TELCLOCK=m CONFIG_DEVPORT=y CONFIG_I2C=m CONFIG_I2C_BOARDINFO=y CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=m # CONFIG_I2C_MUX is not set CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_SMBUS=m CONFIG_I2C_ALGOBIT=m CONFIG_I2C_ALGOPCA=m # # I2C Hardware Bus support # # # PC SMBus host controller drivers # CONFIG_I2C_ALI1535=m CONFIG_I2C_ALI1563=m CONFIG_I2C_ALI15X3=m CONFIG_I2C_AMD756=m CONFIG_I2C_AMD756_S4882=m CONFIG_I2C_AMD8111=m CONFIG_I2C_I801=m CONFIG_I2C_ISCH=m CONFIG_I2C_PIIX4=m CONFIG_I2C_NFORCE2=m CONFIG_I2C_NFORCE2_S4985=m CONFIG_I2C_SIS5595=m CONFIG_I2C_SIS630=m CONFIG_I2C_SIS96X=m CONFIG_I2C_VIA=m CONFIG_I2C_VIAPRO=m # # ACPI drivers # CONFIG_I2C_SCMI=m # # I2C system bus drivers (mostly embedded / system-on-chip) # # CONFIG_I2C_DESIGNWARE_PCI is not set CONFIG_I2C_EG20T=m # CONFIG_I2C_GPIO is not set # CONFIG_I2C_INTEL_MID is not set CONFIG_I2C_OCORES=m CONFIG_I2C_PCA_PLATFORM=m # CONFIG_I2C_PXA_PCI is not set CONFIG_I2C_SIMTEC=m # CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers # CONFIG_I2C_DIOLAN_U2C=m CONFIG_I2C_PARPORT=m CONFIG_I2C_PARPORT_LIGHT=m CONFIG_I2C_TAOS_EVM=m CONFIG_I2C_TINY_USB=m # # Other I2C/SMBus bus drivers # CONFIG_I2C_STUB=m # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set CONFIG_SPI=y # CONFIG_SPI_DEBUG is not set CONFIG_SPI_MASTER=y # # SPI Master Controller Drivers # # CONFIG_SPI_ALTERA is not set CONFIG_SPI_BITBANG=m CONFIG_SPI_BUTTERFLY=m # CONFIG_SPI_GPIO is not set CONFIG_SPI_LM70_LLP=m # CONFIG_SPI_OC_TINY is not set # CONFIG_SPI_PXA2XX_PCI is not set CONFIG_SPI_TOPCLIFF_PCH=m # CONFIG_SPI_XILINX is not set # CONFIG_SPI_DESIGNWARE is not set # # SPI Protocol Masters # # CONFIG_SPI_SPIDEV is not set CONFIG_SPI_TLE62X0=m # CONFIG_HSI is not set # # PPS support # CONFIG_PPS=m # CONFIG_PPS_DEBUG is not set # # PPS clients support # # CONFIG_PPS_CLIENT_KTIMER is not set CONFIG_PPS_CLIENT_LDISC=m CONFIG_PPS_CLIENT_PARPORT=m # CONFIG_PPS_CLIENT_GPIO is not set # # PPS generators support # # # PTP clock support # CONFIG_PTP_1588_CLOCK=m # # Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. # # CONFIG_PTP_1588_CLOCK_PCH is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y CONFIG_GPIOLIB=y # CONFIG_DEBUG_GPIO is not set # CONFIG_GPIO_SYSFS is not set # # Memory mapped GPIO drivers: # # CONFIG_GPIO_GENERIC_PLATFORM is not set # CONFIG_GPIO_IT8761E is not set # CONFIG_GPIO_SCH is not set # CONFIG_GPIO_ICH is not set # CONFIG_GPIO_VX855 is not set # # I2C GPIO expanders: # # CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set # CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: # # CONFIG_GPIO_LANGWELL is not set CONFIG_GPIO_PCH=m CONFIG_GPIO_ML_IOH=m # CONFIG_GPIO_RDC321X is not set # # SPI GPIO expanders: # # CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set # CONFIG_GPIO_MC33880 is not set # CONFIG_GPIO_74X164 is not set # # AC97 GPIO expanders: # # # MODULbus GPIO expanders: # CONFIG_W1=m CONFIG_W1_CON=y # # 1-wire Bus Masters # CONFIG_W1_MASTER_MATROX=m CONFIG_W1_MASTER_DS2490=m CONFIG_W1_MASTER_DS2482=m # CONFIG_W1_MASTER_DS1WM is not set # CONFIG_W1_MASTER_GPIO is not set # # 1-wire Slaves # CONFIG_W1_SLAVE_THERM=m CONFIG_W1_SLAVE_SMEM=m # CONFIG_W1_SLAVE_DS2408 is not set # CONFIG_W1_SLAVE_DS2423 is not set CONFIG_W1_SLAVE_DS2431=m CONFIG_W1_SLAVE_DS2433=m # CONFIG_W1_SLAVE_DS2433_CRC is not set CONFIG_W1_SLAVE_DS2760=m # CONFIG_W1_SLAVE_DS2780 is not set # CONFIG_W1_SLAVE_DS2781 is not set CONFIG_W1_SLAVE_BQ27000=m CONFIG_POWER_SUPPLY=y # CONFIG_POWER_SUPPLY_DEBUG is not set CONFIG_PDA_POWER=m # CONFIG_TEST_POWER is not set CONFIG_BATTERY_DS2760=m # CONFIG_BATTERY_DS2780 is not set # CONFIG_BATTERY_DS2781 is not set CONFIG_BATTERY_DS2782=m CONFIG_BATTERY_SBS=m CONFIG_BATTERY_BQ27x00=m CONFIG_BATTERY_BQ27X00_I2C=y CONFIG_BATTERY_BQ27X00_PLATFORM=y CONFIG_BATTERY_MAX17040=m # CONFIG_BATTERY_MAX17042 is not set CONFIG_CHARGER_PCF50633=m # CONFIG_CHARGER_ISP1704 is not set # CONFIG_CHARGER_MAX8903 is not set # CONFIG_CHARGER_LP8727 is not set # CONFIG_CHARGER_GPIO is not set # CONFIG_CHARGER_MANAGER is not set # CONFIG_CHARGER_SMB347 is not set CONFIG_HWMON=y CONFIG_HWMON_VID=m # CONFIG_HWMON_DEBUG_CHIP is not set # # Native drivers # CONFIG_SENSORS_ABITUGURU=m CONFIG_SENSORS_ABITUGURU3=m # CONFIG_SENSORS_AD7314 is not set CONFIG_SENSORS_AD7414=m CONFIG_SENSORS_AD7418=m CONFIG_SENSORS_ADCXX=m CONFIG_SENSORS_ADM1021=m CONFIG_SENSORS_ADM1025=m CONFIG_SENSORS_ADM1026=m CONFIG_SENSORS_ADM1029=m CONFIG_SENSORS_ADM1031=m CONFIG_SENSORS_ADM9240=m CONFIG_SENSORS_ADT7411=m CONFIG_SENSORS_ADT7462=m CONFIG_SENSORS_ADT7470=m CONFIG_SENSORS_ADT7475=m CONFIG_SENSORS_ASC7621=m CONFIG_SENSORS_K8TEMP=m CONFIG_SENSORS_K10TEMP=m CONFIG_SENSORS_FAM15H_POWER=m CONFIG_SENSORS_ASB100=m CONFIG_SENSORS_ATXP1=m CONFIG_SENSORS_DS620=m CONFIG_SENSORS_DS1621=m CONFIG_SENSORS_I5K_AMB=m CONFIG_SENSORS_F71805F=m CONFIG_SENSORS_F71882FG=m CONFIG_SENSORS_F75375S=m CONFIG_SENSORS_FSCHMD=m CONFIG_SENSORS_G760A=m CONFIG_SENSORS_GL518SM=m CONFIG_SENSORS_GL520SM=m # CONFIG_SENSORS_GPIO_FAN is not set CONFIG_SENSORS_CORETEMP=m CONFIG_SENSORS_IBMAEM=m CONFIG_SENSORS_IBMPEX=m CONFIG_SENSORS_IT87=m # CONFIG_SENSORS_JC42 is not set CONFIG_SENSORS_LINEAGE=m CONFIG_SENSORS_LM63=m CONFIG_SENSORS_LM70=m CONFIG_SENSORS_LM73=m CONFIG_SENSORS_LM75=m CONFIG_SENSORS_LM77=m CONFIG_SENSORS_LM78=m CONFIG_SENSORS_LM80=m CONFIG_SENSORS_LM83=m CONFIG_SENSORS_LM85=m CONFIG_SENSORS_LM87=m CONFIG_SENSORS_LM90=m CONFIG_SENSORS_LM92=m CONFIG_SENSORS_LM93=m CONFIG_SENSORS_LTC4151=m CONFIG_SENSORS_LTC4215=m CONFIG_SENSORS_LTC4245=m CONFIG_SENSORS_LTC4261=m CONFIG_SENSORS_LM95241=m CONFIG_SENSORS_LM95245=m CONFIG_SENSORS_MAX1111=m CONFIG_SENSORS_MAX16065=m CONFIG_SENSORS_MAX1619=m CONFIG_SENSORS_MAX1668=m CONFIG_SENSORS_MAX6639=m CONFIG_SENSORS_MAX6642=m CONFIG_SENSORS_MAX6650=m # CONFIG_SENSORS_MCP3021 is not set CONFIG_SENSORS_NTC_THERMISTOR=m CONFIG_SENSORS_PC87360=m CONFIG_SENSORS_PC87427=m CONFIG_SENSORS_PCF8591=m # CONFIG_PMBUS is not set # CONFIG_SENSORS_SHT15 is not set CONFIG_SENSORS_SHT21=m CONFIG_SENSORS_SIS5595=m CONFIG_SENSORS_SMM665=m CONFIG_SENSORS_DME1737=m CONFIG_SENSORS_EMC1403=m CONFIG_SENSORS_EMC2103=m CONFIG_SENSORS_EMC6W201=m CONFIG_SENSORS_SMSC47M1=m CONFIG_SENSORS_SMSC47M192=m CONFIG_SENSORS_SMSC47B397=m CONFIG_SENSORS_SCH56XX_COMMON=m CONFIG_SENSORS_SCH5627=m CONFIG_SENSORS_SCH5636=m CONFIG_SENSORS_ADS1015=m CONFIG_SENSORS_ADS7828=m CONFIG_SENSORS_ADS7871=m CONFIG_SENSORS_AMC6821=m # CONFIG_SENSORS_INA2XX is not set CONFIG_SENSORS_THMC50=m CONFIG_SENSORS_TMP102=m CONFIG_SENSORS_TMP401=m CONFIG_SENSORS_TMP421=m CONFIG_SENSORS_VIA_CPUTEMP=m CONFIG_SENSORS_VIA686A=m CONFIG_SENSORS_VT1211=m CONFIG_SENSORS_VT8231=m CONFIG_SENSORS_W83781D=m CONFIG_SENSORS_W83791D=m CONFIG_SENSORS_W83792D=m CONFIG_SENSORS_W83793=m CONFIG_SENSORS_W83795=m # CONFIG_SENSORS_W83795_FANCTRL is not set CONFIG_SENSORS_W83L785TS=m CONFIG_SENSORS_W83L786NG=m CONFIG_SENSORS_W83627HF=m CONFIG_SENSORS_W83627EHF=m CONFIG_SENSORS_APPLESMC=m # # ACPI drivers # CONFIG_SENSORS_ACPI_POWER=m CONFIG_SENSORS_ATK0110=m CONFIG_THERMAL=m CONFIG_THERMAL_HWMON=y CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y # CONFIG_WATCHDOG_NOWAYOUT is not set # # Watchdog Device Drivers # CONFIG_SOFT_WATCHDOG=m CONFIG_ACQUIRE_WDT=m CONFIG_ADVANTECH_WDT=m CONFIG_ALIM1535_WDT=m CONFIG_ALIM7101_WDT=m CONFIG_F71808E_WDT=m CONFIG_SP5100_TCO=m CONFIG_SC520_WDT=m CONFIG_SBC_FITPC2_WATCHDOG=m CONFIG_EUROTECH_WDT=m CONFIG_IB700_WDT=m CONFIG_IBMASR=m CONFIG_WAFER_WDT=m CONFIG_I6300ESB_WDT=m # CONFIG_IE6XX_WDT is not set CONFIG_ITCO_WDT=m CONFIG_ITCO_VENDOR_SUPPORT=y CONFIG_IT8712F_WDT=m CONFIG_IT87_WDT=m CONFIG_HP_WATCHDOG=m CONFIG_HPWDT_NMI_DECODING=y CONFIG_SC1200_WDT=m CONFIG_PC87413_WDT=m CONFIG_NV_TCO=m CONFIG_60XX_WDT=m CONFIG_SBC8360_WDT=m CONFIG_CPU5_WDT=m CONFIG_SMSC_SCH311X_WDT=m CONFIG_SMSC37B787_WDT=m # CONFIG_VIA_WDT is not set CONFIG_W83627HF_WDT=m CONFIG_W83697HF_WDT=m CONFIG_W83697UG_WDT=m CONFIG_W83877F_WDT=m CONFIG_W83977F_WDT=m CONFIG_MACHZ_WDT=m CONFIG_SBC_EPX_C3_WATCHDOG=m CONFIG_XEN_WDT=m # # PCI-based Watchdog Cards # CONFIG_PCIPCWATCHDOG=m CONFIG_WDTPCI=m # # USB-based Watchdog Cards # CONFIG_USBPCWATCHDOG=m CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # CONFIG_SSB=m CONFIG_SSB_SPROM=y CONFIG_SSB_BLOCKIO=y CONFIG_SSB_PCIHOST_POSSIBLE=y CONFIG_SSB_PCIHOST=y CONFIG_SSB_B43_PCI_BRIDGE=y CONFIG_SSB_PCMCIAHOST_POSSIBLE=y CONFIG_SSB_PCMCIAHOST=y CONFIG_SSB_SDIOHOST_POSSIBLE=y CONFIG_SSB_SDIOHOST=y # CONFIG_SSB_DEBUG is not set CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y CONFIG_SSB_DRIVER_PCICORE=y CONFIG_BCMA_POSSIBLE=y # # Broadcom specific AMBA # CONFIG_BCMA=m CONFIG_BCMA_BLOCKIO=y CONFIG_BCMA_HOST_PCI_POSSIBLE=y CONFIG_BCMA_HOST_PCI=y # CONFIG_BCMA_DEBUG is not set # # Multifunction device drivers # CONFIG_MFD_CORE=m CONFIG_MFD_SM501=m # CONFIG_MFD_SM501_GPIO is not set CONFIG_HTC_PASIC3=m # CONFIG_UCB1400_CORE is not set # CONFIG_MFD_LM3533 is not set # CONFIG_TPS6105X is not set CONFIG_TPS65010=m # CONFIG_TPS6507X is not set # CONFIG_MFD_TPS65217 is not set # CONFIG_MFD_TPS65912_SPI is not set # CONFIG_MFD_STMPE is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_DA9052_SPI is not set # CONFIG_MFD_WM831X_SPI is not set CONFIG_MFD_PCF50633=m CONFIG_PCF50633_ADC=m CONFIG_PCF50633_GPIO=m # CONFIG_MFD_MC13XXX_SPI is not set # CONFIG_MFD_MC13XXX_I2C is not set # CONFIG_ABX500_CORE is not set # CONFIG_EZX_PCAP is not set # CONFIG_MFD_CS5535 is not set # CONFIG_MFD_TIMBERDALE is not set CONFIG_LPC_SCH=m CONFIG_LPC_ICH=m # CONFIG_MFD_RDC321X is not set # CONFIG_MFD_JANZ_CMODIO is not set # CONFIG_MFD_VX855 is not set CONFIG_MFD_WL1273_CORE=m CONFIG_REGULATOR=y # CONFIG_REGULATOR_DEBUG is not set # CONFIG_REGULATOR_DUMMY is not set CONFIG_REGULATOR_FIXED_VOLTAGE=m # CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set CONFIG_REGULATOR_USERSPACE_CONSUMER=m # CONFIG_REGULATOR_GPIO is not set # CONFIG_REGULATOR_AD5398 is not set # CONFIG_REGULATOR_ISL6271A is not set CONFIG_REGULATOR_MAX1586=m CONFIG_REGULATOR_MAX8649=m CONFIG_REGULATOR_MAX8660=m # CONFIG_REGULATOR_MAX8952 is not set CONFIG_REGULATOR_LP3971=m # CONFIG_REGULATOR_LP3972 is not set CONFIG_REGULATOR_PCF50633=m # CONFIG_REGULATOR_TPS62360 is not set CONFIG_REGULATOR_TPS65023=m CONFIG_REGULATOR_TPS6507X=m # CONFIG_REGULATOR_TPS6524X is not set CONFIG_MEDIA_SUPPORT=m # # Multimedia core support # CONFIG_MEDIA_CONTROLLER=y CONFIG_VIDEO_DEV=m CONFIG_VIDEO_V4L2_COMMON=m # CONFIG_VIDEO_V4L2_SUBDEV_API is not set CONFIG_DVB_CORE=m CONFIG_DVB_NET=y CONFIG_VIDEO_MEDIA=m # # Multimedia drivers # CONFIG_VIDEO_SAA7146=m CONFIG_VIDEO_SAA7146_VV=m CONFIG_RC_CORE=m CONFIG_LIRC=m CONFIG_RC_MAP=m CONFIG_IR_NEC_DECODER=m CONFIG_IR_RC5_DECODER=m CONFIG_IR_RC6_DECODER=m CONFIG_IR_JVC_DECODER=m CONFIG_IR_SONY_DECODER=m CONFIG_IR_RC5_SZ_DECODER=m CONFIG_IR_SANYO_DECODER=m CONFIG_IR_MCE_KBD_DECODER=m CONFIG_IR_LIRC_CODEC=m CONFIG_RC_ATI_REMOTE=m CONFIG_IR_ENE=m CONFIG_IR_IMON=m CONFIG_IR_MCEUSB=m CONFIG_IR_ITE_CIR=m CONFIG_IR_FINTEK=m CONFIG_IR_NUVOTON=m CONFIG_IR_REDRAT3=m CONFIG_IR_STREAMZAP=m CONFIG_IR_WINBOND_CIR=m CONFIG_RC_LOOPBACK=m # CONFIG_IR_GPIO_CIR is not set CONFIG_MEDIA_ATTACH=y CONFIG_MEDIA_TUNER=m # CONFIG_MEDIA_TUNER_CUSTOMISE is not set CONFIG_MEDIA_TUNER_SIMPLE=m CONFIG_MEDIA_TUNER_TDA8290=m CONFIG_MEDIA_TUNER_TDA827X=m CONFIG_MEDIA_TUNER_TDA18271=m CONFIG_MEDIA_TUNER_TDA9887=m CONFIG_MEDIA_TUNER_TEA5761=m CONFIG_MEDIA_TUNER_TEA5767=m CONFIG_MEDIA_TUNER_MT20XX=m CONFIG_MEDIA_TUNER_MT2060=m CONFIG_MEDIA_TUNER_MT2266=m CONFIG_MEDIA_TUNER_MT2131=m CONFIG_MEDIA_TUNER_QT1010=m CONFIG_MEDIA_TUNER_XC2028=m CONFIG_MEDIA_TUNER_XC5000=m CONFIG_MEDIA_TUNER_XC4000=m CONFIG_MEDIA_TUNER_MXL5005S=m CONFIG_MEDIA_TUNER_MXL5007T=m CONFIG_MEDIA_TUNER_MC44S803=m CONFIG_MEDIA_TUNER_MAX2165=m CONFIG_MEDIA_TUNER_TDA18218=m CONFIG_MEDIA_TUNER_TDA18212=m CONFIG_VIDEO_V4L2=m CONFIG_VIDEOBUF_GEN=m CONFIG_VIDEOBUF_DMA_SG=m CONFIG_VIDEOBUF_VMALLOC=m CONFIG_VIDEOBUF_DVB=m CONFIG_VIDEO_BTCX=m CONFIG_VIDEO_TVEEPROM=m CONFIG_VIDEO_TUNER=m CONFIG_VIDEOBUF2_CORE=m CONFIG_VIDEOBUF2_MEMOPS=m CONFIG_VIDEOBUF2_VMALLOC=m CONFIG_VIDEO_CAPTURE_DRIVERS=y # CONFIG_VIDEO_ADV_DEBUG is not set # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set CONFIG_VIDEO_HELPER_CHIPS_AUTO=y CONFIG_VIDEO_IR_I2C=m # # Audio decoders, processors and mixers # CONFIG_VIDEO_TVAUDIO=m CONFIG_VIDEO_TDA7432=m CONFIG_VIDEO_TDA9840=m CONFIG_VIDEO_TEA6415C=m CONFIG_VIDEO_TEA6420=m CONFIG_VIDEO_MSP3400=m CONFIG_VIDEO_CS5345=m CONFIG_VIDEO_CS53L32A=m CONFIG_VIDEO_WM8775=m CONFIG_VIDEO_WM8739=m CONFIG_VIDEO_VP27SMPX=m # # RDS decoders # CONFIG_VIDEO_SAA6588=m # # Video decoders # CONFIG_VIDEO_BT819=m CONFIG_VIDEO_BT856=m CONFIG_VIDEO_BT866=m CONFIG_VIDEO_KS0127=m CONFIG_VIDEO_SAA7110=m CONFIG_VIDEO_SAA711X=m CONFIG_VIDEO_TVP5150=m CONFIG_VIDEO_VPX3220=m # # Video and audio decoders # CONFIG_VIDEO_SAA717X=m CONFIG_VIDEO_CX25840=m # # MPEG video encoders # CONFIG_VIDEO_CX2341X=m # # Video encoders # CONFIG_VIDEO_SAA7127=m CONFIG_VIDEO_SAA7185=m CONFIG_VIDEO_ADV7170=m CONFIG_VIDEO_ADV7175=m # # Camera sensor devices # CONFIG_VIDEO_MT9V011=m # # Flash devices # # # Video improvement chips # CONFIG_VIDEO_UPD64031A=m CONFIG_VIDEO_UPD64083=m # # Miscelaneous helper chips # CONFIG_VIDEO_M52790=m CONFIG_VIDEO_VIVI=m CONFIG_V4L_USB_DRIVERS=y CONFIG_VIDEO_AU0828=m CONFIG_USB_VIDEO_CLASS=m CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y CONFIG_USB_GSPCA=m CONFIG_USB_M5602=m CONFIG_USB_STV06XX=m CONFIG_USB_GL860=m CONFIG_USB_GSPCA_BENQ=m CONFIG_USB_GSPCA_CONEX=m CONFIG_USB_GSPCA_CPIA1=m CONFIG_USB_GSPCA_ETOMS=m CONFIG_USB_GSPCA_FINEPIX=m CONFIG_USB_GSPCA_JEILINJ=m # CONFIG_USB_GSPCA_JL2005BCD is not set CONFIG_USB_GSPCA_KINECT=m CONFIG_USB_GSPCA_KONICA=m CONFIG_USB_GSPCA_MARS=m CONFIG_USB_GSPCA_MR97310A=m CONFIG_USB_GSPCA_NW80X=m CONFIG_USB_GSPCA_OV519=m CONFIG_USB_GSPCA_OV534=m CONFIG_USB_GSPCA_OV534_9=m CONFIG_USB_GSPCA_PAC207=m CONFIG_USB_GSPCA_PAC7302=m CONFIG_USB_GSPCA_PAC7311=m CONFIG_USB_GSPCA_SE401=m CONFIG_USB_GSPCA_SN9C2028=m CONFIG_USB_GSPCA_SN9C20X=m CONFIG_USB_GSPCA_SONIXB=m CONFIG_USB_GSPCA_SONIXJ=m CONFIG_USB_GSPCA_SPCA500=m CONFIG_USB_GSPCA_SPCA501=m CONFIG_USB_GSPCA_SPCA505=m CONFIG_USB_GSPCA_SPCA506=m CONFIG_USB_GSPCA_SPCA508=m CONFIG_USB_GSPCA_SPCA561=m CONFIG_USB_GSPCA_SPCA1528=m CONFIG_USB_GSPCA_SQ905=m CONFIG_USB_GSPCA_SQ905C=m CONFIG_USB_GSPCA_SQ930X=m CONFIG_USB_GSPCA_STK014=m CONFIG_USB_GSPCA_STV0680=m CONFIG_USB_GSPCA_SUNPLUS=m CONFIG_USB_GSPCA_T613=m CONFIG_USB_GSPCA_TOPRO=m CONFIG_USB_GSPCA_TV8532=m CONFIG_USB_GSPCA_VC032X=m CONFIG_USB_GSPCA_VICAM=m CONFIG_USB_GSPCA_XIRLINK_CIT=m CONFIG_USB_GSPCA_ZC3XX=m CONFIG_VIDEO_PVRUSB2=m CONFIG_VIDEO_PVRUSB2_SYSFS=y CONFIG_VIDEO_PVRUSB2_DVB=y # CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set CONFIG_VIDEO_HDPVR=m CONFIG_VIDEO_EM28XX=m CONFIG_VIDEO_EM28XX_ALSA=m CONFIG_VIDEO_EM28XX_DVB=m CONFIG_VIDEO_EM28XX_RC=m CONFIG_VIDEO_TLG2300=m CONFIG_VIDEO_CX231XX=m CONFIG_VIDEO_CX231XX_RC=y CONFIG_VIDEO_CX231XX_ALSA=m CONFIG_VIDEO_CX231XX_DVB=m CONFIG_VIDEO_TM6000=m CONFIG_VIDEO_TM6000_ALSA=m CONFIG_VIDEO_TM6000_DVB=m CONFIG_VIDEO_USBVISION=m CONFIG_USB_SN9C102=m CONFIG_USB_PWC=m # CONFIG_USB_PWC_DEBUG is not set CONFIG_USB_PWC_INPUT_EVDEV=y CONFIG_VIDEO_CPIA2=m CONFIG_USB_ZR364XX=m CONFIG_USB_STKWEBCAM=m CONFIG_USB_S2255=m CONFIG_V4L_PCI_DRIVERS=y CONFIG_VIDEO_BT848=m CONFIG_VIDEO_BT848_DVB=y CONFIG_VIDEO_CX18=m CONFIG_VIDEO_CX18_ALSA=m CONFIG_VIDEO_CX23885=m # CONFIG_MEDIA_ALTERA_CI is not set # CONFIG_VIDEO_CX25821 is not set CONFIG_VIDEO_CX88=m CONFIG_VIDEO_CX88_ALSA=m CONFIG_VIDEO_CX88_BLACKBIRD=m CONFIG_VIDEO_CX88_DVB=m CONFIG_VIDEO_CX88_VP3054=m CONFIG_VIDEO_CX88_MPEG=m CONFIG_VIDEO_HEXIUM_GEMINI=m CONFIG_VIDEO_HEXIUM_ORION=m CONFIG_VIDEO_IVTV=m CONFIG_VIDEO_FB_IVTV=m CONFIG_VIDEO_MEYE=m CONFIG_VIDEO_MXB=m CONFIG_VIDEO_SAA7134=m CONFIG_VIDEO_SAA7134_ALSA=m CONFIG_VIDEO_SAA7134_RC=y CONFIG_VIDEO_SAA7134_DVB=m CONFIG_VIDEO_SAA7164=m CONFIG_VIDEO_ZORAN=m CONFIG_VIDEO_ZORAN_DC30=m CONFIG_VIDEO_ZORAN_ZR36060=m CONFIG_VIDEO_ZORAN_BUZ=m CONFIG_VIDEO_ZORAN_DC10=m CONFIG_VIDEO_ZORAN_LML33=m CONFIG_VIDEO_ZORAN_LML33R10=m CONFIG_VIDEO_ZORAN_AVS6EYES=m # CONFIG_V4L_ISA_PARPORT_DRIVERS is not set # CONFIG_V4L_PLATFORM_DRIVERS is not set CONFIG_V4L_MEM2MEM_DRIVERS=y # CONFIG_VIDEO_MEM2MEM_TESTDEV is not set CONFIG_RADIO_ADAPTERS=y CONFIG_RADIO_SI470X=y CONFIG_USB_SI470X=m CONFIG_I2C_SI470X=m CONFIG_USB_MR800=m CONFIG_USB_DSBR=m CONFIG_RADIO_MAXIRADIO=m CONFIG_I2C_SI4713=m CONFIG_RADIO_SI4713=m # CONFIG_USB_KEENE is not set CONFIG_RADIO_TEA5764=m CONFIG_RADIO_SAA7706H=m CONFIG_RADIO_TEF6862=m CONFIG_RADIO_WL1273=m # # Texas Instruments WL128x FM driver (ST based) # # CONFIG_RADIO_WL128X is not set CONFIG_DVB_MAX_ADAPTERS=8 CONFIG_DVB_DYNAMIC_MINORS=y CONFIG_DVB_CAPTURE_DRIVERS=y # # Supported SAA7146 based PCI Adapters # CONFIG_TTPCI_EEPROM=m CONFIG_DVB_AV7110=m CONFIG_DVB_AV7110_OSD=y CONFIG_DVB_BUDGET_CORE=m CONFIG_DVB_BUDGET=m CONFIG_DVB_BUDGET_CI=m CONFIG_DVB_BUDGET_AV=m CONFIG_DVB_BUDGET_PATCH=m # # Supported USB Adapters # CONFIG_DVB_USB=m # CONFIG_DVB_USB_DEBUG is not set CONFIG_DVB_USB_A800=m CONFIG_DVB_USB_DIBUSB_MB=m CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y CONFIG_DVB_USB_DIBUSB_MC=m CONFIG_DVB_USB_DIB0700=m CONFIG_DVB_USB_UMT_010=m CONFIG_DVB_USB_CXUSB=m CONFIG_DVB_USB_M920X=m CONFIG_DVB_USB_GL861=m CONFIG_DVB_USB_AU6610=m CONFIG_DVB_USB_DIGITV=m CONFIG_DVB_USB_VP7045=m CONFIG_DVB_USB_VP702X=m CONFIG_DVB_USB_GP8PSK=m CONFIG_DVB_USB_NOVA_T_USB2=m CONFIG_DVB_USB_TTUSB2=m CONFIG_DVB_USB_DTT200U=m CONFIG_DVB_USB_OPERA1=m CONFIG_DVB_USB_AF9005=m CONFIG_DVB_USB_AF9005_REMOTE=m CONFIG_DVB_USB_PCTV452E=m CONFIG_DVB_USB_DW2102=m CONFIG_DVB_USB_CINERGY_T2=m CONFIG_DVB_USB_ANYSEE=m CONFIG_DVB_USB_DTV5100=m CONFIG_DVB_USB_AF9015=m CONFIG_DVB_USB_CE6230=m CONFIG_DVB_USB_FRIIO=m CONFIG_DVB_USB_EC168=m # CONFIG_DVB_USB_AZ6007 is not set CONFIG_DVB_USB_AZ6027=m CONFIG_DVB_USB_LME2510=m CONFIG_DVB_USB_TECHNISAT_USB2=m CONFIG_DVB_USB_IT913X=m CONFIG_DVB_USB_MXL111SF=m # CONFIG_DVB_USB_RTL28XXU is not set # CONFIG_DVB_USB_AF9035 is not set CONFIG_DVB_TTUSB_BUDGET=m CONFIG_DVB_TTUSB_DEC=m CONFIG_SMS_SIANO_MDTV=m # # Siano module components # CONFIG_SMS_USB_DRV=m CONFIG_SMS_SDIO_DRV=m # # Supported FlexCopII (B2C2) Adapters # CONFIG_DVB_B2C2_FLEXCOP=m CONFIG_DVB_B2C2_FLEXCOP_PCI=m CONFIG_DVB_B2C2_FLEXCOP_USB=m # CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set # # Supported BT878 Adapters # CONFIG_DVB_BT8XX=m # # Supported Pluto2 Adapters # CONFIG_DVB_PLUTO2=m # # Supported SDMC DM1105 Adapters # CONFIG_DVB_DM1105=m # # Supported FireWire (IEEE 1394) Adapters # CONFIG_DVB_FIREDTV=m CONFIG_DVB_FIREDTV_INPUT=y # # Supported Earthsoft PT1 Adapters # CONFIG_DVB_PT1=m # # Supported Mantis Adapters # CONFIG_MANTIS_CORE=m CONFIG_DVB_MANTIS=m CONFIG_DVB_HOPPER=m # # Supported nGene Adapters # CONFIG_DVB_NGENE=m # # Supported ddbridge ('Octopus') Adapters # CONFIG_DVB_DDBRIDGE=m # # Supported DVB Frontends # # CONFIG_DVB_FE_CUSTOMISE is not set # # Multistandard (satellite) frontends # CONFIG_DVB_STB0899=m CONFIG_DVB_STB6100=m CONFIG_DVB_STV090x=m CONFIG_DVB_STV6110x=m # # Multistandard (cable + terrestrial) frontends # CONFIG_DVB_DRXK=m CONFIG_DVB_TDA18271C2DD=m # # DVB-S (satellite) frontends # CONFIG_DVB_CX24110=m CONFIG_DVB_CX24123=m CONFIG_DVB_MT312=m CONFIG_DVB_ZL10036=m CONFIG_DVB_ZL10039=m CONFIG_DVB_S5H1420=m CONFIG_DVB_STV0288=m CONFIG_DVB_STB6000=m CONFIG_DVB_STV0299=m CONFIG_DVB_STV6110=m CONFIG_DVB_STV0900=m CONFIG_DVB_TDA8083=m CONFIG_DVB_TDA10086=m CONFIG_DVB_TDA8261=m CONFIG_DVB_VES1X93=m CONFIG_DVB_TUNER_ITD1000=m CONFIG_DVB_TUNER_CX24113=m CONFIG_DVB_TDA826X=m CONFIG_DVB_TUA6100=m CONFIG_DVB_CX24116=m CONFIG_DVB_SI21XX=m CONFIG_DVB_DS3000=m CONFIG_DVB_MB86A16=m CONFIG_DVB_TDA10071=m # # DVB-T (terrestrial) frontends # CONFIG_DVB_SP8870=m CONFIG_DVB_SP887X=m CONFIG_DVB_CX22700=m CONFIG_DVB_CX22702=m CONFIG_DVB_DRXD=m CONFIG_DVB_L64781=m CONFIG_DVB_TDA1004X=m CONFIG_DVB_NXT6000=m CONFIG_DVB_MT352=m CONFIG_DVB_ZL10353=m CONFIG_DVB_DIB3000MB=m CONFIG_DVB_DIB3000MC=m CONFIG_DVB_DIB7000M=m CONFIG_DVB_DIB7000P=m CONFIG_DVB_TDA10048=m CONFIG_DVB_AF9013=m CONFIG_DVB_EC100=m CONFIG_DVB_STV0367=m CONFIG_DVB_CXD2820R=m # # DVB-C (cable) frontends # CONFIG_DVB_VES1820=m CONFIG_DVB_TDA10021=m CONFIG_DVB_TDA10023=m CONFIG_DVB_STV0297=m # # ATSC (North American/Korean Terrestrial/Cable DTV) frontends # CONFIG_DVB_NXT200X=m CONFIG_DVB_OR51211=m CONFIG_DVB_OR51132=m CONFIG_DVB_BCM3510=m CONFIG_DVB_LGDT330X=m CONFIG_DVB_LGDT3305=m CONFIG_DVB_LG2160=m CONFIG_DVB_S5H1409=m CONFIG_DVB_AU8522=m CONFIG_DVB_AU8522_DTV=m CONFIG_DVB_AU8522_V4L=m CONFIG_DVB_S5H1411=m # # ISDB-T (terrestrial) frontends # CONFIG_DVB_S921=m CONFIG_DVB_DIB8000=m CONFIG_DVB_MB86A20S=m # # Digital terrestrial only tuners/PLL # CONFIG_DVB_PLL=m CONFIG_DVB_TUNER_DIB0070=m CONFIG_DVB_TUNER_DIB0090=m # # SEC control devices for DVB-S # CONFIG_DVB_LNBP21=m CONFIG_DVB_LNBP22=m CONFIG_DVB_ISL6405=m CONFIG_DVB_ISL6421=m CONFIG_DVB_ISL6423=m CONFIG_DVB_A8293=m CONFIG_DVB_LGS8GXX=m CONFIG_DVB_ATBM8830=m CONFIG_DVB_TDA665x=m CONFIG_DVB_IX2505V=m CONFIG_DVB_IT913X_FE=m CONFIG_DVB_M88RS2000=m # # Tools to develop new frontends # # CONFIG_DVB_DUMMY_FE is not set # # Graphics support # CONFIG_AGP=y CONFIG_AGP_AMD64=y CONFIG_AGP_INTEL=y CONFIG_AGP_SIS=y CONFIG_AGP_VIA=y CONFIG_VGA_ARB=y CONFIG_VGA_ARB_MAX_GPUS=16 CONFIG_VGA_SWITCHEROO=y CONFIG_DRM=m CONFIG_DRM_KMS_HELPER=m # CONFIG_DRM_LOAD_EDID_FIRMWARE is not set CONFIG_DRM_TTM=m CONFIG_DRM_TDFX=m CONFIG_DRM_R128=m CONFIG_DRM_RADEON=m CONFIG_DRM_RADEON_KMS=y CONFIG_DRM_NOUVEAU=m CONFIG_DRM_NOUVEAU_BACKLIGHT=y # CONFIG_DRM_NOUVEAU_DEBUG is not set # # I2C encoder or helper chips # CONFIG_DRM_I2C_CH7006=m CONFIG_DRM_I2C_SIL164=m # CONFIG_DRM_I810 is not set CONFIG_DRM_I915=m CONFIG_DRM_I915_KMS=y CONFIG_DRM_MGA=m CONFIG_DRM_SIS=m CONFIG_DRM_VIA=m CONFIG_DRM_SAVAGE=m CONFIG_DRM_VMWGFX=m # CONFIG_DRM_GMA500 is not set # CONFIG_DRM_UDL is not set # CONFIG_DRM_AST is not set # CONFIG_DRM_MGAG200 is not set # CONFIG_DRM_CIRRUS_QEMU is not set # CONFIG_STUB_POULSBO is not set CONFIG_VGASTATE=m CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_DDC=m CONFIG_FB_BOOT_VESA_SUPPORT=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set CONFIG_FB_SYS_FILLRECT=y CONFIG_FB_SYS_COPYAREA=y CONFIG_FB_SYS_IMAGEBLIT=y # CONFIG_FB_FOREIGN_ENDIAN is not set CONFIG_FB_SYS_FOPS=y # CONFIG_FB_WMT_GE_ROPS is not set CONFIG_FB_DEFERRED_IO=y CONFIG_FB_HECUBA=m CONFIG_FB_SVGALIB=m # CONFIG_FB_MACMODES is not set CONFIG_FB_BACKLIGHT=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y # # Frame buffer hardware drivers # CONFIG_FB_CIRRUS=m CONFIG_FB_PM2=m CONFIG_FB_PM2_FIFO_DISCONNECT=y CONFIG_FB_CYBER2000=m CONFIG_FB_CYBER2000_DDC=y CONFIG_FB_ARC=m # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set CONFIG_FB_VGA16=m CONFIG_FB_UVESA=m CONFIG_FB_VESA=y CONFIG_FB_EFI=y CONFIG_FB_N411=m CONFIG_FB_HGA=m CONFIG_FB_S1D13XXX=m # CONFIG_FB_I740 is not set CONFIG_FB_LE80578=m CONFIG_FB_CARILLO_RANCH=m CONFIG_FB_MATROX=m CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y CONFIG_FB_MATROX_G=y CONFIG_FB_MATROX_I2C=m CONFIG_FB_MATROX_MAVEN=m CONFIG_FB_RADEON=m CONFIG_FB_RADEON_I2C=y CONFIG_FB_RADEON_BACKLIGHT=y # CONFIG_FB_RADEON_DEBUG is not set CONFIG_FB_ATY128=m CONFIG_FB_ATY128_BACKLIGHT=y CONFIG_FB_ATY=m CONFIG_FB_ATY_CT=y # CONFIG_FB_ATY_GENERIC_LCD is not set CONFIG_FB_ATY_GX=y CONFIG_FB_ATY_BACKLIGHT=y CONFIG_FB_S3=m CONFIG_FB_S3_DDC=y CONFIG_FB_SAVAGE=m # CONFIG_FB_SAVAGE_I2C is not set # CONFIG_FB_SAVAGE_ACCEL is not set CONFIG_FB_SIS=m CONFIG_FB_SIS_300=y CONFIG_FB_SIS_315=y CONFIG_FB_VIA=m # CONFIG_FB_VIA_DIRECT_PROCFS is not set CONFIG_FB_VIA_X_COMPATIBILITY=y CONFIG_FB_NEOMAGIC=m CONFIG_FB_KYRO=m CONFIG_FB_3DFX=m # CONFIG_FB_3DFX_ACCEL is not set CONFIG_FB_3DFX_I2C=y CONFIG_FB_VOODOO1=m CONFIG_FB_VT8623=m CONFIG_FB_TRIDENT=m CONFIG_FB_ARK=m CONFIG_FB_PM3=m # CONFIG_FB_CARMINE is not set # CONFIG_FB_GEODE is not set # CONFIG_FB_TMIO is not set CONFIG_FB_SM501=m # CONFIG_FB_SMSCUFX is not set CONFIG_FB_UDL=m CONFIG_FB_VIRTUAL=m CONFIG_XEN_FBDEV_FRONTEND=y CONFIG_FB_METRONOME=m CONFIG_FB_MB862XX=m CONFIG_FB_MB862XX_PCI_GDC=y CONFIG_FB_MB862XX_I2C=y # CONFIG_FB_BROADSHEET is not set # CONFIG_FB_AUO_K190X is not set # CONFIG_EXYNOS_VIDEO is not set CONFIG_BACKLIGHT_LCD_SUPPORT=y # CONFIG_LCD_CLASS_DEVICE is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y # CONFIG_BACKLIGHT_GENERIC is not set CONFIG_BACKLIGHT_PROGEAR=m CONFIG_BACKLIGHT_APPLE=m # CONFIG_BACKLIGHT_SAHARA is not set # CONFIG_BACKLIGHT_ADP8860 is not set # CONFIG_BACKLIGHT_ADP8870 is not set # CONFIG_BACKLIGHT_PCF50633 is not set # CONFIG_BACKLIGHT_LP855X is not set # # Console display driver support # CONFIG_VGA_CONSOLE=y # CONFIG_VGACON_SOFT_SCROLLBACK is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y # CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y # CONFIG_LOGO is not set CONFIG_SOUND=m CONFIG_SOUND_OSS_CORE=y # CONFIG_SOUND_OSS_CORE_PRECLAIM is not set CONFIG_SND=m CONFIG_SND_TIMER=m CONFIG_SND_PCM=m CONFIG_SND_HWDEP=m CONFIG_SND_RAWMIDI=m CONFIG_SND_JACK=y CONFIG_SND_SEQUENCER=m CONFIG_SND_SEQ_DUMMY=m CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m CONFIG_SND_PCM_OSS_PLUGINS=y # CONFIG_SND_SEQUENCER_OSS is not set CONFIG_SND_HRTIMER=m CONFIG_SND_SEQ_HRTIMER_DEFAULT=y CONFIG_SND_DYNAMIC_MINORS=y CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set CONFIG_SND_VMASTER=y CONFIG_SND_KCTL_JACK=y CONFIG_SND_DMA_SGBUF=y CONFIG_SND_RAWMIDI_SEQ=m CONFIG_SND_OPL3_LIB_SEQ=m # CONFIG_SND_OPL4_LIB_SEQ is not set # CONFIG_SND_SBAWE_SEQ is not set CONFIG_SND_EMU10K1_SEQ=m CONFIG_SND_MPU401_UART=m CONFIG_SND_OPL3_LIB=m CONFIG_SND_VX_LIB=m CONFIG_SND_AC97_CODEC=m CONFIG_SND_DRIVERS=y CONFIG_SND_PCSP=m CONFIG_SND_DUMMY=m CONFIG_SND_ALOOP=m CONFIG_SND_VIRMIDI=m CONFIG_SND_MTPAV=m CONFIG_SND_MTS64=m CONFIG_SND_SERIAL_U16550=m CONFIG_SND_MPU401=m CONFIG_SND_PORTMAN2X4=m CONFIG_SND_AC97_POWER_SAVE=y CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0 CONFIG_SND_SB_COMMON=m CONFIG_SND_SB16_DSP=m CONFIG_SND_TEA575X=m CONFIG_SND_PCI=y CONFIG_SND_AD1889=m CONFIG_SND_ALS300=m CONFIG_SND_ALS4000=m CONFIG_SND_ALI5451=m CONFIG_SND_ASIHPI=m CONFIG_SND_ATIIXP=m CONFIG_SND_ATIIXP_MODEM=m CONFIG_SND_AU8810=m CONFIG_SND_AU8820=m CONFIG_SND_AU8830=m # CONFIG_SND_AW2 is not set CONFIG_SND_AZT3328=m CONFIG_SND_BT87X=m # CONFIG_SND_BT87X_OVERCLOCK is not set CONFIG_SND_CA0106=m CONFIG_SND_CMIPCI=m CONFIG_SND_OXYGEN_LIB=m CONFIG_SND_OXYGEN=m CONFIG_SND_CS4281=m CONFIG_SND_CS46XX=m CONFIG_SND_CS5530=m CONFIG_SND_CS5535AUDIO=m CONFIG_SND_CTXFI=m CONFIG_SND_DARLA20=m CONFIG_SND_GINA20=m CONFIG_SND_LAYLA20=m CONFIG_SND_DARLA24=m CONFIG_SND_GINA24=m CONFIG_SND_LAYLA24=m CONFIG_SND_MONA=m CONFIG_SND_MIA=m CONFIG_SND_ECHO3G=m CONFIG_SND_INDIGO=m CONFIG_SND_INDIGOIO=m CONFIG_SND_INDIGODJ=m CONFIG_SND_INDIGOIOX=m CONFIG_SND_INDIGODJX=m CONFIG_SND_EMU10K1=m CONFIG_SND_EMU10K1X=m CONFIG_SND_ENS1370=m CONFIG_SND_ENS1371=m CONFIG_SND_ES1938=m CONFIG_SND_ES1968=m CONFIG_SND_ES1968_INPUT=y CONFIG_SND_ES1968_RADIO=y CONFIG_SND_FM801=m CONFIG_SND_FM801_TEA575X_BOOL=y CONFIG_SND_HDA_INTEL=m CONFIG_SND_HDA_PREALLOC_SIZE=64 CONFIG_SND_HDA_HWDEP=y CONFIG_SND_HDA_RECONFIG=y CONFIG_SND_HDA_INPUT_BEEP=y CONFIG_SND_HDA_INPUT_BEEP_MODE=1 CONFIG_SND_HDA_INPUT_JACK=y CONFIG_SND_HDA_PATCH_LOADER=y CONFIG_SND_HDA_CODEC_REALTEK=y CONFIG_SND_HDA_CODEC_ANALOG=y CONFIG_SND_HDA_CODEC_SIGMATEL=y CONFIG_SND_HDA_CODEC_VIA=y CONFIG_SND_HDA_CODEC_HDMI=y CONFIG_SND_HDA_CODEC_CIRRUS=y CONFIG_SND_HDA_CODEC_CONEXANT=y CONFIG_SND_HDA_CODEC_CA0110=y CONFIG_SND_HDA_CODEC_CA0132=y CONFIG_SND_HDA_CODEC_CMEDIA=y CONFIG_SND_HDA_CODEC_SI3054=y CONFIG_SND_HDA_GENERIC=y CONFIG_SND_HDA_POWER_SAVE=y CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 CONFIG_SND_HDSP=m CONFIG_SND_HDSPM=m CONFIG_SND_ICE1712=m CONFIG_SND_ICE1724=m CONFIG_SND_INTEL8X0=m CONFIG_SND_INTEL8X0M=m CONFIG_SND_KORG1212=m CONFIG_SND_LOLA=m CONFIG_SND_LX6464ES=m CONFIG_SND_MAESTRO3=m CONFIG_SND_MAESTRO3_INPUT=y CONFIG_SND_MIXART=m CONFIG_SND_NM256=m CONFIG_SND_PCXHR=m CONFIG_SND_RIPTIDE=m CONFIG_SND_RME32=m CONFIG_SND_RME96=m CONFIG_SND_RME9652=m CONFIG_SND_SONICVIBES=m CONFIG_SND_TRIDENT=m CONFIG_SND_VIA82XX=m CONFIG_SND_VIA82XX_MODEM=m CONFIG_SND_VIRTUOSO=m CONFIG_SND_VX222=m CONFIG_SND_YMFPCI=m CONFIG_SND_SPI=y CONFIG_SND_USB=y CONFIG_SND_USB_AUDIO=m CONFIG_SND_USB_UA101=m CONFIG_SND_USB_USX2Y=m CONFIG_SND_USB_CAIAQ=m CONFIG_SND_USB_CAIAQ_INPUT=y CONFIG_SND_USB_US122L=m CONFIG_SND_USB_6FIRE=m CONFIG_SND_FIREWIRE=y CONFIG_SND_FIREWIRE_LIB=m CONFIG_SND_FIREWIRE_SPEAKERS=m CONFIG_SND_ISIGHT=m CONFIG_SND_PCMCIA=y CONFIG_SND_VXPOCKET=m CONFIG_SND_PDAUDIOCF=m # CONFIG_SND_SOC is not set # CONFIG_SOUND_PRIME is not set CONFIG_AC97_BUS=m # # HID support # CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_HID_GENERIC=m # # Special HID drivers # CONFIG_HID_A4TECH=m CONFIG_HID_ACRUX=m CONFIG_HID_ACRUX_FF=y CONFIG_HID_APPLE=m # CONFIG_HID_AUREAL is not set CONFIG_HID_BELKIN=m CONFIG_HID_CHERRY=m CONFIG_HID_CHICONY=m CONFIG_HID_PRODIKEYS=m CONFIG_HID_CYPRESS=m CONFIG_HID_DRAGONRISE=m CONFIG_DRAGONRISE_FF=y CONFIG_HID_EMS_FF=m CONFIG_HID_ELECOM=m CONFIG_HID_EZKEY=m CONFIG_HID_HOLTEK=m # CONFIG_HOLTEK_FF is not set CONFIG_HID_KEYTOUCH=m # CONFIG_HID_KYE is not set CONFIG_HID_UCLOGIC=m CONFIG_HID_WALTOP=m CONFIG_HID_GYRATION=m CONFIG_HID_TWINHAN=m CONFIG_HID_KENSINGTON=m CONFIG_HID_LCPOWER=m CONFIG_HID_LOGITECH=m CONFIG_HID_LOGITECH_DJ=m CONFIG_LOGITECH_FF=y CONFIG_LOGIRUMBLEPAD2_FF=y CONFIG_LOGIG940_FF=y CONFIG_LOGIWHEELS_FF=y CONFIG_HID_MAGICMOUSE=m CONFIG_HID_MICROSOFT=m CONFIG_HID_MONTEREY=m CONFIG_HID_MULTITOUCH=m CONFIG_HID_NTRIG=m CONFIG_HID_ORTEK=m CONFIG_HID_PANTHERLORD=m CONFIG_PANTHERLORD_FF=y CONFIG_HID_PETALYNX=m CONFIG_HID_PICOLCD=m CONFIG_HID_PICOLCD_FB=y CONFIG_HID_PICOLCD_BACKLIGHT=y CONFIG_HID_PICOLCD_LEDS=y CONFIG_HID_PRIMAX=m CONFIG_HID_ROCCAT=m # CONFIG_HID_SAITEK is not set CONFIG_HID_SAMSUNG=m CONFIG_HID_SONY=m CONFIG_HID_SPEEDLINK=m CONFIG_HID_SUNPLUS=m CONFIG_HID_GREENASIA=m CONFIG_GREENASIA_FF=y # CONFIG_HID_HYPERV_MOUSE is not set CONFIG_HID_SMARTJOYPLUS=m CONFIG_SMARTJOYPLUS_FF=y # CONFIG_HID_TIVO is not set CONFIG_HID_TOPSEED=m CONFIG_HID_THRUSTMASTER=m CONFIG_THRUSTMASTER_FF=y CONFIG_HID_WACOM=m CONFIG_HID_WIIMOTE=m CONFIG_HID_WIIMOTE_EXT=y CONFIG_HID_ZEROPLUS=m CONFIG_ZEROPLUS_FF=y CONFIG_HID_ZYDACRON=m # # USB HID support # CONFIG_USB_HID=m CONFIG_HID_PID=y CONFIG_USB_HIDDEV=y CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y CONFIG_USB_ARCH_HAS_XHCI=y CONFIG_USB_SUPPORT=y CONFIG_USB_COMMON=m CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB=m # CONFIG_USB_DEBUG is not set CONFIG_USB_ANNOUNCE_NEW_DEVICES=y # # Miscellaneous USB options # CONFIG_USB_DYNAMIC_MINORS=y CONFIG_USB_SUSPEND=y # CONFIG_USB_OTG is not set # CONFIG_USB_DWC3 is not set CONFIG_USB_MON=m CONFIG_USB_WUSB=m CONFIG_USB_WUSB_CBAF=m # CONFIG_USB_WUSB_CBAF_DEBUG is not set # # USB Host Controller Drivers # CONFIG_USB_C67X00_HCD=m CONFIG_USB_XHCI_HCD=m # CONFIG_USB_XHCI_HCD_DEBUGGING is not set CONFIG_USB_EHCI_HCD=m CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_TT_NEWSCHED=y # CONFIG_USB_OXU210HP_HCD is not set CONFIG_USB_ISP116X_HCD=m # CONFIG_USB_ISP1760_HCD is not set # CONFIG_USB_ISP1362_HCD is not set CONFIG_USB_OHCI_HCD=m # CONFIG_USB_OHCI_HCD_SSB is not set # CONFIG_USB_OHCI_HCD_PLATFORM is not set # CONFIG_USB_EHCI_HCD_PLATFORM is not set # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_UHCI_HCD=m CONFIG_USB_U132_HCD=m CONFIG_USB_SL811_HCD=m # CONFIG_USB_SL811_HCD_ISO is not set CONFIG_USB_SL811_CS=m CONFIG_USB_R8A66597_HCD=m CONFIG_USB_WHCI_HCD=m CONFIG_USB_HWA_HCD=m # CONFIG_USB_HCD_BCMA is not set # CONFIG_USB_HCD_SSB is not set # CONFIG_USB_MUSB_HDRC is not set # CONFIG_USB_CHIPIDEA is not set # CONFIG_USB_RENESAS_USBHS is not set # # USB Device Class drivers # CONFIG_USB_ACM=m CONFIG_USB_PRINTER=m CONFIG_USB_WDM=m CONFIG_USB_TMC=m # # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # # # also be needed; see USB_STORAGE Help for more info # CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set CONFIG_USB_STORAGE_REALTEK=m CONFIG_REALTEK_AUTOPM=y CONFIG_USB_STORAGE_DATAFAB=m CONFIG_USB_STORAGE_FREECOM=m CONFIG_USB_STORAGE_ISD200=m CONFIG_USB_STORAGE_USBAT=m CONFIG_USB_STORAGE_SDDR09=m CONFIG_USB_STORAGE_SDDR55=m CONFIG_USB_STORAGE_JUMPSHOT=m CONFIG_USB_STORAGE_ALAUDA=m CONFIG_USB_STORAGE_ONETOUCH=m CONFIG_USB_STORAGE_KARMA=m CONFIG_USB_STORAGE_CYPRESS_ATACB=m CONFIG_USB_STORAGE_ENE_UB6250=m CONFIG_USB_UAS=m # CONFIG_USB_LIBUSUAL is not set # # USB Imaging devices # CONFIG_USB_MDC800=m CONFIG_USB_MICROTEK=m # # USB port drivers # CONFIG_USB_USS720=m CONFIG_USB_SERIAL=m CONFIG_USB_EZUSB=y CONFIG_USB_SERIAL_GENERIC=y CONFIG_USB_SERIAL_AIRCABLE=m CONFIG_USB_SERIAL_ARK3116=m CONFIG_USB_SERIAL_BELKIN=m CONFIG_USB_SERIAL_CH341=m CONFIG_USB_SERIAL_WHITEHEAT=m CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m CONFIG_USB_SERIAL_CP210X=m CONFIG_USB_SERIAL_CYPRESS_M8=m CONFIG_USB_SERIAL_EMPEG=m CONFIG_USB_SERIAL_FTDI_SIO=m CONFIG_USB_SERIAL_FUNSOFT=m CONFIG_USB_SERIAL_VISOR=m CONFIG_USB_SERIAL_IPAQ=m CONFIG_USB_SERIAL_IR=m CONFIG_USB_SERIAL_EDGEPORT=m CONFIG_USB_SERIAL_EDGEPORT_TI=m # CONFIG_USB_SERIAL_F81232 is not set CONFIG_USB_SERIAL_GARMIN=m CONFIG_USB_SERIAL_IPW=m CONFIG_USB_SERIAL_IUU=m CONFIG_USB_SERIAL_KEYSPAN_PDA=m CONFIG_USB_SERIAL_KEYSPAN=m CONFIG_USB_SERIAL_KLSI=m CONFIG_USB_SERIAL_KOBIL_SCT=m CONFIG_USB_SERIAL_MCT_U232=m # CONFIG_USB_SERIAL_METRO is not set CONFIG_USB_SERIAL_MOS7720=m CONFIG_USB_SERIAL_MOS7715_PARPORT=y CONFIG_USB_SERIAL_MOS7840=m CONFIG_USB_SERIAL_MOTOROLA=m CONFIG_USB_SERIAL_NAVMAN=m CONFIG_USB_SERIAL_PL2303=m CONFIG_USB_SERIAL_OTI6858=m CONFIG_USB_SERIAL_QCAUX=m CONFIG_USB_SERIAL_QUALCOMM=m CONFIG_USB_SERIAL_SPCP8X5=m CONFIG_USB_SERIAL_HP4X=m CONFIG_USB_SERIAL_SAFE=m # CONFIG_USB_SERIAL_SAFE_PADDED is not set CONFIG_USB_SERIAL_SIEMENS_MPI=m CONFIG_USB_SERIAL_SIERRAWIRELESS=m CONFIG_USB_SERIAL_SYMBOL=m CONFIG_USB_SERIAL_TI=m CONFIG_USB_SERIAL_CYBERJACK=m CONFIG_USB_SERIAL_XIRCOM=m CONFIG_USB_SERIAL_WWAN=m CONFIG_USB_SERIAL_OPTION=m CONFIG_USB_SERIAL_OMNINET=m CONFIG_USB_SERIAL_OPTICON=m CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m CONFIG_USB_SERIAL_ZIO=m CONFIG_USB_SERIAL_SSU100=m # CONFIG_USB_SERIAL_QT2 is not set CONFIG_USB_SERIAL_DEBUG=m # # USB Miscellaneous drivers # CONFIG_USB_EMI62=m CONFIG_USB_EMI26=m CONFIG_USB_ADUTUX=m CONFIG_USB_SEVSEG=m CONFIG_USB_RIO500=m CONFIG_USB_LEGOTOWER=m CONFIG_USB_LCD=m CONFIG_USB_LED=m CONFIG_USB_CYPRESS_CY7C63=m CONFIG_USB_CYTHERM=m CONFIG_USB_IDMOUSE=m CONFIG_USB_FTDI_ELAN=m CONFIG_USB_APPLEDISPLAY=m CONFIG_USB_SISUSBVGA=m CONFIG_USB_SISUSBVGA_CON=y CONFIG_USB_LD=m CONFIG_USB_TRANCEVIBRATOR=m CONFIG_USB_IOWARRIOR=m CONFIG_USB_TEST=m CONFIG_USB_ISIGHTFW=m CONFIG_USB_YUREX=m # # USB Physical Layer drivers # # CONFIG_USB_ISP1301 is not set CONFIG_USB_ATM=m CONFIG_USB_SPEEDTOUCH=m CONFIG_USB_CXACRU=m CONFIG_USB_UEAGLEATM=m CONFIG_USB_XUSBATM=m CONFIG_USB_GADGET=m # CONFIG_USB_GADGET_DEBUG is not set # CONFIG_USB_GADGET_DEBUG_FILES is not set # CONFIG_USB_GADGET_DEBUG_FS is not set CONFIG_USB_GADGET_VBUS_DRAW=2 CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 # # USB Peripheral Controller # # CONFIG_USB_R8A66597 is not set # CONFIG_USB_MV_UDC is not set # CONFIG_USB_M66592 is not set # CONFIG_USB_AMD5536UDC is not set # CONFIG_USB_NET2272 is not set # CONFIG_USB_NET2280 is not set # CONFIG_USB_GOKU is not set CONFIG_USB_EG20T=m # CONFIG_USB_DUMMY_HCD is not set CONFIG_USB_GADGET_DUALSPEED=y # CONFIG_USB_ZERO is not set # CONFIG_USB_AUDIO is not set # CONFIG_USB_ETH is not set # CONFIG_USB_G_NCM is not set # CONFIG_USB_GADGETFS is not set # CONFIG_USB_FUNCTIONFS is not set # CONFIG_USB_FILE_STORAGE is not set # CONFIG_USB_MASS_STORAGE is not set # CONFIG_USB_GADGET_TARGET is not set # CONFIG_USB_G_SERIAL is not set # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set # CONFIG_USB_CDC_COMPOSITE is not set # CONFIG_USB_G_NOKIA is not set # CONFIG_USB_G_ACM_MS is not set # CONFIG_USB_G_MULTI is not set # CONFIG_USB_G_HID is not set # CONFIG_USB_G_DBGP is not set # CONFIG_USB_G_WEBCAM is not set # # OTG and related infrastructure # CONFIG_USB_OTG_UTILS=y # CONFIG_USB_GPIO_VBUS is not set CONFIG_NOP_USB_XCEIV=m CONFIG_UWB=m CONFIG_UWB_HWA=m CONFIG_UWB_WHCI=m CONFIG_UWB_I1480U=m CONFIG_MMC=m # CONFIG_MMC_DEBUG is not set # CONFIG_MMC_UNSAFE_RESUME is not set # CONFIG_MMC_CLKGATE is not set # # MMC/SD/SDIO Card Drivers # CONFIG_MMC_BLOCK=m CONFIG_MMC_BLOCK_MINORS=8 CONFIG_MMC_BLOCK_BOUNCE=y CONFIG_SDIO_UART=m # CONFIG_MMC_TEST is not set # # MMC/SD/SDIO Host Controller Drivers # CONFIG_MMC_SDHCI=m CONFIG_MMC_SDHCI_PCI=m CONFIG_MMC_RICOH_MMC=y CONFIG_MMC_SDHCI_PLTFM=m CONFIG_MMC_WBSD=m CONFIG_MMC_TIFM_SD=m CONFIG_MMC_SPI=m CONFIG_MMC_SDRICOH_CS=m CONFIG_MMC_CB710=m CONFIG_MMC_VIA_SDMMC=m CONFIG_MMC_VUB300=m CONFIG_MMC_USHC=m CONFIG_MEMSTICK=m # CONFIG_MEMSTICK_DEBUG is not set # # MemoryStick drivers # # CONFIG_MEMSTICK_UNSAFE_RESUME is not set CONFIG_MSPRO_BLOCK=m # # MemoryStick Host Controller Drivers # CONFIG_MEMSTICK_TIFM_MS=m CONFIG_MEMSTICK_JMICRON_38X=m CONFIG_MEMSTICK_R592=m CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y # # LED drivers # # CONFIG_LEDS_LM3530 is not set CONFIG_LEDS_PCA9532=m # CONFIG_LEDS_PCA9532_GPIO is not set # CONFIG_LEDS_GPIO is not set CONFIG_LEDS_LP3944=m # CONFIG_LEDS_LP5521 is not set # CONFIG_LEDS_LP5523 is not set CONFIG_LEDS_CLEVO_MAIL=m CONFIG_LEDS_PCA955X=m # CONFIG_LEDS_PCA9633 is not set CONFIG_LEDS_DAC124S085=m CONFIG_LEDS_REGULATOR=m CONFIG_LEDS_BD2802=m CONFIG_LEDS_INTEL_SS4200=m CONFIG_LEDS_LT3593=m CONFIG_LEDS_DELL_NETBOOKS=m # CONFIG_LEDS_TCA6507 is not set # CONFIG_LEDS_OT200 is not set CONFIG_LEDS_TRIGGERS=y # # LED Triggers # CONFIG_LEDS_TRIGGER_TIMER=m CONFIG_LEDS_TRIGGER_HEARTBEAT=m CONFIG_LEDS_TRIGGER_BACKLIGHT=m # CONFIG_LEDS_TRIGGER_GPIO is not set CONFIG_LEDS_TRIGGER_DEFAULT_ON=m # # iptables trigger is under Netfilter config (LED target) # # CONFIG_LEDS_TRIGGER_TRANSIENT is not set CONFIG_ACCESSIBILITY=y CONFIG_A11Y_BRAILLE_CONSOLE=y CONFIG_INFINIBAND=m CONFIG_INFINIBAND_USER_MAD=m CONFIG_INFINIBAND_USER_ACCESS=m CONFIG_INFINIBAND_USER_MEM=y CONFIG_INFINIBAND_ADDR_TRANS=y CONFIG_INFINIBAND_MTHCA=m CONFIG_INFINIBAND_MTHCA_DEBUG=y CONFIG_INFINIBAND_IPATH=m CONFIG_INFINIBAND_QIB=m CONFIG_INFINIBAND_AMSO1100=m # CONFIG_INFINIBAND_AMSO1100_DEBUG is not set CONFIG_INFINIBAND_CXGB3=m # CONFIG_INFINIBAND_CXGB3_DEBUG is not set CONFIG_INFINIBAND_CXGB4=m CONFIG_MLX4_INFINIBAND=m CONFIG_INFINIBAND_NES=m # CONFIG_INFINIBAND_NES_DEBUG is not set # CONFIG_INFINIBAND_OCRDMA is not set CONFIG_INFINIBAND_IPOIB=m CONFIG_INFINIBAND_IPOIB_CM=y CONFIG_INFINIBAND_IPOIB_DEBUG=y # CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set CONFIG_INFINIBAND_SRP=m CONFIG_INFINIBAND_SRPT=m CONFIG_INFINIBAND_ISER=m CONFIG_EDAC=y # # Reporting subsystems # # CONFIG_EDAC_DEBUG is not set CONFIG_EDAC_DECODE_MCE=m # CONFIG_EDAC_MCE_INJ is not set CONFIG_EDAC_MM_EDAC=m CONFIG_EDAC_AMD64=m # CONFIG_EDAC_AMD64_ERROR_INJECTION is not set CONFIG_EDAC_E752X=m CONFIG_EDAC_I82975X=m CONFIG_EDAC_I3000=m CONFIG_EDAC_I3200=m CONFIG_EDAC_X38=m CONFIG_EDAC_I5400=m CONFIG_EDAC_I7CORE=m CONFIG_EDAC_I5000=m CONFIG_EDAC_I5100=m CONFIG_EDAC_I7300=m # CONFIG_EDAC_SBRIDGE is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y CONFIG_RTC_HCTOSYS_DEVICE="rtc0" # CONFIG_RTC_DEBUG is not set # # RTC interfaces # CONFIG_RTC_INTF_SYSFS=y CONFIG_RTC_INTF_PROC=y CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set # CONFIG_RTC_DRV_TEST is not set # # I2C RTC drivers # CONFIG_RTC_DRV_DS1307=m CONFIG_RTC_DRV_DS1374=m CONFIG_RTC_DRV_DS1672=m # CONFIG_RTC_DRV_DS3232 is not set CONFIG_RTC_DRV_MAX6900=m CONFIG_RTC_DRV_RS5C372=m CONFIG_RTC_DRV_ISL1208=m # CONFIG_RTC_DRV_ISL12022 is not set CONFIG_RTC_DRV_X1205=m CONFIG_RTC_DRV_PCF8563=m CONFIG_RTC_DRV_PCF8583=m CONFIG_RTC_DRV_M41T80=m # CONFIG_RTC_DRV_M41T80_WDT is not set CONFIG_RTC_DRV_BQ32K=m CONFIG_RTC_DRV_S35390A=m CONFIG_RTC_DRV_FM3130=m CONFIG_RTC_DRV_RX8581=m CONFIG_RTC_DRV_RX8025=m # CONFIG_RTC_DRV_EM3027 is not set # CONFIG_RTC_DRV_RV3029C2 is not set # # SPI RTC drivers # # CONFIG_RTC_DRV_M41T93 is not set CONFIG_RTC_DRV_M41T94=m CONFIG_RTC_DRV_DS1305=m CONFIG_RTC_DRV_DS1390=m CONFIG_RTC_DRV_MAX6902=m CONFIG_RTC_DRV_R9701=m CONFIG_RTC_DRV_RS5C348=m CONFIG_RTC_DRV_DS3234=m CONFIG_RTC_DRV_PCF2123=m # # Platform RTC drivers # CONFIG_RTC_DRV_CMOS=y CONFIG_RTC_DRV_DS1286=m CONFIG_RTC_DRV_DS1511=m CONFIG_RTC_DRV_DS1553=m CONFIG_RTC_DRV_DS1742=m CONFIG_RTC_DRV_STK17TA8=m CONFIG_RTC_DRV_M48T86=m CONFIG_RTC_DRV_M48T35=m CONFIG_RTC_DRV_M48T59=m CONFIG_RTC_DRV_MSM6242=m CONFIG_RTC_DRV_BQ4802=m CONFIG_RTC_DRV_RP5C01=m CONFIG_RTC_DRV_V3020=m CONFIG_RTC_DRV_PCF50633=m # # on-CPU RTC drivers # CONFIG_DMADEVICES=y # CONFIG_DMADEVICES_DEBUG is not set # # DMA Devices # # CONFIG_INTEL_MID_DMAC is not set CONFIG_INTEL_IOATDMA=m # CONFIG_TIMB_DMA is not set CONFIG_PCH_DMA=m CONFIG_DMA_ENGINE=y # # DMA Clients # CONFIG_NET_DMA=y CONFIG_ASYNC_TX_DMA=y # CONFIG_DMATEST is not set CONFIG_DCA=m # CONFIG_AUXDISPLAY is not set CONFIG_UIO=m CONFIG_UIO_CIF=m CONFIG_UIO_PDRV=m CONFIG_UIO_PDRV_GENIRQ=m CONFIG_UIO_AEC=m CONFIG_UIO_SERCOS3=m CONFIG_UIO_PCI_GENERIC=m CONFIG_UIO_NETX=m CONFIG_VIRTIO=m CONFIG_VIRTIO_RING=m # # Virtio drivers # CONFIG_VIRTIO_PCI=m CONFIG_VIRTIO_BALLOON=m # CONFIG_VIRTIO_MMIO is not set # # Microsoft Hyper-V guest support # CONFIG_HYPERV=m CONFIG_HYPERV_UTILS=m # # Xen driver support # CONFIG_XEN_BALLOON=y # CONFIG_XEN_BALLOON_MEMORY_HOTPLUG is not set CONFIG_XEN_SCRUB_PAGES=y CONFIG_XEN_DEV_EVTCHN=m CONFIG_XEN_BACKEND=y CONFIG_XENFS=m CONFIG_XEN_COMPAT_XENFS=y CONFIG_XEN_SYS_HYPERVISOR=y CONFIG_XEN_XENBUS_FRONTEND=y CONFIG_XEN_GNTDEV=m CONFIG_XEN_GRANT_DEV_ALLOC=m CONFIG_SWIOTLB_XEN=y CONFIG_XEN_PCIDEV_BACKEND=m CONFIG_XEN_PRIVCMD=m CONFIG_XEN_ACPI_PROCESSOR=m CONFIG_STAGING=y CONFIG_ET131X=m # CONFIG_SLICOSS is not set CONFIG_USBIP_CORE=m CONFIG_USBIP_VHCI_HCD=m CONFIG_USBIP_HOST=m # CONFIG_USBIP_DEBUG is not set # CONFIG_W35UND is not set CONFIG_PRISM2_USB=m # CONFIG_ECHO is not set CONFIG_COMEDI=m # CONFIG_COMEDI_DEBUG is not set CONFIG_COMEDI_DEFAULT_BUF_SIZE_KB=2048 CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB=20480 CONFIG_COMEDI_MISC_DRIVERS=m CONFIG_COMEDI_KCOMEDILIB=m CONFIG_COMEDI_BOND=m CONFIG_COMEDI_TEST=m CONFIG_COMEDI_PARPORT=m CONFIG_COMEDI_SERIAL2002=m # CONFIG_COMEDI_SKEL is not set CONFIG_COMEDI_PCI_DRIVERS=m CONFIG_COMEDI_ADDI_APCI_035=m CONFIG_COMEDI_ADDI_APCI_1032=m CONFIG_COMEDI_ADDI_APCI_1500=m CONFIG_COMEDI_ADDI_APCI_1516=m CONFIG_COMEDI_ADDI_APCI_1564=m CONFIG_COMEDI_ADDI_APCI_16XX=m CONFIG_COMEDI_ADDI_APCI_2016=m CONFIG_COMEDI_ADDI_APCI_2032=m CONFIG_COMEDI_ADDI_APCI_2200=m CONFIG_COMEDI_ADDI_APCI_3001=m CONFIG_COMEDI_ADDI_APCI_3120=m CONFIG_COMEDI_ADDI_APCI_3501=m CONFIG_COMEDI_ADDI_APCI_3XXX=m CONFIG_COMEDI_ADL_PCI6208=m # CONFIG_COMEDI_ADL_PCI7230 is not set CONFIG_COMEDI_ADL_PCI7296=m CONFIG_COMEDI_ADL_PCI7432=m CONFIG_COMEDI_ADL_PCI8164=m CONFIG_COMEDI_ADL_PCI9111=m CONFIG_COMEDI_ADL_PCI9118=m CONFIG_COMEDI_ADV_PCI1710=m CONFIG_COMEDI_ADV_PCI1723=m CONFIG_COMEDI_ADV_PCI_DIO=m # CONFIG_COMEDI_AMPLC_DIO200_PCI is not set # CONFIG_COMEDI_AMPLC_PC236_PCI is not set # CONFIG_COMEDI_AMPLC_PC263_PCI is not set CONFIG_COMEDI_AMPLC_PCI224=m CONFIG_COMEDI_AMPLC_PCI230=m CONFIG_COMEDI_CONTEC_PCI_DIO=m # CONFIG_COMEDI_DAS08_PCI is not set CONFIG_COMEDI_DT3000=m # CONFIG_COMEDI_DYNA_PCI10XX is not set CONFIG_COMEDI_UNIOXX5=m CONFIG_COMEDI_GSC_HPDI=m CONFIG_COMEDI_ICP_MULTI=m CONFIG_COMEDI_II_PCI20KC=m CONFIG_COMEDI_DAQBOARD2000=m CONFIG_COMEDI_JR3_PCI=m CONFIG_COMEDI_KE_COUNTER=m CONFIG_COMEDI_CB_PCIDAS64=m CONFIG_COMEDI_CB_PCIDAS=m CONFIG_COMEDI_CB_PCIDDA=m CONFIG_COMEDI_CB_PCIDIO=m CONFIG_COMEDI_CB_PCIMDAS=m CONFIG_COMEDI_CB_PCIMDDA=m CONFIG_COMEDI_ME4000=m CONFIG_COMEDI_ME_DAQ=m CONFIG_COMEDI_NI_6527=m CONFIG_COMEDI_NI_65XX=m CONFIG_COMEDI_NI_660X=m CONFIG_COMEDI_NI_670X=m CONFIG_COMEDI_NI_PCIDIO=m CONFIG_COMEDI_NI_PCIMIO=m CONFIG_COMEDI_RTD520=m CONFIG_COMEDI_S526=m CONFIG_COMEDI_S626=m CONFIG_COMEDI_SSV_DNP=m CONFIG_COMEDI_PCMCIA_DRIVERS=m CONFIG_COMEDI_CB_DAS16_CS=m CONFIG_COMEDI_DAS08_CS=m CONFIG_COMEDI_NI_DAQ_700_CS=m CONFIG_COMEDI_NI_DAQ_DIO24_CS=m CONFIG_COMEDI_NI_LABPC_CS=m CONFIG_COMEDI_NI_MIO_CS=m CONFIG_COMEDI_QUATECH_DAQP_CS=m CONFIG_COMEDI_USB_DRIVERS=m CONFIG_COMEDI_DT9812=m CONFIG_COMEDI_USBDUX=m CONFIG_COMEDI_USBDUXFAST=m # CONFIG_COMEDI_USBDUXSIGMA is not set CONFIG_COMEDI_VMK80XX=m CONFIG_COMEDI_NI_COMMON=m CONFIG_COMEDI_MITE=m CONFIG_COMEDI_NI_TIO=m CONFIG_COMEDI_NI_LABPC=m CONFIG_COMEDI_8255=m CONFIG_COMEDI_FC=m CONFIG_COMEDI_DAS08=m # CONFIG_ASUS_OLED is not set # CONFIG_PANEL is not set CONFIG_R8187SE=m CONFIG_RTL8192U=m # CONFIG_RTLLIB is not set CONFIG_R8712U=m CONFIG_RTS_PSTOR=m # CONFIG_RTS_PSTOR_DEBUG is not set CONFIG_RTS5139=m # CONFIG_RTS5139_DEBUG is not set # CONFIG_TRANZPORT is not set # CONFIG_IDE_PHISON is not set # CONFIG_LINE6_USB is not set # CONFIG_USB_SERIAL_QUATECH2 is not set # CONFIG_VT6655 is not set CONFIG_VT6656=m # CONFIG_DX_SEP is not set CONFIG_ZRAM=m # CONFIG_ZRAM_DEBUG is not set CONFIG_ZSMALLOC=m # CONFIG_FB_SM7XX is not set # CONFIG_CRYSTALHD is not set # CONFIG_CXT1E1 is not set # CONFIG_FB_XGI is not set # CONFIG_ACPI_QUICKSTART is not set # CONFIG_SBE_2T3E3 is not set # CONFIG_USB_ENESTORAGE is not set # CONFIG_BCM_WIMAX is not set # CONFIG_FT1000 is not set # # Speakup console speech # CONFIG_SPEAKUP=m CONFIG_SPEAKUP_SYNTH_ACNTSA=m CONFIG_SPEAKUP_SYNTH_ACNTPC=m CONFIG_SPEAKUP_SYNTH_APOLLO=m CONFIG_SPEAKUP_SYNTH_AUDPTR=m CONFIG_SPEAKUP_SYNTH_BNS=m CONFIG_SPEAKUP_SYNTH_DECTLK=m CONFIG_SPEAKUP_SYNTH_DECEXT=m # CONFIG_SPEAKUP_SYNTH_DECPC is not set CONFIG_SPEAKUP_SYNTH_DTLK=m CONFIG_SPEAKUP_SYNTH_KEYPC=m CONFIG_SPEAKUP_SYNTH_LTLK=m CONFIG_SPEAKUP_SYNTH_SOFT=m CONFIG_SPEAKUP_SYNTH_SPKOUT=m CONFIG_SPEAKUP_SYNTH_TXPRT=m CONFIG_SPEAKUP_SYNTH_DUMMY=m # CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set # CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set CONFIG_STAGING_MEDIA=y # CONFIG_DVB_AS102 is not set # CONFIG_DVB_CXD2099 is not set # CONFIG_VIDEO_DT3155 is not set CONFIG_EASYCAP=m # CONFIG_EASYCAP_DEBUG is not set # CONFIG_VIDEO_GO7007 is not set # CONFIG_SOLO6X10 is not set CONFIG_LIRC_STAGING=y CONFIG_LIRC_BT829=m CONFIG_LIRC_IGORPLUGUSB=m CONFIG_LIRC_IMON=m # CONFIG_LIRC_PARALLEL is not set CONFIG_LIRC_SASEM=m CONFIG_LIRC_SERIAL=m CONFIG_LIRC_SERIAL_TRANSMITTER=y CONFIG_LIRC_SIR=m CONFIG_LIRC_TTUSBIR=m CONFIG_LIRC_ZILOG=m # # Android # # CONFIG_ANDROID is not set CONFIG_PHONE=m CONFIG_PHONE_IXJ=m CONFIG_PHONE_IXJ_PCMCIA=m # CONFIG_USB_WPAN_HCD is not set # CONFIG_USB_G_CCG is not set # CONFIG_IPACK_BUS is not set # CONFIG_WIMAX_GDM72XX is not set CONFIG_X86_PLATFORM_DEVICES=y CONFIG_ACER_WMI=m CONFIG_ACERHDF=m CONFIG_ASUS_LAPTOP=m CONFIG_DELL_LAPTOP=m CONFIG_DELL_WMI=m CONFIG_DELL_WMI_AIO=m CONFIG_FUJITSU_LAPTOP=m # CONFIG_FUJITSU_LAPTOP_DEBUG is not set # CONFIG_FUJITSU_TABLET is not set CONFIG_AMILO_RFKILL=m CONFIG_HP_ACCEL=m CONFIG_HP_WMI=m CONFIG_MSI_LAPTOP=m CONFIG_PANASONIC_LAPTOP=m CONFIG_COMPAL_LAPTOP=m CONFIG_SONY_LAPTOP=m CONFIG_SONYPI_COMPAT=y CONFIG_IDEAPAD_LAPTOP=m CONFIG_THINKPAD_ACPI=m CONFIG_THINKPAD_ACPI_ALSA_SUPPORT=y # CONFIG_THINKPAD_ACPI_DEBUGFACILITIES is not set # CONFIG_THINKPAD_ACPI_DEBUG is not set # CONFIG_THINKPAD_ACPI_UNSAFE_LEDS is not set CONFIG_THINKPAD_ACPI_VIDEO=y CONFIG_THINKPAD_ACPI_HOTKEY_POLL=y CONFIG_SENSORS_HDAPS=m # CONFIG_INTEL_MENLOW is not set CONFIG_EEEPC_LAPTOP=m CONFIG_ASUS_WMI=m CONFIG_ASUS_NB_WMI=m CONFIG_EEEPC_WMI=m CONFIG_ACPI_WMI=m CONFIG_MSI_WMI=m CONFIG_TOPSTAR_LAPTOP=m CONFIG_ACPI_TOSHIBA=m CONFIG_TOSHIBA_BT_RFKILL=m CONFIG_ACPI_CMPC=m CONFIG_INTEL_IPS=m # CONFIG_IBM_RTL is not set # CONFIG_XO15_EBOOK is not set CONFIG_SAMSUNG_LAPTOP=m CONFIG_MXM_WMI=m CONFIG_INTEL_OAKTRAIL=m # CONFIG_SAMSUNG_Q10 is not set # CONFIG_APPLE_GMUX is not set # # Hardware Spinlock drivers # CONFIG_CLKEVT_I8253=y CONFIG_I8253_LOCK=y CONFIG_CLKBLD_I8253=y CONFIG_IOMMU_API=y CONFIG_IOMMU_SUPPORT=y CONFIG_AMD_IOMMU=y # CONFIG_AMD_IOMMU_STATS is not set # CONFIG_AMD_IOMMU_V2 is not set CONFIG_DMAR_TABLE=y CONFIG_INTEL_IOMMU=y # CONFIG_INTEL_IOMMU_DEFAULT_ON is not set CONFIG_INTEL_IOMMU_FLOPPY_WA=y CONFIG_IRQ_REMAP=y # # Remoteproc drivers (EXPERIMENTAL) # # # Rpmsg drivers (EXPERIMENTAL) # # CONFIG_VIRT_DRIVERS is not set # CONFIG_PM_DEVFREQ is not set # CONFIG_EXTCON is not set # CONFIG_MEMORY is not set # CONFIG_IIO is not set # CONFIG_VME_BUS is not set # # Firmware Drivers # CONFIG_EDD=m # CONFIG_EDD_OFF is not set CONFIG_FIRMWARE_MEMMAP=y CONFIG_EFI_VARS=m CONFIG_DELL_RBU=m CONFIG_DCDBAS=m CONFIG_DMIID=y # CONFIG_DMI_SYSFS is not set CONFIG_ISCSI_IBFT_FIND=y CONFIG_ISCSI_IBFT=m # CONFIG_GOOGLE_FIRMWARE is not set # # File systems # CONFIG_DCACHE_WORD_ACCESS=y CONFIG_EXT2_FS=m CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=m CONFIG_EXT3_DEFAULTS_TO_ORDERED=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y CONFIG_EXT4_FS=m CONFIG_EXT4_FS_XATTR=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y # CONFIG_EXT4_DEBUG is not set CONFIG_JBD=m # CONFIG_JBD_DEBUG is not set CONFIG_JBD2=m # CONFIG_JBD2_DEBUG is not set CONFIG_FS_MBCACHE=m CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set CONFIG_REISERFS_FS_XATTR=y CONFIG_REISERFS_FS_POSIX_ACL=y CONFIG_REISERFS_FS_SECURITY=y CONFIG_JFS_FS=m CONFIG_JFS_POSIX_ACL=y CONFIG_JFS_SECURITY=y # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set CONFIG_XFS_FS=m CONFIG_XFS_QUOTA=y CONFIG_XFS_POSIX_ACL=y CONFIG_XFS_RT=y # CONFIG_XFS_DEBUG is not set CONFIG_GFS2_FS=m CONFIG_GFS2_FS_LOCKING_DLM=y CONFIG_OCFS2_FS=m CONFIG_OCFS2_FS_O2CB=m CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m CONFIG_OCFS2_FS_STATS=y CONFIG_OCFS2_DEBUG_MASKLOG=y # CONFIG_OCFS2_DEBUG_FS is not set CONFIG_BTRFS_FS=m CONFIG_BTRFS_FS_POSIX_ACL=y # CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set CONFIG_NILFS2_FS=m CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y CONFIG_FILE_LOCKING=y CONFIG_FSNOTIFY=y CONFIG_DNOTIFY=y CONFIG_INOTIFY_USER=y CONFIG_FANOTIFY=y # CONFIG_FANOTIFY_ACCESS_PERMISSIONS is not set CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_PRINT_QUOTA_WARNING=y # CONFIG_QUOTA_DEBUG is not set CONFIG_QUOTA_TREE=m CONFIG_QFMT_V1=m CONFIG_QFMT_V2=m CONFIG_QUOTACTL=y CONFIG_QUOTACTL_COMPAT=y CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m CONFIG_CUSE=m CONFIG_GENERIC_ACL=y # # Caches # CONFIG_FSCACHE=m CONFIG_FSCACHE_STATS=y # CONFIG_FSCACHE_HISTOGRAM is not set # CONFIG_FSCACHE_DEBUG is not set # CONFIG_FSCACHE_OBJECT_LIST is not set CONFIG_CACHEFILES=m # CONFIG_CACHEFILES_DEBUG is not set # CONFIG_CACHEFILES_HISTOGRAM is not set # # CD-ROM/DVD Filesystems # CONFIG_ISO9660_FS=m CONFIG_JOLIET=y CONFIG_ZISOFS=y CONFIG_UDF_FS=m CONFIG_UDF_NLS=y # # DOS/FAT/NT Filesystems # CONFIG_FAT_FS=m CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m CONFIG_FAT_DEFAULT_CODEPAGE=437 CONFIG_FAT_DEFAULT_IOCHARSET="utf8" CONFIG_NTFS_FS=m # CONFIG_NTFS_DEBUG is not set CONFIG_NTFS_RW=y # # Pseudo filesystems # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_PROC_VMCORE=y CONFIG_PROC_SYSCTL=y CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y CONFIG_TMPFS_XATTR=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_CONFIGFS_FS=m CONFIG_MISC_FILESYSTEMS=y CONFIG_ADFS_FS=m # CONFIG_ADFS_FS_RW is not set CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_HFS_FS=m CONFIG_HFSPLUS_FS=m CONFIG_BEFS_FS=m # CONFIG_BEFS_DEBUG is not set CONFIG_BFS_FS=m CONFIG_EFS_FS=m CONFIG_JFFS2_FS=m CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y # CONFIG_JFFS2_FS_WBUF_VERIFY is not set CONFIG_JFFS2_SUMMARY=y CONFIG_JFFS2_FS_XATTR=y CONFIG_JFFS2_FS_POSIX_ACL=y CONFIG_JFFS2_FS_SECURITY=y CONFIG_JFFS2_COMPRESSION_OPTIONS=y CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_LZO=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set # CONFIG_JFFS2_CMODE_NONE is not set CONFIG_JFFS2_CMODE_PRIORITY=y # CONFIG_JFFS2_CMODE_SIZE is not set # CONFIG_JFFS2_CMODE_FAVOURLZO is not set CONFIG_UBIFS_FS=m CONFIG_UBIFS_FS_ADVANCED_COMPR=y CONFIG_UBIFS_FS_LZO=y CONFIG_UBIFS_FS_ZLIB=y CONFIG_LOGFS=m CONFIG_CRAMFS=m CONFIG_SQUASHFS=m CONFIG_SQUASHFS_XATTR=y CONFIG_SQUASHFS_ZLIB=y CONFIG_SQUASHFS_LZO=y CONFIG_SQUASHFS_XZ=y # CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set # CONFIG_SQUASHFS_EMBEDDED is not set CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 CONFIG_VXFS_FS=m CONFIG_MINIX_FS=m CONFIG_OMFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m # CONFIG_QNX6FS_FS is not set CONFIG_ROMFS_FS=m # CONFIG_ROMFS_BACKED_BY_BLOCK is not set # CONFIG_ROMFS_BACKED_BY_MTD is not set CONFIG_ROMFS_BACKED_BY_BOTH=y CONFIG_ROMFS_ON_BLOCK=y CONFIG_ROMFS_ON_MTD=y CONFIG_PSTORE=y # CONFIG_PSTORE_RAM is not set CONFIG_SYSV_FS=m CONFIG_UFS_FS=m # CONFIG_UFS_FS_WRITE is not set # CONFIG_UFS_DEBUG is not set CONFIG_EXOFS_FS=m # CONFIG_EXOFS_DEBUG is not set CONFIG_AUFS_FS=m CONFIG_AUFS_BRANCH_MAX_127=y # CONFIG_AUFS_BRANCH_MAX_511 is not set # CONFIG_AUFS_BRANCH_MAX_1023 is not set # CONFIG_AUFS_BRANCH_MAX_32767 is not set CONFIG_AUFS_SBILIST=y # CONFIG_AUFS_HNOTIFY is not set CONFIG_AUFS_EXPORT=y CONFIG_AUFS_INO_T_64=y # CONFIG_AUFS_RDU is not set # CONFIG_AUFS_PROC_MAP is not set # CONFIG_AUFS_SP_IATTR is not set # CONFIG_AUFS_SHWH is not set # CONFIG_AUFS_BR_RAMFS is not set # CONFIG_AUFS_BR_FUSE is not set CONFIG_AUFS_BR_HFSPLUS=y CONFIG_AUFS_BDEV_LOOP=y # CONFIG_AUFS_DEBUG is not set CONFIG_ORE=m CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m CONFIG_NFS_V2=y CONFIG_NFS_V3=y CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y CONFIG_NFS_V4_1=y CONFIG_PNFS_FILE_LAYOUT=m CONFIG_PNFS_BLOCK=m CONFIG_PNFS_OBJLAYOUT=m CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" CONFIG_NFS_FSCACHE=y # CONFIG_NFS_USE_LEGACY_DNS is not set CONFIG_NFS_USE_KERNEL_DNS=y CONFIG_NFSD=m CONFIG_NFSD_V2_ACL=y CONFIG_NFSD_V3=y CONFIG_NFSD_V3_ACL=y CONFIG_NFSD_V4=y # CONFIG_NFSD_FAULT_INJECTION is not set CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_NFS_ACL_SUPPORT=m CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m CONFIG_SUNRPC_BACKCHANNEL=y CONFIG_SUNRPC_XPRT_RDMA=m CONFIG_RPCSEC_GSS_KRB5=m # CONFIG_SUNRPC_DEBUG is not set CONFIG_CEPH_FS=m CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set CONFIG_CIFS_WEAK_PW_HASH=y CONFIG_CIFS_UPCALL=y CONFIG_CIFS_XATTR=y CONFIG_CIFS_POSIX=y # CONFIG_CIFS_DEBUG2 is not set CONFIG_CIFS_DFS_UPCALL=y CONFIG_CIFS_FSCACHE=y CONFIG_CIFS_ACL=y CONFIG_NCP_FS=m CONFIG_NCPFS_PACKET_SIGNING=y CONFIG_NCPFS_IOCTL_LOCKING=y CONFIG_NCPFS_STRONG=y CONFIG_NCPFS_NFS_NS=y CONFIG_NCPFS_OS2_NS=y # CONFIG_NCPFS_SMALLDOS is not set CONFIG_NCPFS_NLS=y CONFIG_NCPFS_EXTRAS=y CONFIG_CODA_FS=m CONFIG_AFS_FS=m # CONFIG_AFS_DEBUG is not set CONFIG_AFS_FSCACHE=y CONFIG_9P_FS=m CONFIG_9P_FSCACHE=y CONFIG_9P_FS_POSIX_ACL=y CONFIG_NLS=y CONFIG_NLS_DEFAULT="utf8" CONFIG_NLS_CODEPAGE_437=m CONFIG_NLS_CODEPAGE_737=m CONFIG_NLS_CODEPAGE_775=m CONFIG_NLS_CODEPAGE_850=m CONFIG_NLS_CODEPAGE_852=m CONFIG_NLS_CODEPAGE_855=m CONFIG_NLS_CODEPAGE_857=m CONFIG_NLS_CODEPAGE_860=m CONFIG_NLS_CODEPAGE_861=m CONFIG_NLS_CODEPAGE_862=m CONFIG_NLS_CODEPAGE_863=m CONFIG_NLS_CODEPAGE_864=m CONFIG_NLS_CODEPAGE_865=m CONFIG_NLS_CODEPAGE_866=m CONFIG_NLS_CODEPAGE_869=m CONFIG_NLS_CODEPAGE_936=m CONFIG_NLS_CODEPAGE_950=m CONFIG_NLS_CODEPAGE_932=m CONFIG_NLS_CODEPAGE_949=m CONFIG_NLS_CODEPAGE_874=m CONFIG_NLS_ISO8859_8=m CONFIG_NLS_CODEPAGE_1250=m CONFIG_NLS_CODEPAGE_1251=m CONFIG_NLS_ASCII=m CONFIG_NLS_ISO8859_1=m CONFIG_NLS_ISO8859_2=m CONFIG_NLS_ISO8859_3=m CONFIG_NLS_ISO8859_4=m CONFIG_NLS_ISO8859_5=m CONFIG_NLS_ISO8859_6=m CONFIG_NLS_ISO8859_7=m CONFIG_NLS_ISO8859_9=m CONFIG_NLS_ISO8859_13=m CONFIG_NLS_ISO8859_14=m CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m # CONFIG_NLS_MAC_ROMAN is not set # CONFIG_NLS_MAC_CELTIC is not set # CONFIG_NLS_MAC_CENTEURO is not set # CONFIG_NLS_MAC_CROATIAN is not set # CONFIG_NLS_MAC_CYRILLIC is not set # CONFIG_NLS_MAC_GAELIC is not set # CONFIG_NLS_MAC_GREEK is not set # CONFIG_NLS_MAC_ICELAND is not set # CONFIG_NLS_MAC_INUIT is not set # CONFIG_NLS_MAC_ROMANIAN is not set # CONFIG_NLS_MAC_TURKISH is not set CONFIG_NLS_UTF8=m CONFIG_DLM=m CONFIG_DLM_DEBUG=y CONFIG_PROTECTED_LINKS=y CONFIG_PROTECTED_SYMLINKS=y CONFIG_PROTECTED_SYMLINKS_SYSCTL=1 CONFIG_PROTECTED_HARDLINKS=y CONFIG_PROTECTED_HARDLINKS_SYSCTL=1 # # Kernel hacking # CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_PRINTK_TIME=y CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=2048 CONFIG_MAGIC_SYSRQ=y CONFIG_MAGIC_SYSRQ_DEFAULT_MASK=0x01b6 CONFIG_STRIP_ASM_SYMS=y # CONFIG_READABLE_ASM is not set CONFIG_UNUSED_SYMBOLS=y CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_SECTION_MISMATCH is not set CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set CONFIG_LOCKUP_DETECTOR=y CONFIG_HARDLOCKUP_DETECTOR=y # CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 # CONFIG_PANIC_ON_OOPS is not set CONFIG_PANIC_ON_OOPS_VALUE=0 CONFIG_DETECT_HUNG_TASK=y CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 # CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set CONFIG_TIMER_STATS=y # CONFIG_DEBUG_OBJECTS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_KMEMLEAK is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_LOCK_ALLOC is not set # CONFIG_PROVE_LOCKING is not set # CONFIG_SPARSE_RCU_POINTER is not set # CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_ATOMIC_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set CONFIG_STACKTRACE=y # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_INFO_REDUCED is not set # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_VIRTUAL is not set # CONFIG_DEBUG_WRITECOUNT is not set CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_DEBUG_LIST is not set # CONFIG_TEST_LIST_SORT is not set # CONFIG_DEBUG_SG is not set # CONFIG_DEBUG_NOTIFIERS is not set # CONFIG_DEBUG_CREDENTIALS is not set CONFIG_ARCH_WANT_FRAME_POINTERS=y # CONFIG_FRAME_POINTER is not set CONFIG_BOOT_PRINTK_DELAY=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_RCU_CPU_STALL_TIMEOUT=60 # CONFIG_RCU_CPU_STALL_INFO is not set # CONFIG_RCU_TRACE is not set # CONFIG_KPROBES_SANITY_TEST is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_DEBUG_PER_CPU_MAPS is not set # CONFIG_LKDTM is not set # CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set # CONFIG_DEBUG_PAGEALLOC is not set CONFIG_USER_STACKTRACE_SUPPORT=y CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_HAVE_C_RECORDMCOUNT=y CONFIG_RING_BUFFER=y CONFIG_EVENT_TRACING=y CONFIG_EVENT_POWER_TRACING_DEPRECATED=y CONFIG_CONTEXT_SWITCH_TRACER=y CONFIG_RING_BUFFER_ALLOW_SWAP=y CONFIG_TRACING=y CONFIG_GENERIC_TRACER=y CONFIG_TRACING_SUPPORT=y CONFIG_FTRACE=y # CONFIG_FUNCTION_TRACER is not set # CONFIG_IRQSOFF_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_FTRACE_SYSCALLS is not set CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set # CONFIG_PROFILE_ALL_BRANCHES is not set # CONFIG_STACK_TRACER is not set CONFIG_BLK_DEV_IO_TRACE=y # CONFIG_KPROBE_EVENT is not set # CONFIG_UPROBE_EVENT is not set # CONFIG_PROBE_EVENTS is not set # CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_MMIOTRACE is not set # CONFIG_RING_BUFFER_BENCHMARK is not set # CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set # CONFIG_FIREWIRE_OHCI_REMOTE_DMA is not set # CONFIG_DYNAMIC_DEBUG is not set # CONFIG_DMA_API_DEBUG is not set # CONFIG_ATOMIC64_SELFTEST is not set # CONFIG_ASYNC_RAID6_TEST is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set CONFIG_HAVE_ARCH_KMEMCHECK=y # CONFIG_TEST_KSTRTOX is not set CONFIG_STRICT_DEVMEM=y CONFIG_X86_VERBOSE_BOOTUP=y CONFIG_EARLY_PRINTK=y # CONFIG_EARLY_PRINTK_DBGP is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_X86_PTDUMP is not set CONFIG_DEBUG_RODATA=y # CONFIG_DEBUG_RODATA_TEST is not set CONFIG_DEBUG_SET_MODULE_RONX=y # CONFIG_DEBUG_NX_TEST is not set # CONFIG_IOMMU_DEBUG is not set # CONFIG_IOMMU_STRESS is not set CONFIG_HAVE_MMIOTRACE_SUPPORT=y # CONFIG_X86_DECODER_SELFTEST is not set CONFIG_IO_DELAY_TYPE_0X80=0 CONFIG_IO_DELAY_TYPE_0XED=1 CONFIG_IO_DELAY_TYPE_UDELAY=2 CONFIG_IO_DELAY_TYPE_NONE=3 CONFIG_IO_DELAY_0X80=y # CONFIG_IO_DELAY_0XED is not set # CONFIG_IO_DELAY_UDELAY is not set # CONFIG_IO_DELAY_NONE is not set CONFIG_DEFAULT_IO_DELAY_TYPE=0 # CONFIG_DEBUG_BOOT_PARAMS is not set # CONFIG_CPA_DEBUG is not set CONFIG_OPTIMIZE_INLINING=y # CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set # CONFIG_DEBUG_NMI_SELFTEST is not set # # Security options # CONFIG_KEYS=y # CONFIG_TRUSTED_KEYS is not set # CONFIG_ENCRYPTED_KEYS is not set CONFIG_KEYS_DEBUG_PROC_KEYS=y # CONFIG_SECURITY_DMESG_RESTRICT is not set CONFIG_SECURITY=y CONFIG_SECURITYFS=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_PATH=y # CONFIG_INTEL_TXT is not set CONFIG_LSM_MMAP_MIN_ADDR=65536 CONFIG_SECURITY_SELINUX=y # CONFIG_SECURITY_SELINUX_BOOTPARAM is not set # CONFIG_SECURITY_SELINUX_DISABLE is not set CONFIG_SECURITY_SELINUX_DEVELOP=y CONFIG_SECURITY_SELINUX_AVC_STATS=y CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 # CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set CONFIG_SECURITY_TOMOYO=y CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY=2048 CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG=1024 # CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER is not set CONFIG_SECURITY_TOMOYO_POLICY_LOADER="/sbin/tomoyo-init" CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER="/sbin/init" CONFIG_SECURITY_APPARMOR=y CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 # CONFIG_SECURITY_YAMA is not set # CONFIG_IMA is not set # CONFIG_EVM is not set # CONFIG_DEFAULT_SECURITY_SELINUX is not set # CONFIG_DEFAULT_SECURITY_TOMOYO is not set # CONFIG_DEFAULT_SECURITY_APPARMOR is not set CONFIG_DEFAULT_SECURITY_DAC=y CONFIG_DEFAULT_SECURITY="" CONFIG_XOR_BLOCKS=m CONFIG_ASYNC_CORE=m CONFIG_ASYNC_MEMCPY=m CONFIG_ASYNC_XOR=m CONFIG_ASYNC_PQ=m CONFIG_ASYNC_RAID6_RECOV=m CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA=y CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA=y CONFIG_CRYPTO=y # # Crypto core or helper # CONFIG_CRYPTO_FIPS=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=m CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=m CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_HASH2=y CONFIG_CRYPTO_RNG=m CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_PCOMP=m CONFIG_CRYPTO_PCOMP2=y CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_USER is not set # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set CONFIG_CRYPTO_GF128MUL=m CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_PCRYPT=m CONFIG_CRYPTO_WORKQUEUE=y CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_TEST=m # # Authenticated Encryption with Associated Data # CONFIG_CRYPTO_CCM=m CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_SEQIV=m # # Block modes # CONFIG_CRYPTO_CBC=m CONFIG_CRYPTO_CTR=m CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XTS=m # # Hash modes # CONFIG_CRYPTO_HMAC=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m # # Digest # CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_CRC32C_INTEL=m CONFIG_CRYPTO_GHASH=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_RMD128=m CONFIG_CRYPTO_RMD160=m CONFIG_CRYPTO_RMD256=m CONFIG_CRYPTO_RMD320=m CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA1_SSSE3=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=m # # Ciphers # CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_AES_X86_64=m CONFIG_CRYPTO_AES_NI_INTEL=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_BLOWFISH_COMMON=m CONFIG_CRYPTO_BLOWFISH_X86_64=m CONFIG_CRYPTO_CAMELLIA=m # CONFIG_CRYPTO_CAMELLIA_X86_64 is not set CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m CONFIG_CRYPTO_DES=m CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m CONFIG_CRYPTO_SALSA20=m CONFIG_CRYPTO_SALSA20_X86_64=m CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_SERPENT_SSE2_X86_64=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_TWOFISH_COMMON=m CONFIG_CRYPTO_TWOFISH_X86_64=m CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=m # # Compression # CONFIG_CRYPTO_DEFLATE=m CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m # # Random Number Generation # CONFIG_CRYPTO_ANSI_CPRNG=m CONFIG_CRYPTO_USER_API=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m CONFIG_CRYPTO_HW=y CONFIG_CRYPTO_DEV_PADLOCK=m CONFIG_CRYPTO_DEV_PADLOCK_AES=m CONFIG_CRYPTO_DEV_PADLOCK_SHA=m CONFIG_HAVE_KVM=y CONFIG_HAVE_KVM_IRQCHIP=y CONFIG_HAVE_KVM_EVENTFD=y CONFIG_KVM_APIC_ARCHITECTURE=y CONFIG_KVM_MMIO=y CONFIG_KVM_ASYNC_PF=y CONFIG_HAVE_KVM_MSI=y CONFIG_VIRTUALIZATION=y CONFIG_KVM=m CONFIG_KVM_INTEL=m CONFIG_KVM_AMD=m # CONFIG_KVM_MMU_AUDIT is not set CONFIG_VHOST_NET=m CONFIG_BINARY_PRINTF=y # # Library routines # CONFIG_RAID6_PQ=m CONFIG_BITREVERSE=y CONFIG_GENERIC_STRNCPY_FROM_USER=y CONFIG_GENERIC_STRNLEN_USER=y CONFIG_GENERIC_FIND_FIRST_BIT=y CONFIG_GENERIC_PCI_IOMAP=y CONFIG_GENERIC_IOMAP=y CONFIG_GENERIC_IO=y CONFIG_CRC_CCITT=m CONFIG_CRC16=m CONFIG_CRC_T10DIF=m CONFIG_CRC_ITU_T=m CONFIG_CRC32=y # CONFIG_CRC32_SELFTEST is not set CONFIG_CRC32_SLICEBY8=y # CONFIG_CRC32_SLICEBY4 is not set # CONFIG_CRC32_SARWATE is not set # CONFIG_CRC32_BIT is not set CONFIG_CRC7=m CONFIG_LIBCRC32C=m CONFIG_CRC8=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m CONFIG_LZO_COMPRESS=y CONFIG_LZO_DECOMPRESS=y CONFIG_XZ_DEC=y CONFIG_XZ_DEC_X86=y CONFIG_XZ_DEC_POWERPC=y CONFIG_XZ_DEC_IA64=y CONFIG_XZ_DEC_ARM=y CONFIG_XZ_DEC_ARMTHUMB=y CONFIG_XZ_DEC_SPARC=y CONFIG_XZ_DEC_BCJ=y # CONFIG_XZ_DEC_TEST is not set CONFIG_DECOMPRESS_GZIP=y CONFIG_DECOMPRESS_BZIP2=y CONFIG_DECOMPRESS_LZMA=y CONFIG_DECOMPRESS_XZ=y CONFIG_DECOMPRESS_LZO=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_REED_SOLOMON=m CONFIG_REED_SOLOMON_DEC16=y CONFIG_TEXTSEARCH=y CONFIG_TEXTSEARCH_KMP=m CONFIG_TEXTSEARCH_BM=m CONFIG_TEXTSEARCH_FSM=m CONFIG_BTREE=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y CONFIG_CHECK_SIGNATURE=y CONFIG_CPU_RMAP=y CONFIG_DQL=y CONFIG_NLATTR=y CONFIG_LRU_CACHE=m CONFIG_AVERAGE=y CONFIG_CORDIC=m # CONFIG_DDR is not set -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at polymtl.ca Fri Jan 25 12:30:30 2013 From: mathieu.desnoyers at polymtl.ca (Mathieu Desnoyers) Date: Fri, 25 Jan 2013 12:30:30 -0500 Subject: [lttng-dev] [tracepoint] cargo-culting considered harmful... In-Reply-To: <20130125153159.GE4503@ZenIV.linux.org.uk> References: <20130123225523.GY4939@ZenIV.linux.org.uk> <20130123155147.25fe49a2.akpm@linux-foundation.org> <20130124014840.GA4503@ZenIV.linux.org.uk> <20130125144953.GB20597@Krystal> <20130125153159.GE4503@ZenIV.linux.org.uk> Message-ID: <20130125173030.GB23720@Krystal> * Al Viro (viro at ZenIV.linux.org.uk) wrote: > On Fri, Jan 25, 2013 at 09:49:53AM -0500, Mathieu Desnoyers wrote: > > static > > void lttng_enumerate_task_fd(struct lttng_session *session, > > struct task_struct *p, char *tmp) > > { > > struct fdtable *fdt; > > struct file *filp; > > unsigned int i; > > const unsigned char *path; > > > > task_lock(p); > > if (!p->files) > > goto unlock_task; > > spin_lock(&p->files->file_lock); > > fdt = files_fdtable(p->files); > > for (i = 0; i < fdt->max_fds; i++) { > > filp = fcheck_files(p->files, i); > > if (!filp) > > continue; > > path = d_path(&filp->f_path, tmp, PAGE_SIZE); > > /* Make sure we give at least some info */ > > trace_lttng_statedump_file_descriptor(session, p, i, > > IS_ERR(path) ? > > filp->f_dentry->d_name.name : > > path); > > } > > spin_unlock(&p->files->file_lock); > > unlock_task: > > task_unlock(p); > > } > > *cringe* > > a) yes, it needs d_lock for that ->d_name access > b) iterate_fd() is there for purpose; use it, instead of open-coding the > damn loop. Something like > > struct ctx { > char *page; > struct lttng_session *session, > struct task_struct *p; > }; > > static int dump_one(void *p, struct file *file, unsigned fd) > { > struct ctx *ctx = p; > const char *s = d_path(&file->f_path, ctx->page, PAGE_SIZE); > struct dentry *dentry; > if (!IS_ERR(s)) { > trace_lttng_statedump_file_descriptor(ctx->session, ctx->p, fd, s); > return 0; > } > /* Make sure we give at least some info */ > dentry = file->f_path.dentry; > spin_lock(&dentry->d_lock); > trace_lttng_statedump_file_descriptor(ctx->session, ctx->p, fd, > dentry->d_name); > spin_unlock(&dentry->d_lock); > return 0; > } > > ... > task_lock(p); > iterate_fd(p->files, 0, dump_one, &(struct ctx){tmp, session, p}); > task_unlock(p); > > assuming it wouldn't be better to pass tmp/session/p as the single pointer > to struct in the first place - I don't know enough about the callers of > that sucker to tell. And yes, iterate_fd() will DTRT if given NULL as the > first argument. The second argument is "which descriptor should I start > from?", callback is called for everything present in the table starting from > that place until it returns non-zero or the end of table is reached... Thanks !! Modulo a couple of trivial nits, I've integrated your suggestions. I'm creating a lttng_iterate_fd() wrapper for older kernels (yeah.. we deal with kernels back to 2.6.32). Mathieu -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From Daniel.Thibault at drdc-rddc.gc.ca Fri Jan 25 12:32:41 2013 From: Daniel.Thibault at drdc-rddc.gc.ca (Thibault, Daniel) Date: Fri, 25 Jan 2013 12:32:41 -0500 Subject: [lttng-dev] Odd dependency for lttng-ust - resolved Message-ID: <3CA1A65C03C1A34C81BBC6272782E696987A76@valcartierex01.valcartier.drdc-rddc.gc.ca> -----Message d'origine----- Date: Mon, 21 Jan 2013 14:34:29 -0500 Subject: Re: [lttng-dev] Odd dependency for lttng-ust -----Message d'origine (int?rieur)----- De?: Mathieu Desnoyers [mailto:mathieu.desnoyers at efficios.com] Envoy??: 21 janvier 2013 13:39 As the error messages suggests, please try: LDFLAGS=-L/usr/local/lib ./configure instead of "./configure" Mathieu -----Fin du message d'origine (int?rieur)----- Interesting, that prefix does allow configure to complete successfully. lttng-tools runs into the same problem as lttng-ust, and requires the same LDFLAGS prefix for its configure. No other problems arise. So how do we fix userspace-rcu so the bootstrap -configure - make - install sequence doesn't run into this problem? I'm presuming here that userspace-rcu's install needs to be touched up. Or maybe lttng-ust's (and lttng-tools's) bootstrap. (It's a problem because the ReadMe for the lttng-ust and lttng-tools packages stipulate a plain ./configure invocation: as they currently stand, the instructions fail) -----Fin du message d'origine----- I've finally stumbled onto what was causing ./configure to fail for lttng-ust and lttng-tools. According to the ld-linux man pages, the Linux default library/header paths are just /lib and /usr/lib: they do not include /usr/local/lib. However, /etc/ld.so.conf.d/libc.conf (installed by the Ubuntu libc-bin package) adds /usr/local/bin to the system loader's path, so any application that relies on /usr/local/bin libraries will find them. Why does ./configure fail, then? It turns out this particular failure is a known bug (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42756, January 2010) with the gold linker from the binutils-gold package (specified by the lttng-tools ReadMe): unlike the linker it replaces, gold's linker does not look into /usr/local/lib by default and ignores the ld.so.conf instructions. Hence the explicit LDFLAGS=-L/usr/local/lib prefix requirement. Until this old gold bug is fixed (which looks unlikely considering its age), maybe each package's configure.ac could be made to explicitly look into /usr/local/lib when /lib and /usr/lib fail? Or the ReadMe files of lttng-ust and lttng-tools could be modified to mention the workaround? Daniel U. Thibault R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) 2459 route de la Bravoure Qu?bec, QC? G3J 1X5 CANADA Vox?: (418) 844-4000 x4245 Fax?: (418) 844-4538 NAC?: 918V QSDJ Gouvernement du Canada?/ Government of Canada From alexmonthy at voxpopuli.im Fri Jan 25 12:57:14 2013 From: alexmonthy at voxpopuli.im (Alexandre Montplaisir) Date: Fri, 25 Jan 2013 12:57:14 -0500 Subject: [lttng-dev] Odd dependency for lttng-ust - resolved In-Reply-To: <3CA1A65C03C1A34C81BBC6272782E696987A76@valcartierex01.valcartier.drdc-rddc.gc.ca> References: <3CA1A65C03C1A34C81BBC6272782E696987A76@valcartierex01.valcartier.drdc-rddc.gc.ca> Message-ID: <5102C77A.5040409@voxpopuli.im> Hi Daniel, On 13-01-25 12:32 PM, Thibault, Daniel wrote: > [...] > > Until this old gold bug is fixed (which looks unlikely considering its age), maybe each package's configure.ac could be made to explicitly look into /usr/local/lib when /lib and /usr/lib fail? Or the ReadMe files of lttng-ust and lttng-tools could be modified to mention the workaround? > I'm not sure if they are any distro that uses gold by default, instead of the more venerable/tested "ld". I know Ubuntu doesn't. I think in your case the problem was because you still had the libraries from Ubuntu's older package installed in /usr/lib, and as you mentioned, the linker looks in that location before trying /usr/local/lib. In such a "custom" setup, you would need to override LDFLAGS. But someone that has nothing installed in /usr/lib should get the libraries in /usr/local/lib selected by the linker automatically. Cheers, Alexandre From Daniel.Thibault at drdc-rddc.gc.ca Fri Jan 25 13:26:47 2013 From: Daniel.Thibault at drdc-rddc.gc.ca (Thibault, Daniel) Date: Fri, 25 Jan 2013 13:26:47 -0500 Subject: [lttng-dev] Odd dependency for lttng-ust - resolved In-Reply-To: <5102C77A.5040409@voxpopuli.im> References: <3CA1A65C03C1A34C81BBC6272782E696987A76@valcartierex01.valcartier.drdc-rddc.gc.ca> <5102C77A.5040409@voxpopuli.im> Message-ID: <3CA1A65C03C1A34C81BBC6272782E696987A7F@valcartierex01.valcartier.drdc-rddc.gc.ca> -----Message d'origine----- De?: Alexandre Montplaisir [mailto:alexmonthy at voxpopuli.im] Envoy??: 25 janvier 2013 12:57 On 13-01-25 12:32 PM, Thibault, Daniel wrote: > [...] > Until this old gold bug is fixed (which looks unlikely considering its age), maybe each package's configure.ac could be made to explicitly look into /usr/local/lib when /lib and /usr/lib fail? Or the ReadMe files of lttng-ust and lttng-tools could be modified to mention the workaround? I'm not sure if they are any distro that uses gold by default, instead of the more venerable/tested "ld". I know Ubuntu doesn't. I think in your case the problem was because you still had the libraries from Ubuntu's older package installed in /usr/lib, and as you mentioned, the linker looks in that location before trying /usr/local/lib. In such a "custom" setup, you would need to override LDFLAGS. But someone that has nothing installed in /usr/lib should get the libraries in /usr/local/lib selected by the linker automatically. Cheers, Alexandre -----Fin du message d'origine----- Nope, my /usr/lib is clean. The problem is unavoidable on a clean system because lttng-tools's README lists GNU Gold (2.22 or better) in its requirements when building from git. On the other hand, if you had a liburcu package installed and it were not too old, configure's checks would be passed. You could run into trouble during the make though, depending on which liburcu (/usr/lib vs. /usr/local/lib) it linked against. But that scenario is moot as Mathieu rightly warned against mixing old and new stuff together. "But someone that has nothing installed in /usr/lib should get the libraries in /usr/local/lib selected by the linker automatically." Only if using ld.bfd or if binutils-gold were not installed -in which latter case one would not be following the instructions. (See http://stackoverflow.com/questions/5873516/shared-library-in-usr-local-lib-not-found for a very similar problem and its diagnostic; this is the page that clinched it for me) Daniel U. Thibault R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) 2459 route de la Bravoure Qu?bec, QC G3J 1X5 CANADA Vox : (418) 844-4000 x4245 Fax : (418) 844-4538 [Valcartier]\\vsi-wdut-o980, [Secteur-SI]\\edge NAC : 918V QSDJ Gouvernement du Canada / Government of Canada LinkedIn: Research Gate: From christian.babeux at efficios.com Fri Jan 25 13:48:28 2013 From: christian.babeux at efficios.com (Christian Babeux) Date: Fri, 25 Jan 2013 13:48:28 -0500 Subject: [lttng-dev] Odd dependency for lttng-ust - resolved In-Reply-To: <3CA1A65C03C1A34C81BBC6272782E696987A7F@valcartierex01.valcartier.drdc-rddc.gc.ca> References: <3CA1A65C03C1A34C81BBC6272782E696987A76@valcartierex01.valcartier.drdc-rddc.gc.ca> <5102C77A.5040409@voxpopuli.im> <3CA1A65C03C1A34C81BBC6272782E696987A7F@valcartierex01.valcartier.drdc-rddc.gc.ca> Message-ID: > Nope, my /usr/lib is clean. The problem is unavoidable on a clean system because lttng-tools's README lists GNU Gold (2.22 or better) in its requirements when building from git. On the other hand, if you had a liburcu package installed and it were not too old, configure's checks would be passed. You could run into trouble during the make though, depending on which liburcu (/usr/lib vs. /usr/local/lib) it linked against. But that scenario is moot as Mathieu rightly warned against mixing old and new stuff together. The README has been clarified in commit ee10cdeb41ab238ebdc9ae3d1b2a4dbbe930df9b. The bottom line is: With GNU ld: ./configure *should* work as is if "/usr/local/lib" is correctly specified in /etc/ld.so.conf. Note that this is _distribution specific_ and you might have to use LDFLAGS=-L/usr/local/lib ./configure on other distros. With GNU Gold: Use LDFLAGS=-L/usr/local/lib ./configure if dependencies have been installed in /usr/local/*. Thanks, Christian From dgoulet at ev0ke.net Fri Jan 25 14:49:31 2013 From: dgoulet at ev0ke.net (David Goulet) Date: Fri, 25 Jan 2013 14:49:31 -0500 Subject: [lttng-dev] [PATCH lttng-modules] Fix: missing event's prefix in btrfs probe Message-ID: <1359143371-1953-1-git-send-email-dgoulet@ev0ke.net> From: David Goulet Signed-off-by: David Goulet --- instrumentation/events/lttng-module/btrfs.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/instrumentation/events/lttng-module/btrfs.h b/instrumentation/events/lttng-module/btrfs.h index c01a6e0..34ae480 100644 --- a/instrumentation/events/lttng-module/btrfs.h +++ b/instrumentation/events/lttng-module/btrfs.h @@ -390,7 +390,7 @@ DECLARE_EVENT_CLASS(btrfs__writepage, #endif ) -DEFINE_EVENT(btrfs__writepage, __extent_writepage, +DEFINE_EVENT(btrfs__writepage, btrfs_extent_writepage, TP_PROTO(struct page *page, struct inode *inode, struct writeback_control *wbc), @@ -792,7 +792,7 @@ DEFINE_EVENT(btrfs__reserved_extent, btrfs_reserved_extent_free, ) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) -TRACE_EVENT(find_free_extent, +TRACE_EVENT(btrfs_find_free_extent, TP_PROTO(struct btrfs_root *root, u64 num_bytes, u64 empty_size, u64 data), @@ -956,7 +956,7 @@ TRACE_EVENT(btrfs_setup_cluster, #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) -TRACE_EVENT(alloc_extent_state, +TRACE_EVENT(btrfs_alloc_extent_state, TP_PROTO(struct extent_state *state, gfp_t mask, unsigned long IP), @@ -978,7 +978,7 @@ TRACE_EVENT(alloc_extent_state, show_gfp_flags(__entry->mask), (void *)__entry->ip) ) -TRACE_EVENT(free_extent_state, +TRACE_EVENT(btrfs_free_extent_state, TP_PROTO(struct extent_state *state, unsigned long IP), -- 1.7.10.4 From dgoulet at efficios.com Fri Jan 25 14:51:11 2013 From: dgoulet at efficios.com (David Goulet) Date: Fri, 25 Jan 2013 14:51:11 -0500 Subject: [lttng-dev] [PATCH lttng-modules] Fix: missing event's prefix in btrfs probe In-Reply-To: <1359143371-1953-1-git-send-email-dgoulet@ev0ke.net> References: <1359143371-1953-1-git-send-email-dgoulet@ev0ke.net> Message-ID: <5102E22F.7080304@efficios.com> Meh... A file is missing in this patch. Ignore, resending soon! David Goulet: > From: David Goulet > > Signed-off-by: David Goulet > --- > instrumentation/events/lttng-module/btrfs.h | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/instrumentation/events/lttng-module/btrfs.h b/instrumentation/events/lttng-module/btrfs.h > index c01a6e0..34ae480 100644 > --- a/instrumentation/events/lttng-module/btrfs.h > +++ b/instrumentation/events/lttng-module/btrfs.h > @@ -390,7 +390,7 @@ DECLARE_EVENT_CLASS(btrfs__writepage, > #endif > ) > > -DEFINE_EVENT(btrfs__writepage, __extent_writepage, > +DEFINE_EVENT(btrfs__writepage, btrfs_extent_writepage, > > TP_PROTO(struct page *page, struct inode *inode, > struct writeback_control *wbc), > @@ -792,7 +792,7 @@ DEFINE_EVENT(btrfs__reserved_extent, btrfs_reserved_extent_free, > ) > > #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) > -TRACE_EVENT(find_free_extent, > +TRACE_EVENT(btrfs_find_free_extent, > > TP_PROTO(struct btrfs_root *root, u64 num_bytes, u64 empty_size, > u64 data), > @@ -956,7 +956,7 @@ TRACE_EVENT(btrfs_setup_cluster, > #endif > > #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) > -TRACE_EVENT(alloc_extent_state, > +TRACE_EVENT(btrfs_alloc_extent_state, > > TP_PROTO(struct extent_state *state, gfp_t mask, unsigned long IP), > > @@ -978,7 +978,7 @@ TRACE_EVENT(alloc_extent_state, > show_gfp_flags(__entry->mask), (void *)__entry->ip) > ) > > -TRACE_EVENT(free_extent_state, > +TRACE_EVENT(btrfs_free_extent_state, > > TP_PROTO(struct extent_state *state, unsigned long IP), > From mathieu.desnoyers at efficios.com Fri Jan 25 15:01:59 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 25 Jan 2013 15:01:59 -0500 Subject: [lttng-dev] [PATCH lttng-modules] Fix: missing event's prefix in btrfs probe In-Reply-To: <1359143371-1953-1-git-send-email-dgoulet@ev0ke.net> References: <1359143371-1953-1-git-send-email-dgoulet@ev0ke.net> Message-ID: <20130125200159.GA6859@Krystal> * David Goulet (dgoulet at ev0ke.net) wrote: > From: David Goulet Nope, those prefix are missing upstream. I cannot take them until Linux upstream is fixed. You might want to submit a patch on LKML, ccing those responsible for: commit 3f7de037fb3727b20bc27332cdcf2488b702394c Author: Josef Bacik Date: Thu Nov 10 08:29:20 2011 -0500 Btrfs: add allocator tracepoints I used these tracepoints when figuring out what the cluster stuff was doing, so add them to mainline in case we need to profile this stuff again. Thanks, Signed-off-by: Josef Bacik And the btrfs maintainer (found in MAINTAINERS). Thanks, Mathieu > > Signed-off-by: David Goulet > --- > instrumentation/events/lttng-module/btrfs.h | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/instrumentation/events/lttng-module/btrfs.h b/instrumentation/events/lttng-module/btrfs.h > index c01a6e0..34ae480 100644 > --- a/instrumentation/events/lttng-module/btrfs.h > +++ b/instrumentation/events/lttng-module/btrfs.h > @@ -390,7 +390,7 @@ DECLARE_EVENT_CLASS(btrfs__writepage, > #endif > ) > > -DEFINE_EVENT(btrfs__writepage, __extent_writepage, > +DEFINE_EVENT(btrfs__writepage, btrfs_extent_writepage, > > TP_PROTO(struct page *page, struct inode *inode, > struct writeback_control *wbc), > @@ -792,7 +792,7 @@ DEFINE_EVENT(btrfs__reserved_extent, btrfs_reserved_extent_free, > ) > > #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) > -TRACE_EVENT(find_free_extent, > +TRACE_EVENT(btrfs_find_free_extent, > > TP_PROTO(struct btrfs_root *root, u64 num_bytes, u64 empty_size, > u64 data), > @@ -956,7 +956,7 @@ TRACE_EVENT(btrfs_setup_cluster, > #endif > > #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) > -TRACE_EVENT(alloc_extent_state, > +TRACE_EVENT(btrfs_alloc_extent_state, > > TP_PROTO(struct extent_state *state, gfp_t mask, unsigned long IP), > > @@ -978,7 +978,7 @@ TRACE_EVENT(alloc_extent_state, > show_gfp_flags(__entry->mask), (void *)__entry->ip) > ) > > -TRACE_EVENT(free_extent_state, > +TRACE_EVENT(btrfs_free_extent_state, > > TP_PROTO(struct extent_state *state, unsigned long IP), > > -- > 1.7.10.4 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From francis.giraldeau at gmail.com Fri Jan 25 17:10:26 2013 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Fri, 25 Jan 2013 17:10:26 -0500 Subject: [lttng-dev] Sync instrumentation to today's linux 3.8 Message-ID: To prepare instrumentation for the next linux release, here is the ticket I was working on. It's mostly straight forward. http://redmine.dorsal.polymtl.ca/issues/431 There is one issue with ext4 includes. I had to copy fs/ext4/ext4.h and ext4_extent.h for the function ext4_ext_get_actual_len(). I added them to instrumentation/mainline/fs/ext4 directory. I'm not sure if it's the best solution. Still testing to do, thought. BTW, is there a test setup for regression? I would like to verify that it doesn't break any supported kernel and I don't have the required setup. With this, maybe lttng-modules 2.1 can target linux 3.8? Cheers, Francis -------------- next part -------------- An HTML attachment was scrubbed... URL: From mathieu.desnoyers at efficios.com Sat Jan 26 10:57:31 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sat, 26 Jan 2013 10:57:31 -0500 Subject: [lttng-dev] [COMMIT urcu] doc/cds-api.txt: expand documentation Message-ID: <20130126155731.GA20955@Krystal> Expand explanations, reorder items to have all wait-free descriptions first, so that the rculfqueue API comes last, since it is less featureful and is the only API of the queues/stacks to actually rely on RCU. Signed-off-by: Mathieu Desnoyers --- diff --git a/doc/cds-api.txt b/doc/cds-api.txt index 81d511c..8896e20 100644 --- a/doc/cds-api.txt +++ b/doc/cds-api.txt @@ -28,28 +28,36 @@ urcu/rcuhlist.h: for implementing hash tables. Downside over rculist.h: lookup of tail in O(n). -urcu/rculfqueue.h: +urcu/wfstack.h: - RCU queue with lock-free enqueue, lock-free dequeue. RCU used to - provide existance guarantees. + Stack with wait-free push and wait-free pop_all. Both blocking + and non-blocking pop and traversal operations are provided. + This stack does _not_ specifically rely on RCU. + Various synchronization techniques can be used to deal with + pop ABA. Those are detailed in the API. urcu/wfcqueue.h: - Concurrent queue with wait-free enqueue, blocking traversal. - This queue does _not_ use RCU. + Concurrent queue with wait-free enqueue. Both blocking and + non-blocking dequeue, splice (move all elements from one queue + to another), and traversal operations are provided. + This queue does _not_ specifically rely on RCU. Mutual exclusion + is used to protect dequeue, splice (from source queue) and + traversal (see API for details). (note: deprecates urcu/wfqueue.h) urcu/lfstack.h: - RCU stack with lock-free push, lock-free dequeue. Various - synchronization techniques can be used to deal with "pop" ABA. - Those are detailed in the API. + Stack with lock-free push, lock-free pop, wait-free pop_all, + wait-free traversal. Various synchronization techniques can be + used to deal with pop ABA. Those are detailed in the API. + This stack does _not_ specifically rely on RCU. (note: deprecates urcu/rculfstack.h) -urcu/wfstack.h: +urcu/rculfqueue.h: - Stack with wait-free enqueue, blocking dequeue. This stack does - _not_ use RCU. + RCU queue with lock-free enqueue, lock-free dequeue. + This queue relies on RCU for existence guarantees. urcu/rculfhash.h: -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From jeremie.galarneau at efficios.com Mon Jan 28 05:36:07 2013 From: jeremie.galarneau at efficios.com (=?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=) Date: Mon, 28 Jan 2013 10:36:07 +0000 Subject: [lttng-dev] [PATCH babeltrace] Fix: Added a null pointer check to bt_ctf_field_name. Message-ID: <1359369367-12876-1-git-send-email-jeremie.galarneau@efficios.com> This function is called indirectly when calling __repr__ (print) in the python bindings on the definition object returned by the get_top_level_scope method thus resulting in a segmentation fault when the name attribute is not set. Fixes #373 Signed-off-by: J?r?mie Galarneau --- formats/ctf/events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/formats/ctf/events.c b/formats/ctf/events.c index ac7dce4..182d0de 100644 --- a/formats/ctf/events.c +++ b/formats/ctf/events.c @@ -168,7 +168,7 @@ const char *bt_ctf_event_name(const struct bt_ctf_event *ctf_event) const char *bt_ctf_field_name(const struct definition *def) { - if (!def) + if (!def || !def->name) return NULL; return rem_(g_quark_to_string(def->name)); -- 1.8.1.1 From mathieu.desnoyers at efficios.com Mon Jan 28 11:09:50 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 28 Jan 2013 11:09:50 -0500 Subject: [lttng-dev] [PATCH babeltrace] Fix: Added a null pointer check to bt_ctf_field_name. In-Reply-To: <1359369367-12876-1-git-send-email-jeremie.galarneau@efficios.com> References: <1359369367-12876-1-git-send-email-jeremie.galarneau@efficios.com> Message-ID: <20130128160950.GA23309@Krystal> * J?r?mie Galarneau (jeremie.galarneau at efficios.com) wrote: > This function is called indirectly when calling __repr__ (print) in the python > bindings on the definition object returned by the get_top_level_scope method > thus resulting in a segmentation fault when the name attribute is not set. merged into master and python bindings branches, thanks! Mathieu > > Fixes #373 > > Signed-off-by: J?r?mie Galarneau > --- > formats/ctf/events.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/formats/ctf/events.c b/formats/ctf/events.c > index ac7dce4..182d0de 100644 > --- a/formats/ctf/events.c > +++ b/formats/ctf/events.c > @@ -168,7 +168,7 @@ const char *bt_ctf_event_name(const struct bt_ctf_event *ctf_event) > > const char *bt_ctf_field_name(const struct definition *def) > { > - if (!def) > + if (!def || !def->name) > return NULL; > > return rem_(g_quark_to_string(def->name)); > -- > 1.8.1.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon Jan 28 11:15:55 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 28 Jan 2013 11:15:55 -0500 Subject: [lttng-dev] Sync instrumentation to today's linux 3.8 In-Reply-To: References: Message-ID: <20130128161555.GA23427@Krystal> * Francis Giraldeau (francis.giraldeau at gmail.com) wrote: > To prepare instrumentation for the next linux release, here is the ticket I > was working on. It's mostly straight forward. > > http://redmine.dorsal.polymtl.ca/issues/431 > > There is one issue with ext4 includes. I had to copy fs/ext4/ext4.h and > ext4_extent.h for the function ext4_ext_get_actual_len(). I added them to > instrumentation/mainline/fs/ext4 directory. I'm not sure if it's the best > solution. > > Still testing to do, thought. BTW, is there a test setup for regression? I > would like to verify that it doesn't break any supported kernel and I don't > have the required setup. > > With this, maybe lttng-modules 2.1 can target linux 3.8? Please send the patch by email. 3.8 is still in rc stage. Removing ext4_ext_get_actual_len() seems like a bad move from upstream Linux if it is needed in the instrumentation headers. This should be fixed upstream rather than duplicated within our own code. Thanks, Mathieu > > Cheers, > > Francis > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon Jan 28 11:19:53 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 28 Jan 2013 11:19:53 -0500 Subject: [lttng-dev] Sync instrumentation to today's linux 3.8 In-Reply-To: <20130128161555.GA23427@Krystal> References: <20130128161555.GA23427@Krystal> Message-ID: <20130128161953.GB23427@Krystal> * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > * Francis Giraldeau (francis.giraldeau at gmail.com) wrote: > > To prepare instrumentation for the next linux release, here is the ticket I > > was working on. It's mostly straight forward. > > > > http://redmine.dorsal.polymtl.ca/issues/431 > > > > There is one issue with ext4 includes. I had to copy fs/ext4/ext4.h and > > ext4_extent.h for the function ext4_ext_get_actual_len(). I added them to > > instrumentation/mainline/fs/ext4 directory. I'm not sure if it's the best > > solution. > > > > Still testing to do, thought. BTW, is there a test setup for regression? I > > would like to verify that it doesn't break any supported kernel and I don't > > have the required setup. > > > > With this, maybe lttng-modules 2.1 can target linux 3.8? And FYI, ext4 tracepoints are only in lttng-modules master branch. They were excluded from 2.1.x because they arrived too late in the 2.1 cycle. Thanks, Mathieu > > Please send the patch by email. > > 3.8 is still in rc stage. Removing ext4_ext_get_actual_len() seems like > a bad move from upstream Linux if it is needed in the instrumentation > headers. This should be fixed upstream rather than duplicated within our > own code. > > Thanks, > > Mathieu > > > > > Cheers, > > > > Francis > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > -- > Mathieu Desnoyers > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon Jan 28 11:37:12 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 28 Jan 2013 11:37:12 -0500 Subject: [lttng-dev] bug? In-Reply-To: <8E0A14A4C9B95B459AE214584119C1EB3BC909B3@Hal.ad.unb.ca> References: <8E0A14A4C9B95B459AE214584119C1EB3BC909B3@Hal.ad.unb.ca> Message-ID: <20130128163712.GA23710@Krystal> * Yang Wang (yangw.wang5 at unb.ca) wrote: > Hello, > > I am Yang Wang, I am currently using lttng to trace my JVM. > > During my using lttng in tracing JVM, I found three problems, > > 1) in lttng-ust-2.1.0/include/lttng/ust-tracepoint-event.h > > why using an assertion "assert(!ret);" (Line676)? > not allowing double registering and init? > if double registering or initialization (provider), why not allowed just returning silently instead > of aborting"? How about comments assert(!ret); ==>//assert(!ret); what is the side-effects > of doing this? This would be caused by having two different versions of .so with conflicting provider name. This is usually a linking issue, and/or due to the fact that your system has old/deprecated provider .so still reachable. If your system has only one version of the provider available, you would not trigger double registering. So I don't see how silently allowing multiple non-matching providers (and using just the first one that happened to be loaded) would help diagnosing bogus setups. > > 2) The other problem is in ./userspace-rcu-0.7.5/urcu/list.h Line85 > > I have to add a guard "if" statement as the assertion in my program fails otherwise > > static inline void > __cds_list_del (struct cds_list_head *prev, struct cds_list_head *next) > { > if (prev != NULL && next != NULL) { > //assert(prev != NULL && next != NULL); > next->prev = prev; > prev->next = next; > } It might be caused by e.g. double registration issues I'm talking about, now that you removed the assert in __lttng_events_init__. You should verify which provider .so are reachable, and make sure you don't try to load two different providers with the same name. > > 3) Now my instrumented prog is ready to run. Here is my commands: > lttng create > lttng enable-event -u -a > lttng start > ./prog > > The (lttng) instrumented prog is stuck there without any outputs > related to lttng tracing, how can I know what happen inside. > In other words, does lttng have any mechanism to trace itself? Start with LTTNG_UST_DEBUG=1 env. var. set (see man 3 lttng-ust) gdb is usually pretty good at letting us know the culprit of such a hang. Recommendation: compile your program with CFLAGS="-O0 -g", and use "thread apply all bt full" to see the stack of each thread. Best regards, Mathieu > > Thanks > > Yang > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From Daniel.Thibault at drdc-rddc.gc.ca Tue Jan 29 11:34:00 2013 From: Daniel.Thibault at drdc-rddc.gc.ca (Thibault, Daniel) Date: Tue, 29 Jan 2013 11:34:00 -0500 Subject: [lttng-dev] The disable-libtool-linkdep-fixup configure option Message-ID: <3CA1A65C03C1A34C81BBC6272782E6969BDD05@valcartierex01.valcartier.drdc-rddc.gc.ca> The git.lttng.org packages lttng-ust and lttng-tools have a configure option named disable-libtool-linkdep-fixup. The 'linkdep fixup', if I understand correctly, serves to fix a problem with the version of the libtool package used with Debian systems (and possibly others), as described in http://bugs.lttng.org/issues/321. The fixup in question consists of changing occurrences of the 'link_all_deplibs=no' flag in config/libtool.m4 to 'link_all_deplibs=unknown' instead. The default value of the option is 'yes' (re: configure.ac), which means the fixup is applied. Setting the option to another value, such as 'no', means the fixup is not applied. Why then is the option named *disable*-libtool-linkdep-fixup? Shouldn't it be named *enable*-libtool-linkdep-fixup instead? Daniel U. Thibault R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) 2459 route de la Bravoure Qu?bec, QC? G3J 1X5 CANADA Vox?: (418) 844-4000 x4245 Fax?: (418) 844-4538 NAC?: 918V QSDJ Gouvernement du Canada?/ Government of Canada From christian.babeux at efficios.com Tue Jan 29 11:54:03 2013 From: christian.babeux at efficios.com (Christian Babeux) Date: Tue, 29 Jan 2013 11:54:03 -0500 Subject: [lttng-dev] The disable-libtool-linkdep-fixup configure option In-Reply-To: <3CA1A65C03C1A34C81BBC6272782E6969BDD05@valcartierex01.valcartier.drdc-rddc.gc.ca> References: <3CA1A65C03C1A34C81BBC6272782E6969BDD05@valcartierex01.valcartier.drdc-rddc.gc.ca> Message-ID: Hi Daniel, > Why then is the option named *disable*-libtool-linkdep-fixup? Shouldn't it be named *enable*-libtool-linkdep-fixup instead? Because the option is enabled by default on all systems. This is to facilitate cross-compilation on Debian/Ubuntu systems. Thanks, Christian From Daniel.Thibault at drdc-rddc.gc.ca Tue Jan 29 12:20:59 2013 From: Daniel.Thibault at drdc-rddc.gc.ca (Thibault, Daniel) Date: Tue, 29 Jan 2013 12:20:59 -0500 Subject: [lttng-dev] The disable-libtool-linkdep-fixup configure option Message-ID: <3CA1A65C03C1A34C81BBC6272782E6969BDD0C@valcartierex01.valcartier.drdc-rddc.gc.ca> > > The default value of the option is 'yes' (re: configure.ac), which means the fixup is applied. Setting the option to another value, such as 'no', means the fixup is not applied. > > Why then is the option named *disable*-libtool-linkdep-fixup? Shouldn't it be named *enable*-libtool-linkdep-fixup instead? > >Because the option is enabled by default on all systems. This is to facilitate cross-compilation on Debian/Ubuntu systems. > > Christian If you had to compare the following two command lines, which one would you say disabled the fixup? ./configure --disable-libtool-linkdep-fixup=yes ./configure --disable-libtool-linkdep-fixup=no The first line is the current default, and it leaves the fixup enabled (right?). That's why I suspect enable-libtool-linkdep-fixup would be a more meaningful name. Daniel U. Thibault R & D pour la d?fense Canada - Valcartier (RDDC Valcartier) / Defence R&D Canada - Valcartier (DRDC Valcartier) Cyber s?curit? pour les missions essentielles (CME) / Mission Critical Cyber Security (MCCS) Protection des syst?mes et contremesures (PSC) / Systems Protection & Countermeasures (SPC) 2459 route de la Bravoure Qu?bec, QC G3J 1X5 CANADA Vox : (418) 844-4000 x4245 Fax : (418) 844-4538 NAC : 918V QSDJ Gouvernement du Canada / Government of Canada From mathieu.desnoyers at efficios.com Tue Jan 29 12:32:40 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 29 Jan 2013 12:32:40 -0500 Subject: [lttng-dev] The disable-libtool-linkdep-fixup configure option In-Reply-To: <3CA1A65C03C1A34C81BBC6272782E6969BDD0C@valcartierex01.valcartier.drdc-rddc.gc.ca> References: <3CA1A65C03C1A34C81BBC6272782E6969BDD0C@valcartierex01.valcartier.drdc-rddc.gc.ca> Message-ID: <20130129173240.GA9703@Krystal> * Thibault, Daniel (Daniel.Thibault at drdc-rddc.gc.ca) wrote: > > > The default value of the option is 'yes' (re: configure.ac), which means the fixup is applied. Setting the option to another value, such as 'no', means the fixup is not applied. > > > Why then is the option named *disable*-libtool-linkdep-fixup? Shouldn't it be named *enable*-libtool-linkdep-fixup instead? > > > >Because the option is enabled by default on all systems. This is to facilitate cross-compilation on Debian/Ubuntu systems. > > > > Christian > > If you had to compare the following two command lines, which one would you say disabled the fixup? > > ./configure --disable-libtool-linkdep-fixup=yes > ./configure --disable-libtool-linkdep-fixup=no > > The first line is the current default, and it leaves the fixup enabled > (right?). That's why I suspect enable-libtool-linkdep-fixup would be > a more meaningful name. Please read the autoconf documentation, and become familiar with the usual practices of other open source projects on this matter. The autoconf documentation would, amongst other things, tell you about "./configure --help". Its output lists: --disable-libtool-linkdep-fixup disable the libtool fixup for linking all dependent libraries (link_all_deplibs) as a matter of fact, this option does not take "=yes/=no" parameters as you suggest, nor does any of the --enable/disable-* configure options in general. This option is enabled by default, unless you specify --disable-libtool-linkdep-fixup. As a general guide-line, you should never need to use this override, except in very exceptional situations (e.g. in the event of future distribution changes). Thank you, Mathieu -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From jeremie.galarneau at efficios.com Thu Jan 31 08:50:50 2013 From: jeremie.galarneau at efficios.com (=?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=) Date: Thu, 31 Jan 2013 13:50:50 +0000 Subject: [lttng-dev] [PATCH babeltrace 1/2] Added Python 3.0 or better requirement to the README file Message-ID: <1359640251-6133-1-git-send-email-jeremie.galarneau@efficios.com> Signed-off-by: J?r?mie Galarneau --- README | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README b/README index 9df02e7..ce98e24 100644 --- a/README +++ b/README @@ -49,6 +49,8 @@ To compile Babeltrace, you will need: (Debian/Ubuntu : python-dev) swig >= 2.0 (optional) (Debian/Ubuntu : swig2.0) + python 3.0 or better (optional) + (Debian/Ubuntu : python3) For developers using the git tree: -- 1.8.1.1 From jeremie.galarneau at efficios.com Thu Jan 31 08:50:51 2013 From: jeremie.galarneau at efficios.com (=?UTF-8?q?J=C3=A9r=C3=A9mie=20Galarneau?=) Date: Thu, 31 Jan 2013 13:50:51 +0000 Subject: [lttng-dev] [PATCH babeltrace 2/2] Added Python interpreter version directives and reorganized example scripts In-Reply-To: <1359640251-6133-1-git-send-email-jeremie.galarneau@efficios.com> References: <1359640251-6133-1-git-send-email-jeremie.galarneau@efficios.com> Message-ID: <1359640251-6133-2-git-send-email-jeremie.galarneau@efficios.com> Signed-off-by: J?r?mie Galarneau --- bindings/python/examples/babeltrace_and_lttng.py | 12 +- bindings/python/examples/eventcount.py | 84 - bindings/python/examples/eventcountlist.py | 83 - bindings/python/examples/events_per_cpu.py | 99 - bindings/python/examples/example-api-test.py | 11 +- bindings/python/examples/histogram.py | 139 -- .../examples/output_format_modules/cairoplot.py | 2336 -------------------- .../examples/output_format_modules/pprint_table.py | 37 - .../examples/output_format_modules/series.py | 1140 ---------- bindings/python/examples/python2/eventcount.py | 85 + bindings/python/examples/python2/eventcountlist.py | 84 + bindings/python/examples/python2/events_per_cpu.py | 100 + bindings/python/examples/python2/histogram.py | 140 ++ .../python2/output_format_modules/cairoplot.py | 2336 ++++++++++++++++++++ .../python2/output_format_modules/pprint_table.py | 37 + .../python2/output_format_modules/series.py | 1140 ++++++++++ bindings/python/examples/python2/softirqtimes.py | 154 ++ .../python/examples/python2/syscalls_by_pid.py | 85 + bindings/python/examples/sched_switch.py | 11 +- bindings/python/examples/softirqtimes.py | 153 -- bindings/python/examples/syscalls_by_pid.py | 84 - tests/tests-python.py | 1 + 22 files changed, 4183 insertions(+), 4168 deletions(-) mode change 100644 => 100755 bindings/python/examples/babeltrace_and_lttng.py delete mode 100644 bindings/python/examples/eventcount.py delete mode 100644 bindings/python/examples/eventcountlist.py delete mode 100644 bindings/python/examples/events_per_cpu.py mode change 100644 => 100755 bindings/python/examples/example-api-test.py delete mode 100644 bindings/python/examples/histogram.py delete mode 100644 bindings/python/examples/output_format_modules/cairoplot.py delete mode 100644 bindings/python/examples/output_format_modules/pprint_table.py delete mode 100644 bindings/python/examples/output_format_modules/series.py create mode 100755 bindings/python/examples/python2/eventcount.py create mode 100755 bindings/python/examples/python2/eventcountlist.py create mode 100755 bindings/python/examples/python2/events_per_cpu.py create mode 100755 bindings/python/examples/python2/histogram.py create mode 100644 bindings/python/examples/python2/output_format_modules/cairoplot.py create mode 100644 bindings/python/examples/python2/output_format_modules/pprint_table.py create mode 100644 bindings/python/examples/python2/output_format_modules/series.py create mode 100755 bindings/python/examples/python2/softirqtimes.py create mode 100755 bindings/python/examples/python2/syscalls_by_pid.py mode change 100644 => 100755 bindings/python/examples/sched_switch.py delete mode 100644 bindings/python/examples/softirqtimes.py delete mode 100644 bindings/python/examples/syscalls_by_pid.py mode change 100644 => 100755 tests/tests-python.py diff --git a/bindings/python/examples/babeltrace_and_lttng.py b/bindings/python/examples/babeltrace_and_lttng.py old mode 100644 new mode 100755 index cb44796..cfd611f --- a/bindings/python/examples/babeltrace_and_lttng.py +++ b/bindings/python/examples/babeltrace_and_lttng.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # babeltrace_and_lttng.py # # Babeltrace and LTTng example script @@ -59,18 +60,23 @@ ret = lttng.create(ses_name,trace_path) if ret < 0: raise LTTngError(lttng.strerror(ret)) +domain = lttng.Domain() +domain.type = lttng.DOMAIN_KERNEL + han = None -han = lttng.Handle(ses_name, lttng.Domain()) +han = lttng.Handle(ses_name, domain) if han is None: raise LTTngError("Handle not created") # Enabling all events -ret = lttng.enable_event(han, lttng.Event(), None) +event = lttng.Event() +event.type = lttng.EVENT_ALL +event.loglevel_type = lttng.EVENT_LOGLEVEL_ALL +ret = lttng.enable_event(han, event, None) if ret < 0: raise LTTngError(lttng.strerror(ret)) - # Start, wait, stop ret = lttng.start(ses_name) if ret < 0: diff --git a/bindings/python/examples/eventcount.py b/bindings/python/examples/eventcount.py deleted file mode 100644 index 5e96a43..0000000 --- a/bindings/python/examples/eventcount.py +++ /dev/null @@ -1,84 +0,0 @@ -# eventcount.py -# -# Babeltrace event count example script -# -# Copyright 2012 EfficiOS Inc. -# -# Author: Danny Serres -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# The script prints a count of specified events and -# their related tid's in a given trace. -# The trace needs TID context (lttng add-context -k -t tid) - -import sys -from babeltrace import * -from output_format_modules.pprint_table import pprint_table as pprint - -if len(sys.argv) < 3: - raise TypeError("Usage: python eventcount.py event1 [event2 ...] path/to/trace") - -ctx = Context() -ret = ctx.add_trace(sys.argv[len(sys.argv)-1], "ctf") -if ret is None: - raise IOError("Error adding trace") - -counts = {} - -# Setting iterator -bp = IterPos(SEEK_BEGIN) -ctf_it = ctf.Iterator(ctx, bp) - -# Reading events -event = ctf_it.read_event() -while(event is not None): - for event_type in sys.argv[1:len(sys.argv)-1]: - if event_type == event.get_name(): - - # Getting scope definition - sco = event.get_top_level_scope(ctf.scope.STREAM_EVENT_CONTEXT) - if sco is None: - print("ERROR: Cannot get definition scope for {}".format( - event.get_name())) - continue - - # Getting TID - tid_field = event.get_field(sco, "_tid") - tid = tid_field.get_int64() - - if ctf.field_error(): - print("ERROR: Missing TID info for {}".format( - event.get_name())) - continue - - tmp = (tid, event.get_name()) - - if tmp in counts: - counts[tmp] += 1 - else: - counts[tmp] = 1 - - # Next event - ret = ctf_it.next() - if ret < 0: - break - event = ctf_it.read_event() - -del ctf_it - -# Appending data to table for output -table = [] -for item in counts: - table.append([item[0], item[1], counts[item]]) -table = sorted(table) -table.insert(0,["TID", "EVENT", "COUNT"]) -pprint(table, 2) diff --git a/bindings/python/examples/eventcountlist.py b/bindings/python/examples/eventcountlist.py deleted file mode 100644 index 945a960..0000000 --- a/bindings/python/examples/eventcountlist.py +++ /dev/null @@ -1,83 +0,0 @@ -# eventcountlist.py -# -# Babeltrace event count list example script -# -# Copyright 2012 EfficiOS Inc. -# -# Author: Danny Serres -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# The script prints a count and rate of events. -# It also outputs a bar graph of count per event, using the cairoplot module. - -import sys -from babeltrace import * -from output_format_modules import cairoplot -from output_format_modules.pprint_table import pprint_table as pprint - -# Check for path arg: -if len(sys.argv) < 2: - raise TypeError("Usage: python eventcountlist.py path/to/trace") - -ctx = Context() -ret = ctx.add_trace(sys.argv[1], "ctf") -if ret is None: - raise IOError("Error adding trace") - -# Events and their assossiated count -# will be stored as a dict: -events_count = {} - -# Setting iterator: -bp = IterPos(SEEK_BEGIN) -ctf_it = ctf.Iterator(ctx,bp) - -prev_event = None -event = ctf_it.read_event() - -start_time = event.get_timestamp() - -# Reading events: -while(event is not None): - if event.get_name() in events_count: - events_count[event.get_name()] += 1 - else: - events_count[event.get_name()] = 1 - - ret = ctf_it.next() - if ret < 0: - break - else: - prev_event = event - event = ctf_it.read_event() - -if event: - total_time = event.get_timestamp() - start_time -else: - total_time = prev_event.get_timestamp() - start_time - -del ctf_it - -# Printing encountered events with respective count and rate: -print("Total time: {} ns".format(total_time)) -table = [["EVENT", "COUNT", "RATE (Hz)"]] -for item in sorted(events_count.iterkeys()): - tmp = [item, events_count[item], - events_count[item]/(total_time/1000000000.0)] - table.append(tmp) -pprint(table) - -# Exporting data as bar graph -cairoplot.vertical_bar_plot ( 'eventcountlist.svg', events_count, 50+85*len(events_count), - 800, border = 20, display_values = True, grid = True, - rounded_corners = True, - x_labels = sorted(events_count.keys()) ) diff --git a/bindings/python/examples/events_per_cpu.py b/bindings/python/examples/events_per_cpu.py deleted file mode 100644 index be497ec..0000000 --- a/bindings/python/examples/events_per_cpu.py +++ /dev/null @@ -1,99 +0,0 @@ -# events_per_cpu.py -# -# Babeltrace events per cpu example script -# -# Copyright 2012 EfficiOS Inc. -# -# Author: Danny Serres -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# The script opens a trace and prints out CPU statistics -# for the given trace (event count per CPU, total active -# time and % of time processing events). -# It also outputs a .txt file showing each time interval -# (since the beginning of the trace) in which each CPU -# was active and the corresponding event. - -import sys, multiprocessing -from output_format_modules.pprint_table import pprint_table as pprint -from babeltrace import * - -if len(sys.argv) < 2: - raise TypeError("Usage: python events_per_cpu.py path/to/trace") - -# Adding trace -ctx = Context() -ret = ctx.add_trace(sys.argv[1], "ctf") -if ret is None: - raise IOError("Error adding trace") - -cpu_usage = [] -nbEvents = 0 -i = 0 -while i < multiprocessing.cpu_count(): - cpu_usage.append([]) - i += 1 - -# Setting iterator -bp = IterPos(SEEK_BEGIN) -ctf_it = ctf.Iterator(ctx, bp) - -# Reading events -event = ctf_it.read_event() -start_time = event.get_timestamp() - -while(event is not None): - - event_name = event.get_name() - ts = event.get_timestamp() - - # Getting cpu_id - scope = event.get_top_level_scope(ctf.scope.STREAM_PACKET_CONTEXT) - field = event.get_field(scope, "cpu_id") - cpu_id = field.get_uint64() - if ctf.field_error(): - print("ERROR: Missing cpu_id info for {}".format(event.get_name())) - else: - cpu_usage[cpu_id].append( (int(ts), event_name) ) - nbEvents += 1 - - # Next Event - ret = ctf_it.next() - if ret < 0: - break - event = ctf_it.read_event() - - -# Outputting -table = [] -output = open("events_per_cpu.txt", "wt") -output.write("(timestamp, event)\n") - -for cpu in range(len(cpu_usage)): - # Setting table - event_str = str(100.0 * len(cpu_usage[cpu]) / nbEvents) + '000' - # % is printed with 2 decimals - table.append([cpu, len(cpu_usage[cpu]), event_str[0:event_str.find('.') + 3] + ' %']) - - # Writing to file - output.write("\n\n\n----------------------\n") - output.write("CPU {}\n\n".format(cpu)) - for event in cpu_usage[cpu]: - output.write(str(event) + '\n') - -# Printing table -table.insert(0, ["CPU ID", "EVENT COUNT", "TRACE EVENT %"]) -pprint(table) -print("Total event count: {}".format(nbEvents)) -print("Total trace time: {} ns".format(ts - start_time)) - -output.close() diff --git a/bindings/python/examples/example-api-test.py b/bindings/python/examples/example-api-test.py old mode 100644 new mode 100755 index 104f2d5..fc59e24 --- a/bindings/python/examples/example-api-test.py +++ b/bindings/python/examples/example-api-test.py @@ -1,18 +1,19 @@ +#!/usr/bin/env python3 # example_api_test.py -# +# # Babeltrace example script based on the Babeltrace API test script -# +# # Copyright 2012 EfficiOS Inc. -# +# # Author: Danny Serres -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. diff --git a/bindings/python/examples/histogram.py b/bindings/python/examples/histogram.py deleted file mode 100644 index 44616a6..0000000 --- a/bindings/python/examples/histogram.py +++ /dev/null @@ -1,139 +0,0 @@ -# histogram.py -# -# Babeltrace histogram example script -# -# Copyright 2012 EfficiOS Inc. -# -# Author: Danny Serres -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# The script checks the number of events in the trace -# and outputs a table and a .svg histogram for the specified -# range (microseconds) or the total trace if no range specified. -# The graph is generated using the cairoplot module. - -import sys -from babeltrace import * -from output_format_modules import cairoplot -from output_format_modules.pprint_table import pprint_table as pprint - -# ------------------------------------------------ -# Output settings - -# number of intervals: -nbDiv = 25 # Should not be over 150 - # for usable graph output - -# table output stream (file-like object): -out = sys.stdout -# ------------------------------------------------- - -if len(sys.argv) < 2 or len(sys.argv) > 4: - raise TypeError("Usage: python histogram.py [ start_time [end_time] ] path/to/trace") - -ctx = Context() -ret = ctx.add_trace(sys.argv[len(sys.argv)-1], "ctf") -if ret is None: - raise IOError("Error adding trace") - -# Check when to start/stop graphing -sinceBegin = True -beginTime = 0.0 -if len(sys.argv) > 2: - sinceBegin = False - beginTime = float(sys.argv[1]) -untilEnd = True -if len(sys.argv) == 4: - untilEnd = False - -# Setting iterator -bp = IterPos(SEEK_BEGIN) -ctf_it = ctf.Iterator(ctx, bp) - -# Reading events -event = ctf_it.read_event() -start_time = event.get_timestamp() -time = 0 -count = {} - -while(event is not None): - # Microsec. - time = (event.get_timestamp() - start_time)/1000.0 - - # Check if in range - if not sinceBegin: - if time < beginTime: - # Next Event - ret = ctf_it.next() - if ret < 0: - break - event = ctf_it.read_event() - continue - if not untilEnd: - if time > float(sys.argv[2]): - break - - # Counting events per timestamp: - if time in count: - count[time] += 1 - else: - count[time] = 1 - - # Next Event - ret = ctf_it.next() - if ret < 0: - break - event = ctf_it.read_event() - -del ctf_it - -# Setting data for output -interval = (time - beginTime)/nbDiv -div_begin_time = beginTime -div_end_time = beginTime + interval -data = {} - -# Prefix for string sorting, considering -# there should not be over 150 intervals. -# This would work up to 9999 intervals. -# If needed, add zeros. -prefix = 0.0001 - -while div_end_time <= time: - key = str(prefix) + '[' + str(div_begin_time) + ';' + str(div_end_time) + '[' - for tmp in count: - if tmp >= div_begin_time and tmp < div_end_time: - if key in data: - data[key] += count[tmp] - else: - data[key] = count[tmp] - if not key in data: - data[key] = 0 - div_begin_time = div_end_time - div_end_time += interval - # Prefix increment - prefix += 0.001 - -table = [] -x_labels = [] -for key in sorted(data): - table.append([key[key.find('['):], data[key]]) - x_labels.append(key[key.find('['):]) - -# Table output -table.insert(0, ["INTERVAL (us)", "COUNT"]) -pprint(table, 1, out) - -# Graph output -cairoplot.vertical_bar_plot ( 'histogram.svg', data, 50 + 150*nbDiv, 50*nbDiv, - border = 20, display_values = True, grid = True, - x_labels = x_labels, rounded_corners = True ) diff --git a/bindings/python/examples/output_format_modules/cairoplot.py b/bindings/python/examples/output_format_modules/cairoplot.py deleted file mode 100644 index a27113f..0000000 --- a/bindings/python/examples/output_format_modules/cairoplot.py +++ /dev/null @@ -1,2336 +0,0 @@ -?#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# CairoPlot.py -# -# Copyright (c) 2008 Rodrigo Moreira Ara?jo -# -# Author: Rodrigo Moreiro Araujo -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser 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 Lesser 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 - -#Contributor: Jo?o S. O. Bueno - -#TODO: review BarPlot Code -#TODO: x_label colision problem on Horizontal Bar Plot -#TODO: y_label's eat too much space on HBP - - -__version__ = 1.2 - -import cairo -import math -import random -from series import Series, Group, Data - -HORZ = 0 -VERT = 1 -NORM = 2 - -COLORS = {"red" : (1.0,0.0,0.0,1.0), "lime" : (0.0,1.0,0.0,1.0), "blue" : (0.0,0.0,1.0,1.0), - "maroon" : (0.5,0.0,0.0,1.0), "green" : (0.0,0.5,0.0,1.0), "navy" : (0.0,0.0,0.5,1.0), - "yellow" : (1.0,1.0,0.0,1.0), "magenta" : (1.0,0.0,1.0,1.0), "cyan" : (0.0,1.0,1.0,1.0), - "orange" : (1.0,0.5,0.0,1.0), "white" : (1.0,1.0,1.0,1.0), "black" : (0.0,0.0,0.0,1.0), - "gray" : (0.5,0.5,0.5,1.0), "light_gray" : (0.9,0.9,0.9,1.0), - "transparent" : (0.0,0.0,0.0,0.0)} - -THEMES = {"black_red" : [(0.0,0.0,0.0,1.0), (1.0,0.0,0.0,1.0)], - "red_green_blue" : [(1.0,0.0,0.0,1.0), (0.0,1.0,0.0,1.0), (0.0,0.0,1.0,1.0)], - "red_orange_yellow" : [(1.0,0.2,0.0,1.0), (1.0,0.7,0.0,1.0), (1.0,1.0,0.0,1.0)], - "yellow_orange_red" : [(1.0,1.0,0.0,1.0), (1.0,0.7,0.0,1.0), (1.0,0.2,0.0,1.0)], - "rainbow" : [(1.0,0.0,0.0,1.0), (1.0,0.5,0.0,1.0), (1.0,1.0,0.0,1.0), (0.0,1.0,0.0,1.0), (0.0,0.0,1.0,1.0), (0.3, 0.0, 0.5,1.0), (0.5, 0.0, 1.0, 1.0)]} - -def colors_from_theme( theme, series_length, mode = 'solid' ): - colors = [] - if theme not in THEMES.keys() : - raise Exception, "Theme not defined" - color_steps = THEMES[theme] - n_colors = len(color_steps) - if series_length <= n_colors: - colors = [color + tuple([mode]) for color in color_steps[0:n_colors]] - else: - iterations = [(series_length - n_colors)/(n_colors - 1) for i in color_steps[:-1]] - over_iterations = (series_length - n_colors) % (n_colors - 1) - for i in range(n_colors - 1): - if over_iterations <= 0: - break - iterations[i] += 1 - over_iterations -= 1 - for index,color in enumerate(color_steps[:-1]): - colors.append(color + tuple([mode])) - if iterations[index] == 0: - continue - next_color = color_steps[index+1] - color_step = ((next_color[0] - color[0])/(iterations[index] + 1), - (next_color[1] - color[1])/(iterations[index] + 1), - (next_color[2] - color[2])/(iterations[index] + 1), - (next_color[3] - color[3])/(iterations[index] + 1)) - for i in range( iterations[index] ): - colors.append((color[0] + color_step[0]*(i+1), - color[1] + color_step[1]*(i+1), - color[2] + color_step[2]*(i+1), - color[3] + color_step[3]*(i+1), - mode)) - colors.append(color_steps[-1] + tuple([mode])) - return colors - - -def other_direction(direction): - "explicit is better than implicit" - if direction == HORZ: - return VERT - else: - return HORZ - -#Class definition - -class Plot(object): - def __init__(self, - surface=None, - data=None, - width=640, - height=480, - background=None, - border = 0, - x_labels = None, - y_labels = None, - series_colors = None): - random.seed(2) - self.create_surface(surface, width, height) - self.dimensions = {} - self.dimensions[HORZ] = width - self.dimensions[VERT] = height - self.context = cairo.Context(self.surface) - self.labels={} - self.labels[HORZ] = x_labels - self.labels[VERT] = y_labels - self.load_series(data, x_labels, y_labels, series_colors) - self.font_size = 10 - self.set_background (background) - self.border = border - self.borders = {} - self.line_color = (0.5, 0.5, 0.5) - self.line_width = 0.5 - self.label_color = (0.0, 0.0, 0.0) - self.grid_color = (0.8, 0.8, 0.8) - - def create_surface(self, surface, width=None, height=None): - self.filename = None - if isinstance(surface, cairo.Surface): - self.surface = surface - return - if not type(surface) in (str, unicode): - raise TypeError("Surface should be either a Cairo surface or a filename, not %s" % surface) - sufix = surface.rsplit(".")[-1].lower() - self.filename = surface - if sufix == "png": - self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) - elif sufix == "ps": - self.surface = cairo.PSSurface(surface, width, height) - elif sufix == "pdf": - self.surface = cairo.PSSurface(surface, width, height) - else: - if sufix != "svg": - self.filename += ".svg" - self.surface = cairo.SVGSurface(self.filename, width, height) - - def commit(self): - try: - self.context.show_page() - if self.filename and self.filename.endswith(".png"): - self.surface.write_to_png(self.filename) - else: - self.surface.finish() - except cairo.Error: - pass - - def load_series (self, data, x_labels=None, y_labels=None, series_colors=None): - self.series_labels = [] - self.series = None - - #The pretty way - #if not isinstance(data, Series): - # # Not an instance of Series - # self.series = Series(data) - #else: - # self.series = data - # - #self.series_labels = self.series.get_names() - - #TODO: Remove on next version - # The ugly way, keeping retrocompatibility... - if callable(data) or type(data) is list and callable(data[0]): # Lambda or List of lambdas - self.series = data - self.series_labels = None - elif isinstance(data, Series): # Instance of Series - self.series = data - self.series_labels = data.get_names() - else: # Anything else - self.series = Series(data) - self.series_labels = self.series.get_names() - - #TODO: allow user passed series_widths - self.series_widths = [1.0 for group in self.series] - - #TODO: Remove on next version - self.process_colors( series_colors ) - - def process_colors( self, series_colors, length = None, mode = 'solid' ): - #series_colors might be None, a theme, a string of colors names or a list of color tuples - if length is None : - length = len( self.series.to_list() ) - - #no colors passed - if not series_colors: - #Randomize colors - self.series_colors = [ [random.random() for i in range(3)] + [1.0, mode] for series in range( length ) ] - else: - #Just theme pattern - if not hasattr( series_colors, "__iter__" ): - theme = series_colors - self.series_colors = colors_from_theme( theme.lower(), length ) - - #Theme pattern and mode - elif not hasattr(series_colors, '__delitem__') and not hasattr( series_colors[0], "__iter__" ): - theme = series_colors[0] - mode = series_colors[1] - self.series_colors = colors_from_theme( theme.lower(), length, mode ) - - #List - else: - self.series_colors = series_colors - for index, color in enumerate( self.series_colors ): - #element is a color name - if not hasattr(color, "__iter__"): - self.series_colors[index] = COLORS[color.lower()] + tuple([mode]) - #element is rgb tuple instead of rgba - elif len( color ) == 3 : - self.series_colors[index] += (1.0,mode) - #element has 4 elements, might be rgba tuple or rgb tuple with mode - elif len( color ) == 4 : - #last element is mode - if not hasattr(color[3], "__iter__"): - self.series_colors[index] += tuple([color[3]]) - self.series_colors[index][3] = 1.0 - #last element is alpha - else: - self.series_colors[index] += tuple([mode]) - - def get_width(self): - return self.surface.get_width() - - def get_height(self): - return self.surface.get_height() - - def set_background(self, background): - if background is None: - self.background = (0.0,0.0,0.0,0.0) - elif type(background) in (cairo.LinearGradient, tuple): - self.background = background - elif not hasattr(background,"__iter__"): - colors = background.split(" ") - if len(colors) == 1 and colors[0] in COLORS: - self.background = COLORS[background] - elif len(colors) > 1: - self.background = cairo.LinearGradient(self.dimensions[HORZ] / 2, 0, self.dimensions[HORZ] / 2, self.dimensions[VERT]) - for index,color in enumerate(colors): - self.background.add_color_stop_rgba(float(index)/(len(colors)-1),*COLORS[color]) - else: - raise TypeError ("Background should be either cairo.LinearGradient or a 3/4-tuple, not %s" % type(background)) - - def render_background(self): - if isinstance(self.background, cairo.LinearGradient): - self.context.set_source(self.background) - else: - self.context.set_source_rgba(*self.background) - self.context.rectangle(0,0, self.dimensions[HORZ], self.dimensions[VERT]) - self.context.fill() - - def render_bounding_box(self): - self.context.set_source_rgba(*self.line_color) - self.context.set_line_width(self.line_width) - self.context.rectangle(self.border, self.border, - self.dimensions[HORZ] - 2 * self.border, - self.dimensions[VERT] - 2 * self.border) - self.context.stroke() - - def render(self): - pass - -class ScatterPlot( Plot ): - def __init__(self, - surface=None, - data=None, - errorx=None, - errory=None, - width=640, - height=480, - background=None, - border=0, - axis = False, - dash = False, - discrete = False, - dots = 0, - grid = False, - series_legend = False, - x_labels = None, - y_labels = None, - x_bounds = None, - y_bounds = None, - z_bounds = None, - x_title = None, - y_title = None, - series_colors = None, - circle_colors = None ): - - self.bounds = {} - self.bounds[HORZ] = x_bounds - self.bounds[VERT] = y_bounds - self.bounds[NORM] = z_bounds - self.titles = {} - self.titles[HORZ] = x_title - self.titles[VERT] = y_title - self.max_value = {} - self.axis = axis - self.discrete = discrete - self.dots = dots - self.grid = grid - self.series_legend = series_legend - self.variable_radius = False - self.x_label_angle = math.pi / 2.5 - self.circle_colors = circle_colors - - Plot.__init__(self, surface, data, width, height, background, border, x_labels, y_labels, series_colors) - - self.dash = None - if dash: - if hasattr(dash, "keys"): - self.dash = [dash[key] for key in self.series_labels] - elif max([hasattr(item,'__delitem__') for item in data]) : - self.dash = dash - else: - self.dash = [dash] - - self.load_errors(errorx, errory) - - def convert_list_to_tuple(self, data): - #Data must be converted from lists of coordinates to a single - # list of tuples - out_data = zip(*data) - if len(data) == 3: - self.variable_radius = True - return out_data - - def load_series(self, data, x_labels = None, y_labels = None, series_colors=None): - #TODO: In cairoplot 2.0 keep only the Series instances - - # Convert Data and Group to Series - if isinstance(data, Data) or isinstance(data, Group): - data = Series(data) - - # Series - if isinstance(data, Series): - for group in data: - for item in group: - if len(item) is 3: - self.variable_radius = True - - #Dictionary with lists - if hasattr(data, "keys") : - if hasattr( data.values()[0][0], "__delitem__" ) : - for key in data.keys() : - data[key] = self.convert_list_to_tuple(data[key]) - elif len(data.values()[0][0]) == 3: - self.variable_radius = True - #List - elif hasattr(data[0], "__delitem__") : - #List of lists - if hasattr(data[0][0], "__delitem__") : - for index,value in enumerate(data) : - data[index] = self.convert_list_to_tuple(value) - #List - elif type(data[0][0]) != type((0,0)): - data = self.convert_list_to_tuple(data) - #Three dimensional data - elif len(data[0][0]) == 3: - self.variable_radius = True - - #List with three dimensional tuples - elif len(data[0]) == 3: - self.variable_radius = True - Plot.load_series(self, data, x_labels, y_labels, series_colors) - self.calc_boundaries() - self.calc_labels() - - def load_errors(self, errorx, errory): - self.errors = None - if errorx == None and errory == None: - return - self.errors = {} - self.errors[HORZ] = None - self.errors[VERT] = None - #asimetric errors - if errorx and hasattr(errorx[0], "__delitem__"): - self.errors[HORZ] = errorx - #simetric errors - elif errorx: - self.errors[HORZ] = [errorx] - #asimetric errors - if errory and hasattr(errory[0], "__delitem__"): - self.errors[VERT] = errory - #simetric errors - elif errory: - self.errors[VERT] = [errory] - - def calc_labels(self): - if not self.labels[HORZ]: - amplitude = self.bounds[HORZ][1] - self.bounds[HORZ][0] - if amplitude % 10: #if horizontal labels need floating points - self.labels[HORZ] = ["%.2lf" % (float(self.bounds[HORZ][0] + (amplitude * i / 10.0))) for i in range(11) ] - else: - self.labels[HORZ] = ["%d" % (int(self.bounds[HORZ][0] + (amplitude * i / 10.0))) for i in range(11) ] - if not self.labels[VERT]: - amplitude = self.bounds[VERT][1] - self.bounds[VERT][0] - if amplitude % 10: #if vertical labels need floating points - self.labels[VERT] = ["%.2lf" % (float(self.bounds[VERT][0] + (amplitude * i / 10.0))) for i in range(11) ] - else: - self.labels[VERT] = ["%d" % (int(self.bounds[VERT][0] + (amplitude * i / 10.0))) for i in range(11) ] - - def calc_extents(self, direction): - self.context.set_font_size(self.font_size * 0.8) - self.max_value[direction] = max(self.context.text_extents(item)[2] for item in self.labels[direction]) - self.borders[other_direction(direction)] = self.max_value[direction] + self.border + 20 - - def calc_boundaries(self): - #HORZ = 0, VERT = 1, NORM = 2 - min_data_value = [0,0,0] - max_data_value = [0,0,0] - - for group in self.series: - if type(group[0].content) in (int, float, long): - group = [Data((index, item.content)) for index,item in enumerate(group)] - - for point in group: - for index, item in enumerate(point.content): - if item > max_data_value[index]: - max_data_value[index] = item - elif item < min_data_value[index]: - min_data_value[index] = item - - if not self.bounds[HORZ]: - self.bounds[HORZ] = (min_data_value[HORZ], max_data_value[HORZ]) - if not self.bounds[VERT]: - self.bounds[VERT] = (min_data_value[VERT], max_data_value[VERT]) - if not self.bounds[NORM]: - self.bounds[NORM] = (min_data_value[NORM], max_data_value[NORM]) - - def calc_all_extents(self): - self.calc_extents(HORZ) - self.calc_extents(VERT) - - self.plot_height = self.dimensions[VERT] - 2 * self.borders[VERT] - self.plot_width = self.dimensions[HORZ] - 2* self.borders[HORZ] - - self.plot_top = self.dimensions[VERT] - self.borders[VERT] - - def calc_steps(self): - #Calculates all the x, y, z and color steps - series_amplitude = [self.bounds[index][1] - self.bounds[index][0] for index in range(3)] - - if series_amplitude[HORZ]: - self.horizontal_step = float (self.plot_width) / series_amplitude[HORZ] - else: - self.horizontal_step = 0.00 - - if series_amplitude[VERT]: - self.vertical_step = float (self.plot_height) / series_amplitude[VERT] - else: - self.vertical_step = 0.00 - - if series_amplitude[NORM]: - if self.variable_radius: - self.z_step = float (self.bounds[NORM][1]) / series_amplitude[NORM] - if self.circle_colors: - self.circle_color_step = tuple([float(self.circle_colors[1][i]-self.circle_colors[0][i])/series_amplitude[NORM] for i in range(4)]) - else: - self.z_step = 0.00 - self.circle_color_step = ( 0.0, 0.0, 0.0, 0.0 ) - - def get_circle_color(self, value): - return tuple( [self.circle_colors[0][i] + value*self.circle_color_step[i] for i in range(4)] ) - - def render(self): - self.calc_all_extents() - self.calc_steps() - self.render_background() - self.render_bounding_box() - if self.axis: - self.render_axis() - if self.grid: - self.render_grid() - self.render_labels() - self.render_plot() - if self.errors: - self.render_errors() - if self.series_legend and self.series_labels: - self.render_legend() - - def render_axis(self): - #Draws both the axis lines and their titles - cr = self.context - cr.set_source_rgba(*self.line_color) - cr.move_to(self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT]) - cr.line_to(self.borders[HORZ], self.borders[VERT]) - cr.stroke() - - cr.move_to(self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT]) - cr.line_to(self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT]) - cr.stroke() - - cr.set_source_rgba(*self.label_color) - self.context.set_font_size( 1.2 * self.font_size ) - if self.titles[HORZ]: - title_width,title_height = cr.text_extents(self.titles[HORZ])[2:4] - cr.move_to( self.dimensions[HORZ]/2 - title_width/2, self.borders[VERT] - title_height/2 ) - cr.show_text( self.titles[HORZ] ) - - if self.titles[VERT]: - title_width,title_height = cr.text_extents(self.titles[VERT])[2:4] - cr.move_to( self.dimensions[HORZ] - self.borders[HORZ] + title_height/2, self.dimensions[VERT]/2 - title_width/2) - cr.save() - cr.rotate( math.pi/2 ) - cr.show_text( self.titles[VERT] ) - cr.restore() - - def render_grid(self): - cr = self.context - horizontal_step = float( self.plot_height ) / ( len( self.labels[VERT] ) - 1 ) - vertical_step = float( self.plot_width ) / ( len( self.labels[HORZ] ) - 1 ) - - x = self.borders[HORZ] + vertical_step - y = self.plot_top - horizontal_step - - for label in self.labels[HORZ][:-1]: - cr.set_source_rgba(*self.grid_color) - cr.move_to(x, self.dimensions[VERT] - self.borders[VERT]) - cr.line_to(x, self.borders[VERT]) - cr.stroke() - x += vertical_step - for label in self.labels[VERT][:-1]: - cr.set_source_rgba(*self.grid_color) - cr.move_to(self.borders[HORZ], y) - cr.line_to(self.dimensions[HORZ] - self.borders[HORZ], y) - cr.stroke() - y -= horizontal_step - - def render_labels(self): - self.context.set_font_size(self.font_size * 0.8) - self.render_horz_labels() - self.render_vert_labels() - - def render_horz_labels(self): - cr = self.context - step = float( self.plot_width ) / ( len( self.labels[HORZ] ) - 1 ) - x = self.borders[HORZ] - y = self.dimensions[VERT] - self.borders[VERT] + 5 - - # store rotation matrix from the initial state - rotation_matrix = cr.get_matrix() - rotation_matrix.rotate(self.x_label_angle) - - cr.set_source_rgba(*self.label_color) - - for item in self.labels[HORZ]: - width = cr.text_extents(item)[2] - cr.move_to(x, y) - cr.save() - cr.set_matrix(rotation_matrix) - cr.show_text(item) - cr.restore() - x += step - - def render_vert_labels(self): - cr = self.context - step = ( self.plot_height ) / ( len( self.labels[VERT] ) - 1 ) - y = self.plot_top - cr.set_source_rgba(*self.label_color) - for item in self.labels[VERT]: - width = cr.text_extents(item)[2] - cr.move_to(self.borders[HORZ] - width - 5,y) - cr.show_text(item) - y -= step - - def render_legend(self): - cr = self.context - cr.set_font_size(self.font_size) - cr.set_line_width(self.line_width) - - widest_word = max(self.series_labels, key = lambda item: self.context.text_extents(item)[2]) - tallest_word = max(self.series_labels, key = lambda item: self.context.text_extents(item)[3]) - max_width = self.context.text_extents(widest_word)[2] - max_height = self.context.text_extents(tallest_word)[3] * 1.1 - - color_box_height = max_height / 2 - color_box_width = color_box_height * 2 - - #Draw a bounding box - bounding_box_width = max_width + color_box_width + 15 - bounding_box_height = (len(self.series_labels)+0.5) * max_height - cr.set_source_rgba(1,1,1) - cr.rectangle(self.dimensions[HORZ] - self.borders[HORZ] - bounding_box_width, self.borders[VERT], - bounding_box_width, bounding_box_height) - cr.fill() - - cr.set_source_rgba(*self.line_color) - cr.set_line_width(self.line_width) - cr.rectangle(self.dimensions[HORZ] - self.borders[HORZ] - bounding_box_width, self.borders[VERT], - bounding_box_width, bounding_box_height) - cr.stroke() - - for idx,key in enumerate(self.series_labels): - #Draw color box - cr.set_source_rgba(*self.series_colors[idx][:4]) - cr.rectangle(self.dimensions[HORZ] - self.borders[HORZ] - max_width - color_box_width - 10, - self.borders[VERT] + color_box_height + (idx*max_height) , - color_box_width, color_box_height) - cr.fill() - - cr.set_source_rgba(0, 0, 0) - cr.rectangle(self.dimensions[HORZ] - self.borders[HORZ] - max_width - color_box_width - 10, - self.borders[VERT] + color_box_height + (idx*max_height), - color_box_width, color_box_height) - cr.stroke() - - #Draw series labels - cr.set_source_rgba(0, 0, 0) - cr.move_to(self.dimensions[HORZ] - self.borders[HORZ] - max_width - 5, self.borders[VERT] + ((idx+1)*max_height)) - cr.show_text(key) - - def render_errors(self): - cr = self.context - cr.rectangle(self.borders[HORZ], self.borders[VERT], self.plot_width, self.plot_height) - cr.clip() - radius = self.dots - x0 = self.borders[HORZ] - self.bounds[HORZ][0]*self.horizontal_step - y0 = self.borders[VERT] - self.bounds[VERT][0]*self.vertical_step - for index, group in enumerate(self.series): - cr.set_source_rgba(*self.series_colors[index][:4]) - for number, data in enumerate(group): - x = x0 + self.horizontal_step * data.content[0] - y = self.dimensions[VERT] - y0 - self.vertical_step * data.content[1] - if self.errors[HORZ]: - cr.move_to(x, y) - x1 = x - self.horizontal_step * self.errors[HORZ][0][number] - cr.line_to(x1, y) - cr.line_to(x1, y - radius) - cr.line_to(x1, y + radius) - cr.stroke() - if self.errors[HORZ] and len(self.errors[HORZ]) == 2: - cr.move_to(x, y) - x1 = x + self.horizontal_step * self.errors[HORZ][1][number] - cr.line_to(x1, y) - cr.line_to(x1, y - radius) - cr.line_to(x1, y + radius) - cr.stroke() - if self.errors[VERT]: - cr.move_to(x, y) - y1 = y + self.vertical_step * self.errors[VERT][0][number] - cr.line_to(x, y1) - cr.line_to(x - radius, y1) - cr.line_to(x + radius, y1) - cr.stroke() - if self.errors[VERT] and len(self.errors[VERT]) == 2: - cr.move_to(x, y) - y1 = y - self.vertical_step * self.errors[VERT][1][number] - cr.line_to(x, y1) - cr.line_to(x - radius, y1) - cr.line_to(x + radius, y1) - cr.stroke() - - - def render_plot(self): - cr = self.context - if self.discrete: - cr.rectangle(self.borders[HORZ], self.borders[VERT], self.plot_width, self.plot_height) - cr.clip() - x0 = self.borders[HORZ] - self.bounds[HORZ][0]*self.horizontal_step - y0 = self.borders[VERT] - self.bounds[VERT][0]*self.vertical_step - radius = self.dots - for number, group in enumerate (self.series): - cr.set_source_rgba(*self.series_colors[number][:4]) - for data in group : - if self.variable_radius: - radius = data.content[2]*self.z_step - if self.circle_colors: - cr.set_source_rgba( *self.get_circle_color( data.content[2]) ) - x = x0 + self.horizontal_step*data.content[0] - y = y0 + self.vertical_step*data.content[1] - cr.arc(x, self.dimensions[VERT] - y, radius, 0, 2*math.pi) - cr.fill() - else: - cr.rectangle(self.borders[HORZ], self.borders[VERT], self.plot_width, self.plot_height) - cr.clip() - x0 = self.borders[HORZ] - self.bounds[HORZ][0]*self.horizontal_step - y0 = self.borders[VERT] - self.bounds[VERT][0]*self.vertical_step - radius = self.dots - for number, group in enumerate (self.series): - last_data = None - cr.set_source_rgba(*self.series_colors[number][:4]) - for data in group : - x = x0 + self.horizontal_step*data.content[0] - y = y0 + self.vertical_step*data.content[1] - if self.dots: - if self.variable_radius: - radius = data.content[2]*self.z_step - cr.arc(x, self.dimensions[VERT] - y, radius, 0, 2*math.pi) - cr.fill() - if last_data : - old_x = x0 + self.horizontal_step*last_data.content[0] - old_y = y0 + self.vertical_step*last_data.content[1] - cr.move_to( old_x, self.dimensions[VERT] - old_y ) - cr.line_to( x, self.dimensions[VERT] - y) - cr.set_line_width(self.series_widths[number]) - - #?Display line as dash line - if self.dash and self.dash[number]: - s = self.series_widths[number] - cr.set_dash([s*3, s*3], 0) - - cr.stroke() - cr.set_dash([]) - last_data = data - -class DotLinePlot(ScatterPlot): - def __init__(self, - surface=None, - data=None, - width=640, - height=480, - background=None, - border=0, - axis = False, - dash = False, - dots = 0, - grid = False, - series_legend = False, - x_labels = None, - y_labels = None, - x_bounds = None, - y_bounds = None, - x_title = None, - y_title = None, - series_colors = None): - - ScatterPlot.__init__(self, surface, data, None, None, width, height, background, border, - axis, dash, False, dots, grid, series_legend, x_labels, y_labels, - x_bounds, y_bounds, None, x_title, y_title, series_colors, None ) - - - def load_series(self, data, x_labels = None, y_labels = None, series_colors=None): - Plot.load_series(self, data, x_labels, y_labels, series_colors) - for group in self.series : - for index,data in enumerate(group): - group[index].content = (index, data.content) - - self.calc_boundaries() - self.calc_labels() - -class FunctionPlot(ScatterPlot): - def __init__(self, - surface=None, - data=None, - width=640, - height=480, - background=None, - border=0, - axis = False, - discrete = False, - dots = 0, - grid = False, - series_legend = False, - x_labels = None, - y_labels = None, - x_bounds = None, - y_bounds = None, - x_title = None, - y_title = None, - series_colors = None, - step = 1): - - self.function = data - self.step = step - self.discrete = discrete - - data, x_bounds = self.load_series_from_function( self.function, x_bounds ) - - ScatterPlot.__init__(self, surface, data, None, None, width, height, background, border, - axis, False, discrete, dots, grid, series_legend, x_labels, y_labels, - x_bounds, y_bounds, None, x_title, y_title, series_colors, None ) - - def load_series(self, data, x_labels = None, y_labels = None, series_colors=None): - Plot.load_series(self, data, x_labels, y_labels, series_colors) - - if len(self.series[0][0]) is 1: - for group_id, group in enumerate(self.series) : - for index,data in enumerate(group): - group[index].content = (self.bounds[HORZ][0] + self.step*index, data.content) - - self.calc_boundaries() - self.calc_labels() - - def load_series_from_function( self, function, x_bounds ): - #TODO: Add the possibility for the user to define multiple functions with different discretization parameters - - #This function converts a function, a list of functions or a dictionary - #of functions into its corresponding array of data - series = Series() - - if isinstance(function, Group) or isinstance(function, Data): - function = Series(function) - - # If is instance of Series - if isinstance(function, Series): - # Overwrite any bounds passed by the function - x_bounds = (function.range[0],function.range[-1]) - - #if no bounds are provided - if x_bounds == None: - x_bounds = (0,10) - - - #TODO: Finish the dict translation - if hasattr(function, "keys"): #dictionary: - for key in function.keys(): - group = Group(name=key) - #data[ key ] = [] - i = x_bounds[0] - while i <= x_bounds[1] : - group.add_data(function[ key ](i)) - #data[ key ].append( function[ key ](i) ) - i += self.step - series.add_group(group) - - elif hasattr(function, "__delitem__"): #list of functions - for index,f in enumerate( function ) : - group = Group() - #data.append( [] ) - i = x_bounds[0] - while i <= x_bounds[1] : - group.add_data(f(i)) - #data[ index ].append( f(i) ) - i += self.step - series.add_group(group) - - elif isinstance(function, Series): # instance of Series - series = function - - else: #function - group = Group() - i = x_bounds[0] - while i <= x_bounds[1] : - group.add_data(function(i)) - i += self.step - series.add_group(group) - - - return series, x_bounds - - def calc_labels(self): - if not self.labels[HORZ]: - self.labels[HORZ] = [] - i = self.bounds[HORZ][0] - while i<=self.bounds[HORZ][1]: - self.labels[HORZ].append(str(i)) - i += float(self.bounds[HORZ][1] - self.bounds[HORZ][0])/10 - ScatterPlot.calc_labels(self) - - def render_plot(self): - if not self.discrete: - ScatterPlot.render_plot(self) - else: - last = None - cr = self.context - for number, group in enumerate (self.series): - cr.set_source_rgba(*self.series_colors[number][:4]) - x0 = self.borders[HORZ] - self.bounds[HORZ][0]*self.horizontal_step - y0 = self.borders[VERT] - self.bounds[VERT][0]*self.vertical_step - for data in group: - x = x0 + self.horizontal_step * data.content[0] - y = y0 + self.vertical_step * data.content[1] - cr.move_to(x, self.dimensions[VERT] - y) - cr.line_to(x, self.plot_top) - cr.set_line_width(self.series_widths[number]) - cr.stroke() - if self.dots: - cr.new_path() - cr.arc(x, self.dimensions[VERT] - y, 3, 0, 2.1 * math.pi) - cr.close_path() - cr.fill() - -class BarPlot(Plot): - def __init__(self, - surface = None, - data = None, - width = 640, - height = 480, - background = "white light_gray", - border = 0, - display_values = False, - grid = False, - rounded_corners = False, - stack = False, - three_dimension = False, - x_labels = None, - y_labels = None, - x_bounds = None, - y_bounds = None, - series_colors = None, - main_dir = None): - - self.bounds = {} - self.bounds[HORZ] = x_bounds - self.bounds[VERT] = y_bounds - self.display_values = display_values - self.grid = grid - self.rounded_corners = rounded_corners - self.stack = stack - self.three_dimension = three_dimension - self.x_label_angle = math.pi / 2.5 - self.main_dir = main_dir - self.max_value = {} - self.plot_dimensions = {} - self.steps = {} - self.value_label_color = (0.5,0.5,0.5,1.0) - - Plot.__init__(self, surface, data, width, height, background, border, x_labels, y_labels, series_colors) - - def load_series(self, data, x_labels = None, y_labels = None, series_colors = None): - Plot.load_series(self, data, x_labels, y_labels, series_colors) - self.calc_boundaries() - - def process_colors(self, series_colors): - #Data for a BarPlot might be a List or a List of Lists. - #On the first case, colors must be generated for all bars, - #On the second, colors must be generated for each of the inner lists. - - #TODO: Didn't get it... - #if hasattr(self.data[0], '__getitem__'): - # length = max(len(series) for series in self.data) - #else: - # length = len( self.data ) - - length = max(len(group) for group in self.series) - - Plot.process_colors( self, series_colors, length, 'linear') - - def calc_boundaries(self): - if not self.bounds[self.main_dir]: - if self.stack: - max_data_value = max(sum(group.to_list()) for group in self.series) - else: - max_data_value = max(max(group.to_list()) for group in self.series) - self.bounds[self.main_dir] = (0, max_data_value) - if not self.bounds[other_direction(self.main_dir)]: - self.bounds[other_direction(self.main_dir)] = (0, len(self.series)) - - def calc_extents(self, direction): - self.max_value[direction] = 0 - if self.labels[direction]: - widest_word = max(self.labels[direction], key = lambda item: self.context.text_extents(item)[2]) - self.max_value[direction] = self.context.text_extents(widest_word)[3 - direction] - self.borders[other_direction(direction)] = (2-direction)*self.max_value[direction] + self.border + direction*(5) - else: - self.borders[other_direction(direction)] = self.border - - def calc_horz_extents(self): - self.calc_extents(HORZ) - - def calc_vert_extents(self): - self.calc_extents(VERT) - - def calc_all_extents(self): - self.calc_horz_extents() - self.calc_vert_extents() - other_dir = other_direction(self.main_dir) - self.value_label = 0 - if self.display_values: - if self.stack: - self.value_label = self.context.text_extents(str(max(sum(group.to_list()) for group in self.series)))[2 + self.main_dir] - else: - self.value_label = self.context.text_extents(str(max(max(group.to_list()) for group in self.series)))[2 + self.main_dir] - if self.labels[self.main_dir]: - self.plot_dimensions[self.main_dir] = self.dimensions[self.main_dir] - 2*self.borders[self.main_dir] - self.value_label - else: - self.plot_dimensions[self.main_dir] = self.dimensions[self.main_dir] - self.borders[self.main_dir] - 1.2*self.border - self.value_label - self.plot_dimensions[other_dir] = self.dimensions[other_dir] - self.borders[other_dir] - self.border - self.plot_top = self.dimensions[VERT] - self.borders[VERT] - - def calc_steps(self): - other_dir = other_direction(self.main_dir) - self.series_amplitude = self.bounds[self.main_dir][1] - self.bounds[self.main_dir][0] - if self.series_amplitude: - self.steps[self.main_dir] = float(self.plot_dimensions[self.main_dir])/self.series_amplitude - else: - self.steps[self.main_dir] = 0.00 - series_length = len(self.series) - self.steps[other_dir] = float(self.plot_dimensions[other_dir])/(series_length + 0.1*(series_length + 1)) - self.space = 0.1*self.steps[other_dir] - - def render(self): - self.calc_all_extents() - self.calc_steps() - self.render_background() - self.render_bounding_box() - if self.grid: - self.render_grid() - if self.three_dimension: - self.render_ground() - if self.display_values: - self.render_values() - self.render_labels() - self.render_plot() - if self.series_labels: - self.render_legend() - - def draw_3d_rectangle_front(self, x0, y0, x1, y1, shift): - self.context.rectangle(x0-shift, y0+shift, x1-x0, y1-y0) - - def draw_3d_rectangle_side(self, x0, y0, x1, y1, shift): - self.context.move_to(x1-shift,y0+shift) - self.context.line_to(x1, y0) - self.context.line_to(x1, y1) - self.context.line_to(x1-shift, y1+shift) - self.context.line_to(x1-shift, y0+shift) - self.context.close_path() - - def draw_3d_rectangle_top(self, x0, y0, x1, y1, shift): - self.context.move_to(x0-shift,y0+shift) - self.context.line_to(x0, y0) - self.context.line_to(x1, y0) - self.context.line_to(x1-shift, y0+shift) - self.context.line_to(x0-shift, y0+shift) - self.context.close_path() - - def draw_round_rectangle(self, x0, y0, x1, y1): - self.context.arc(x0+5, y0+5, 5, -math.pi, -math.pi/2) - self.context.line_to(x1-5, y0) - self.context.arc(x1-5, y0+5, 5, -math.pi/2, 0) - self.context.line_to(x1, y1-5) - self.context.arc(x1-5, y1-5, 5, 0, math.pi/2) - self.context.line_to(x0+5, y1) - self.context.arc(x0+5, y1-5, 5, math.pi/2, math.pi) - self.context.line_to(x0, y0+5) - self.context.close_path() - - def render_ground(self): - self.draw_3d_rectangle_front(self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], - self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) - self.context.fill() - - self.draw_3d_rectangle_side (self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], - self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) - self.context.fill() - - self.draw_3d_rectangle_top (self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], - self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) - self.context.fill() - - def render_labels(self): - self.context.set_font_size(self.font_size * 0.8) - if self.labels[HORZ]: - self.render_horz_labels() - if self.labels[VERT]: - self.render_vert_labels() - - def render_legend(self): - cr = self.context - cr.set_font_size(self.font_size) - cr.set_line_width(self.line_width) - - widest_word = max(self.series_labels, key = lambda item: self.context.text_extents(item)[2]) - tallest_word = max(self.series_labels, key = lambda item: self.context.text_extents(item)[3]) - max_width = self.context.text_extents(widest_word)[2] - max_height = self.context.text_extents(tallest_word)[3] * 1.1 + 5 - - color_box_height = max_height / 2 - color_box_width = color_box_height * 2 - - #Draw a bounding box - bounding_box_width = max_width + color_box_width + 15 - bounding_box_height = (len(self.series_labels)+0.5) * max_height - cr.set_source_rgba(1,1,1) - cr.rectangle(self.dimensions[HORZ] - self.border - bounding_box_width, self.border, - bounding_box_width, bounding_box_height) - cr.fill() - - cr.set_source_rgba(*self.line_color) - cr.set_line_width(self.line_width) - cr.rectangle(self.dimensions[HORZ] - self.border - bounding_box_width, self.border, - bounding_box_width, bounding_box_height) - cr.stroke() - - for idx,key in enumerate(self.series_labels): - #Draw color box - cr.set_source_rgba(*self.series_colors[idx][:4]) - cr.rectangle(self.dimensions[HORZ] - self.border - max_width - color_box_width - 10, - self.border + color_box_height + (idx*max_height) , - color_box_width, color_box_height) - cr.fill() - - cr.set_source_rgba(0, 0, 0) - cr.rectangle(self.dimensions[HORZ] - self.border - max_width - color_box_width - 10, - self.border + color_box_height + (idx*max_height), - color_box_width, color_box_height) - cr.stroke() - - #Draw series labels - cr.set_source_rgba(0, 0, 0) - cr.move_to(self.dimensions[HORZ] - self.border - max_width - 5, self.border + ((idx+1)*max_height)) - cr.show_text(key) - - -class HorizontalBarPlot(BarPlot): - def __init__(self, - surface = None, - data = None, - width = 640, - height = 480, - background = "white light_gray", - border = 0, - display_values = False, - grid = False, - rounded_corners = False, - stack = False, - three_dimension = False, - series_labels = None, - x_labels = None, - y_labels = None, - x_bounds = None, - y_bounds = None, - series_colors = None): - - BarPlot.__init__(self, surface, data, width, height, background, border, - display_values, grid, rounded_corners, stack, three_dimension, - x_labels, y_labels, x_bounds, y_bounds, series_colors, HORZ) - self.series_labels = series_labels - - def calc_vert_extents(self): - self.calc_extents(VERT) - if self.labels[HORZ] and not self.labels[VERT]: - self.borders[HORZ] += 10 - - def draw_rectangle_bottom(self, x0, y0, x1, y1): - self.context.arc(x0+5, y1-5, 5, math.pi/2, math.pi) - self.context.line_to(x0, y0+5) - self.context.arc(x0+5, y0+5, 5, -math.pi, -math.pi/2) - self.context.line_to(x1, y0) - self.context.line_to(x1, y1) - self.context.line_to(x0+5, y1) - self.context.close_path() - - def draw_rectangle_top(self, x0, y0, x1, y1): - self.context.arc(x1-5, y0+5, 5, -math.pi/2, 0) - self.context.line_to(x1, y1-5) - self.context.arc(x1-5, y1-5, 5, 0, math.pi/2) - self.context.line_to(x0, y1) - self.context.line_to(x0, y0) - self.context.line_to(x1, y0) - self.context.close_path() - - def draw_rectangle(self, index, length, x0, y0, x1, y1): - if length == 1: - BarPlot.draw_rectangle(self, x0, y0, x1, y1) - elif index == 0: - self.draw_rectangle_bottom(x0, y0, x1, y1) - elif index == length-1: - self.draw_rectangle_top(x0, y0, x1, y1) - else: - self.context.rectangle(x0, y0, x1-x0, y1-y0) - - #TODO: Review BarPlot.render_grid code - def render_grid(self): - self.context.set_source_rgba(0.8, 0.8, 0.8) - if self.labels[HORZ]: - self.context.set_font_size(self.font_size * 0.8) - step = (self.dimensions[HORZ] - 2*self.borders[HORZ] - self.value_label)/(len(self.labels[HORZ])-1) - x = self.borders[HORZ] - next_x = 0 - for item in self.labels[HORZ]: - width = self.context.text_extents(item)[2] - if x - width/2 > next_x and x - width/2 > self.border: - self.context.move_to(x, self.border) - self.context.line_to(x, self.dimensions[VERT] - self.borders[VERT]) - self.context.stroke() - next_x = x + width/2 - x += step - else: - lines = 11 - horizontal_step = float(self.plot_dimensions[HORZ])/(lines-1) - x = self.borders[HORZ] - for y in xrange(0, lines): - self.context.move_to(x, self.border) - self.context.line_to(x, self.dimensions[VERT] - self.borders[VERT]) - self.context.stroke() - x += horizontal_step - - def render_horz_labels(self): - step = (self.dimensions[HORZ] - 2*self.borders[HORZ])/(len(self.labels[HORZ])-1) - x = self.borders[HORZ] - next_x = 0 - - for item in self.labels[HORZ]: - self.context.set_source_rgba(*self.label_color) - width = self.context.text_extents(item)[2] - if x - width/2 > next_x and x - width/2 > self.border: - self.context.move_to(x - width/2, self.dimensions[VERT] - self.borders[VERT] + self.max_value[HORZ] + 3) - self.context.show_text(item) - next_x = x + width/2 - x += step - - def render_vert_labels(self): - series_length = len(self.labels[VERT]) - step = (self.plot_dimensions[VERT] - (series_length + 1)*self.space)/(len(self.labels[VERT])) - y = self.border + step/2 + self.space - - for item in self.labels[VERT]: - self.context.set_source_rgba(*self.label_color) - width, height = self.context.text_extents(item)[2:4] - self.context.move_to(self.borders[HORZ] - width - 5, y + height/2) - self.context.show_text(item) - y += step + self.space - self.labels[VERT].reverse() - - def render_values(self): - self.context.set_source_rgba(*self.value_label_color) - self.context.set_font_size(self.font_size * 0.8) - if self.stack: - for i,group in enumerate(self.series): - value = sum(group.to_list()) - height = self.context.text_extents(str(value))[3] - x = self.borders[HORZ] + value*self.steps[HORZ] + 2 - y = self.borders[VERT] + (i+0.5)*self.steps[VERT] + (i+1)*self.space + height/2 - self.context.move_to(x, y) - self.context.show_text(str(value)) - else: - for i,group in enumerate(self.series): - inner_step = self.steps[VERT]/len(group) - y0 = self.border + i*self.steps[VERT] + (i+1)*self.space - for number,data in enumerate(group): - height = self.context.text_extents(str(data.content))[3] - self.context.move_to(self.borders[HORZ] + data.content*self.steps[HORZ] + 2, y0 + 0.5*inner_step + height/2, ) - self.context.show_text(str(data.content)) - y0 += inner_step - - def render_plot(self): - if self.stack: - for i,group in enumerate(self.series): - x0 = self.borders[HORZ] - y0 = self.borders[VERT] + i*self.steps[VERT] + (i+1)*self.space - for number,data in enumerate(group): - if self.series_colors[number][4] in ('radial','linear') : - linear = cairo.LinearGradient( data.content*self.steps[HORZ]/2, y0, data.content*self.steps[HORZ]/2, y0 + self.steps[VERT] ) - color = self.series_colors[number] - linear.add_color_stop_rgba(0.0, 3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) - linear.add_color_stop_rgba(1.0, *color[:4]) - self.context.set_source(linear) - elif self.series_colors[number][4] == 'solid': - self.context.set_source_rgba(*self.series_colors[number][:4]) - if self.rounded_corners: - self.draw_rectangle(number, len(group), x0, y0, x0+data.content*self.steps[HORZ], y0+self.steps[VERT]) - self.context.fill() - else: - self.context.rectangle(x0, y0, data.content*self.steps[HORZ], self.steps[VERT]) - self.context.fill() - x0 += data.content*self.steps[HORZ] - else: - for i,group in enumerate(self.series): - inner_step = self.steps[VERT]/len(group) - x0 = self.borders[HORZ] - y0 = self.border + i*self.steps[VERT] + (i+1)*self.space - for number,data in enumerate(group): - linear = cairo.LinearGradient(data.content*self.steps[HORZ]/2, y0, data.content*self.steps[HORZ]/2, y0 + inner_step) - color = self.series_colors[number] - linear.add_color_stop_rgba(0.0, 3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) - linear.add_color_stop_rgba(1.0, *color[:4]) - self.context.set_source(linear) - if self.rounded_corners and data.content != 0: - BarPlot.draw_round_rectangle(self,x0, y0, x0 + data.content*self.steps[HORZ], y0 + inner_step) - self.context.fill() - else: - self.context.rectangle(x0, y0, data.content*self.steps[HORZ], inner_step) - self.context.fill() - y0 += inner_step - -class VerticalBarPlot(BarPlot): - def __init__(self, - surface = None, - data = None, - width = 640, - height = 480, - background = "white light_gray", - border = 0, - display_values = False, - grid = False, - rounded_corners = False, - stack = False, - three_dimension = False, - series_labels = None, - x_labels = None, - y_labels = None, - x_bounds = None, - y_bounds = None, - series_colors = None): - - BarPlot.__init__(self, surface, data, width, height, background, border, - display_values, grid, rounded_corners, stack, three_dimension, - x_labels, y_labels, x_bounds, y_bounds, series_colors, VERT) - self.series_labels = series_labels - - def calc_vert_extents(self): - self.calc_extents(VERT) - if self.labels[VERT] and not self.labels[HORZ]: - self.borders[VERT] += 10 - - def draw_rectangle_bottom(self, x0, y0, x1, y1): - self.context.move_to(x1,y1) - self.context.arc(x1-5, y1-5, 5, 0, math.pi/2) - self.context.line_to(x0+5, y1) - self.context.arc(x0+5, y1-5, 5, math.pi/2, math.pi) - self.context.line_to(x0, y0) - self.context.line_to(x1, y0) - self.context.line_to(x1, y1) - self.context.close_path() - - def draw_rectangle_top(self, x0, y0, x1, y1): - self.context.arc(x0+5, y0+5, 5, -math.pi, -math.pi/2) - self.context.line_to(x1-5, y0) - self.context.arc(x1-5, y0+5, 5, -math.pi/2, 0) - self.context.line_to(x1, y1) - self.context.line_to(x0, y1) - self.context.line_to(x0, y0) - self.context.close_path() - - def draw_rectangle(self, index, length, x0, y0, x1, y1): - if length == 1: - BarPlot.draw_rectangle(self, x0, y0, x1, y1) - elif index == 0: - self.draw_rectangle_bottom(x0, y0, x1, y1) - elif index == length-1: - self.draw_rectangle_top(x0, y0, x1, y1) - else: - self.context.rectangle(x0, y0, x1-x0, y1-y0) - - def render_grid(self): - self.context.set_source_rgba(0.8, 0.8, 0.8) - if self.labels[VERT]: - lines = len(self.labels[VERT]) - vertical_step = float(self.plot_dimensions[self.main_dir])/(lines-1) - y = self.borders[VERT] + self.value_label - else: - lines = 11 - vertical_step = float(self.plot_dimensions[self.main_dir])/(lines-1) - y = 1.2*self.border + self.value_label - for x in xrange(0, lines): - self.context.move_to(self.borders[HORZ], y) - self.context.line_to(self.dimensions[HORZ] - self.border, y) - self.context.stroke() - y += vertical_step - - def render_ground(self): - self.draw_3d_rectangle_front(self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], - self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) - self.context.fill() - - self.draw_3d_rectangle_side (self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], - self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) - self.context.fill() - - self.draw_3d_rectangle_top (self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], - self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) - self.context.fill() - - def render_horz_labels(self): - series_length = len(self.labels[HORZ]) - step = float (self.plot_dimensions[HORZ] - (series_length + 1)*self.space)/len(self.labels[HORZ]) - x = self.borders[HORZ] + step/2 + self.space - next_x = 0 - - for item in self.labels[HORZ]: - self.context.set_source_rgba(*self.label_color) - width = self.context.text_extents(item)[2] - if x - width/2 > next_x and x - width/2 > self.borders[HORZ]: - self.context.move_to(x - width/2, self.dimensions[VERT] - self.borders[VERT] + self.max_value[HORZ] + 3) - self.context.show_text(item) - next_x = x + width/2 - x += step + self.space - - def render_vert_labels(self): - self.context.set_source_rgba(*self.label_color) - y = self.borders[VERT] + self.value_label - step = (self.dimensions[VERT] - 2*self.borders[VERT] - self.value_label)/(len(self.labels[VERT]) - 1) - self.labels[VERT].reverse() - for item in self.labels[VERT]: - width, height = self.context.text_extents(item)[2:4] - self.context.move_to(self.borders[HORZ] - width - 5, y + height/2) - self.context.show_text(item) - y += step - self.labels[VERT].reverse() - - def render_values(self): - self.context.set_source_rgba(*self.value_label_color) - self.context.set_font_size(self.font_size * 0.8) - if self.stack: - for i,group in enumerate(self.series): - value = sum(group.to_list()) - width = self.context.text_extents(str(value))[2] - x = self.borders[HORZ] + (i+0.5)*self.steps[HORZ] + (i+1)*self.space - width/2 - y = value*self.steps[VERT] + 2 - self.context.move_to(x, self.plot_top-y) - self.context.show_text(str(value)) - else: - for i,group in enumerate(self.series): - inner_step = self.steps[HORZ]/len(group) - x0 = self.borders[HORZ] + i*self.steps[HORZ] + (i+1)*self.space - for number,data in enumerate(group): - width = self.context.text_extents(str(data.content))[2] - self.context.move_to(x0 + 0.5*inner_step - width/2, self.plot_top - data.content*self.steps[VERT] - 2) - self.context.show_text(str(data.content)) - x0 += inner_step - - def render_plot(self): - if self.stack: - for i,group in enumerate(self.series): - x0 = self.borders[HORZ] + i*self.steps[HORZ] + (i+1)*self.space - y0 = 0 - for number,data in enumerate(group): - if self.series_colors[number][4] in ('linear','radial'): - linear = cairo.LinearGradient( x0, data.content*self.steps[VERT]/2, x0 + self.steps[HORZ], data.content*self.steps[VERT]/2 ) - color = self.series_colors[number] - linear.add_color_stop_rgba(0.0, 3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) - linear.add_color_stop_rgba(1.0, *color[:4]) - self.context.set_source(linear) - elif self.series_colors[number][4] == 'solid': - self.context.set_source_rgba(*self.series_colors[number][:4]) - if self.rounded_corners: - self.draw_rectangle(number, len(group), x0, self.plot_top - y0 - data.content*self.steps[VERT], x0 + self.steps[HORZ], self.plot_top - y0) - self.context.fill() - else: - self.context.rectangle(x0, self.plot_top - y0 - data.content*self.steps[VERT], self.steps[HORZ], data.content*self.steps[VERT]) - self.context.fill() - y0 += data.content*self.steps[VERT] - else: - for i,group in enumerate(self.series): - inner_step = self.steps[HORZ]/len(group) - y0 = self.borders[VERT] - x0 = self.borders[HORZ] + i*self.steps[HORZ] + (i+1)*self.space - for number,data in enumerate(group): - if self.series_colors[number][4] == 'linear': - linear = cairo.LinearGradient( x0, data.content*self.steps[VERT]/2, x0 + inner_step, data.content*self.steps[VERT]/2 ) - color = self.series_colors[number] - linear.add_color_stop_rgba(0.0, 3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) - linear.add_color_stop_rgba(1.0, *color[:4]) - self.context.set_source(linear) - elif self.series_colors[number][4] == 'solid': - self.context.set_source_rgba(*self.series_colors[number][:4]) - if self.rounded_corners and data.content != 0: - BarPlot.draw_round_rectangle(self, x0, self.plot_top - data.content*self.steps[VERT], x0+inner_step, self.plot_top) - self.context.fill() - elif self.three_dimension: - self.draw_3d_rectangle_front(x0, self.plot_top - data.content*self.steps[VERT], x0+inner_step, self.plot_top, 5) - self.context.fill() - self.draw_3d_rectangle_side(x0, self.plot_top - data.content*self.steps[VERT], x0+inner_step, self.plot_top, 5) - self.context.fill() - self.draw_3d_rectangle_top(x0, self.plot_top - data.content*self.steps[VERT], x0+inner_step, self.plot_top, 5) - self.context.fill() - else: - self.context.rectangle(x0, self.plot_top - data.content*self.steps[VERT], inner_step, data.content*self.steps[VERT]) - self.context.fill() - - x0 += inner_step - -class StreamChart(VerticalBarPlot): - def __init__(self, - surface = None, - data = None, - width = 640, - height = 480, - background = "white light_gray", - border = 0, - grid = False, - series_legend = None, - x_labels = None, - x_bounds = None, - y_bounds = None, - series_colors = None): - - VerticalBarPlot.__init__(self, surface, data, width, height, background, border, - False, grid, False, True, False, - None, x_labels, None, x_bounds, y_bounds, series_colors) - - def calc_steps(self): - other_dir = other_direction(self.main_dir) - self.series_amplitude = self.bounds[self.main_dir][1] - self.bounds[self.main_dir][0] - if self.series_amplitude: - self.steps[self.main_dir] = float(self.plot_dimensions[self.main_dir])/self.series_amplitude - else: - self.steps[self.main_dir] = 0.00 - series_length = len(self.data) - self.steps[other_dir] = float(self.plot_dimensions[other_dir])/series_length - - def render_legend(self): - pass - - def ground(self, index): - sum_values = sum(self.data[index]) - return -0.5*sum_values - - def calc_angles(self): - middle = self.plot_top - self.plot_dimensions[VERT]/2.0 - self.angles = [tuple([0.0 for x in range(len(self.data)+1)])] - for x_index in range(1, len(self.data)-1): - t = [] - x0 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ] - x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ] - y0 = middle - self.ground(x_index-1)*self.steps[VERT] - y2 = middle - self.ground(x_index+1)*self.steps[VERT] - t.append(math.atan(float(y0-y2)/(x0-x2))) - for data_index in range(len(self.data[x_index])): - x0 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ] - x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ] - y0 = middle - self.ground(x_index-1)*self.steps[VERT] - self.data[x_index-1][data_index]*self.steps[VERT] - y2 = middle - self.ground(x_index+1)*self.steps[VERT] - self.data[x_index+1][data_index]*self.steps[VERT] - - for i in range(0,data_index): - y0 -= self.data[x_index-1][i]*self.steps[VERT] - y2 -= self.data[x_index+1][i]*self.steps[VERT] - - if data_index == len(self.data[0])-1 and False: - self.context.set_source_rgba(0.0,0.0,0.0,0.3) - self.context.move_to(x0,y0) - self.context.line_to(x2,y2) - self.context.stroke() - self.context.arc(x0,y0,2,0,2*math.pi) - self.context.fill() - t.append(math.atan(float(y0-y2)/(x0-x2))) - self.angles.append(tuple(t)) - self.angles.append(tuple([0.0 for x in range(len(self.data)+1)])) - - def render_plot(self): - self.calc_angles() - middle = self.plot_top - self.plot_dimensions[VERT]/2.0 - p = 0.4*self.steps[HORZ] - for data_index in range(len(self.data[0])-1,-1,-1): - self.context.set_source_rgba(*self.series_colors[data_index][:4]) - - #draw the upper line - for x_index in range(len(self.data)-1) : - x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ] - y1 = middle - self.ground(x_index)*self.steps[VERT] - self.data[x_index][data_index]*self.steps[VERT] - x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ] - y2 = middle - self.ground(x_index + 1)*self.steps[VERT] - self.data[x_index + 1][data_index]*self.steps[VERT] - - for i in range(0,data_index): - y1 -= self.data[x_index][i]*self.steps[VERT] - y2 -= self.data[x_index+1][i]*self.steps[VERT] - - if x_index == 0: - self.context.move_to(x1,y1) - - ang1 = self.angles[x_index][data_index+1] - ang2 = self.angles[x_index+1][data_index+1] + math.pi - self.context.curve_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1), - x2+p*math.cos(ang2),y2+p*math.sin(ang2), - x2,y2) - - for x_index in range(len(self.data)-1,0,-1) : - x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ] - y1 = middle - self.ground(x_index)*self.steps[VERT] - x2 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ] - y2 = middle - self.ground(x_index - 1)*self.steps[VERT] - - for i in range(0,data_index): - y1 -= self.data[x_index][i]*self.steps[VERT] - y2 -= self.data[x_index-1][i]*self.steps[VERT] - - if x_index == len(self.data)-1: - self.context.line_to(x1,y1+2) - - #revert angles by pi degrees to take the turn back - ang1 = self.angles[x_index][data_index] + math.pi - ang2 = self.angles[x_index-1][data_index] - self.context.curve_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1), - x2+p*math.cos(ang2),y2+p*math.sin(ang2), - x2,y2+2) - - self.context.close_path() - self.context.fill() - - if False: - self.context.move_to(self.borders[HORZ] + 0.5*self.steps[HORZ], middle) - for x_index in range(len(self.data)-1) : - x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ] - y1 = middle - self.ground(x_index)*self.steps[VERT] - self.data[x_index][data_index]*self.steps[VERT] - x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ] - y2 = middle - self.ground(x_index + 1)*self.steps[VERT] - self.data[x_index + 1][data_index]*self.steps[VERT] - - for i in range(0,data_index): - y1 -= self.data[x_index][i]*self.steps[VERT] - y2 -= self.data[x_index+1][i]*self.steps[VERT] - - ang1 = self.angles[x_index][data_index+1] - ang2 = self.angles[x_index+1][data_index+1] + math.pi - self.context.set_source_rgba(1.0,0.0,0.0) - self.context.arc(x1+p*math.cos(ang1),y1+p*math.sin(ang1),2,0,2*math.pi) - self.context.fill() - self.context.set_source_rgba(0.0,0.0,0.0) - self.context.arc(x2+p*math.cos(ang2),y2+p*math.sin(ang2),2,0,2*math.pi) - self.context.fill() - '''self.context.set_source_rgba(0.0,0.0,0.0,0.3) - self.context.arc(x2,y2,2,0,2*math.pi) - self.context.fill()''' - self.context.move_to(x1,y1) - self.context.line_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1)) - self.context.stroke() - self.context.move_to(x2,y2) - self.context.line_to(x2+p*math.cos(ang2),y2+p*math.sin(ang2)) - self.context.stroke() - if False: - for x_index in range(len(self.data)-1,0,-1) : - x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ] - y1 = middle - self.ground(x_index)*self.steps[VERT] - x2 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ] - y2 = middle - self.ground(x_index - 1)*self.steps[VERT] - - for i in range(0,data_index): - y1 -= self.data[x_index][i]*self.steps[VERT] - y2 -= self.data[x_index-1][i]*self.steps[VERT] - - #revert angles by pi degrees to take the turn back - ang1 = self.angles[x_index][data_index] + math.pi - ang2 = self.angles[x_index-1][data_index] - self.context.set_source_rgba(0.0,1.0,0.0) - self.context.arc(x1+p*math.cos(ang1),y1+p*math.sin(ang1),2,0,2*math.pi) - self.context.fill() - self.context.set_source_rgba(0.0,0.0,1.0) - self.context.arc(x2+p*math.cos(ang2),y2+p*math.sin(ang2),2,0,2*math.pi) - self.context.fill() - '''self.context.set_source_rgba(0.0,0.0,0.0,0.3) - self.context.arc(x2,y2,2,0,2*math.pi) - self.context.fill()''' - self.context.move_to(x1,y1) - self.context.line_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1)) - self.context.stroke() - self.context.move_to(x2,y2) - self.context.line_to(x2+p*math.cos(ang2),y2+p*math.sin(ang2)) - self.context.stroke() - #break - - #self.context.arc(self.dimensions[HORZ]/2, self.dimensions[VERT]/2,50,0,3*math.pi/2) - #self.context.fill() - - -class PiePlot(Plot): - #TODO: Check the old cairoplot, graphs aren't matching - def __init__ (self, - surface = None, - data = None, - width = 640, - height = 480, - background = "white light_gray", - gradient = False, - shadow = False, - colors = None): - - Plot.__init__( self, surface, data, width, height, background, series_colors = colors ) - self.center = (self.dimensions[HORZ]/2, self.dimensions[VERT]/2) - self.total = sum( self.series.to_list() ) - self.radius = min(self.dimensions[HORZ]/3,self.dimensions[VERT]/3) - self.gradient = gradient - self.shadow = shadow - - def sort_function(x,y): - return x.content - y.content - - def load_series(self, data, x_labels=None, y_labels=None, series_colors=None): - Plot.load_series(self, data, x_labels, y_labels, series_colors) - # Already done inside series - #self.data = sorted(self.data) - - def draw_piece(self, angle, next_angle): - self.context.move_to(self.center[0],self.center[1]) - self.context.line_to(self.center[0] + self.radius*math.cos(angle), self.center[1] + self.radius*math.sin(angle)) - self.context.arc(self.center[0], self.center[1], self.radius, angle, next_angle) - self.context.line_to(self.center[0], self.center[1]) - self.context.close_path() - - def render(self): - self.render_background() - self.render_bounding_box() - if self.shadow: - self.render_shadow() - self.render_plot() - self.render_series_labels() - - def render_shadow(self): - horizontal_shift = 3 - vertical_shift = 3 - self.context.set_source_rgba(0, 0, 0, 0.5) - self.context.arc(self.center[0] + horizontal_shift, self.center[1] + vertical_shift, self.radius, 0, 2*math.pi) - self.context.fill() - - def render_series_labels(self): - angle = 0 - next_angle = 0 - x0,y0 = self.center - cr = self.context - for number,key in enumerate(self.series_labels): - # self.data[number] should be just a number - data = sum(self.series[number].to_list()) - - next_angle = angle + 2.0*math.pi*data/self.total - cr.set_source_rgba(*self.series_colors[number][:4]) - w = cr.text_extents(key)[2] - if (angle + next_angle)/2 < math.pi/2 or (angle + next_angle)/2 > 3*math.pi/2: - cr.move_to(x0 + (self.radius+10)*math.cos((angle+next_angle)/2), y0 + (self.radius+10)*math.sin((angle+next_angle)/2) ) - else: - cr.move_to(x0 + (self.radius+10)*math.cos((angle+next_angle)/2) - w, y0 + (self.radius+10)*math.sin((angle+next_angle)/2) ) - cr.show_text(key) - angle = next_angle - - def render_plot(self): - angle = 0 - next_angle = 0 - x0,y0 = self.center - cr = self.context - for number,group in enumerate(self.series): - # Group should be just a number - data = sum(group.to_list()) - next_angle = angle + 2.0*math.pi*data/self.total - if self.gradient or self.series_colors[number][4] in ('linear','radial'): - gradient_color = cairo.RadialGradient(self.center[0], self.center[1], 0, self.center[0], self.center[1], self.radius) - gradient_color.add_color_stop_rgba(0.3, *self.series_colors[number][:4]) - gradient_color.add_color_stop_rgba(1, self.series_colors[number][0]*0.7, - self.series_colors[number][1]*0.7, - self.series_colors[number][2]*0.7, - self.series_colors[number][3]) - cr.set_source(gradient_color) - else: - cr.set_source_rgba(*self.series_colors[number][:4]) - - self.draw_piece(angle, next_angle) - cr.fill() - - cr.set_source_rgba(1.0, 1.0, 1.0) - self.draw_piece(angle, next_angle) - cr.stroke() - - angle = next_angle - -class DonutPlot(PiePlot): - def __init__ (self, - surface = None, - data = None, - width = 640, - height = 480, - background = "white light_gray", - gradient = False, - shadow = False, - colors = None, - inner_radius=-1): - - Plot.__init__( self, surface, data, width, height, background, series_colors = colors ) - - self.center = ( self.dimensions[HORZ]/2, self.dimensions[VERT]/2 ) - self.total = sum( self.series.to_list() ) - self.radius = min( self.dimensions[HORZ]/3,self.dimensions[VERT]/3 ) - self.inner_radius = inner_radius*self.radius - - if inner_radius == -1: - self.inner_radius = self.radius/3 - - self.gradient = gradient - self.shadow = shadow - - def draw_piece(self, angle, next_angle): - self.context.move_to(self.center[0] + (self.inner_radius)*math.cos(angle), self.center[1] + (self.inner_radius)*math.sin(angle)) - self.context.line_to(self.center[0] + self.radius*math.cos(angle), self.center[1] + self.radius*math.sin(angle)) - self.context.arc(self.center[0], self.center[1], self.radius, angle, next_angle) - self.context.line_to(self.center[0] + (self.inner_radius)*math.cos(next_angle), self.center[1] + (self.inner_radius)*math.sin(next_angle)) - self.context.arc_negative(self.center[0], self.center[1], self.inner_radius, next_angle, angle) - self.context.close_path() - - def render_shadow(self): - horizontal_shift = 3 - vertical_shift = 3 - self.context.set_source_rgba(0, 0, 0, 0.5) - self.context.arc(self.center[0] + horizontal_shift, self.center[1] + vertical_shift, self.inner_radius, 0, 2*math.pi) - self.context.arc_negative(self.center[0] + horizontal_shift, self.center[1] + vertical_shift, self.radius, 0, -2*math.pi) - self.context.fill() - -class GanttChart (Plot) : - def __init__(self, - surface = None, - data = None, - width = 640, - height = 480, - x_labels = None, - y_labels = None, - colors = None): - self.bounds = {} - self.max_value = {} - Plot.__init__(self, surface, data, width, height, x_labels = x_labels, y_labels = y_labels, series_colors = colors) - - def load_series(self, data, x_labels=None, y_labels=None, series_colors=None): - Plot.load_series(self, data, x_labels, y_labels, series_colors) - self.calc_boundaries() - - def calc_boundaries(self): - self.bounds[HORZ] = (0,len(self.series)) - end_pos = max(self.series.to_list()) - - #for group in self.series: - # if hasattr(item, "__delitem__"): - # for sub_item in item: - # end_pos = max(sub_item) - # else: - # end_pos = max(item) - self.bounds[VERT] = (0,end_pos) - - def calc_extents(self, direction): - self.max_value[direction] = 0 - if self.labels[direction]: - self.max_value[direction] = max(self.context.text_extents(item)[2] for item in self.labels[direction]) - else: - self.max_value[direction] = self.context.text_extents( str(self.bounds[direction][1] + 1) )[2] - - def calc_horz_extents(self): - self.calc_extents(HORZ) - self.borders[HORZ] = 100 + self.max_value[HORZ] - - def calc_vert_extents(self): - self.calc_extents(VERT) - self.borders[VERT] = self.dimensions[VERT]/(self.bounds[HORZ][1] + 1) - - def calc_steps(self): - self.horizontal_step = (self.dimensions[HORZ] - self.borders[HORZ])/(len(self.labels[VERT])) - self.vertical_step = self.borders[VERT] - - def render(self): - self.calc_horz_extents() - self.calc_vert_extents() - self.calc_steps() - self.render_background() - - self.render_labels() - self.render_grid() - self.render_plot() - - def render_background(self): - cr = self.context - cr.set_source_rgba(255,255,255) - cr.rectangle(0,0,self.dimensions[HORZ], self.dimensions[VERT]) - cr.fill() - for number,group in enumerate(self.series): - linear = cairo.LinearGradient(self.dimensions[HORZ]/2, self.borders[VERT] + number*self.vertical_step, - self.dimensions[HORZ]/2, self.borders[VERT] + (number+1)*self.vertical_step) - linear.add_color_stop_rgba(0,1.0,1.0,1.0,1.0) - linear.add_color_stop_rgba(1.0,0.9,0.9,0.9,1.0) - cr.set_source(linear) - cr.rectangle(0,self.borders[VERT] + number*self.vertical_step,self.dimensions[HORZ],self.vertical_step) - cr.fill() - - def render_grid(self): - cr = self.context - cr.set_source_rgba(0.7, 0.7, 0.7) - cr.set_dash((1,0,0,0,0,0,1)) - cr.set_line_width(0.5) - for number,label in enumerate(self.labels[VERT]): - h = cr.text_extents(label)[3] - cr.move_to(self.borders[HORZ] + number*self.horizontal_step, self.vertical_step/2 + h) - cr.line_to(self.borders[HORZ] + number*self.horizontal_step, self.dimensions[VERT]) - cr.stroke() - - def render_labels(self): - self.context.set_font_size(0.02 * self.dimensions[HORZ]) - - self.render_horz_labels() - self.render_vert_labels() - - def render_horz_labels(self): - cr = self.context - labels = self.labels[HORZ] - if not labels: - labels = [str(i) for i in range(1, self.bounds[HORZ][1] + 1) ] - for number,label in enumerate(labels): - if label != None: - cr.set_source_rgba(0.5, 0.5, 0.5) - w,h = cr.text_extents(label)[2], cr.text_extents(label)[3] - cr.move_to(40,self.borders[VERT] + number*self.vertical_step + self.vertical_step/2 + h/2) - cr.show_text(label) - - def render_vert_labels(self): - cr = self.context - labels = self.labels[VERT] - if not labels: - labels = [str(i) for i in range(1, self.bounds[VERT][1] + 1) ] - for number,label in enumerate(labels): - w,h = cr.text_extents(label)[2], cr.text_extents(label)[3] - cr.move_to(self.borders[HORZ] + number*self.horizontal_step - w/2, self.vertical_step/2) - cr.show_text(label) - - def render_rectangle(self, x0, y0, x1, y1, color): - self.draw_shadow(x0, y0, x1, y1) - self.draw_rectangle(x0, y0, x1, y1, color) - - def draw_rectangular_shadow(self, gradient, x0, y0, w, h): - self.context.set_source(gradient) - self.context.rectangle(x0,y0,w,h) - self.context.fill() - - def draw_circular_shadow(self, x, y, radius, ang_start, ang_end, mult, shadow): - gradient = cairo.RadialGradient(x, y, 0, x, y, 2*radius) - gradient.add_color_stop_rgba(0, 0, 0, 0, shadow) - gradient.add_color_stop_rgba(1, 0, 0, 0, 0) - self.context.set_source(gradient) - self.context.move_to(x,y) - self.context.line_to(x + mult[0]*radius,y + mult[1]*radius) - self.context.arc(x, y, 8, ang_start, ang_end) - self.context.line_to(x,y) - self.context.close_path() - self.context.fill() - - def draw_rectangle(self, x0, y0, x1, y1, color): - cr = self.context - middle = (x0+x1)/2 - linear = cairo.LinearGradient(middle,y0,middle,y1) - linear.add_color_stop_rgba(0,3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) - linear.add_color_stop_rgba(1,*color[:4]) - cr.set_source(linear) - - cr.arc(x0+5, y0+5, 5, 0, 2*math.pi) - cr.arc(x1-5, y0+5, 5, 0, 2*math.pi) - cr.arc(x0+5, y1-5, 5, 0, 2*math.pi) - cr.arc(x1-5, y1-5, 5, 0, 2*math.pi) - cr.rectangle(x0+5,y0,x1-x0-10,y1-y0) - cr.rectangle(x0,y0+5,x1-x0,y1-y0-10) - cr.fill() - - def draw_shadow(self, x0, y0, x1, y1): - shadow = 0.4 - h_mid = (x0+x1)/2 - v_mid = (y0+y1)/2 - h_linear_1 = cairo.LinearGradient(h_mid,y0-4,h_mid,y0+4) - h_linear_2 = cairo.LinearGradient(h_mid,y1-4,h_mid,y1+4) - v_linear_1 = cairo.LinearGradient(x0-4,v_mid,x0+4,v_mid) - v_linear_2 = cairo.LinearGradient(x1-4,v_mid,x1+4,v_mid) - - h_linear_1.add_color_stop_rgba( 0, 0, 0, 0, 0) - h_linear_1.add_color_stop_rgba( 1, 0, 0, 0, shadow) - h_linear_2.add_color_stop_rgba( 0, 0, 0, 0, shadow) - h_linear_2.add_color_stop_rgba( 1, 0, 0, 0, 0) - v_linear_1.add_color_stop_rgba( 0, 0, 0, 0, 0) - v_linear_1.add_color_stop_rgba( 1, 0, 0, 0, shadow) - v_linear_2.add_color_stop_rgba( 0, 0, 0, 0, shadow) - v_linear_2.add_color_stop_rgba( 1, 0, 0, 0, 0) - - self.draw_rectangular_shadow(h_linear_1,x0+4,y0-4,x1-x0-8,8) - self.draw_rectangular_shadow(h_linear_2,x0+4,y1-4,x1-x0-8,8) - self.draw_rectangular_shadow(v_linear_1,x0-4,y0+4,8,y1-y0-8) - self.draw_rectangular_shadow(v_linear_2,x1-4,y0+4,8,y1-y0-8) - - self.draw_circular_shadow(x0+4, y0+4, 4, math.pi, 3*math.pi/2, (-1,0), shadow) - self.draw_circular_shadow(x1-4, y0+4, 4, 3*math.pi/2, 2*math.pi, (0,-1), shadow) - self.draw_circular_shadow(x0+4, y1-4, 4, math.pi/2, math.pi, (0,1), shadow) - self.draw_circular_shadow(x1-4, y1-4, 4, 0, math.pi/2, (1,0), shadow) - - def render_plot(self): - for index,group in enumerate(self.series): - for data in group: - self.render_rectangle(self.borders[HORZ] + data.content[0]*self.horizontal_step, - self.borders[VERT] + index*self.vertical_step + self.vertical_step/4.0, - self.borders[HORZ] + data.content[1]*self.horizontal_step, - self.borders[VERT] + index*self.vertical_step + 3.0*self.vertical_step/4.0, - self.series_colors[index]) - -# Function definition - -def scatter_plot(name, - data = None, - errorx = None, - errory = None, - width = 640, - height = 480, - background = "white light_gray", - border = 0, - axis = False, - dash = False, - discrete = False, - dots = False, - grid = False, - series_legend = False, - x_labels = None, - y_labels = None, - x_bounds = None, - y_bounds = None, - z_bounds = None, - x_title = None, - y_title = None, - series_colors = None, - circle_colors = None): - - ''' - - Function to plot scatter data. - - - Parameters - - data - The values to be ploted might be passed in a two basic: - list of points: [(0,0), (0,1), (0,2)] or [(0,0,1), (0,1,4), (0,2,1)] - lists of coordinates: [ [0,0,0] , [0,1,2] ] or [ [0,0,0] , [0,1,2] , [1,4,1] ] - Notice that these kinds of that can be grouped in order to form more complex data - using lists of lists or dictionaries; - series_colors - Define color values for each of the series - circle_colors - Define a lower and an upper bound for the circle colors for variable radius - (3 dimensions) series - ''' - - plot = ScatterPlot( name, data, errorx, errory, width, height, background, border, - axis, dash, discrete, dots, grid, series_legend, x_labels, y_labels, - x_bounds, y_bounds, z_bounds, x_title, y_title, series_colors, circle_colors ) - plot.render() - plot.commit() - -def dot_line_plot(name, - data, - width, - height, - background = "white light_gray", - border = 0, - axis = False, - dash = False, - dots = False, - grid = False, - series_legend = False, - x_labels = None, - y_labels = None, - x_bounds = None, - y_bounds = None, - x_title = None, - y_title = None, - series_colors = None): - ''' - - Function to plot graphics using dots and lines. - - dot_line_plot (name, data, width, height, background = "white light_gray", border = 0, axis = False, grid = False, x_labels = None, y_labels = None, x_bounds = None, y_bounds = None) - - - Parameters - - name - Name of the desired output file, no need to input the .svg as it will be added at runtim; - data - The list, list of lists or dictionary holding the data to be plotted; - width, height - Dimensions of the output image; - background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. - If left None, a gray to white gradient will be generated; - border - Distance in pixels of a square border into which the graphics will be drawn; - axis - Whether or not the axis are to be drawn; - dash - Boolean or a list or a dictionary of booleans indicating whether or not the associated series should be drawn in dashed mode; - dots - Whether or not dots should be drawn on each point; - grid - Whether or not the gris is to be drawn; - series_legend - Whether or not the legend is to be drawn; - x_labels, y_labels - lists of strings containing the horizontal and vertical labels for the axis; - x_bounds, y_bounds - tuples containing the lower and upper value bounds for the data to be plotted; - x_title - Whether or not to plot a title over the x axis. - y_title - Whether or not to plot a title over the y axis. - - - Examples of use - - data = [0, 1, 3, 8, 9, 0, 10, 10, 2, 1] - CairoPlot.dot_line_plot('teste', data, 400, 300) - - data = { "john" : [10, 10, 10, 10, 30], "mary" : [0, 0, 3, 5, 15], "philip" : [13, 32, 11, 25, 2] } - x_labels = ["jan/2008", "feb/2008", "mar/2008", "apr/2008", "may/2008" ] - CairoPlot.dot_line_plot( 'test', data, 400, 300, axis = True, grid = True, - series_legend = True, x_labels = x_labels ) - ''' - plot = DotLinePlot( name, data, width, height, background, border, - axis, dash, dots, grid, series_legend, x_labels, y_labels, - x_bounds, y_bounds, x_title, y_title, series_colors ) - plot.render() - plot.commit() - -def function_plot(name, - data, - width, - height, - background = "white light_gray", - border = 0, - axis = True, - dots = False, - discrete = False, - grid = False, - series_legend = False, - x_labels = None, - y_labels = None, - x_bounds = None, - y_bounds = None, - x_title = None, - y_title = None, - series_colors = None, - step = 1): - - ''' - - Function to plot functions. - - function_plot(name, data, width, height, background = "white light_gray", border = 0, axis = True, grid = False, dots = False, x_labels = None, y_labels = None, x_bounds = None, y_bounds = None, step = 1, discrete = False) - - - Parameters - - name - Name of the desired output file, no need to input the .svg as it will be added at runtim; - data - The list, list of lists or dictionary holding the data to be plotted; - width, height - Dimensions of the output image; - background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. - If left None, a gray to white gradient will be generated; - border - Distance in pixels of a square border into which the graphics will be drawn; - axis - Whether or not the axis are to be drawn; - grid - Whether or not the gris is to be drawn; - dots - Whether or not dots should be shown at each point; - x_labels, y_labels - lists of strings containing the horizontal and vertical labels for the axis; - x_bounds, y_bounds - tuples containing the lower and upper value bounds for the data to be plotted; - step - the horizontal distance from one point to the other. The smaller, the smoother the curve will be; - discrete - whether or not the function should be plotted in discrete format. - - - Example of use - - data = lambda x : x**2 - CairoPlot.function_plot('function4', data, 400, 300, grid = True, x_bounds=(-10,10), step = 0.1) - ''' - - plot = FunctionPlot( name, data, width, height, background, border, - axis, discrete, dots, grid, series_legend, x_labels, y_labels, - x_bounds, y_bounds, x_title, y_title, series_colors, step ) - plot.render() - plot.commit() - -def pie_plot( name, data, width, height, background = "white light_gray", gradient = False, shadow = False, colors = None ): - - ''' - - Function to plot pie graphics. - - pie_plot(name, data, width, height, background = "white light_gray", gradient = False, colors = None) - - - Parameters - - name - Name of the desired output file, no need to input the .svg as it will be added at runtim; - data - The list, list of lists or dictionary holding the data to be plotted; - width, height - Dimensions of the output image; - background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. - If left None, a gray to white gradient will be generated; - gradient - Whether or not the pie color will be painted with a gradient; - shadow - Whether or not there will be a shadow behind the pie; - colors - List of slices colors. - - - Example of use - - teste_data = {"john" : 123, "mary" : 489, "philip" : 890 , "suzy" : 235} - CairoPlot.pie_plot("pie_teste", teste_data, 500, 500) - ''' - - plot = PiePlot( name, data, width, height, background, gradient, shadow, colors ) - plot.render() - plot.commit() - -def donut_plot(name, data, width, height, background = "white light_gray", gradient = False, shadow = False, colors = None, inner_radius = -1): - - ''' - - Function to plot donut graphics. - - donut_plot(name, data, width, height, background = "white light_gray", gradient = False, inner_radius = -1) - - - Parameters - - name - Name of the desired output file, no need to input the .svg as it will be added at runtim; - data - The list, list of lists or dictionary holding the data to be plotted; - width, height - Dimensions of the output image; - background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. - If left None, a gray to white gradient will be generated; - shadow - Whether or not there will be a shadow behind the donut; - gradient - Whether or not the donut color will be painted with a gradient; - colors - List of slices colors; - inner_radius - The radius of the donut's inner circle. - - - Example of use - - teste_data = {"john" : 123, "mary" : 489, "philip" : 890 , "suzy" : 235} - CairoPlot.donut_plot("donut_teste", teste_data, 500, 500) - ''' - - plot = DonutPlot(name, data, width, height, background, gradient, shadow, colors, inner_radius) - plot.render() - plot.commit() - -def gantt_chart(name, pieces, width, height, x_labels, y_labels, colors): - - ''' - - Function to generate Gantt Charts. - - gantt_chart(name, pieces, width, height, x_labels, y_labels, colors): - - - Parameters - - name - Name of the desired output file, no need to input the .svg as it will be added at runtim; - pieces - A list defining the spaces to be drawn. The user must pass, for each line, the index of its start and the index of its end. If a line must have two or more spaces, they must be passed inside a list; - width, height - Dimensions of the output image; - x_labels - A list of names for each of the vertical lines; - y_labels - A list of names for each of the horizontal spaces; - colors - List containing the colors expected for each of the horizontal spaces - - - Example of use - - pieces = [ (0.5,5.5) , [(0,4),(6,8)] , (5.5,7) , (7,8)] - x_labels = [ 'teste01', 'teste02', 'teste03', 'teste04'] - y_labels = [ '0001', '0002', '0003', '0004', '0005', '0006', '0007', '0008', '0009', '0010' ] - colors = [ (1.0, 0.0, 0.0), (1.0, 0.7, 0.0), (1.0, 1.0, 0.0), (0.0, 1.0, 0.0) ] - CairoPlot.gantt_chart('gantt_teste', pieces, 600, 300, x_labels, y_labels, colors) - ''' - - plot = GanttChart(name, pieces, width, height, x_labels, y_labels, colors) - plot.render() - plot.commit() - -def vertical_bar_plot(name, - data, - width, - height, - background = "white light_gray", - border = 0, - display_values = False, - grid = False, - rounded_corners = False, - stack = False, - three_dimension = False, - series_labels = None, - x_labels = None, - y_labels = None, - x_bounds = None, - y_bounds = None, - colors = None): - #TODO: Fix docstring for vertical_bar_plot - ''' - - Function to generate vertical Bar Plot Charts. - - bar_plot(name, data, width, height, background, border, grid, rounded_corners, three_dimension, - x_labels, y_labels, x_bounds, y_bounds, colors): - - - Parameters - - name - Name of the desired output file, no need to input the .svg as it will be added at runtime; - data - The list, list of lists or dictionary holding the data to be plotted; - width, height - Dimensions of the output image; - background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. - If left None, a gray to white gradient will be generated; - border - Distance in pixels of a square border into which the graphics will be drawn; - grid - Whether or not the gris is to be drawn; - rounded_corners - Whether or not the bars should have rounded corners; - three_dimension - Whether or not the bars should be drawn in pseudo 3D; - x_labels, y_labels - lists of strings containing the horizontal and vertical labels for the axis; - x_bounds, y_bounds - tuples containing the lower and upper value bounds for the data to be plotted; - colors - List containing the colors expected for each of the bars. - - - Example of use - - data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - CairoPlot.vertical_bar_plot ('bar2', data, 400, 300, border = 20, grid = True, rounded_corners = False) - ''' - - plot = VerticalBarPlot(name, data, width, height, background, border, - display_values, grid, rounded_corners, stack, three_dimension, - series_labels, x_labels, y_labels, x_bounds, y_bounds, colors) - plot.render() - plot.commit() - -def horizontal_bar_plot(name, - data, - width, - height, - background = "white light_gray", - border = 0, - display_values = False, - grid = False, - rounded_corners = False, - stack = False, - three_dimension = False, - series_labels = None, - x_labels = None, - y_labels = None, - x_bounds = None, - y_bounds = None, - colors = None): - - #TODO: Fix docstring for horizontal_bar_plot - ''' - - Function to generate Horizontal Bar Plot Charts. - - bar_plot(name, data, width, height, background, border, grid, rounded_corners, three_dimension, - x_labels, y_labels, x_bounds, y_bounds, colors): - - - Parameters - - name - Name of the desired output file, no need to input the .svg as it will be added at runtime; - data - The list, list of lists or dictionary holding the data to be plotted; - width, height - Dimensions of the output image; - background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. - If left None, a gray to white gradient will be generated; - border - Distance in pixels of a square border into which the graphics will be drawn; - grid - Whether or not the gris is to be drawn; - rounded_corners - Whether or not the bars should have rounded corners; - three_dimension - Whether or not the bars should be drawn in pseudo 3D; - x_labels, y_labels - lists of strings containing the horizontal and vertical labels for the axis; - x_bounds, y_bounds - tuples containing the lower and upper value bounds for the data to be plotted; - colors - List containing the colors expected for each of the bars. - - - Example of use - - data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - CairoPlot.bar_plot ('bar2', data, 400, 300, border = 20, grid = True, rounded_corners = False) - ''' - - plot = HorizontalBarPlot(name, data, width, height, background, border, - display_values, grid, rounded_corners, stack, three_dimension, - series_labels, x_labels, y_labels, x_bounds, y_bounds, colors) - plot.render() - plot.commit() - -def stream_chart(name, - data, - width, - height, - background = "white light_gray", - border = 0, - grid = False, - series_legend = None, - x_labels = None, - x_bounds = None, - y_bounds = None, - colors = None): - - #TODO: Fix docstring for horizontal_bar_plot - plot = StreamChart(name, data, width, height, background, border, - grid, series_legend, x_labels, x_bounds, y_bounds, colors) - plot.render() - plot.commit() - - -if __name__ == "__main__": - import tests - import seriestests diff --git a/bindings/python/examples/output_format_modules/pprint_table.py b/bindings/python/examples/output_format_modules/pprint_table.py deleted file mode 100644 index a7e8255..0000000 --- a/bindings/python/examples/output_format_modules/pprint_table.py +++ /dev/null @@ -1,37 +0,0 @@ -# pprint_table.py -# -# This module is used to pretty-print a table -# Adapted from -# http://ginstrom.com/scribbles/2007/09/04/pretty-printing-a-table-in-python/ - -import sys - -def get_max_width(table, index): - """Get the maximum width of the given column index""" - - return max([len(str(row[index])) for row in table]) - - -def pprint_table(table, nbLeft=1, out=sys.stdout): - """ - Prints out a table of data, padded for alignment - @param table: The table to print. A list of lists. - Each row must have the same number of columns. - @param nbLeft: The number of columns aligned left - @param out: Output stream (file-like object) - """ - - col_paddings = [] - - for i in range(len(table[0])): - col_paddings.append(get_max_width(table, i)) - - for row in table: - # left cols - for i in range(nbLeft): - print >> out, str(row[i]).ljust(col_paddings[i] + 1), - # rest of the cols - for i in range(nbLeft, len(row)): - col = str(row[i]).rjust(col_paddings[i] + 2) - print >> out, col, - print >> out diff --git a/bindings/python/examples/output_format_modules/series.py b/bindings/python/examples/output_format_modules/series.py deleted file mode 100644 index 8e8b236..0000000 --- a/bindings/python/examples/output_format_modules/series.py +++ /dev/null @@ -1,1140 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# Serie.py -# -# Copyright (c) 2008 Magnun Leno da Silva -# -# Author: Magnun Leno da Silva -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser 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 Lesser 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 - -# Contributor: Rodrigo Moreiro Araujo - -#import cairoplot -import doctest - -NUMTYPES = (int, float, long) -LISTTYPES = (list, tuple) -STRTYPES = (str, unicode) -FILLING_TYPES = ['linear', 'solid', 'gradient'] -DEFAULT_COLOR_FILLING = 'solid' -#TODO: Define default color list -DEFAULT_COLOR_LIST = None - -class Data(object): - ''' - Class that models the main data structure. - It can hold: - - a number type (int, float or long) - - a tuple, witch represents a point and can have 2 or 3 items (x,y,z) - - if a list is passed it will be converted to a tuple. - - obs: In case a tuple is passed it will convert to tuple - ''' - def __init__(self, data=None, name=None, parent=None): - ''' - Starts main atributes from the Data class - @name - Name for each point; - @content - The real data, can be an int, float, long or tuple, which - represents a point (x,y) or (x,y,z); - @parent - A pointer that give the data access to it's parent. - - Usage: - >>> d = Data(name='empty'); print d - empty: () - >>> d = Data((1,1),'point a'); print d - point a: (1, 1) - >>> d = Data((1,2,3),'point b'); print d - point b: (1, 2, 3) - >>> d = Data([2,3],'point c'); print d - point c: (2, 3) - >>> d = Data(12, 'simple value'); print d - simple value: 12 - ''' - # Initial values - self.__content = None - self.__name = None - - # Setting passed values - self.parent = parent - self.name = name - self.content = data - - # Name property - @apply - def name(): - doc = ''' - Name is a read/write property that controls the input of name. - - If passed an invalid value it cleans the name with None - - Usage: - >>> d = Data(13); d.name = 'name_test'; print d - name_test: 13 - >>> d.name = 11; print d - 13 - >>> d.name = 'other_name'; print d - other_name: 13 - >>> d.name = None; print d - 13 - >>> d.name = 'last_name'; print d - last_name: 13 - >>> d.name = ''; print d - 13 - ''' - def fget(self): - ''' - returns the name as a string - ''' - return self.__name - - def fset(self, name): - ''' - Sets the name of the Data - ''' - if type(name) in STRTYPES and len(name) > 0: - self.__name = name - else: - self.__name = None - - - - return property(**locals()) - - # Content property - @apply - def content(): - doc = ''' - Content is a read/write property that validate the data passed - and return it. - - Usage: - >>> d = Data(); d.content = 13; d.content - 13 - >>> d = Data(); d.content = (1,2); d.content - (1, 2) - >>> d = Data(); d.content = (1,2,3); d.content - (1, 2, 3) - >>> d = Data(); d.content = [1,2,3]; d.content - (1, 2, 3) - >>> d = Data(); d.content = [1.5,.2,3.3]; d.content - (1.5, 0.20000000000000001, 3.2999999999999998) - ''' - def fget(self): - ''' - Return the content of Data - ''' - return self.__content - - def fset(self, data): - ''' - Ensures that data is a valid tuple/list or a number (int, float - or long) - ''' - # Type: None - if data is None: - self.__content = None - return - - # Type: Int or Float - elif type(data) in NUMTYPES: - self.__content = data - - # Type: List or Tuple - elif type(data) in LISTTYPES: - # Ensures the correct size - if len(data) not in (2, 3): - raise TypeError, "Data (as list/tuple) must have 2 or 3 items" - return - - # Ensures that all items in list/tuple is a number - isnum = lambda x : type(x) not in NUMTYPES - - if max(map(isnum, data)): - # An item in data isn't an int or a float - raise TypeError, "All content of data must be a number (int or float)" - - # Convert the tuple to list - if type(data) is list: - data = tuple(data) - - # Append a copy and sets the type - self.__content = data[:] - - # Unknown type! - else: - self.__content = None - raise TypeError, "Data must be an int, float or a tuple with two or three items" - return - - return property(**locals()) - - - def clear(self): - ''' - Clear the all Data (content, name and parent) - ''' - self.content = None - self.name = None - self.parent = None - - def copy(self): - ''' - Returns a copy of the Data structure - ''' - # The copy - new_data = Data() - if self.content is not None: - # If content is a point - if type(self.content) is tuple: - new_data.__content = self.content[:] - - # If content is a number - else: - new_data.__content = self.content - - # If it has a name - if self.name is not None: - new_data.__name = self.name - - return new_data - - def __str__(self): - ''' - Return a string representation of the Data structure - ''' - if self.name is None: - if self.content is None: - return '' - return str(self.content) - else: - if self.content is None: - return self.name+": ()" - return self.name+": "+str(self.content) - - def __len__(self): - ''' - Return the length of the Data. - - If it's a number return 1; - - If it's a list return it's length; - - If its None return 0. - ''' - if self.content is None: - return 0 - elif type(self.content) in NUMTYPES: - return 1 - return len(self.content) - - - - -class Group(object): - ''' - Class that models a group of data. Every value (int, float, long, tuple - or list) passed is converted to a list of Data. - It can receive: - - A single number (int, float, long); - - A list of numbers; - - A tuple of numbers; - - An instance of Data; - - A list of Data; - - Obs: If a tuple with 2 or 3 items is passed it is converted to a point. - If a tuple with only 1 item is passed it's converted to a number; - If a tuple with more than 2 items is passed it's converted to a - list of numbers - ''' - def __init__(self, group=None, name=None, parent=None): - ''' - Starts main atributes in Group instance. - @data_list - a list of data which forms the group; - @range - a range that represent the x axis of possible functions; - @name - name of the data group; - @parent - the Serie parent of this group. - - Usage: - >>> g = Group(13, 'simple number'); print g - simple number ['13'] - >>> g = Group((1,2), 'simple point'); print g - simple point ['(1, 2)'] - >>> g = Group([1,2,3,4], 'list of numbers'); print g - list of numbers ['1', '2', '3', '4'] - >>> g = Group((1,2,3,4),'int in tuple'); print g - int in tuple ['1', '2', '3', '4'] - >>> g = Group([(1,2),(2,3),(3,4)], 'list of points'); print g - list of points ['(1, 2)', '(2, 3)', '(3, 4)'] - >>> g = Group([[1,2,3],[1,2,3]], '2D coordinate lists'); print g - 2D coordinated lists ['(1, 1)', '(2, 2)', '(3, 3)'] - >>> g = Group([[1,2],[1,2],[1,2]], '3D coordinate lists'); print g - 3D coordinated lists ['(1, 1, 1)', '(2, 2, 2)'] - ''' - # Initial values - self.__data_list = [] - self.__range = [] - self.__name = None - - - self.parent = parent - self.name = name - self.data_list = group - - # Name property - @apply - def name(): - doc = ''' - Name is a read/write property that controls the input of name. - - If passed an invalid value it cleans the name with None - - Usage: - >>> g = Group(13); g.name = 'name_test'; print g - name_test ['13'] - >>> g.name = 11; print g - ['13'] - >>> g.name = 'other_name'; print g - other_name ['13'] - >>> g.name = None; print g - ['13'] - >>> g.name = 'last_name'; print g - last_name ['13'] - >>> g.name = ''; print g - ['13'] - ''' - def fget(self): - ''' - Returns the name as a string - ''' - return self.__name - - def fset(self, name): - ''' - Sets the name of the Group - ''' - if type(name) in STRTYPES and len(name) > 0: - self.__name = name - else: - self.__name = None - - return property(**locals()) - - # data_list property - @apply - def data_list(): - doc = ''' - The data_list is a read/write property that can be a list of - numbers, a list of points or a list of 2 or 3 coordinate lists. This - property uses mainly the self.add_data method. - - Usage: - >>> g = Group(); g.data_list = 13; print g - ['13'] - >>> g.data_list = (1,2); print g - ['(1, 2)'] - >>> g.data_list = Data((1,2),'point a'); print g - ['point a: (1, 2)'] - >>> g.data_list = [1,2,3]; print g - ['1', '2', '3'] - >>> g.data_list = (1,2,3,4); print g - ['1', '2', '3', '4'] - >>> g.data_list = [(1,2),(2,3),(3,4)]; print g - ['(1, 2)', '(2, 3)', '(3, 4)'] - >>> g.data_list = [[1,2],[1,2]]; print g - ['(1, 1)', '(2, 2)'] - >>> g.data_list = [[1,2],[1,2],[1,2]]; print g - ['(1, 1, 1)', '(2, 2, 2)'] - >>> g.range = (10); g.data_list = lambda x:x**2; print g - ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 4.0)', '(3.0, 9.0)', '(4.0, 16.0)', '(5.0, 25.0)', '(6.0, 36.0)', '(7.0, 49.0)', '(8.0, 64.0)', '(9.0, 81.0)'] - ''' - def fget(self): - ''' - Returns the value of data_list - ''' - return self.__data_list - - def fset(self, group): - ''' - Ensures that group is valid. - ''' - # None - if group is None: - self.__data_list = [] - - # Int/float/long or Instance of Data - elif type(group) in NUMTYPES or isinstance(group, Data): - # Clean data_list - self.__data_list = [] - self.add_data(group) - - # One point - elif type(group) is tuple and len(group) in (2,3): - self.__data_list = [] - self.add_data(group) - - # list of items - elif type(group) in LISTTYPES and type(group[0]) is not list: - # Clean data_list - self.__data_list = [] - for item in group: - # try to append and catch an exception - self.add_data(item) - - # function lambda - elif callable(group): - # Explicit is better than implicit - function = group - # Has range - if len(self.range) is not 0: - # Clean data_list - self.__data_list = [] - # Generate values for the lambda function - for x in self.range: - #self.add_data((x,round(group(x),2))) - self.add_data((x,function(x))) - - # Only have range in parent - elif self.parent is not None and len(self.parent.range) is not 0: - # Copy parent range - self.__range = self.parent.range[:] - # Clean data_list - self.__data_list = [] - # Generate values for the lambda function - for x in self.range: - #self.add_data((x,round(group(x),2))) - self.add_data((x,function(x))) - - # Don't have range anywhere - else: - # x_data don't exist - raise Exception, "Data argument is valid but to use function type please set x_range first" - - # Coordinate Lists - elif type(group) in LISTTYPES and type(group[0]) is list: - # Clean data_list - self.__data_list = [] - data = [] - if len(group) == 3: - data = zip(group[0], group[1], group[2]) - elif len(group) == 2: - data = zip(group[0], group[1]) - else: - raise TypeError, "Only one list of coordinates was received." - - for item in data: - self.add_data(item) - - else: - raise TypeError, "Group type not supported" - - return property(**locals()) - - @apply - def range(): - doc = ''' - The range is a read/write property that generates a range of values - for the x axis of the functions. When passed a tuple it almost works - like the built-in range funtion: - - 1 item, represent the end of the range started from 0; - - 2 items, represents the start and the end, respectively; - - 3 items, the last one represents the step; - - When passed a list the range function understands as a valid range. - - Usage: - >>> g = Group(); g.range = 10; print g.range - [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] - >>> g = Group(); g.range = (5); print g.range - [0.0, 1.0, 2.0, 3.0, 4.0] - >>> g = Group(); g.range = (1,7); print g.range - [1.0, 2.0, 3.0, 4.0, 5.0, 6.0] - >>> g = Group(); g.range = (0,10,2); print g.range - [0.0, 2.0, 4.0, 6.0, 8.0] - >>> - >>> g = Group(); g.range = [0]; print g.range - [0.0] - >>> g = Group(); g.range = [0,10,20]; print g.range - [0.0, 10.0, 20.0] - ''' - def fget(self): - ''' - Returns the range - ''' - return self.__range - - def fset(self, x_range): - ''' - Controls the input of a valid type and generate the range - ''' - # if passed a simple number convert to tuple - if type(x_range) in NUMTYPES: - x_range = (x_range,) - - # A list, just convert to float - if type(x_range) is list and len(x_range) > 0: - # Convert all to float - x_range = map(float, x_range) - # Prevents repeated values and convert back to list - self.__range = list(set(x_range[:])) - # Sort the list to ascending order - self.__range.sort() - - # A tuple, must check the lengths and generate the values - elif type(x_range) is tuple and len(x_range) in (1,2,3): - # Convert all to float - x_range = map(float, x_range) - - # Inital values - start = 0.0 - step = 1.0 - end = 0.0 - - # Only the end and it can't be less or iqual to 0 - if len(x_range) is 1 and x_range > 0: - end = x_range[0] - - # The start and the end but the start must be less then the end - elif len(x_range) is 2 and x_range[0] < x_range[1]: - start = x_range[0] - end = x_range[1] - - # All 3, but the start must be less then the end - elif x_range[0] <= x_range[1]: - start = x_range[0] - end = x_range[1] - step = x_range[2] - - # Starts the range - self.__range = [] - # Generate the range - # Can't use the range function because it doesn't support float values - while start < end: - self.__range.append(start) - start += step - - # Incorrect type - else: - raise Exception, "x_range must be a list with one or more items or a tuple with 2 or 3 items" - - return property(**locals()) - - def add_data(self, data, name=None): - ''' - Append a new data to the data_list. - - If data is an instance of Data, append it - - If it's an int, float, tuple or list create an instance of Data and append it - - Usage: - >>> g = Group() - >>> g.add_data(12); print g - ['12'] - >>> g.add_data(7,'other'); print g - ['12', 'other: 7'] - >>> - >>> g = Group() - >>> g.add_data((1,1),'a'); print g - ['a: (1, 1)'] - >>> g.add_data((2,2),'b'); print g - ['a: (1, 1)', 'b: (2, 2)'] - >>> - >>> g.add_data(Data((1,2),'c')); print g - ['a: (1, 1)', 'b: (2, 2)', 'c: (1, 2)'] - ''' - if not isinstance(data, Data): - # Try to convert - data = Data(data,name,self) - - if data.content is not None: - self.__data_list.append(data.copy()) - self.__data_list[-1].parent = self - - - def to_list(self): - ''' - Returns the group as a list of numbers (int, float or long) or a - list of tuples (points 2D or 3D). - - Usage: - >>> g = Group([1,2,3,4],'g1'); g.to_list() - [1, 2, 3, 4] - >>> g = Group([(1,2),(2,3),(3,4)],'g2'); g.to_list() - [(1, 2), (2, 3), (3, 4)] - >>> g = Group([(1,2,3),(3,4,5)],'g2'); g.to_list() - [(1, 2, 3), (3, 4, 5)] - ''' - return [data.content for data in self] - - def copy(self): - ''' - Returns a copy of this group - ''' - new_group = Group() - new_group.__name = self.__name - if self.__range is not None: - new_group.__range = self.__range[:] - for data in self: - new_group.add_data(data.copy()) - return new_group - - def get_names(self): - ''' - Return a list with the names of all data in this group - ''' - names = [] - for data in self: - if data.name is None: - names.append('Data '+str(data.index()+1)) - else: - names.append(data.name) - return names - - - def __str__ (self): - ''' - Returns a string representing the Group - ''' - ret = "" - if self.name is not None: - ret += self.name + " " - if len(self) > 0: - list_str = [str(item) for item in self] - ret += str(list_str) - else: - ret += "[]" - return ret - - def __getitem__(self, key): - ''' - Makes a Group iterable, based in the data_list property - ''' - return self.data_list[key] - - def __len__(self): - ''' - Returns the length of the Group, based in the data_list property - ''' - return len(self.data_list) - - -class Colors(object): - ''' - Class that models the colors its labels (names) and its properties, RGB - and filling type. - - It can receive: - - A list where each item is a list with 3 or 4 items. The - first 3 items represent the RGB values and the last argument - defines the filling type. The list will be converted to a dict - and each color will receve a name based in its position in the - list. - - A dictionary where each key will be the color name and its item - can be a list with 3 or 4 items. The first 3 items represent - the RGB colors and the last argument defines the filling type. - ''' - def __init__(self, color_list=None): - ''' - Start the color_list property - @ color_list - the list or dict contaning the colors properties. - ''' - self.__color_list = None - - self.color_list = color_list - - @apply - def color_list(): - doc = ''' - >>> c = Colors([[1,1,1],[2,2,2,'linear'],[3,3,3,'gradient']]) - >>> print c.color_list - {'Color 2': [2, 2, 2, 'linear'], 'Color 3': [3, 3, 3, 'gradient'], 'Color 1': [1, 1, 1, 'solid']} - >>> c.color_list = [[1,1,1],(2,2,2,'solid'),(3,3,3,'linear')] - >>> print c.color_list - {'Color 2': [2, 2, 2, 'solid'], 'Color 3': [3, 3, 3, 'linear'], 'Color 1': [1, 1, 1, 'solid']} - >>> c.color_list = {'a':[1,1,1],'b':(2,2,2,'solid'),'c':(3,3,3,'linear'), 'd':(4,4,4)} - >>> print c.color_list - {'a': [1, 1, 1, 'solid'], 'c': [3, 3, 3, 'linear'], 'b': [2, 2, 2, 'solid'], 'd': [4, 4, 4, 'solid']} - ''' - def fget(self): - ''' - Return the color list - ''' - return self.__color_list - - def fset(self, color_list): - ''' - Format the color list to a dictionary - ''' - if color_list is None: - self.__color_list = None - return - - if type(color_list) in LISTTYPES and type(color_list[0]) in LISTTYPES: - old_color_list = color_list[:] - color_list = {} - for index, color in enumerate(old_color_list): - if len(color) is 3 and max(map(type, color)) in NUMTYPES: - color_list['Color '+str(index+1)] = list(color)+[DEFAULT_COLOR_FILLING] - elif len(color) is 4 and max(map(type, color[:-1])) in NUMTYPES and color[-1] in FILLING_TYPES: - color_list['Color '+str(index+1)] = list(color) - else: - raise TypeError, "Unsuported color format" - elif type(color_list) is not dict: - raise TypeError, "Unsuported color format" - - for name, color in color_list.items(): - if len(color) is 3: - if max(map(type, color)) in NUMTYPES: - color_list[name] = list(color)+[DEFAULT_COLOR_FILLING] - else: - raise TypeError, "Unsuported color format" - elif len(color) is 4: - if max(map(type, color[:-1])) in NUMTYPES and color[-1] in FILLING_TYPES: - color_list[name] = list(color) - else: - raise TypeError, "Unsuported color format" - self.__color_list = color_list.copy() - - return property(**locals()) - - -class Series(object): - ''' - Class that models a Series (group of groups). Every value (int, float, - long, tuple or list) passed is converted to a list of Group or Data. - It can receive: - - a single number or point, will be converted to a Group of one Data; - - a list of numbers, will be converted to a group of numbers; - - a list of tuples, will converted to a single Group of points; - - a list of lists of numbers, each 'sublist' will be converted to a - group of numbers; - - a list of lists of tuples, each 'sublist' will be converted to a - group of points; - - a list of lists of lists, the content of the 'sublist' will be - processed as coordinated lists and the result will be converted to - a group of points; - - a Dictionary where each item can be the same of the list: number, - point, list of numbers, list of points or list of lists (coordinated - lists); - - an instance of Data; - - an instance of group. - ''' - def __init__(self, series=None, name=None, property=[], colors=None): - ''' - Starts main atributes in Group instance. - @series - a list, dict of data of which the series is composed; - @name - name of the series; - @property - a list/dict of properties to be used in the plots of - this Series - - Usage: - >>> print Series([1,2,3,4]) - ["Group 1 ['1', '2', '3', '4']"] - >>> print Series([[1,2,3],[4,5,6]]) - ["Group 1 ['1', '2', '3']", "Group 2 ['4', '5', '6']"] - >>> print Series((1,2)) - ["Group 1 ['(1, 2)']"] - >>> print Series([(1,2),(2,3)]) - ["Group 1 ['(1, 2)', '(2, 3)']"] - >>> print Series([[(1,2),(2,3)],[(4,5),(5,6)]]) - ["Group 1 ['(1, 2)', '(2, 3)']", "Group 2 ['(4, 5)', '(5, 6)']"] - >>> print Series([[[1,2,3],[1,2,3],[1,2,3]]]) - ["Group 1 ['(1, 1, 1)', '(2, 2, 2)', '(3, 3, 3)']"] - >>> print Series({'g1':[1,2,3], 'g2':[4,5,6]}) - ["g1 ['1', '2', '3']", "g2 ['4', '5', '6']"] - >>> print Series({'g1':[(1,2),(2,3)], 'g2':[(4,5),(5,6)]}) - ["g1 ['(1, 2)', '(2, 3)']", "g2 ['(4, 5)', '(5, 6)']"] - >>> print Series({'g1':[[1,2],[1,2]], 'g2':[[4,5],[4,5]]}) - ["g1 ['(1, 1)', '(2, 2)']", "g2 ['(4, 4)', '(5, 5)']"] - >>> print Series(Data(1,'d1')) - ["Group 1 ['d1: 1']"] - >>> print Series(Group([(1,2),(2,3)],'g1')) - ["g1 ['(1, 2)', '(2, 3)']"] - ''' - # Intial values - self.__group_list = [] - self.__name = None - self.__range = None - - # TODO: Implement colors with filling - self.__colors = None - - self.name = name - self.group_list = series - self.colors = colors - - # Name property - @apply - def name(): - doc = ''' - Name is a read/write property that controls the input of name. - - If passed an invalid value it cleans the name with None - - Usage: - >>> s = Series(13); s.name = 'name_test'; print s - name_test ["Group 1 ['13']"] - >>> s.name = 11; print s - ["Group 1 ['13']"] - >>> s.name = 'other_name'; print s - other_name ["Group 1 ['13']"] - >>> s.name = None; print s - ["Group 1 ['13']"] - >>> s.name = 'last_name'; print s - last_name ["Group 1 ['13']"] - >>> s.name = ''; print s - ["Group 1 ['13']"] - ''' - def fget(self): - ''' - Returns the name as a string - ''' - return self.__name - - def fset(self, name): - ''' - Sets the name of the Group - ''' - if type(name) in STRTYPES and len(name) > 0: - self.__name = name - else: - self.__name = None - - return property(**locals()) - - - - # Colors property - @apply - def colors(): - doc = ''' - >>> s = Series() - >>> s.colors = [[1,1,1],[2,2,2,'linear'],[3,3,3,'gradient']] - >>> print s.colors - {'Color 2': [2, 2, 2, 'linear'], 'Color 3': [3, 3, 3, 'gradient'], 'Color 1': [1, 1, 1, 'solid']} - >>> s.colors = [[1,1,1],(2,2,2,'solid'),(3,3,3,'linear')] - >>> print s.colors - {'Color 2': [2, 2, 2, 'solid'], 'Color 3': [3, 3, 3, 'linear'], 'Color 1': [1, 1, 1, 'solid']} - >>> s.colors = {'a':[1,1,1],'b':(2,2,2,'solid'),'c':(3,3,3,'linear'), 'd':(4,4,4)} - >>> print s.colors - {'a': [1, 1, 1, 'solid'], 'c': [3, 3, 3, 'linear'], 'b': [2, 2, 2, 'solid'], 'd': [4, 4, 4, 'solid']} - ''' - def fget(self): - ''' - Return the color list - ''' - return self.__colors.color_list - - def fset(self, colors): - ''' - Format the color list to a dictionary - ''' - self.__colors = Colors(colors) - - return property(**locals()) - - @apply - def range(): - doc = ''' - The range is a read/write property that generates a range of values - for the x axis of the functions. When passed a tuple it almost works - like the built-in range funtion: - - 1 item, represent the end of the range started from 0; - - 2 items, represents the start and the end, respectively; - - 3 items, the last one represents the step; - - When passed a list the range function understands as a valid range. - - Usage: - >>> s = Series(); s.range = 10; print s.range - [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0] - >>> s = Series(); s.range = (5); print s.range - [0.0, 1.0, 2.0, 3.0, 4.0, 5.0] - >>> s = Series(); s.range = (1,7); print s.range - [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] - >>> s = Series(); s.range = (0,10,2); print s.range - [0.0, 2.0, 4.0, 6.0, 8.0, 10.0] - >>> - >>> s = Series(); s.range = [0]; print s.range - [0.0] - >>> s = Series(); s.range = [0,10,20]; print s.range - [0.0, 10.0, 20.0] - ''' - def fget(self): - ''' - Returns the range - ''' - return self.__range - - def fset(self, x_range): - ''' - Controls the input of a valid type and generate the range - ''' - # if passed a simple number convert to tuple - if type(x_range) in NUMTYPES: - x_range = (x_range,) - - # A list, just convert to float - if type(x_range) is list and len(x_range) > 0: - # Convert all to float - x_range = map(float, x_range) - # Prevents repeated values and convert back to list - self.__range = list(set(x_range[:])) - # Sort the list to ascending order - self.__range.sort() - - # A tuple, must check the lengths and generate the values - elif type(x_range) is tuple and len(x_range) in (1,2,3): - # Convert all to float - x_range = map(float, x_range) - - # Inital values - start = 0.0 - step = 1.0 - end = 0.0 - - # Only the end and it can't be less or iqual to 0 - if len(x_range) is 1 and x_range > 0: - end = x_range[0] - - # The start and the end but the start must be lesser then the end - elif len(x_range) is 2 and x_range[0] < x_range[1]: - start = x_range[0] - end = x_range[1] - - # All 3, but the start must be lesser then the end - elif x_range[0] < x_range[1]: - start = x_range[0] - end = x_range[1] - step = x_range[2] - - # Starts the range - self.__range = [] - # Generate the range - # Cnat use the range function becouse it don't suport float values - while start <= end: - self.__range.append(start) - start += step - - # Incorrect type - else: - raise Exception, "x_range must be a list with one or more item or a tuple with 2 or 3 items" - - return property(**locals()) - - @apply - def group_list(): - doc = ''' - The group_list is a read/write property used to pre-process the list - of Groups. - It can be: - - a single number, point or lambda, will be converted to a single - Group of one Data; - - a list of numbers, will be converted to a group of numbers; - - a list of tuples, will converted to a single Group of points; - - a list of lists of numbers, each 'sublist' will be converted to - a group of numbers; - - a list of lists of tuples, each 'sublist' will be converted to a - group of points; - - a list of lists of lists, the content of the 'sublist' will be - processed as coordinated lists and the result will be converted - to a group of points; - - a list of lambdas, each lambda represents a Group; - - a Dictionary where each item can be the same of the list: number, - point, list of numbers, list of points, list of lists - (coordinated lists) or lambdas - - an instance of Data; - - an instance of group. - - Usage: - >>> s = Series() - >>> s.group_list = [1,2,3,4]; print s - ["Group 1 ['1', '2', '3', '4']"] - >>> s.group_list = [[1,2,3],[4,5,6]]; print s - ["Group 1 ['1', '2', '3']", "Group 2 ['4', '5', '6']"] - >>> s.group_list = (1,2); print s - ["Group 1 ['(1, 2)']"] - >>> s.group_list = [(1,2),(2,3)]; print s - ["Group 1 ['(1, 2)', '(2, 3)']"] - >>> s.group_list = [[(1,2),(2,3)],[(4,5),(5,6)]]; print s - ["Group 1 ['(1, 2)', '(2, 3)']", "Group 2 ['(4, 5)', '(5, 6)']"] - >>> s.group_list = [[[1,2,3],[1,2,3],[1,2,3]]]; print s - ["Group 1 ['(1, 1, 1)', '(2, 2, 2)', '(3, 3, 3)']"] - >>> s.group_list = [(0.5,5.5) , [(0,4),(6,8)] , (5.5,7) , (7,9)]; print s - ["Group 1 ['(0.5, 5.5)']", "Group 2 ['(0, 4)', '(6, 8)']", "Group 3 ['(5.5, 7)']", "Group 4 ['(7, 9)']"] - >>> s.group_list = {'g1':[1,2,3], 'g2':[4,5,6]}; print s - ["g1 ['1', '2', '3']", "g2 ['4', '5', '6']"] - >>> s.group_list = {'g1':[(1,2),(2,3)], 'g2':[(4,5),(5,6)]}; print s - ["g1 ['(1, 2)', '(2, 3)']", "g2 ['(4, 5)', '(5, 6)']"] - >>> s.group_list = {'g1':[[1,2],[1,2]], 'g2':[[4,5],[4,5]]}; print s - ["g1 ['(1, 1)', '(2, 2)']", "g2 ['(4, 4)', '(5, 5)']"] - >>> s.range = 10 - >>> s.group_list = lambda x:x*2 - >>> s.group_list = [lambda x:x*2, lambda x:x**2, lambda x:x**3]; print s - ["Group 1 ['(0.0, 0.0)', '(1.0, 2.0)', '(2.0, 4.0)', '(3.0, 6.0)', '(4.0, 8.0)', '(5.0, 10.0)', '(6.0, 12.0)', '(7.0, 14.0)', '(8.0, 16.0)', '(9.0, 18.0)', '(10.0, 20.0)']", "Group 2 ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 4.0)', '(3.0, 9.0)', '(4.0, 16.0)', '(5.0, 25.0)', '(6.0, 36.0)', '(7.0, 49.0)', '(8.0, 64.0)', '(9.0, 81.0)', '(10.0, 100.0)']", "Group 3 ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 8.0)', '(3.0, 27.0)', '(4.0, 64.0)', '(5.0, 125.0)', '(6.0, 216.0)', '(7.0, 343.0)', '(8.0, 512.0)', '(9.0, 729.0)', '(10.0, 1000.0)']"] - >>> s.group_list = {'linear':lambda x:x*2, 'square':lambda x:x**2, 'cubic':lambda x:x**3}; print s - ["cubic ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 8.0)', '(3.0, 27.0)', '(4.0, 64.0)', '(5.0, 125.0)', '(6.0, 216.0)', '(7.0, 343.0)', '(8.0, 512.0)', '(9.0, 729.0)', '(10.0, 1000.0)']", "linear ['(0.0, 0.0)', '(1.0, 2.0)', '(2.0, 4.0)', '(3.0, 6.0)', '(4.0, 8.0)', '(5.0, 10.0)', '(6.0, 12.0)', '(7.0, 14.0)', '(8.0, 16.0)', '(9.0, 18.0)', '(10.0, 20.0)']", "square ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 4.0)', '(3.0, 9.0)', '(4.0, 16.0)', '(5.0, 25.0)', '(6.0, 36.0)', '(7.0, 49.0)', '(8.0, 64.0)', '(9.0, 81.0)', '(10.0, 100.0)']"] - >>> s.group_list = Data(1,'d1'); print s - ["Group 1 ['d1: 1']"] - >>> s.group_list = Group([(1,2),(2,3)],'g1'); print s - ["g1 ['(1, 2)', '(2, 3)']"] - ''' - def fget(self): - ''' - Return the group list. - ''' - return self.__group_list - - def fset(self, series): - ''' - Controls the input of a valid group list. - ''' - #TODO: Add support to the following strem of data: [ (0.5,5.5) , [(0,4),(6,8)] , (5.5,7) , (7,9)] - - # Type: None - if series is None: - self.__group_list = [] - - # List or Tuple - elif type(series) in LISTTYPES: - self.__group_list = [] - - is_function = lambda x: callable(x) - # Groups - if list in map(type, series) or max(map(is_function, series)): - for group in series: - self.add_group(group) - - # single group - else: - self.add_group(series) - - #old code - ## List of numbers - #if type(series[0]) in NUMTYPES or type(series[0]) is tuple: - # print series - # self.add_group(series) - # - ## List of anything else - #else: - # for group in series: - # self.add_group(group) - - # Dict representing series of groups - elif type(series) is dict: - self.__group_list = [] - names = series.keys() - names.sort() - for name in names: - self.add_group(Group(series[name],name,self)) - - # A single lambda - elif callable(series): - self.__group_list = [] - self.add_group(series) - - # Int/float, instance of Group or Data - elif type(series) in NUMTYPES or isinstance(series, Group) or isinstance(series, Data): - self.__group_list = [] - self.add_group(series) - - # Default - else: - raise TypeError, "Serie type not supported" - - return property(**locals()) - - def add_group(self, group, name=None): - ''' - Append a new group in group_list - ''' - if not isinstance(group, Group): - #Try to convert - group = Group(group, name, self) - - if len(group.data_list) is not 0: - # Auto naming groups - if group.name is None: - group.name = "Group "+str(len(self.__group_list)+1) - - self.__group_list.append(group) - self.__group_list[-1].parent = self - - def copy(self): - ''' - Returns a copy of the Series - ''' - new_series = Series() - new_series.__name = self.__name - if self.__range is not None: - new_series.__range = self.__range[:] - #Add color property in the copy method - #self.__colors = None - - for group in self: - new_series.add_group(group.copy()) - - return new_series - - def get_names(self): - ''' - Returns a list of the names of all groups in the Serie - ''' - names = [] - for group in self: - if group.name is None: - names.append('Group '+str(group.index()+1)) - else: - names.append(group.name) - - return names - - def to_list(self): - ''' - Returns a list with the content of all groups and data - ''' - big_list = [] - for group in self: - for data in group: - if type(data.content) in NUMTYPES: - big_list.append(data.content) - else: - big_list = big_list + list(data.content) - return big_list - - def __getitem__(self, key): - ''' - Makes the Series iterable, based in the group_list property - ''' - return self.__group_list[key] - - def __str__(self): - ''' - Returns a string that represents the Series - ''' - ret = "" - if self.name is not None: - ret += self.name + " " - if len(self) > 0: - list_str = [str(item) for item in self] - ret += str(list_str) - else: - ret += "[]" - return ret - - def __len__(self): - ''' - Returns the length of the Series, based in the group_lsit property - ''' - return len(self.group_list) - - -if __name__ == '__main__': - doctest.testmod() diff --git a/bindings/python/examples/python2/eventcount.py b/bindings/python/examples/python2/eventcount.py new file mode 100755 index 0000000..079633c --- /dev/null +++ b/bindings/python/examples/python2/eventcount.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python2 +# eventcount.py +# +# Babeltrace event count example script +# +# Copyright 2012 EfficiOS Inc. +# +# Author: Danny Serres +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# The script prints a count of specified events and +# their related tid's in a given trace. +# The trace needs TID context (lttng add-context -k -t tid) + +import sys +from babeltrace import * +from output_format_modules.pprint_table import pprint_table as pprint + +if len(sys.argv) < 3: + raise TypeError("Usage: python eventcount.py event1 [event2 ...] path/to/trace") + +ctx = Context() +ret = ctx.add_trace(sys.argv[len(sys.argv)-1], "ctf") +if ret is None: + raise IOError("Error adding trace") + +counts = {} + +# Setting iterator +bp = IterPos(SEEK_BEGIN) +ctf_it = ctf.Iterator(ctx, bp) + +# Reading events +event = ctf_it.read_event() +while(event is not None): + for event_type in sys.argv[1:len(sys.argv)-1]: + if event_type == event.get_name(): + + # Getting scope definition + sco = event.get_top_level_scope(ctf.scope.STREAM_EVENT_CONTEXT) + if sco is None: + print("ERROR: Cannot get definition scope for {}".format( + event.get_name())) + continue + + # Getting TID + tid_field = event.get_field(sco, "_tid") + tid = tid_field.get_int64() + + if ctf.field_error(): + print("ERROR: Missing TID info for {}".format( + event.get_name())) + continue + + tmp = (tid, event.get_name()) + + if tmp in counts: + counts[tmp] += 1 + else: + counts[tmp] = 1 + + # Next event + ret = ctf_it.next() + if ret < 0: + break + event = ctf_it.read_event() + +del ctf_it + +# Appending data to table for output +table = [] +for item in counts: + table.append([item[0], item[1], counts[item]]) +table = sorted(table) +table.insert(0,["TID", "EVENT", "COUNT"]) +pprint(table, 2) diff --git a/bindings/python/examples/python2/eventcountlist.py b/bindings/python/examples/python2/eventcountlist.py new file mode 100755 index 0000000..1b42b4e --- /dev/null +++ b/bindings/python/examples/python2/eventcountlist.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python2 +# eventcountlist.py +# +# Babeltrace event count list example script +# +# Copyright 2012 EfficiOS Inc. +# +# Author: Danny Serres +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# The script prints a count and rate of events. +# It also outputs a bar graph of count per event, using the cairoplot module. + +import sys +from babeltrace import * +from output_format_modules import cairoplot +from output_format_modules.pprint_table import pprint_table as pprint + +# Check for path arg: +if len(sys.argv) < 2: + raise TypeError("Usage: python eventcountlist.py path/to/trace") + +ctx = Context() +ret = ctx.add_trace(sys.argv[1], "ctf") +if ret is None: + raise IOError("Error adding trace") + +# Events and their assossiated count +# will be stored as a dict: +events_count = {} + +# Setting iterator: +bp = IterPos(SEEK_BEGIN) +ctf_it = ctf.Iterator(ctx,bp) + +prev_event = None +event = ctf_it.read_event() + +start_time = event.get_timestamp() + +# Reading events: +while(event is not None): + if event.get_name() in events_count: + events_count[event.get_name()] += 1 + else: + events_count[event.get_name()] = 1 + + ret = ctf_it.next() + if ret < 0: + break + else: + prev_event = event + event = ctf_it.read_event() + +if event: + total_time = event.get_timestamp() - start_time +else: + total_time = prev_event.get_timestamp() - start_time + +del ctf_it + +# Printing encountered events with respective count and rate: +print("Total time: {} ns".format(total_time)) +table = [["EVENT", "COUNT", "RATE (Hz)"]] +for item in sorted(events_count.iterkeys()): + tmp = [item, events_count[item], + events_count[item]/(total_time/1000000000.0)] + table.append(tmp) +pprint(table) + +# Exporting data as bar graph +cairoplot.vertical_bar_plot ( 'eventcountlist.svg', events_count, 50+85*len(events_count), + 800, border = 20, display_values = True, grid = True, + rounded_corners = True, + x_labels = sorted(events_count.keys()) ) diff --git a/bindings/python/examples/python2/events_per_cpu.py b/bindings/python/examples/python2/events_per_cpu.py new file mode 100755 index 0000000..6425b2d --- /dev/null +++ b/bindings/python/examples/python2/events_per_cpu.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python2 +# events_per_cpu.py +# +# Babeltrace events per cpu example script +# +# Copyright 2012 EfficiOS Inc. +# +# Author: Danny Serres +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# The script opens a trace and prints out CPU statistics +# for the given trace (event count per CPU, total active +# time and % of time processing events). +# It also outputs a .txt file showing each time interval +# (since the beginning of the trace) in which each CPU +# was active and the corresponding event. + +import sys, multiprocessing +from output_format_modules.pprint_table import pprint_table as pprint +from babeltrace import * + +if len(sys.argv) < 2: + raise TypeError("Usage: python events_per_cpu.py path/to/trace") + +# Adding trace +ctx = Context() +ret = ctx.add_trace(sys.argv[1], "ctf") +if ret is None: + raise IOError("Error adding trace") + +cpu_usage = [] +nbEvents = 0 +i = 0 +while i < multiprocessing.cpu_count(): + cpu_usage.append([]) + i += 1 + +# Setting iterator +bp = IterPos(SEEK_BEGIN) +ctf_it = ctf.Iterator(ctx, bp) + +# Reading events +event = ctf_it.read_event() +start_time = event.get_timestamp() + +while(event is not None): + + event_name = event.get_name() + ts = event.get_timestamp() + + # Getting cpu_id + scope = event.get_top_level_scope(ctf.scope.STREAM_PACKET_CONTEXT) + field = event.get_field(scope, "cpu_id") + cpu_id = field.get_uint64() + if ctf.field_error(): + print("ERROR: Missing cpu_id info for {}".format(event.get_name())) + else: + cpu_usage[cpu_id].append( (int(ts), event_name) ) + nbEvents += 1 + + # Next Event + ret = ctf_it.next() + if ret < 0: + break + event = ctf_it.read_event() + + +# Outputting +table = [] +output = open("events_per_cpu.txt", "wt") +output.write("(timestamp, event)\n") + +for cpu in range(len(cpu_usage)): + # Setting table + event_str = str(100.0 * len(cpu_usage[cpu]) / nbEvents) + '000' + # % is printed with 2 decimals + table.append([cpu, len(cpu_usage[cpu]), event_str[0:event_str.find('.') + 3] + ' %']) + + # Writing to file + output.write("\n\n\n----------------------\n") + output.write("CPU {}\n\n".format(cpu)) + for event in cpu_usage[cpu]: + output.write(str(event) + '\n') + +# Printing table +table.insert(0, ["CPU ID", "EVENT COUNT", "TRACE EVENT %"]) +pprint(table) +print("Total event count: {}".format(nbEvents)) +print("Total trace time: {} ns".format(ts - start_time)) + +output.close() diff --git a/bindings/python/examples/python2/histogram.py b/bindings/python/examples/python2/histogram.py new file mode 100755 index 0000000..09618cb --- /dev/null +++ b/bindings/python/examples/python2/histogram.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python2 +# histogram.py +# +# Babeltrace histogram example script +# +# Copyright 2012 EfficiOS Inc. +# +# Author: Danny Serres +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# The script checks the number of events in the trace +# and outputs a table and a .svg histogram for the specified +# range (microseconds) or the total trace if no range specified. +# The graph is generated using the cairoplot module. + +import sys +from babeltrace import * +from output_format_modules import cairoplot +from output_format_modules.pprint_table import pprint_table as pprint + +# ------------------------------------------------ +# Output settings + +# number of intervals: +nbDiv = 25 # Should not be over 150 + # for usable graph output + +# table output stream (file-like object): +out = sys.stdout +# ------------------------------------------------- + +if len(sys.argv) < 2 or len(sys.argv) > 4: + raise TypeError("Usage: python histogram.py [ start_time [end_time] ] path/to/trace") + +ctx = Context() +ret = ctx.add_trace(sys.argv[len(sys.argv)-1], "ctf") +if ret is None: + raise IOError("Error adding trace") + +# Check when to start/stop graphing +sinceBegin = True +beginTime = 0.0 +if len(sys.argv) > 2: + sinceBegin = False + beginTime = float(sys.argv[1]) +untilEnd = True +if len(sys.argv) == 4: + untilEnd = False + +# Setting iterator +bp = IterPos(SEEK_BEGIN) +ctf_it = ctf.Iterator(ctx, bp) + +# Reading events +event = ctf_it.read_event() +start_time = event.get_timestamp() +time = 0 +count = {} + +while(event is not None): + # Microsec. + time = (event.get_timestamp() - start_time)/1000.0 + + # Check if in range + if not sinceBegin: + if time < beginTime: + # Next Event + ret = ctf_it.next() + if ret < 0: + break + event = ctf_it.read_event() + continue + if not untilEnd: + if time > float(sys.argv[2]): + break + + # Counting events per timestamp: + if time in count: + count[time] += 1 + else: + count[time] = 1 + + # Next Event + ret = ctf_it.next() + if ret < 0: + break + event = ctf_it.read_event() + +del ctf_it + +# Setting data for output +interval = (time - beginTime)/nbDiv +div_begin_time = beginTime +div_end_time = beginTime + interval +data = {} + +# Prefix for string sorting, considering +# there should not be over 150 intervals. +# This would work up to 9999 intervals. +# If needed, add zeros. +prefix = 0.0001 + +while div_end_time <= time: + key = str(prefix) + '[' + str(div_begin_time) + ';' + str(div_end_time) + '[' + for tmp in count: + if tmp >= div_begin_time and tmp < div_end_time: + if key in data: + data[key] += count[tmp] + else: + data[key] = count[tmp] + if not key in data: + data[key] = 0 + div_begin_time = div_end_time + div_end_time += interval + # Prefix increment + prefix += 0.001 + +table = [] +x_labels = [] +for key in sorted(data): + table.append([key[key.find('['):], data[key]]) + x_labels.append(key[key.find('['):]) + +# Table output +table.insert(0, ["INTERVAL (us)", "COUNT"]) +pprint(table, 1, out) + +# Graph output +cairoplot.vertical_bar_plot ( 'histogram.svg', data, 50 + 150*nbDiv, 50*nbDiv, + border = 20, display_values = True, grid = True, + x_labels = x_labels, rounded_corners = True ) diff --git a/bindings/python/examples/python2/output_format_modules/cairoplot.py b/bindings/python/examples/python2/output_format_modules/cairoplot.py new file mode 100644 index 0000000..a27113f --- /dev/null +++ b/bindings/python/examples/python2/output_format_modules/cairoplot.py @@ -0,0 +1,2336 @@ +?#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# CairoPlot.py +# +# Copyright (c) 2008 Rodrigo Moreira Ara?jo +# +# Author: Rodrigo Moreiro Araujo +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser 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 Lesser 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 + +#Contributor: Jo?o S. O. Bueno + +#TODO: review BarPlot Code +#TODO: x_label colision problem on Horizontal Bar Plot +#TODO: y_label's eat too much space on HBP + + +__version__ = 1.2 + +import cairo +import math +import random +from series import Series, Group, Data + +HORZ = 0 +VERT = 1 +NORM = 2 + +COLORS = {"red" : (1.0,0.0,0.0,1.0), "lime" : (0.0,1.0,0.0,1.0), "blue" : (0.0,0.0,1.0,1.0), + "maroon" : (0.5,0.0,0.0,1.0), "green" : (0.0,0.5,0.0,1.0), "navy" : (0.0,0.0,0.5,1.0), + "yellow" : (1.0,1.0,0.0,1.0), "magenta" : (1.0,0.0,1.0,1.0), "cyan" : (0.0,1.0,1.0,1.0), + "orange" : (1.0,0.5,0.0,1.0), "white" : (1.0,1.0,1.0,1.0), "black" : (0.0,0.0,0.0,1.0), + "gray" : (0.5,0.5,0.5,1.0), "light_gray" : (0.9,0.9,0.9,1.0), + "transparent" : (0.0,0.0,0.0,0.0)} + +THEMES = {"black_red" : [(0.0,0.0,0.0,1.0), (1.0,0.0,0.0,1.0)], + "red_green_blue" : [(1.0,0.0,0.0,1.0), (0.0,1.0,0.0,1.0), (0.0,0.0,1.0,1.0)], + "red_orange_yellow" : [(1.0,0.2,0.0,1.0), (1.0,0.7,0.0,1.0), (1.0,1.0,0.0,1.0)], + "yellow_orange_red" : [(1.0,1.0,0.0,1.0), (1.0,0.7,0.0,1.0), (1.0,0.2,0.0,1.0)], + "rainbow" : [(1.0,0.0,0.0,1.0), (1.0,0.5,0.0,1.0), (1.0,1.0,0.0,1.0), (0.0,1.0,0.0,1.0), (0.0,0.0,1.0,1.0), (0.3, 0.0, 0.5,1.0), (0.5, 0.0, 1.0, 1.0)]} + +def colors_from_theme( theme, series_length, mode = 'solid' ): + colors = [] + if theme not in THEMES.keys() : + raise Exception, "Theme not defined" + color_steps = THEMES[theme] + n_colors = len(color_steps) + if series_length <= n_colors: + colors = [color + tuple([mode]) for color in color_steps[0:n_colors]] + else: + iterations = [(series_length - n_colors)/(n_colors - 1) for i in color_steps[:-1]] + over_iterations = (series_length - n_colors) % (n_colors - 1) + for i in range(n_colors - 1): + if over_iterations <= 0: + break + iterations[i] += 1 + over_iterations -= 1 + for index,color in enumerate(color_steps[:-1]): + colors.append(color + tuple([mode])) + if iterations[index] == 0: + continue + next_color = color_steps[index+1] + color_step = ((next_color[0] - color[0])/(iterations[index] + 1), + (next_color[1] - color[1])/(iterations[index] + 1), + (next_color[2] - color[2])/(iterations[index] + 1), + (next_color[3] - color[3])/(iterations[index] + 1)) + for i in range( iterations[index] ): + colors.append((color[0] + color_step[0]*(i+1), + color[1] + color_step[1]*(i+1), + color[2] + color_step[2]*(i+1), + color[3] + color_step[3]*(i+1), + mode)) + colors.append(color_steps[-1] + tuple([mode])) + return colors + + +def other_direction(direction): + "explicit is better than implicit" + if direction == HORZ: + return VERT + else: + return HORZ + +#Class definition + +class Plot(object): + def __init__(self, + surface=None, + data=None, + width=640, + height=480, + background=None, + border = 0, + x_labels = None, + y_labels = None, + series_colors = None): + random.seed(2) + self.create_surface(surface, width, height) + self.dimensions = {} + self.dimensions[HORZ] = width + self.dimensions[VERT] = height + self.context = cairo.Context(self.surface) + self.labels={} + self.labels[HORZ] = x_labels + self.labels[VERT] = y_labels + self.load_series(data, x_labels, y_labels, series_colors) + self.font_size = 10 + self.set_background (background) + self.border = border + self.borders = {} + self.line_color = (0.5, 0.5, 0.5) + self.line_width = 0.5 + self.label_color = (0.0, 0.0, 0.0) + self.grid_color = (0.8, 0.8, 0.8) + + def create_surface(self, surface, width=None, height=None): + self.filename = None + if isinstance(surface, cairo.Surface): + self.surface = surface + return + if not type(surface) in (str, unicode): + raise TypeError("Surface should be either a Cairo surface or a filename, not %s" % surface) + sufix = surface.rsplit(".")[-1].lower() + self.filename = surface + if sufix == "png": + self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) + elif sufix == "ps": + self.surface = cairo.PSSurface(surface, width, height) + elif sufix == "pdf": + self.surface = cairo.PSSurface(surface, width, height) + else: + if sufix != "svg": + self.filename += ".svg" + self.surface = cairo.SVGSurface(self.filename, width, height) + + def commit(self): + try: + self.context.show_page() + if self.filename and self.filename.endswith(".png"): + self.surface.write_to_png(self.filename) + else: + self.surface.finish() + except cairo.Error: + pass + + def load_series (self, data, x_labels=None, y_labels=None, series_colors=None): + self.series_labels = [] + self.series = None + + #The pretty way + #if not isinstance(data, Series): + # # Not an instance of Series + # self.series = Series(data) + #else: + # self.series = data + # + #self.series_labels = self.series.get_names() + + #TODO: Remove on next version + # The ugly way, keeping retrocompatibility... + if callable(data) or type(data) is list and callable(data[0]): # Lambda or List of lambdas + self.series = data + self.series_labels = None + elif isinstance(data, Series): # Instance of Series + self.series = data + self.series_labels = data.get_names() + else: # Anything else + self.series = Series(data) + self.series_labels = self.series.get_names() + + #TODO: allow user passed series_widths + self.series_widths = [1.0 for group in self.series] + + #TODO: Remove on next version + self.process_colors( series_colors ) + + def process_colors( self, series_colors, length = None, mode = 'solid' ): + #series_colors might be None, a theme, a string of colors names or a list of color tuples + if length is None : + length = len( self.series.to_list() ) + + #no colors passed + if not series_colors: + #Randomize colors + self.series_colors = [ [random.random() for i in range(3)] + [1.0, mode] for series in range( length ) ] + else: + #Just theme pattern + if not hasattr( series_colors, "__iter__" ): + theme = series_colors + self.series_colors = colors_from_theme( theme.lower(), length ) + + #Theme pattern and mode + elif not hasattr(series_colors, '__delitem__') and not hasattr( series_colors[0], "__iter__" ): + theme = series_colors[0] + mode = series_colors[1] + self.series_colors = colors_from_theme( theme.lower(), length, mode ) + + #List + else: + self.series_colors = series_colors + for index, color in enumerate( self.series_colors ): + #element is a color name + if not hasattr(color, "__iter__"): + self.series_colors[index] = COLORS[color.lower()] + tuple([mode]) + #element is rgb tuple instead of rgba + elif len( color ) == 3 : + self.series_colors[index] += (1.0,mode) + #element has 4 elements, might be rgba tuple or rgb tuple with mode + elif len( color ) == 4 : + #last element is mode + if not hasattr(color[3], "__iter__"): + self.series_colors[index] += tuple([color[3]]) + self.series_colors[index][3] = 1.0 + #last element is alpha + else: + self.series_colors[index] += tuple([mode]) + + def get_width(self): + return self.surface.get_width() + + def get_height(self): + return self.surface.get_height() + + def set_background(self, background): + if background is None: + self.background = (0.0,0.0,0.0,0.0) + elif type(background) in (cairo.LinearGradient, tuple): + self.background = background + elif not hasattr(background,"__iter__"): + colors = background.split(" ") + if len(colors) == 1 and colors[0] in COLORS: + self.background = COLORS[background] + elif len(colors) > 1: + self.background = cairo.LinearGradient(self.dimensions[HORZ] / 2, 0, self.dimensions[HORZ] / 2, self.dimensions[VERT]) + for index,color in enumerate(colors): + self.background.add_color_stop_rgba(float(index)/(len(colors)-1),*COLORS[color]) + else: + raise TypeError ("Background should be either cairo.LinearGradient or a 3/4-tuple, not %s" % type(background)) + + def render_background(self): + if isinstance(self.background, cairo.LinearGradient): + self.context.set_source(self.background) + else: + self.context.set_source_rgba(*self.background) + self.context.rectangle(0,0, self.dimensions[HORZ], self.dimensions[VERT]) + self.context.fill() + + def render_bounding_box(self): + self.context.set_source_rgba(*self.line_color) + self.context.set_line_width(self.line_width) + self.context.rectangle(self.border, self.border, + self.dimensions[HORZ] - 2 * self.border, + self.dimensions[VERT] - 2 * self.border) + self.context.stroke() + + def render(self): + pass + +class ScatterPlot( Plot ): + def __init__(self, + surface=None, + data=None, + errorx=None, + errory=None, + width=640, + height=480, + background=None, + border=0, + axis = False, + dash = False, + discrete = False, + dots = 0, + grid = False, + series_legend = False, + x_labels = None, + y_labels = None, + x_bounds = None, + y_bounds = None, + z_bounds = None, + x_title = None, + y_title = None, + series_colors = None, + circle_colors = None ): + + self.bounds = {} + self.bounds[HORZ] = x_bounds + self.bounds[VERT] = y_bounds + self.bounds[NORM] = z_bounds + self.titles = {} + self.titles[HORZ] = x_title + self.titles[VERT] = y_title + self.max_value = {} + self.axis = axis + self.discrete = discrete + self.dots = dots + self.grid = grid + self.series_legend = series_legend + self.variable_radius = False + self.x_label_angle = math.pi / 2.5 + self.circle_colors = circle_colors + + Plot.__init__(self, surface, data, width, height, background, border, x_labels, y_labels, series_colors) + + self.dash = None + if dash: + if hasattr(dash, "keys"): + self.dash = [dash[key] for key in self.series_labels] + elif max([hasattr(item,'__delitem__') for item in data]) : + self.dash = dash + else: + self.dash = [dash] + + self.load_errors(errorx, errory) + + def convert_list_to_tuple(self, data): + #Data must be converted from lists of coordinates to a single + # list of tuples + out_data = zip(*data) + if len(data) == 3: + self.variable_radius = True + return out_data + + def load_series(self, data, x_labels = None, y_labels = None, series_colors=None): + #TODO: In cairoplot 2.0 keep only the Series instances + + # Convert Data and Group to Series + if isinstance(data, Data) or isinstance(data, Group): + data = Series(data) + + # Series + if isinstance(data, Series): + for group in data: + for item in group: + if len(item) is 3: + self.variable_radius = True + + #Dictionary with lists + if hasattr(data, "keys") : + if hasattr( data.values()[0][0], "__delitem__" ) : + for key in data.keys() : + data[key] = self.convert_list_to_tuple(data[key]) + elif len(data.values()[0][0]) == 3: + self.variable_radius = True + #List + elif hasattr(data[0], "__delitem__") : + #List of lists + if hasattr(data[0][0], "__delitem__") : + for index,value in enumerate(data) : + data[index] = self.convert_list_to_tuple(value) + #List + elif type(data[0][0]) != type((0,0)): + data = self.convert_list_to_tuple(data) + #Three dimensional data + elif len(data[0][0]) == 3: + self.variable_radius = True + + #List with three dimensional tuples + elif len(data[0]) == 3: + self.variable_radius = True + Plot.load_series(self, data, x_labels, y_labels, series_colors) + self.calc_boundaries() + self.calc_labels() + + def load_errors(self, errorx, errory): + self.errors = None + if errorx == None and errory == None: + return + self.errors = {} + self.errors[HORZ] = None + self.errors[VERT] = None + #asimetric errors + if errorx and hasattr(errorx[0], "__delitem__"): + self.errors[HORZ] = errorx + #simetric errors + elif errorx: + self.errors[HORZ] = [errorx] + #asimetric errors + if errory and hasattr(errory[0], "__delitem__"): + self.errors[VERT] = errory + #simetric errors + elif errory: + self.errors[VERT] = [errory] + + def calc_labels(self): + if not self.labels[HORZ]: + amplitude = self.bounds[HORZ][1] - self.bounds[HORZ][0] + if amplitude % 10: #if horizontal labels need floating points + self.labels[HORZ] = ["%.2lf" % (float(self.bounds[HORZ][0] + (amplitude * i / 10.0))) for i in range(11) ] + else: + self.labels[HORZ] = ["%d" % (int(self.bounds[HORZ][0] + (amplitude * i / 10.0))) for i in range(11) ] + if not self.labels[VERT]: + amplitude = self.bounds[VERT][1] - self.bounds[VERT][0] + if amplitude % 10: #if vertical labels need floating points + self.labels[VERT] = ["%.2lf" % (float(self.bounds[VERT][0] + (amplitude * i / 10.0))) for i in range(11) ] + else: + self.labels[VERT] = ["%d" % (int(self.bounds[VERT][0] + (amplitude * i / 10.0))) for i in range(11) ] + + def calc_extents(self, direction): + self.context.set_font_size(self.font_size * 0.8) + self.max_value[direction] = max(self.context.text_extents(item)[2] for item in self.labels[direction]) + self.borders[other_direction(direction)] = self.max_value[direction] + self.border + 20 + + def calc_boundaries(self): + #HORZ = 0, VERT = 1, NORM = 2 + min_data_value = [0,0,0] + max_data_value = [0,0,0] + + for group in self.series: + if type(group[0].content) in (int, float, long): + group = [Data((index, item.content)) for index,item in enumerate(group)] + + for point in group: + for index, item in enumerate(point.content): + if item > max_data_value[index]: + max_data_value[index] = item + elif item < min_data_value[index]: + min_data_value[index] = item + + if not self.bounds[HORZ]: + self.bounds[HORZ] = (min_data_value[HORZ], max_data_value[HORZ]) + if not self.bounds[VERT]: + self.bounds[VERT] = (min_data_value[VERT], max_data_value[VERT]) + if not self.bounds[NORM]: + self.bounds[NORM] = (min_data_value[NORM], max_data_value[NORM]) + + def calc_all_extents(self): + self.calc_extents(HORZ) + self.calc_extents(VERT) + + self.plot_height = self.dimensions[VERT] - 2 * self.borders[VERT] + self.plot_width = self.dimensions[HORZ] - 2* self.borders[HORZ] + + self.plot_top = self.dimensions[VERT] - self.borders[VERT] + + def calc_steps(self): + #Calculates all the x, y, z and color steps + series_amplitude = [self.bounds[index][1] - self.bounds[index][0] for index in range(3)] + + if series_amplitude[HORZ]: + self.horizontal_step = float (self.plot_width) / series_amplitude[HORZ] + else: + self.horizontal_step = 0.00 + + if series_amplitude[VERT]: + self.vertical_step = float (self.plot_height) / series_amplitude[VERT] + else: + self.vertical_step = 0.00 + + if series_amplitude[NORM]: + if self.variable_radius: + self.z_step = float (self.bounds[NORM][1]) / series_amplitude[NORM] + if self.circle_colors: + self.circle_color_step = tuple([float(self.circle_colors[1][i]-self.circle_colors[0][i])/series_amplitude[NORM] for i in range(4)]) + else: + self.z_step = 0.00 + self.circle_color_step = ( 0.0, 0.0, 0.0, 0.0 ) + + def get_circle_color(self, value): + return tuple( [self.circle_colors[0][i] + value*self.circle_color_step[i] for i in range(4)] ) + + def render(self): + self.calc_all_extents() + self.calc_steps() + self.render_background() + self.render_bounding_box() + if self.axis: + self.render_axis() + if self.grid: + self.render_grid() + self.render_labels() + self.render_plot() + if self.errors: + self.render_errors() + if self.series_legend and self.series_labels: + self.render_legend() + + def render_axis(self): + #Draws both the axis lines and their titles + cr = self.context + cr.set_source_rgba(*self.line_color) + cr.move_to(self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT]) + cr.line_to(self.borders[HORZ], self.borders[VERT]) + cr.stroke() + + cr.move_to(self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT]) + cr.line_to(self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT]) + cr.stroke() + + cr.set_source_rgba(*self.label_color) + self.context.set_font_size( 1.2 * self.font_size ) + if self.titles[HORZ]: + title_width,title_height = cr.text_extents(self.titles[HORZ])[2:4] + cr.move_to( self.dimensions[HORZ]/2 - title_width/2, self.borders[VERT] - title_height/2 ) + cr.show_text( self.titles[HORZ] ) + + if self.titles[VERT]: + title_width,title_height = cr.text_extents(self.titles[VERT])[2:4] + cr.move_to( self.dimensions[HORZ] - self.borders[HORZ] + title_height/2, self.dimensions[VERT]/2 - title_width/2) + cr.save() + cr.rotate( math.pi/2 ) + cr.show_text( self.titles[VERT] ) + cr.restore() + + def render_grid(self): + cr = self.context + horizontal_step = float( self.plot_height ) / ( len( self.labels[VERT] ) - 1 ) + vertical_step = float( self.plot_width ) / ( len( self.labels[HORZ] ) - 1 ) + + x = self.borders[HORZ] + vertical_step + y = self.plot_top - horizontal_step + + for label in self.labels[HORZ][:-1]: + cr.set_source_rgba(*self.grid_color) + cr.move_to(x, self.dimensions[VERT] - self.borders[VERT]) + cr.line_to(x, self.borders[VERT]) + cr.stroke() + x += vertical_step + for label in self.labels[VERT][:-1]: + cr.set_source_rgba(*self.grid_color) + cr.move_to(self.borders[HORZ], y) + cr.line_to(self.dimensions[HORZ] - self.borders[HORZ], y) + cr.stroke() + y -= horizontal_step + + def render_labels(self): + self.context.set_font_size(self.font_size * 0.8) + self.render_horz_labels() + self.render_vert_labels() + + def render_horz_labels(self): + cr = self.context + step = float( self.plot_width ) / ( len( self.labels[HORZ] ) - 1 ) + x = self.borders[HORZ] + y = self.dimensions[VERT] - self.borders[VERT] + 5 + + # store rotation matrix from the initial state + rotation_matrix = cr.get_matrix() + rotation_matrix.rotate(self.x_label_angle) + + cr.set_source_rgba(*self.label_color) + + for item in self.labels[HORZ]: + width = cr.text_extents(item)[2] + cr.move_to(x, y) + cr.save() + cr.set_matrix(rotation_matrix) + cr.show_text(item) + cr.restore() + x += step + + def render_vert_labels(self): + cr = self.context + step = ( self.plot_height ) / ( len( self.labels[VERT] ) - 1 ) + y = self.plot_top + cr.set_source_rgba(*self.label_color) + for item in self.labels[VERT]: + width = cr.text_extents(item)[2] + cr.move_to(self.borders[HORZ] - width - 5,y) + cr.show_text(item) + y -= step + + def render_legend(self): + cr = self.context + cr.set_font_size(self.font_size) + cr.set_line_width(self.line_width) + + widest_word = max(self.series_labels, key = lambda item: self.context.text_extents(item)[2]) + tallest_word = max(self.series_labels, key = lambda item: self.context.text_extents(item)[3]) + max_width = self.context.text_extents(widest_word)[2] + max_height = self.context.text_extents(tallest_word)[3] * 1.1 + + color_box_height = max_height / 2 + color_box_width = color_box_height * 2 + + #Draw a bounding box + bounding_box_width = max_width + color_box_width + 15 + bounding_box_height = (len(self.series_labels)+0.5) * max_height + cr.set_source_rgba(1,1,1) + cr.rectangle(self.dimensions[HORZ] - self.borders[HORZ] - bounding_box_width, self.borders[VERT], + bounding_box_width, bounding_box_height) + cr.fill() + + cr.set_source_rgba(*self.line_color) + cr.set_line_width(self.line_width) + cr.rectangle(self.dimensions[HORZ] - self.borders[HORZ] - bounding_box_width, self.borders[VERT], + bounding_box_width, bounding_box_height) + cr.stroke() + + for idx,key in enumerate(self.series_labels): + #Draw color box + cr.set_source_rgba(*self.series_colors[idx][:4]) + cr.rectangle(self.dimensions[HORZ] - self.borders[HORZ] - max_width - color_box_width - 10, + self.borders[VERT] + color_box_height + (idx*max_height) , + color_box_width, color_box_height) + cr.fill() + + cr.set_source_rgba(0, 0, 0) + cr.rectangle(self.dimensions[HORZ] - self.borders[HORZ] - max_width - color_box_width - 10, + self.borders[VERT] + color_box_height + (idx*max_height), + color_box_width, color_box_height) + cr.stroke() + + #Draw series labels + cr.set_source_rgba(0, 0, 0) + cr.move_to(self.dimensions[HORZ] - self.borders[HORZ] - max_width - 5, self.borders[VERT] + ((idx+1)*max_height)) + cr.show_text(key) + + def render_errors(self): + cr = self.context + cr.rectangle(self.borders[HORZ], self.borders[VERT], self.plot_width, self.plot_height) + cr.clip() + radius = self.dots + x0 = self.borders[HORZ] - self.bounds[HORZ][0]*self.horizontal_step + y0 = self.borders[VERT] - self.bounds[VERT][0]*self.vertical_step + for index, group in enumerate(self.series): + cr.set_source_rgba(*self.series_colors[index][:4]) + for number, data in enumerate(group): + x = x0 + self.horizontal_step * data.content[0] + y = self.dimensions[VERT] - y0 - self.vertical_step * data.content[1] + if self.errors[HORZ]: + cr.move_to(x, y) + x1 = x - self.horizontal_step * self.errors[HORZ][0][number] + cr.line_to(x1, y) + cr.line_to(x1, y - radius) + cr.line_to(x1, y + radius) + cr.stroke() + if self.errors[HORZ] and len(self.errors[HORZ]) == 2: + cr.move_to(x, y) + x1 = x + self.horizontal_step * self.errors[HORZ][1][number] + cr.line_to(x1, y) + cr.line_to(x1, y - radius) + cr.line_to(x1, y + radius) + cr.stroke() + if self.errors[VERT]: + cr.move_to(x, y) + y1 = y + self.vertical_step * self.errors[VERT][0][number] + cr.line_to(x, y1) + cr.line_to(x - radius, y1) + cr.line_to(x + radius, y1) + cr.stroke() + if self.errors[VERT] and len(self.errors[VERT]) == 2: + cr.move_to(x, y) + y1 = y - self.vertical_step * self.errors[VERT][1][number] + cr.line_to(x, y1) + cr.line_to(x - radius, y1) + cr.line_to(x + radius, y1) + cr.stroke() + + + def render_plot(self): + cr = self.context + if self.discrete: + cr.rectangle(self.borders[HORZ], self.borders[VERT], self.plot_width, self.plot_height) + cr.clip() + x0 = self.borders[HORZ] - self.bounds[HORZ][0]*self.horizontal_step + y0 = self.borders[VERT] - self.bounds[VERT][0]*self.vertical_step + radius = self.dots + for number, group in enumerate (self.series): + cr.set_source_rgba(*self.series_colors[number][:4]) + for data in group : + if self.variable_radius: + radius = data.content[2]*self.z_step + if self.circle_colors: + cr.set_source_rgba( *self.get_circle_color( data.content[2]) ) + x = x0 + self.horizontal_step*data.content[0] + y = y0 + self.vertical_step*data.content[1] + cr.arc(x, self.dimensions[VERT] - y, radius, 0, 2*math.pi) + cr.fill() + else: + cr.rectangle(self.borders[HORZ], self.borders[VERT], self.plot_width, self.plot_height) + cr.clip() + x0 = self.borders[HORZ] - self.bounds[HORZ][0]*self.horizontal_step + y0 = self.borders[VERT] - self.bounds[VERT][0]*self.vertical_step + radius = self.dots + for number, group in enumerate (self.series): + last_data = None + cr.set_source_rgba(*self.series_colors[number][:4]) + for data in group : + x = x0 + self.horizontal_step*data.content[0] + y = y0 + self.vertical_step*data.content[1] + if self.dots: + if self.variable_radius: + radius = data.content[2]*self.z_step + cr.arc(x, self.dimensions[VERT] - y, radius, 0, 2*math.pi) + cr.fill() + if last_data : + old_x = x0 + self.horizontal_step*last_data.content[0] + old_y = y0 + self.vertical_step*last_data.content[1] + cr.move_to( old_x, self.dimensions[VERT] - old_y ) + cr.line_to( x, self.dimensions[VERT] - y) + cr.set_line_width(self.series_widths[number]) + + #?Display line as dash line + if self.dash and self.dash[number]: + s = self.series_widths[number] + cr.set_dash([s*3, s*3], 0) + + cr.stroke() + cr.set_dash([]) + last_data = data + +class DotLinePlot(ScatterPlot): + def __init__(self, + surface=None, + data=None, + width=640, + height=480, + background=None, + border=0, + axis = False, + dash = False, + dots = 0, + grid = False, + series_legend = False, + x_labels = None, + y_labels = None, + x_bounds = None, + y_bounds = None, + x_title = None, + y_title = None, + series_colors = None): + + ScatterPlot.__init__(self, surface, data, None, None, width, height, background, border, + axis, dash, False, dots, grid, series_legend, x_labels, y_labels, + x_bounds, y_bounds, None, x_title, y_title, series_colors, None ) + + + def load_series(self, data, x_labels = None, y_labels = None, series_colors=None): + Plot.load_series(self, data, x_labels, y_labels, series_colors) + for group in self.series : + for index,data in enumerate(group): + group[index].content = (index, data.content) + + self.calc_boundaries() + self.calc_labels() + +class FunctionPlot(ScatterPlot): + def __init__(self, + surface=None, + data=None, + width=640, + height=480, + background=None, + border=0, + axis = False, + discrete = False, + dots = 0, + grid = False, + series_legend = False, + x_labels = None, + y_labels = None, + x_bounds = None, + y_bounds = None, + x_title = None, + y_title = None, + series_colors = None, + step = 1): + + self.function = data + self.step = step + self.discrete = discrete + + data, x_bounds = self.load_series_from_function( self.function, x_bounds ) + + ScatterPlot.__init__(self, surface, data, None, None, width, height, background, border, + axis, False, discrete, dots, grid, series_legend, x_labels, y_labels, + x_bounds, y_bounds, None, x_title, y_title, series_colors, None ) + + def load_series(self, data, x_labels = None, y_labels = None, series_colors=None): + Plot.load_series(self, data, x_labels, y_labels, series_colors) + + if len(self.series[0][0]) is 1: + for group_id, group in enumerate(self.series) : + for index,data in enumerate(group): + group[index].content = (self.bounds[HORZ][0] + self.step*index, data.content) + + self.calc_boundaries() + self.calc_labels() + + def load_series_from_function( self, function, x_bounds ): + #TODO: Add the possibility for the user to define multiple functions with different discretization parameters + + #This function converts a function, a list of functions or a dictionary + #of functions into its corresponding array of data + series = Series() + + if isinstance(function, Group) or isinstance(function, Data): + function = Series(function) + + # If is instance of Series + if isinstance(function, Series): + # Overwrite any bounds passed by the function + x_bounds = (function.range[0],function.range[-1]) + + #if no bounds are provided + if x_bounds == None: + x_bounds = (0,10) + + + #TODO: Finish the dict translation + if hasattr(function, "keys"): #dictionary: + for key in function.keys(): + group = Group(name=key) + #data[ key ] = [] + i = x_bounds[0] + while i <= x_bounds[1] : + group.add_data(function[ key ](i)) + #data[ key ].append( function[ key ](i) ) + i += self.step + series.add_group(group) + + elif hasattr(function, "__delitem__"): #list of functions + for index,f in enumerate( function ) : + group = Group() + #data.append( [] ) + i = x_bounds[0] + while i <= x_bounds[1] : + group.add_data(f(i)) + #data[ index ].append( f(i) ) + i += self.step + series.add_group(group) + + elif isinstance(function, Series): # instance of Series + series = function + + else: #function + group = Group() + i = x_bounds[0] + while i <= x_bounds[1] : + group.add_data(function(i)) + i += self.step + series.add_group(group) + + + return series, x_bounds + + def calc_labels(self): + if not self.labels[HORZ]: + self.labels[HORZ] = [] + i = self.bounds[HORZ][0] + while i<=self.bounds[HORZ][1]: + self.labels[HORZ].append(str(i)) + i += float(self.bounds[HORZ][1] - self.bounds[HORZ][0])/10 + ScatterPlot.calc_labels(self) + + def render_plot(self): + if not self.discrete: + ScatterPlot.render_plot(self) + else: + last = None + cr = self.context + for number, group in enumerate (self.series): + cr.set_source_rgba(*self.series_colors[number][:4]) + x0 = self.borders[HORZ] - self.bounds[HORZ][0]*self.horizontal_step + y0 = self.borders[VERT] - self.bounds[VERT][0]*self.vertical_step + for data in group: + x = x0 + self.horizontal_step * data.content[0] + y = y0 + self.vertical_step * data.content[1] + cr.move_to(x, self.dimensions[VERT] - y) + cr.line_to(x, self.plot_top) + cr.set_line_width(self.series_widths[number]) + cr.stroke() + if self.dots: + cr.new_path() + cr.arc(x, self.dimensions[VERT] - y, 3, 0, 2.1 * math.pi) + cr.close_path() + cr.fill() + +class BarPlot(Plot): + def __init__(self, + surface = None, + data = None, + width = 640, + height = 480, + background = "white light_gray", + border = 0, + display_values = False, + grid = False, + rounded_corners = False, + stack = False, + three_dimension = False, + x_labels = None, + y_labels = None, + x_bounds = None, + y_bounds = None, + series_colors = None, + main_dir = None): + + self.bounds = {} + self.bounds[HORZ] = x_bounds + self.bounds[VERT] = y_bounds + self.display_values = display_values + self.grid = grid + self.rounded_corners = rounded_corners + self.stack = stack + self.three_dimension = three_dimension + self.x_label_angle = math.pi / 2.5 + self.main_dir = main_dir + self.max_value = {} + self.plot_dimensions = {} + self.steps = {} + self.value_label_color = (0.5,0.5,0.5,1.0) + + Plot.__init__(self, surface, data, width, height, background, border, x_labels, y_labels, series_colors) + + def load_series(self, data, x_labels = None, y_labels = None, series_colors = None): + Plot.load_series(self, data, x_labels, y_labels, series_colors) + self.calc_boundaries() + + def process_colors(self, series_colors): + #Data for a BarPlot might be a List or a List of Lists. + #On the first case, colors must be generated for all bars, + #On the second, colors must be generated for each of the inner lists. + + #TODO: Didn't get it... + #if hasattr(self.data[0], '__getitem__'): + # length = max(len(series) for series in self.data) + #else: + # length = len( self.data ) + + length = max(len(group) for group in self.series) + + Plot.process_colors( self, series_colors, length, 'linear') + + def calc_boundaries(self): + if not self.bounds[self.main_dir]: + if self.stack: + max_data_value = max(sum(group.to_list()) for group in self.series) + else: + max_data_value = max(max(group.to_list()) for group in self.series) + self.bounds[self.main_dir] = (0, max_data_value) + if not self.bounds[other_direction(self.main_dir)]: + self.bounds[other_direction(self.main_dir)] = (0, len(self.series)) + + def calc_extents(self, direction): + self.max_value[direction] = 0 + if self.labels[direction]: + widest_word = max(self.labels[direction], key = lambda item: self.context.text_extents(item)[2]) + self.max_value[direction] = self.context.text_extents(widest_word)[3 - direction] + self.borders[other_direction(direction)] = (2-direction)*self.max_value[direction] + self.border + direction*(5) + else: + self.borders[other_direction(direction)] = self.border + + def calc_horz_extents(self): + self.calc_extents(HORZ) + + def calc_vert_extents(self): + self.calc_extents(VERT) + + def calc_all_extents(self): + self.calc_horz_extents() + self.calc_vert_extents() + other_dir = other_direction(self.main_dir) + self.value_label = 0 + if self.display_values: + if self.stack: + self.value_label = self.context.text_extents(str(max(sum(group.to_list()) for group in self.series)))[2 + self.main_dir] + else: + self.value_label = self.context.text_extents(str(max(max(group.to_list()) for group in self.series)))[2 + self.main_dir] + if self.labels[self.main_dir]: + self.plot_dimensions[self.main_dir] = self.dimensions[self.main_dir] - 2*self.borders[self.main_dir] - self.value_label + else: + self.plot_dimensions[self.main_dir] = self.dimensions[self.main_dir] - self.borders[self.main_dir] - 1.2*self.border - self.value_label + self.plot_dimensions[other_dir] = self.dimensions[other_dir] - self.borders[other_dir] - self.border + self.plot_top = self.dimensions[VERT] - self.borders[VERT] + + def calc_steps(self): + other_dir = other_direction(self.main_dir) + self.series_amplitude = self.bounds[self.main_dir][1] - self.bounds[self.main_dir][0] + if self.series_amplitude: + self.steps[self.main_dir] = float(self.plot_dimensions[self.main_dir])/self.series_amplitude + else: + self.steps[self.main_dir] = 0.00 + series_length = len(self.series) + self.steps[other_dir] = float(self.plot_dimensions[other_dir])/(series_length + 0.1*(series_length + 1)) + self.space = 0.1*self.steps[other_dir] + + def render(self): + self.calc_all_extents() + self.calc_steps() + self.render_background() + self.render_bounding_box() + if self.grid: + self.render_grid() + if self.three_dimension: + self.render_ground() + if self.display_values: + self.render_values() + self.render_labels() + self.render_plot() + if self.series_labels: + self.render_legend() + + def draw_3d_rectangle_front(self, x0, y0, x1, y1, shift): + self.context.rectangle(x0-shift, y0+shift, x1-x0, y1-y0) + + def draw_3d_rectangle_side(self, x0, y0, x1, y1, shift): + self.context.move_to(x1-shift,y0+shift) + self.context.line_to(x1, y0) + self.context.line_to(x1, y1) + self.context.line_to(x1-shift, y1+shift) + self.context.line_to(x1-shift, y0+shift) + self.context.close_path() + + def draw_3d_rectangle_top(self, x0, y0, x1, y1, shift): + self.context.move_to(x0-shift,y0+shift) + self.context.line_to(x0, y0) + self.context.line_to(x1, y0) + self.context.line_to(x1-shift, y0+shift) + self.context.line_to(x0-shift, y0+shift) + self.context.close_path() + + def draw_round_rectangle(self, x0, y0, x1, y1): + self.context.arc(x0+5, y0+5, 5, -math.pi, -math.pi/2) + self.context.line_to(x1-5, y0) + self.context.arc(x1-5, y0+5, 5, -math.pi/2, 0) + self.context.line_to(x1, y1-5) + self.context.arc(x1-5, y1-5, 5, 0, math.pi/2) + self.context.line_to(x0+5, y1) + self.context.arc(x0+5, y1-5, 5, math.pi/2, math.pi) + self.context.line_to(x0, y0+5) + self.context.close_path() + + def render_ground(self): + self.draw_3d_rectangle_front(self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], + self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) + self.context.fill() + + self.draw_3d_rectangle_side (self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], + self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) + self.context.fill() + + self.draw_3d_rectangle_top (self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], + self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) + self.context.fill() + + def render_labels(self): + self.context.set_font_size(self.font_size * 0.8) + if self.labels[HORZ]: + self.render_horz_labels() + if self.labels[VERT]: + self.render_vert_labels() + + def render_legend(self): + cr = self.context + cr.set_font_size(self.font_size) + cr.set_line_width(self.line_width) + + widest_word = max(self.series_labels, key = lambda item: self.context.text_extents(item)[2]) + tallest_word = max(self.series_labels, key = lambda item: self.context.text_extents(item)[3]) + max_width = self.context.text_extents(widest_word)[2] + max_height = self.context.text_extents(tallest_word)[3] * 1.1 + 5 + + color_box_height = max_height / 2 + color_box_width = color_box_height * 2 + + #Draw a bounding box + bounding_box_width = max_width + color_box_width + 15 + bounding_box_height = (len(self.series_labels)+0.5) * max_height + cr.set_source_rgba(1,1,1) + cr.rectangle(self.dimensions[HORZ] - self.border - bounding_box_width, self.border, + bounding_box_width, bounding_box_height) + cr.fill() + + cr.set_source_rgba(*self.line_color) + cr.set_line_width(self.line_width) + cr.rectangle(self.dimensions[HORZ] - self.border - bounding_box_width, self.border, + bounding_box_width, bounding_box_height) + cr.stroke() + + for idx,key in enumerate(self.series_labels): + #Draw color box + cr.set_source_rgba(*self.series_colors[idx][:4]) + cr.rectangle(self.dimensions[HORZ] - self.border - max_width - color_box_width - 10, + self.border + color_box_height + (idx*max_height) , + color_box_width, color_box_height) + cr.fill() + + cr.set_source_rgba(0, 0, 0) + cr.rectangle(self.dimensions[HORZ] - self.border - max_width - color_box_width - 10, + self.border + color_box_height + (idx*max_height), + color_box_width, color_box_height) + cr.stroke() + + #Draw series labels + cr.set_source_rgba(0, 0, 0) + cr.move_to(self.dimensions[HORZ] - self.border - max_width - 5, self.border + ((idx+1)*max_height)) + cr.show_text(key) + + +class HorizontalBarPlot(BarPlot): + def __init__(self, + surface = None, + data = None, + width = 640, + height = 480, + background = "white light_gray", + border = 0, + display_values = False, + grid = False, + rounded_corners = False, + stack = False, + three_dimension = False, + series_labels = None, + x_labels = None, + y_labels = None, + x_bounds = None, + y_bounds = None, + series_colors = None): + + BarPlot.__init__(self, surface, data, width, height, background, border, + display_values, grid, rounded_corners, stack, three_dimension, + x_labels, y_labels, x_bounds, y_bounds, series_colors, HORZ) + self.series_labels = series_labels + + def calc_vert_extents(self): + self.calc_extents(VERT) + if self.labels[HORZ] and not self.labels[VERT]: + self.borders[HORZ] += 10 + + def draw_rectangle_bottom(self, x0, y0, x1, y1): + self.context.arc(x0+5, y1-5, 5, math.pi/2, math.pi) + self.context.line_to(x0, y0+5) + self.context.arc(x0+5, y0+5, 5, -math.pi, -math.pi/2) + self.context.line_to(x1, y0) + self.context.line_to(x1, y1) + self.context.line_to(x0+5, y1) + self.context.close_path() + + def draw_rectangle_top(self, x0, y0, x1, y1): + self.context.arc(x1-5, y0+5, 5, -math.pi/2, 0) + self.context.line_to(x1, y1-5) + self.context.arc(x1-5, y1-5, 5, 0, math.pi/2) + self.context.line_to(x0, y1) + self.context.line_to(x0, y0) + self.context.line_to(x1, y0) + self.context.close_path() + + def draw_rectangle(self, index, length, x0, y0, x1, y1): + if length == 1: + BarPlot.draw_rectangle(self, x0, y0, x1, y1) + elif index == 0: + self.draw_rectangle_bottom(x0, y0, x1, y1) + elif index == length-1: + self.draw_rectangle_top(x0, y0, x1, y1) + else: + self.context.rectangle(x0, y0, x1-x0, y1-y0) + + #TODO: Review BarPlot.render_grid code + def render_grid(self): + self.context.set_source_rgba(0.8, 0.8, 0.8) + if self.labels[HORZ]: + self.context.set_font_size(self.font_size * 0.8) + step = (self.dimensions[HORZ] - 2*self.borders[HORZ] - self.value_label)/(len(self.labels[HORZ])-1) + x = self.borders[HORZ] + next_x = 0 + for item in self.labels[HORZ]: + width = self.context.text_extents(item)[2] + if x - width/2 > next_x and x - width/2 > self.border: + self.context.move_to(x, self.border) + self.context.line_to(x, self.dimensions[VERT] - self.borders[VERT]) + self.context.stroke() + next_x = x + width/2 + x += step + else: + lines = 11 + horizontal_step = float(self.plot_dimensions[HORZ])/(lines-1) + x = self.borders[HORZ] + for y in xrange(0, lines): + self.context.move_to(x, self.border) + self.context.line_to(x, self.dimensions[VERT] - self.borders[VERT]) + self.context.stroke() + x += horizontal_step + + def render_horz_labels(self): + step = (self.dimensions[HORZ] - 2*self.borders[HORZ])/(len(self.labels[HORZ])-1) + x = self.borders[HORZ] + next_x = 0 + + for item in self.labels[HORZ]: + self.context.set_source_rgba(*self.label_color) + width = self.context.text_extents(item)[2] + if x - width/2 > next_x and x - width/2 > self.border: + self.context.move_to(x - width/2, self.dimensions[VERT] - self.borders[VERT] + self.max_value[HORZ] + 3) + self.context.show_text(item) + next_x = x + width/2 + x += step + + def render_vert_labels(self): + series_length = len(self.labels[VERT]) + step = (self.plot_dimensions[VERT] - (series_length + 1)*self.space)/(len(self.labels[VERT])) + y = self.border + step/2 + self.space + + for item in self.labels[VERT]: + self.context.set_source_rgba(*self.label_color) + width, height = self.context.text_extents(item)[2:4] + self.context.move_to(self.borders[HORZ] - width - 5, y + height/2) + self.context.show_text(item) + y += step + self.space + self.labels[VERT].reverse() + + def render_values(self): + self.context.set_source_rgba(*self.value_label_color) + self.context.set_font_size(self.font_size * 0.8) + if self.stack: + for i,group in enumerate(self.series): + value = sum(group.to_list()) + height = self.context.text_extents(str(value))[3] + x = self.borders[HORZ] + value*self.steps[HORZ] + 2 + y = self.borders[VERT] + (i+0.5)*self.steps[VERT] + (i+1)*self.space + height/2 + self.context.move_to(x, y) + self.context.show_text(str(value)) + else: + for i,group in enumerate(self.series): + inner_step = self.steps[VERT]/len(group) + y0 = self.border + i*self.steps[VERT] + (i+1)*self.space + for number,data in enumerate(group): + height = self.context.text_extents(str(data.content))[3] + self.context.move_to(self.borders[HORZ] + data.content*self.steps[HORZ] + 2, y0 + 0.5*inner_step + height/2, ) + self.context.show_text(str(data.content)) + y0 += inner_step + + def render_plot(self): + if self.stack: + for i,group in enumerate(self.series): + x0 = self.borders[HORZ] + y0 = self.borders[VERT] + i*self.steps[VERT] + (i+1)*self.space + for number,data in enumerate(group): + if self.series_colors[number][4] in ('radial','linear') : + linear = cairo.LinearGradient( data.content*self.steps[HORZ]/2, y0, data.content*self.steps[HORZ]/2, y0 + self.steps[VERT] ) + color = self.series_colors[number] + linear.add_color_stop_rgba(0.0, 3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) + linear.add_color_stop_rgba(1.0, *color[:4]) + self.context.set_source(linear) + elif self.series_colors[number][4] == 'solid': + self.context.set_source_rgba(*self.series_colors[number][:4]) + if self.rounded_corners: + self.draw_rectangle(number, len(group), x0, y0, x0+data.content*self.steps[HORZ], y0+self.steps[VERT]) + self.context.fill() + else: + self.context.rectangle(x0, y0, data.content*self.steps[HORZ], self.steps[VERT]) + self.context.fill() + x0 += data.content*self.steps[HORZ] + else: + for i,group in enumerate(self.series): + inner_step = self.steps[VERT]/len(group) + x0 = self.borders[HORZ] + y0 = self.border + i*self.steps[VERT] + (i+1)*self.space + for number,data in enumerate(group): + linear = cairo.LinearGradient(data.content*self.steps[HORZ]/2, y0, data.content*self.steps[HORZ]/2, y0 + inner_step) + color = self.series_colors[number] + linear.add_color_stop_rgba(0.0, 3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) + linear.add_color_stop_rgba(1.0, *color[:4]) + self.context.set_source(linear) + if self.rounded_corners and data.content != 0: + BarPlot.draw_round_rectangle(self,x0, y0, x0 + data.content*self.steps[HORZ], y0 + inner_step) + self.context.fill() + else: + self.context.rectangle(x0, y0, data.content*self.steps[HORZ], inner_step) + self.context.fill() + y0 += inner_step + +class VerticalBarPlot(BarPlot): + def __init__(self, + surface = None, + data = None, + width = 640, + height = 480, + background = "white light_gray", + border = 0, + display_values = False, + grid = False, + rounded_corners = False, + stack = False, + three_dimension = False, + series_labels = None, + x_labels = None, + y_labels = None, + x_bounds = None, + y_bounds = None, + series_colors = None): + + BarPlot.__init__(self, surface, data, width, height, background, border, + display_values, grid, rounded_corners, stack, three_dimension, + x_labels, y_labels, x_bounds, y_bounds, series_colors, VERT) + self.series_labels = series_labels + + def calc_vert_extents(self): + self.calc_extents(VERT) + if self.labels[VERT] and not self.labels[HORZ]: + self.borders[VERT] += 10 + + def draw_rectangle_bottom(self, x0, y0, x1, y1): + self.context.move_to(x1,y1) + self.context.arc(x1-5, y1-5, 5, 0, math.pi/2) + self.context.line_to(x0+5, y1) + self.context.arc(x0+5, y1-5, 5, math.pi/2, math.pi) + self.context.line_to(x0, y0) + self.context.line_to(x1, y0) + self.context.line_to(x1, y1) + self.context.close_path() + + def draw_rectangle_top(self, x0, y0, x1, y1): + self.context.arc(x0+5, y0+5, 5, -math.pi, -math.pi/2) + self.context.line_to(x1-5, y0) + self.context.arc(x1-5, y0+5, 5, -math.pi/2, 0) + self.context.line_to(x1, y1) + self.context.line_to(x0, y1) + self.context.line_to(x0, y0) + self.context.close_path() + + def draw_rectangle(self, index, length, x0, y0, x1, y1): + if length == 1: + BarPlot.draw_rectangle(self, x0, y0, x1, y1) + elif index == 0: + self.draw_rectangle_bottom(x0, y0, x1, y1) + elif index == length-1: + self.draw_rectangle_top(x0, y0, x1, y1) + else: + self.context.rectangle(x0, y0, x1-x0, y1-y0) + + def render_grid(self): + self.context.set_source_rgba(0.8, 0.8, 0.8) + if self.labels[VERT]: + lines = len(self.labels[VERT]) + vertical_step = float(self.plot_dimensions[self.main_dir])/(lines-1) + y = self.borders[VERT] + self.value_label + else: + lines = 11 + vertical_step = float(self.plot_dimensions[self.main_dir])/(lines-1) + y = 1.2*self.border + self.value_label + for x in xrange(0, lines): + self.context.move_to(self.borders[HORZ], y) + self.context.line_to(self.dimensions[HORZ] - self.border, y) + self.context.stroke() + y += vertical_step + + def render_ground(self): + self.draw_3d_rectangle_front(self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], + self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) + self.context.fill() + + self.draw_3d_rectangle_side (self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], + self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) + self.context.fill() + + self.draw_3d_rectangle_top (self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], + self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) + self.context.fill() + + def render_horz_labels(self): + series_length = len(self.labels[HORZ]) + step = float (self.plot_dimensions[HORZ] - (series_length + 1)*self.space)/len(self.labels[HORZ]) + x = self.borders[HORZ] + step/2 + self.space + next_x = 0 + + for item in self.labels[HORZ]: + self.context.set_source_rgba(*self.label_color) + width = self.context.text_extents(item)[2] + if x - width/2 > next_x and x - width/2 > self.borders[HORZ]: + self.context.move_to(x - width/2, self.dimensions[VERT] - self.borders[VERT] + self.max_value[HORZ] + 3) + self.context.show_text(item) + next_x = x + width/2 + x += step + self.space + + def render_vert_labels(self): + self.context.set_source_rgba(*self.label_color) + y = self.borders[VERT] + self.value_label + step = (self.dimensions[VERT] - 2*self.borders[VERT] - self.value_label)/(len(self.labels[VERT]) - 1) + self.labels[VERT].reverse() + for item in self.labels[VERT]: + width, height = self.context.text_extents(item)[2:4] + self.context.move_to(self.borders[HORZ] - width - 5, y + height/2) + self.context.show_text(item) + y += step + self.labels[VERT].reverse() + + def render_values(self): + self.context.set_source_rgba(*self.value_label_color) + self.context.set_font_size(self.font_size * 0.8) + if self.stack: + for i,group in enumerate(self.series): + value = sum(group.to_list()) + width = self.context.text_extents(str(value))[2] + x = self.borders[HORZ] + (i+0.5)*self.steps[HORZ] + (i+1)*self.space - width/2 + y = value*self.steps[VERT] + 2 + self.context.move_to(x, self.plot_top-y) + self.context.show_text(str(value)) + else: + for i,group in enumerate(self.series): + inner_step = self.steps[HORZ]/len(group) + x0 = self.borders[HORZ] + i*self.steps[HORZ] + (i+1)*self.space + for number,data in enumerate(group): + width = self.context.text_extents(str(data.content))[2] + self.context.move_to(x0 + 0.5*inner_step - width/2, self.plot_top - data.content*self.steps[VERT] - 2) + self.context.show_text(str(data.content)) + x0 += inner_step + + def render_plot(self): + if self.stack: + for i,group in enumerate(self.series): + x0 = self.borders[HORZ] + i*self.steps[HORZ] + (i+1)*self.space + y0 = 0 + for number,data in enumerate(group): + if self.series_colors[number][4] in ('linear','radial'): + linear = cairo.LinearGradient( x0, data.content*self.steps[VERT]/2, x0 + self.steps[HORZ], data.content*self.steps[VERT]/2 ) + color = self.series_colors[number] + linear.add_color_stop_rgba(0.0, 3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) + linear.add_color_stop_rgba(1.0, *color[:4]) + self.context.set_source(linear) + elif self.series_colors[number][4] == 'solid': + self.context.set_source_rgba(*self.series_colors[number][:4]) + if self.rounded_corners: + self.draw_rectangle(number, len(group), x0, self.plot_top - y0 - data.content*self.steps[VERT], x0 + self.steps[HORZ], self.plot_top - y0) + self.context.fill() + else: + self.context.rectangle(x0, self.plot_top - y0 - data.content*self.steps[VERT], self.steps[HORZ], data.content*self.steps[VERT]) + self.context.fill() + y0 += data.content*self.steps[VERT] + else: + for i,group in enumerate(self.series): + inner_step = self.steps[HORZ]/len(group) + y0 = self.borders[VERT] + x0 = self.borders[HORZ] + i*self.steps[HORZ] + (i+1)*self.space + for number,data in enumerate(group): + if self.series_colors[number][4] == 'linear': + linear = cairo.LinearGradient( x0, data.content*self.steps[VERT]/2, x0 + inner_step, data.content*self.steps[VERT]/2 ) + color = self.series_colors[number] + linear.add_color_stop_rgba(0.0, 3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) + linear.add_color_stop_rgba(1.0, *color[:4]) + self.context.set_source(linear) + elif self.series_colors[number][4] == 'solid': + self.context.set_source_rgba(*self.series_colors[number][:4]) + if self.rounded_corners and data.content != 0: + BarPlot.draw_round_rectangle(self, x0, self.plot_top - data.content*self.steps[VERT], x0+inner_step, self.plot_top) + self.context.fill() + elif self.three_dimension: + self.draw_3d_rectangle_front(x0, self.plot_top - data.content*self.steps[VERT], x0+inner_step, self.plot_top, 5) + self.context.fill() + self.draw_3d_rectangle_side(x0, self.plot_top - data.content*self.steps[VERT], x0+inner_step, self.plot_top, 5) + self.context.fill() + self.draw_3d_rectangle_top(x0, self.plot_top - data.content*self.steps[VERT], x0+inner_step, self.plot_top, 5) + self.context.fill() + else: + self.context.rectangle(x0, self.plot_top - data.content*self.steps[VERT], inner_step, data.content*self.steps[VERT]) + self.context.fill() + + x0 += inner_step + +class StreamChart(VerticalBarPlot): + def __init__(self, + surface = None, + data = None, + width = 640, + height = 480, + background = "white light_gray", + border = 0, + grid = False, + series_legend = None, + x_labels = None, + x_bounds = None, + y_bounds = None, + series_colors = None): + + VerticalBarPlot.__init__(self, surface, data, width, height, background, border, + False, grid, False, True, False, + None, x_labels, None, x_bounds, y_bounds, series_colors) + + def calc_steps(self): + other_dir = other_direction(self.main_dir) + self.series_amplitude = self.bounds[self.main_dir][1] - self.bounds[self.main_dir][0] + if self.series_amplitude: + self.steps[self.main_dir] = float(self.plot_dimensions[self.main_dir])/self.series_amplitude + else: + self.steps[self.main_dir] = 0.00 + series_length = len(self.data) + self.steps[other_dir] = float(self.plot_dimensions[other_dir])/series_length + + def render_legend(self): + pass + + def ground(self, index): + sum_values = sum(self.data[index]) + return -0.5*sum_values + + def calc_angles(self): + middle = self.plot_top - self.plot_dimensions[VERT]/2.0 + self.angles = [tuple([0.0 for x in range(len(self.data)+1)])] + for x_index in range(1, len(self.data)-1): + t = [] + x0 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ] + x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ] + y0 = middle - self.ground(x_index-1)*self.steps[VERT] + y2 = middle - self.ground(x_index+1)*self.steps[VERT] + t.append(math.atan(float(y0-y2)/(x0-x2))) + for data_index in range(len(self.data[x_index])): + x0 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ] + x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ] + y0 = middle - self.ground(x_index-1)*self.steps[VERT] - self.data[x_index-1][data_index]*self.steps[VERT] + y2 = middle - self.ground(x_index+1)*self.steps[VERT] - self.data[x_index+1][data_index]*self.steps[VERT] + + for i in range(0,data_index): + y0 -= self.data[x_index-1][i]*self.steps[VERT] + y2 -= self.data[x_index+1][i]*self.steps[VERT] + + if data_index == len(self.data[0])-1 and False: + self.context.set_source_rgba(0.0,0.0,0.0,0.3) + self.context.move_to(x0,y0) + self.context.line_to(x2,y2) + self.context.stroke() + self.context.arc(x0,y0,2,0,2*math.pi) + self.context.fill() + t.append(math.atan(float(y0-y2)/(x0-x2))) + self.angles.append(tuple(t)) + self.angles.append(tuple([0.0 for x in range(len(self.data)+1)])) + + def render_plot(self): + self.calc_angles() + middle = self.plot_top - self.plot_dimensions[VERT]/2.0 + p = 0.4*self.steps[HORZ] + for data_index in range(len(self.data[0])-1,-1,-1): + self.context.set_source_rgba(*self.series_colors[data_index][:4]) + + #draw the upper line + for x_index in range(len(self.data)-1) : + x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ] + y1 = middle - self.ground(x_index)*self.steps[VERT] - self.data[x_index][data_index]*self.steps[VERT] + x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ] + y2 = middle - self.ground(x_index + 1)*self.steps[VERT] - self.data[x_index + 1][data_index]*self.steps[VERT] + + for i in range(0,data_index): + y1 -= self.data[x_index][i]*self.steps[VERT] + y2 -= self.data[x_index+1][i]*self.steps[VERT] + + if x_index == 0: + self.context.move_to(x1,y1) + + ang1 = self.angles[x_index][data_index+1] + ang2 = self.angles[x_index+1][data_index+1] + math.pi + self.context.curve_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1), + x2+p*math.cos(ang2),y2+p*math.sin(ang2), + x2,y2) + + for x_index in range(len(self.data)-1,0,-1) : + x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ] + y1 = middle - self.ground(x_index)*self.steps[VERT] + x2 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ] + y2 = middle - self.ground(x_index - 1)*self.steps[VERT] + + for i in range(0,data_index): + y1 -= self.data[x_index][i]*self.steps[VERT] + y2 -= self.data[x_index-1][i]*self.steps[VERT] + + if x_index == len(self.data)-1: + self.context.line_to(x1,y1+2) + + #revert angles by pi degrees to take the turn back + ang1 = self.angles[x_index][data_index] + math.pi + ang2 = self.angles[x_index-1][data_index] + self.context.curve_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1), + x2+p*math.cos(ang2),y2+p*math.sin(ang2), + x2,y2+2) + + self.context.close_path() + self.context.fill() + + if False: + self.context.move_to(self.borders[HORZ] + 0.5*self.steps[HORZ], middle) + for x_index in range(len(self.data)-1) : + x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ] + y1 = middle - self.ground(x_index)*self.steps[VERT] - self.data[x_index][data_index]*self.steps[VERT] + x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ] + y2 = middle - self.ground(x_index + 1)*self.steps[VERT] - self.data[x_index + 1][data_index]*self.steps[VERT] + + for i in range(0,data_index): + y1 -= self.data[x_index][i]*self.steps[VERT] + y2 -= self.data[x_index+1][i]*self.steps[VERT] + + ang1 = self.angles[x_index][data_index+1] + ang2 = self.angles[x_index+1][data_index+1] + math.pi + self.context.set_source_rgba(1.0,0.0,0.0) + self.context.arc(x1+p*math.cos(ang1),y1+p*math.sin(ang1),2,0,2*math.pi) + self.context.fill() + self.context.set_source_rgba(0.0,0.0,0.0) + self.context.arc(x2+p*math.cos(ang2),y2+p*math.sin(ang2),2,0,2*math.pi) + self.context.fill() + '''self.context.set_source_rgba(0.0,0.0,0.0,0.3) + self.context.arc(x2,y2,2,0,2*math.pi) + self.context.fill()''' + self.context.move_to(x1,y1) + self.context.line_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1)) + self.context.stroke() + self.context.move_to(x2,y2) + self.context.line_to(x2+p*math.cos(ang2),y2+p*math.sin(ang2)) + self.context.stroke() + if False: + for x_index in range(len(self.data)-1,0,-1) : + x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ] + y1 = middle - self.ground(x_index)*self.steps[VERT] + x2 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ] + y2 = middle - self.ground(x_index - 1)*self.steps[VERT] + + for i in range(0,data_index): + y1 -= self.data[x_index][i]*self.steps[VERT] + y2 -= self.data[x_index-1][i]*self.steps[VERT] + + #revert angles by pi degrees to take the turn back + ang1 = self.angles[x_index][data_index] + math.pi + ang2 = self.angles[x_index-1][data_index] + self.context.set_source_rgba(0.0,1.0,0.0) + self.context.arc(x1+p*math.cos(ang1),y1+p*math.sin(ang1),2,0,2*math.pi) + self.context.fill() + self.context.set_source_rgba(0.0,0.0,1.0) + self.context.arc(x2+p*math.cos(ang2),y2+p*math.sin(ang2),2,0,2*math.pi) + self.context.fill() + '''self.context.set_source_rgba(0.0,0.0,0.0,0.3) + self.context.arc(x2,y2,2,0,2*math.pi) + self.context.fill()''' + self.context.move_to(x1,y1) + self.context.line_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1)) + self.context.stroke() + self.context.move_to(x2,y2) + self.context.line_to(x2+p*math.cos(ang2),y2+p*math.sin(ang2)) + self.context.stroke() + #break + + #self.context.arc(self.dimensions[HORZ]/2, self.dimensions[VERT]/2,50,0,3*math.pi/2) + #self.context.fill() + + +class PiePlot(Plot): + #TODO: Check the old cairoplot, graphs aren't matching + def __init__ (self, + surface = None, + data = None, + width = 640, + height = 480, + background = "white light_gray", + gradient = False, + shadow = False, + colors = None): + + Plot.__init__( self, surface, data, width, height, background, series_colors = colors ) + self.center = (self.dimensions[HORZ]/2, self.dimensions[VERT]/2) + self.total = sum( self.series.to_list() ) + self.radius = min(self.dimensions[HORZ]/3,self.dimensions[VERT]/3) + self.gradient = gradient + self.shadow = shadow + + def sort_function(x,y): + return x.content - y.content + + def load_series(self, data, x_labels=None, y_labels=None, series_colors=None): + Plot.load_series(self, data, x_labels, y_labels, series_colors) + # Already done inside series + #self.data = sorted(self.data) + + def draw_piece(self, angle, next_angle): + self.context.move_to(self.center[0],self.center[1]) + self.context.line_to(self.center[0] + self.radius*math.cos(angle), self.center[1] + self.radius*math.sin(angle)) + self.context.arc(self.center[0], self.center[1], self.radius, angle, next_angle) + self.context.line_to(self.center[0], self.center[1]) + self.context.close_path() + + def render(self): + self.render_background() + self.render_bounding_box() + if self.shadow: + self.render_shadow() + self.render_plot() + self.render_series_labels() + + def render_shadow(self): + horizontal_shift = 3 + vertical_shift = 3 + self.context.set_source_rgba(0, 0, 0, 0.5) + self.context.arc(self.center[0] + horizontal_shift, self.center[1] + vertical_shift, self.radius, 0, 2*math.pi) + self.context.fill() + + def render_series_labels(self): + angle = 0 + next_angle = 0 + x0,y0 = self.center + cr = self.context + for number,key in enumerate(self.series_labels): + # self.data[number] should be just a number + data = sum(self.series[number].to_list()) + + next_angle = angle + 2.0*math.pi*data/self.total + cr.set_source_rgba(*self.series_colors[number][:4]) + w = cr.text_extents(key)[2] + if (angle + next_angle)/2 < math.pi/2 or (angle + next_angle)/2 > 3*math.pi/2: + cr.move_to(x0 + (self.radius+10)*math.cos((angle+next_angle)/2), y0 + (self.radius+10)*math.sin((angle+next_angle)/2) ) + else: + cr.move_to(x0 + (self.radius+10)*math.cos((angle+next_angle)/2) - w, y0 + (self.radius+10)*math.sin((angle+next_angle)/2) ) + cr.show_text(key) + angle = next_angle + + def render_plot(self): + angle = 0 + next_angle = 0 + x0,y0 = self.center + cr = self.context + for number,group in enumerate(self.series): + # Group should be just a number + data = sum(group.to_list()) + next_angle = angle + 2.0*math.pi*data/self.total + if self.gradient or self.series_colors[number][4] in ('linear','radial'): + gradient_color = cairo.RadialGradient(self.center[0], self.center[1], 0, self.center[0], self.center[1], self.radius) + gradient_color.add_color_stop_rgba(0.3, *self.series_colors[number][:4]) + gradient_color.add_color_stop_rgba(1, self.series_colors[number][0]*0.7, + self.series_colors[number][1]*0.7, + self.series_colors[number][2]*0.7, + self.series_colors[number][3]) + cr.set_source(gradient_color) + else: + cr.set_source_rgba(*self.series_colors[number][:4]) + + self.draw_piece(angle, next_angle) + cr.fill() + + cr.set_source_rgba(1.0, 1.0, 1.0) + self.draw_piece(angle, next_angle) + cr.stroke() + + angle = next_angle + +class DonutPlot(PiePlot): + def __init__ (self, + surface = None, + data = None, + width = 640, + height = 480, + background = "white light_gray", + gradient = False, + shadow = False, + colors = None, + inner_radius=-1): + + Plot.__init__( self, surface, data, width, height, background, series_colors = colors ) + + self.center = ( self.dimensions[HORZ]/2, self.dimensions[VERT]/2 ) + self.total = sum( self.series.to_list() ) + self.radius = min( self.dimensions[HORZ]/3,self.dimensions[VERT]/3 ) + self.inner_radius = inner_radius*self.radius + + if inner_radius == -1: + self.inner_radius = self.radius/3 + + self.gradient = gradient + self.shadow = shadow + + def draw_piece(self, angle, next_angle): + self.context.move_to(self.center[0] + (self.inner_radius)*math.cos(angle), self.center[1] + (self.inner_radius)*math.sin(angle)) + self.context.line_to(self.center[0] + self.radius*math.cos(angle), self.center[1] + self.radius*math.sin(angle)) + self.context.arc(self.center[0], self.center[1], self.radius, angle, next_angle) + self.context.line_to(self.center[0] + (self.inner_radius)*math.cos(next_angle), self.center[1] + (self.inner_radius)*math.sin(next_angle)) + self.context.arc_negative(self.center[0], self.center[1], self.inner_radius, next_angle, angle) + self.context.close_path() + + def render_shadow(self): + horizontal_shift = 3 + vertical_shift = 3 + self.context.set_source_rgba(0, 0, 0, 0.5) + self.context.arc(self.center[0] + horizontal_shift, self.center[1] + vertical_shift, self.inner_radius, 0, 2*math.pi) + self.context.arc_negative(self.center[0] + horizontal_shift, self.center[1] + vertical_shift, self.radius, 0, -2*math.pi) + self.context.fill() + +class GanttChart (Plot) : + def __init__(self, + surface = None, + data = None, + width = 640, + height = 480, + x_labels = None, + y_labels = None, + colors = None): + self.bounds = {} + self.max_value = {} + Plot.__init__(self, surface, data, width, height, x_labels = x_labels, y_labels = y_labels, series_colors = colors) + + def load_series(self, data, x_labels=None, y_labels=None, series_colors=None): + Plot.load_series(self, data, x_labels, y_labels, series_colors) + self.calc_boundaries() + + def calc_boundaries(self): + self.bounds[HORZ] = (0,len(self.series)) + end_pos = max(self.series.to_list()) + + #for group in self.series: + # if hasattr(item, "__delitem__"): + # for sub_item in item: + # end_pos = max(sub_item) + # else: + # end_pos = max(item) + self.bounds[VERT] = (0,end_pos) + + def calc_extents(self, direction): + self.max_value[direction] = 0 + if self.labels[direction]: + self.max_value[direction] = max(self.context.text_extents(item)[2] for item in self.labels[direction]) + else: + self.max_value[direction] = self.context.text_extents( str(self.bounds[direction][1] + 1) )[2] + + def calc_horz_extents(self): + self.calc_extents(HORZ) + self.borders[HORZ] = 100 + self.max_value[HORZ] + + def calc_vert_extents(self): + self.calc_extents(VERT) + self.borders[VERT] = self.dimensions[VERT]/(self.bounds[HORZ][1] + 1) + + def calc_steps(self): + self.horizontal_step = (self.dimensions[HORZ] - self.borders[HORZ])/(len(self.labels[VERT])) + self.vertical_step = self.borders[VERT] + + def render(self): + self.calc_horz_extents() + self.calc_vert_extents() + self.calc_steps() + self.render_background() + + self.render_labels() + self.render_grid() + self.render_plot() + + def render_background(self): + cr = self.context + cr.set_source_rgba(255,255,255) + cr.rectangle(0,0,self.dimensions[HORZ], self.dimensions[VERT]) + cr.fill() + for number,group in enumerate(self.series): + linear = cairo.LinearGradient(self.dimensions[HORZ]/2, self.borders[VERT] + number*self.vertical_step, + self.dimensions[HORZ]/2, self.borders[VERT] + (number+1)*self.vertical_step) + linear.add_color_stop_rgba(0,1.0,1.0,1.0,1.0) + linear.add_color_stop_rgba(1.0,0.9,0.9,0.9,1.0) + cr.set_source(linear) + cr.rectangle(0,self.borders[VERT] + number*self.vertical_step,self.dimensions[HORZ],self.vertical_step) + cr.fill() + + def render_grid(self): + cr = self.context + cr.set_source_rgba(0.7, 0.7, 0.7) + cr.set_dash((1,0,0,0,0,0,1)) + cr.set_line_width(0.5) + for number,label in enumerate(self.labels[VERT]): + h = cr.text_extents(label)[3] + cr.move_to(self.borders[HORZ] + number*self.horizontal_step, self.vertical_step/2 + h) + cr.line_to(self.borders[HORZ] + number*self.horizontal_step, self.dimensions[VERT]) + cr.stroke() + + def render_labels(self): + self.context.set_font_size(0.02 * self.dimensions[HORZ]) + + self.render_horz_labels() + self.render_vert_labels() + + def render_horz_labels(self): + cr = self.context + labels = self.labels[HORZ] + if not labels: + labels = [str(i) for i in range(1, self.bounds[HORZ][1] + 1) ] + for number,label in enumerate(labels): + if label != None: + cr.set_source_rgba(0.5, 0.5, 0.5) + w,h = cr.text_extents(label)[2], cr.text_extents(label)[3] + cr.move_to(40,self.borders[VERT] + number*self.vertical_step + self.vertical_step/2 + h/2) + cr.show_text(label) + + def render_vert_labels(self): + cr = self.context + labels = self.labels[VERT] + if not labels: + labels = [str(i) for i in range(1, self.bounds[VERT][1] + 1) ] + for number,label in enumerate(labels): + w,h = cr.text_extents(label)[2], cr.text_extents(label)[3] + cr.move_to(self.borders[HORZ] + number*self.horizontal_step - w/2, self.vertical_step/2) + cr.show_text(label) + + def render_rectangle(self, x0, y0, x1, y1, color): + self.draw_shadow(x0, y0, x1, y1) + self.draw_rectangle(x0, y0, x1, y1, color) + + def draw_rectangular_shadow(self, gradient, x0, y0, w, h): + self.context.set_source(gradient) + self.context.rectangle(x0,y0,w,h) + self.context.fill() + + def draw_circular_shadow(self, x, y, radius, ang_start, ang_end, mult, shadow): + gradient = cairo.RadialGradient(x, y, 0, x, y, 2*radius) + gradient.add_color_stop_rgba(0, 0, 0, 0, shadow) + gradient.add_color_stop_rgba(1, 0, 0, 0, 0) + self.context.set_source(gradient) + self.context.move_to(x,y) + self.context.line_to(x + mult[0]*radius,y + mult[1]*radius) + self.context.arc(x, y, 8, ang_start, ang_end) + self.context.line_to(x,y) + self.context.close_path() + self.context.fill() + + def draw_rectangle(self, x0, y0, x1, y1, color): + cr = self.context + middle = (x0+x1)/2 + linear = cairo.LinearGradient(middle,y0,middle,y1) + linear.add_color_stop_rgba(0,3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) + linear.add_color_stop_rgba(1,*color[:4]) + cr.set_source(linear) + + cr.arc(x0+5, y0+5, 5, 0, 2*math.pi) + cr.arc(x1-5, y0+5, 5, 0, 2*math.pi) + cr.arc(x0+5, y1-5, 5, 0, 2*math.pi) + cr.arc(x1-5, y1-5, 5, 0, 2*math.pi) + cr.rectangle(x0+5,y0,x1-x0-10,y1-y0) + cr.rectangle(x0,y0+5,x1-x0,y1-y0-10) + cr.fill() + + def draw_shadow(self, x0, y0, x1, y1): + shadow = 0.4 + h_mid = (x0+x1)/2 + v_mid = (y0+y1)/2 + h_linear_1 = cairo.LinearGradient(h_mid,y0-4,h_mid,y0+4) + h_linear_2 = cairo.LinearGradient(h_mid,y1-4,h_mid,y1+4) + v_linear_1 = cairo.LinearGradient(x0-4,v_mid,x0+4,v_mid) + v_linear_2 = cairo.LinearGradient(x1-4,v_mid,x1+4,v_mid) + + h_linear_1.add_color_stop_rgba( 0, 0, 0, 0, 0) + h_linear_1.add_color_stop_rgba( 1, 0, 0, 0, shadow) + h_linear_2.add_color_stop_rgba( 0, 0, 0, 0, shadow) + h_linear_2.add_color_stop_rgba( 1, 0, 0, 0, 0) + v_linear_1.add_color_stop_rgba( 0, 0, 0, 0, 0) + v_linear_1.add_color_stop_rgba( 1, 0, 0, 0, shadow) + v_linear_2.add_color_stop_rgba( 0, 0, 0, 0, shadow) + v_linear_2.add_color_stop_rgba( 1, 0, 0, 0, 0) + + self.draw_rectangular_shadow(h_linear_1,x0+4,y0-4,x1-x0-8,8) + self.draw_rectangular_shadow(h_linear_2,x0+4,y1-4,x1-x0-8,8) + self.draw_rectangular_shadow(v_linear_1,x0-4,y0+4,8,y1-y0-8) + self.draw_rectangular_shadow(v_linear_2,x1-4,y0+4,8,y1-y0-8) + + self.draw_circular_shadow(x0+4, y0+4, 4, math.pi, 3*math.pi/2, (-1,0), shadow) + self.draw_circular_shadow(x1-4, y0+4, 4, 3*math.pi/2, 2*math.pi, (0,-1), shadow) + self.draw_circular_shadow(x0+4, y1-4, 4, math.pi/2, math.pi, (0,1), shadow) + self.draw_circular_shadow(x1-4, y1-4, 4, 0, math.pi/2, (1,0), shadow) + + def render_plot(self): + for index,group in enumerate(self.series): + for data in group: + self.render_rectangle(self.borders[HORZ] + data.content[0]*self.horizontal_step, + self.borders[VERT] + index*self.vertical_step + self.vertical_step/4.0, + self.borders[HORZ] + data.content[1]*self.horizontal_step, + self.borders[VERT] + index*self.vertical_step + 3.0*self.vertical_step/4.0, + self.series_colors[index]) + +# Function definition + +def scatter_plot(name, + data = None, + errorx = None, + errory = None, + width = 640, + height = 480, + background = "white light_gray", + border = 0, + axis = False, + dash = False, + discrete = False, + dots = False, + grid = False, + series_legend = False, + x_labels = None, + y_labels = None, + x_bounds = None, + y_bounds = None, + z_bounds = None, + x_title = None, + y_title = None, + series_colors = None, + circle_colors = None): + + ''' + - Function to plot scatter data. + + - Parameters + + data - The values to be ploted might be passed in a two basic: + list of points: [(0,0), (0,1), (0,2)] or [(0,0,1), (0,1,4), (0,2,1)] + lists of coordinates: [ [0,0,0] , [0,1,2] ] or [ [0,0,0] , [0,1,2] , [1,4,1] ] + Notice that these kinds of that can be grouped in order to form more complex data + using lists of lists or dictionaries; + series_colors - Define color values for each of the series + circle_colors - Define a lower and an upper bound for the circle colors for variable radius + (3 dimensions) series + ''' + + plot = ScatterPlot( name, data, errorx, errory, width, height, background, border, + axis, dash, discrete, dots, grid, series_legend, x_labels, y_labels, + x_bounds, y_bounds, z_bounds, x_title, y_title, series_colors, circle_colors ) + plot.render() + plot.commit() + +def dot_line_plot(name, + data, + width, + height, + background = "white light_gray", + border = 0, + axis = False, + dash = False, + dots = False, + grid = False, + series_legend = False, + x_labels = None, + y_labels = None, + x_bounds = None, + y_bounds = None, + x_title = None, + y_title = None, + series_colors = None): + ''' + - Function to plot graphics using dots and lines. + + dot_line_plot (name, data, width, height, background = "white light_gray", border = 0, axis = False, grid = False, x_labels = None, y_labels = None, x_bounds = None, y_bounds = None) + + - Parameters + + name - Name of the desired output file, no need to input the .svg as it will be added at runtim; + data - The list, list of lists or dictionary holding the data to be plotted; + width, height - Dimensions of the output image; + background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. + If left None, a gray to white gradient will be generated; + border - Distance in pixels of a square border into which the graphics will be drawn; + axis - Whether or not the axis are to be drawn; + dash - Boolean or a list or a dictionary of booleans indicating whether or not the associated series should be drawn in dashed mode; + dots - Whether or not dots should be drawn on each point; + grid - Whether or not the gris is to be drawn; + series_legend - Whether or not the legend is to be drawn; + x_labels, y_labels - lists of strings containing the horizontal and vertical labels for the axis; + x_bounds, y_bounds - tuples containing the lower and upper value bounds for the data to be plotted; + x_title - Whether or not to plot a title over the x axis. + y_title - Whether or not to plot a title over the y axis. + + - Examples of use + + data = [0, 1, 3, 8, 9, 0, 10, 10, 2, 1] + CairoPlot.dot_line_plot('teste', data, 400, 300) + + data = { "john" : [10, 10, 10, 10, 30], "mary" : [0, 0, 3, 5, 15], "philip" : [13, 32, 11, 25, 2] } + x_labels = ["jan/2008", "feb/2008", "mar/2008", "apr/2008", "may/2008" ] + CairoPlot.dot_line_plot( 'test', data, 400, 300, axis = True, grid = True, + series_legend = True, x_labels = x_labels ) + ''' + plot = DotLinePlot( name, data, width, height, background, border, + axis, dash, dots, grid, series_legend, x_labels, y_labels, + x_bounds, y_bounds, x_title, y_title, series_colors ) + plot.render() + plot.commit() + +def function_plot(name, + data, + width, + height, + background = "white light_gray", + border = 0, + axis = True, + dots = False, + discrete = False, + grid = False, + series_legend = False, + x_labels = None, + y_labels = None, + x_bounds = None, + y_bounds = None, + x_title = None, + y_title = None, + series_colors = None, + step = 1): + + ''' + - Function to plot functions. + + function_plot(name, data, width, height, background = "white light_gray", border = 0, axis = True, grid = False, dots = False, x_labels = None, y_labels = None, x_bounds = None, y_bounds = None, step = 1, discrete = False) + + - Parameters + + name - Name of the desired output file, no need to input the .svg as it will be added at runtim; + data - The list, list of lists or dictionary holding the data to be plotted; + width, height - Dimensions of the output image; + background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. + If left None, a gray to white gradient will be generated; + border - Distance in pixels of a square border into which the graphics will be drawn; + axis - Whether or not the axis are to be drawn; + grid - Whether or not the gris is to be drawn; + dots - Whether or not dots should be shown at each point; + x_labels, y_labels - lists of strings containing the horizontal and vertical labels for the axis; + x_bounds, y_bounds - tuples containing the lower and upper value bounds for the data to be plotted; + step - the horizontal distance from one point to the other. The smaller, the smoother the curve will be; + discrete - whether or not the function should be plotted in discrete format. + + - Example of use + + data = lambda x : x**2 + CairoPlot.function_plot('function4', data, 400, 300, grid = True, x_bounds=(-10,10), step = 0.1) + ''' + + plot = FunctionPlot( name, data, width, height, background, border, + axis, discrete, dots, grid, series_legend, x_labels, y_labels, + x_bounds, y_bounds, x_title, y_title, series_colors, step ) + plot.render() + plot.commit() + +def pie_plot( name, data, width, height, background = "white light_gray", gradient = False, shadow = False, colors = None ): + + ''' + - Function to plot pie graphics. + + pie_plot(name, data, width, height, background = "white light_gray", gradient = False, colors = None) + + - Parameters + + name - Name of the desired output file, no need to input the .svg as it will be added at runtim; + data - The list, list of lists or dictionary holding the data to be plotted; + width, height - Dimensions of the output image; + background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. + If left None, a gray to white gradient will be generated; + gradient - Whether or not the pie color will be painted with a gradient; + shadow - Whether or not there will be a shadow behind the pie; + colors - List of slices colors. + + - Example of use + + teste_data = {"john" : 123, "mary" : 489, "philip" : 890 , "suzy" : 235} + CairoPlot.pie_plot("pie_teste", teste_data, 500, 500) + ''' + + plot = PiePlot( name, data, width, height, background, gradient, shadow, colors ) + plot.render() + plot.commit() + +def donut_plot(name, data, width, height, background = "white light_gray", gradient = False, shadow = False, colors = None, inner_radius = -1): + + ''' + - Function to plot donut graphics. + + donut_plot(name, data, width, height, background = "white light_gray", gradient = False, inner_radius = -1) + + - Parameters + + name - Name of the desired output file, no need to input the .svg as it will be added at runtim; + data - The list, list of lists or dictionary holding the data to be plotted; + width, height - Dimensions of the output image; + background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. + If left None, a gray to white gradient will be generated; + shadow - Whether or not there will be a shadow behind the donut; + gradient - Whether or not the donut color will be painted with a gradient; + colors - List of slices colors; + inner_radius - The radius of the donut's inner circle. + + - Example of use + + teste_data = {"john" : 123, "mary" : 489, "philip" : 890 , "suzy" : 235} + CairoPlot.donut_plot("donut_teste", teste_data, 500, 500) + ''' + + plot = DonutPlot(name, data, width, height, background, gradient, shadow, colors, inner_radius) + plot.render() + plot.commit() + +def gantt_chart(name, pieces, width, height, x_labels, y_labels, colors): + + ''' + - Function to generate Gantt Charts. + + gantt_chart(name, pieces, width, height, x_labels, y_labels, colors): + + - Parameters + + name - Name of the desired output file, no need to input the .svg as it will be added at runtim; + pieces - A list defining the spaces to be drawn. The user must pass, for each line, the index of its start and the index of its end. If a line must have two or more spaces, they must be passed inside a list; + width, height - Dimensions of the output image; + x_labels - A list of names for each of the vertical lines; + y_labels - A list of names for each of the horizontal spaces; + colors - List containing the colors expected for each of the horizontal spaces + + - Example of use + + pieces = [ (0.5,5.5) , [(0,4),(6,8)] , (5.5,7) , (7,8)] + x_labels = [ 'teste01', 'teste02', 'teste03', 'teste04'] + y_labels = [ '0001', '0002', '0003', '0004', '0005', '0006', '0007', '0008', '0009', '0010' ] + colors = [ (1.0, 0.0, 0.0), (1.0, 0.7, 0.0), (1.0, 1.0, 0.0), (0.0, 1.0, 0.0) ] + CairoPlot.gantt_chart('gantt_teste', pieces, 600, 300, x_labels, y_labels, colors) + ''' + + plot = GanttChart(name, pieces, width, height, x_labels, y_labels, colors) + plot.render() + plot.commit() + +def vertical_bar_plot(name, + data, + width, + height, + background = "white light_gray", + border = 0, + display_values = False, + grid = False, + rounded_corners = False, + stack = False, + three_dimension = False, + series_labels = None, + x_labels = None, + y_labels = None, + x_bounds = None, + y_bounds = None, + colors = None): + #TODO: Fix docstring for vertical_bar_plot + ''' + - Function to generate vertical Bar Plot Charts. + + bar_plot(name, data, width, height, background, border, grid, rounded_corners, three_dimension, + x_labels, y_labels, x_bounds, y_bounds, colors): + + - Parameters + + name - Name of the desired output file, no need to input the .svg as it will be added at runtime; + data - The list, list of lists or dictionary holding the data to be plotted; + width, height - Dimensions of the output image; + background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. + If left None, a gray to white gradient will be generated; + border - Distance in pixels of a square border into which the graphics will be drawn; + grid - Whether or not the gris is to be drawn; + rounded_corners - Whether or not the bars should have rounded corners; + three_dimension - Whether or not the bars should be drawn in pseudo 3D; + x_labels, y_labels - lists of strings containing the horizontal and vertical labels for the axis; + x_bounds, y_bounds - tuples containing the lower and upper value bounds for the data to be plotted; + colors - List containing the colors expected for each of the bars. + + - Example of use + + data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + CairoPlot.vertical_bar_plot ('bar2', data, 400, 300, border = 20, grid = True, rounded_corners = False) + ''' + + plot = VerticalBarPlot(name, data, width, height, background, border, + display_values, grid, rounded_corners, stack, three_dimension, + series_labels, x_labels, y_labels, x_bounds, y_bounds, colors) + plot.render() + plot.commit() + +def horizontal_bar_plot(name, + data, + width, + height, + background = "white light_gray", + border = 0, + display_values = False, + grid = False, + rounded_corners = False, + stack = False, + three_dimension = False, + series_labels = None, + x_labels = None, + y_labels = None, + x_bounds = None, + y_bounds = None, + colors = None): + + #TODO: Fix docstring for horizontal_bar_plot + ''' + - Function to generate Horizontal Bar Plot Charts. + + bar_plot(name, data, width, height, background, border, grid, rounded_corners, three_dimension, + x_labels, y_labels, x_bounds, y_bounds, colors): + + - Parameters + + name - Name of the desired output file, no need to input the .svg as it will be added at runtime; + data - The list, list of lists or dictionary holding the data to be plotted; + width, height - Dimensions of the output image; + background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. + If left None, a gray to white gradient will be generated; + border - Distance in pixels of a square border into which the graphics will be drawn; + grid - Whether or not the gris is to be drawn; + rounded_corners - Whether or not the bars should have rounded corners; + three_dimension - Whether or not the bars should be drawn in pseudo 3D; + x_labels, y_labels - lists of strings containing the horizontal and vertical labels for the axis; + x_bounds, y_bounds - tuples containing the lower and upper value bounds for the data to be plotted; + colors - List containing the colors expected for each of the bars. + + - Example of use + + data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + CairoPlot.bar_plot ('bar2', data, 400, 300, border = 20, grid = True, rounded_corners = False) + ''' + + plot = HorizontalBarPlot(name, data, width, height, background, border, + display_values, grid, rounded_corners, stack, three_dimension, + series_labels, x_labels, y_labels, x_bounds, y_bounds, colors) + plot.render() + plot.commit() + +def stream_chart(name, + data, + width, + height, + background = "white light_gray", + border = 0, + grid = False, + series_legend = None, + x_labels = None, + x_bounds = None, + y_bounds = None, + colors = None): + + #TODO: Fix docstring for horizontal_bar_plot + plot = StreamChart(name, data, width, height, background, border, + grid, series_legend, x_labels, x_bounds, y_bounds, colors) + plot.render() + plot.commit() + + +if __name__ == "__main__": + import tests + import seriestests diff --git a/bindings/python/examples/python2/output_format_modules/pprint_table.py b/bindings/python/examples/python2/output_format_modules/pprint_table.py new file mode 100644 index 0000000..3a63d62 --- /dev/null +++ b/bindings/python/examples/python2/output_format_modules/pprint_table.py @@ -0,0 +1,37 @@ +# pprint_table.py +# +# This module is used to pretty-print a table +# Adapted from +# http://ginstrom.com/scribbles/2007/09/04/pretty-printing-a-table-in-python/ + +import sys + +def get_max_width(table, index): + """Get the maximum width of the given column index""" + + return max([len(str(row[index])) for row in table]) + + +def pprint_table(table, nbLeft=1, out=sys.stdout): + """ + Prints out a table of data, padded for alignment + @param table: The table to print. A list of lists. + Each row must have the same number of columns. + @param nbLeft: The number of columns aligned left + @param out: Output stream (file-like object) + """ + + col_paddings = [] + + for i in range(len(table[0])): + col_paddings.append(get_max_width(table, i)) + + for row in table: + # left cols + for i in range(nbLeft): + print >> out, str(row[i]).ljust(col_paddings[i] + 1), + # rest of the cols + for i in range(nbLeft, len(row)): + col = str(row[i]).rjust(col_paddings[i] + 2) + print >> out, col, + print >> out diff --git a/bindings/python/examples/python2/output_format_modules/series.py b/bindings/python/examples/python2/output_format_modules/series.py new file mode 100644 index 0000000..8e8b236 --- /dev/null +++ b/bindings/python/examples/python2/output_format_modules/series.py @@ -0,0 +1,1140 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Serie.py +# +# Copyright (c) 2008 Magnun Leno da Silva +# +# Author: Magnun Leno da Silva +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser 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 Lesser 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 + +# Contributor: Rodrigo Moreiro Araujo + +#import cairoplot +import doctest + +NUMTYPES = (int, float, long) +LISTTYPES = (list, tuple) +STRTYPES = (str, unicode) +FILLING_TYPES = ['linear', 'solid', 'gradient'] +DEFAULT_COLOR_FILLING = 'solid' +#TODO: Define default color list +DEFAULT_COLOR_LIST = None + +class Data(object): + ''' + Class that models the main data structure. + It can hold: + - a number type (int, float or long) + - a tuple, witch represents a point and can have 2 or 3 items (x,y,z) + - if a list is passed it will be converted to a tuple. + + obs: In case a tuple is passed it will convert to tuple + ''' + def __init__(self, data=None, name=None, parent=None): + ''' + Starts main atributes from the Data class + @name - Name for each point; + @content - The real data, can be an int, float, long or tuple, which + represents a point (x,y) or (x,y,z); + @parent - A pointer that give the data access to it's parent. + + Usage: + >>> d = Data(name='empty'); print d + empty: () + >>> d = Data((1,1),'point a'); print d + point a: (1, 1) + >>> d = Data((1,2,3),'point b'); print d + point b: (1, 2, 3) + >>> d = Data([2,3],'point c'); print d + point c: (2, 3) + >>> d = Data(12, 'simple value'); print d + simple value: 12 + ''' + # Initial values + self.__content = None + self.__name = None + + # Setting passed values + self.parent = parent + self.name = name + self.content = data + + # Name property + @apply + def name(): + doc = ''' + Name is a read/write property that controls the input of name. + - If passed an invalid value it cleans the name with None + + Usage: + >>> d = Data(13); d.name = 'name_test'; print d + name_test: 13 + >>> d.name = 11; print d + 13 + >>> d.name = 'other_name'; print d + other_name: 13 + >>> d.name = None; print d + 13 + >>> d.name = 'last_name'; print d + last_name: 13 + >>> d.name = ''; print d + 13 + ''' + def fget(self): + ''' + returns the name as a string + ''' + return self.__name + + def fset(self, name): + ''' + Sets the name of the Data + ''' + if type(name) in STRTYPES and len(name) > 0: + self.__name = name + else: + self.__name = None + + + + return property(**locals()) + + # Content property + @apply + def content(): + doc = ''' + Content is a read/write property that validate the data passed + and return it. + + Usage: + >>> d = Data(); d.content = 13; d.content + 13 + >>> d = Data(); d.content = (1,2); d.content + (1, 2) + >>> d = Data(); d.content = (1,2,3); d.content + (1, 2, 3) + >>> d = Data(); d.content = [1,2,3]; d.content + (1, 2, 3) + >>> d = Data(); d.content = [1.5,.2,3.3]; d.content + (1.5, 0.20000000000000001, 3.2999999999999998) + ''' + def fget(self): + ''' + Return the content of Data + ''' + return self.__content + + def fset(self, data): + ''' + Ensures that data is a valid tuple/list or a number (int, float + or long) + ''' + # Type: None + if data is None: + self.__content = None + return + + # Type: Int or Float + elif type(data) in NUMTYPES: + self.__content = data + + # Type: List or Tuple + elif type(data) in LISTTYPES: + # Ensures the correct size + if len(data) not in (2, 3): + raise TypeError, "Data (as list/tuple) must have 2 or 3 items" + return + + # Ensures that all items in list/tuple is a number + isnum = lambda x : type(x) not in NUMTYPES + + if max(map(isnum, data)): + # An item in data isn't an int or a float + raise TypeError, "All content of data must be a number (int or float)" + + # Convert the tuple to list + if type(data) is list: + data = tuple(data) + + # Append a copy and sets the type + self.__content = data[:] + + # Unknown type! + else: + self.__content = None + raise TypeError, "Data must be an int, float or a tuple with two or three items" + return + + return property(**locals()) + + + def clear(self): + ''' + Clear the all Data (content, name and parent) + ''' + self.content = None + self.name = None + self.parent = None + + def copy(self): + ''' + Returns a copy of the Data structure + ''' + # The copy + new_data = Data() + if self.content is not None: + # If content is a point + if type(self.content) is tuple: + new_data.__content = self.content[:] + + # If content is a number + else: + new_data.__content = self.content + + # If it has a name + if self.name is not None: + new_data.__name = self.name + + return new_data + + def __str__(self): + ''' + Return a string representation of the Data structure + ''' + if self.name is None: + if self.content is None: + return '' + return str(self.content) + else: + if self.content is None: + return self.name+": ()" + return self.name+": "+str(self.content) + + def __len__(self): + ''' + Return the length of the Data. + - If it's a number return 1; + - If it's a list return it's length; + - If its None return 0. + ''' + if self.content is None: + return 0 + elif type(self.content) in NUMTYPES: + return 1 + return len(self.content) + + + + +class Group(object): + ''' + Class that models a group of data. Every value (int, float, long, tuple + or list) passed is converted to a list of Data. + It can receive: + - A single number (int, float, long); + - A list of numbers; + - A tuple of numbers; + - An instance of Data; + - A list of Data; + + Obs: If a tuple with 2 or 3 items is passed it is converted to a point. + If a tuple with only 1 item is passed it's converted to a number; + If a tuple with more than 2 items is passed it's converted to a + list of numbers + ''' + def __init__(self, group=None, name=None, parent=None): + ''' + Starts main atributes in Group instance. + @data_list - a list of data which forms the group; + @range - a range that represent the x axis of possible functions; + @name - name of the data group; + @parent - the Serie parent of this group. + + Usage: + >>> g = Group(13, 'simple number'); print g + simple number ['13'] + >>> g = Group((1,2), 'simple point'); print g + simple point ['(1, 2)'] + >>> g = Group([1,2,3,4], 'list of numbers'); print g + list of numbers ['1', '2', '3', '4'] + >>> g = Group((1,2,3,4),'int in tuple'); print g + int in tuple ['1', '2', '3', '4'] + >>> g = Group([(1,2),(2,3),(3,4)], 'list of points'); print g + list of points ['(1, 2)', '(2, 3)', '(3, 4)'] + >>> g = Group([[1,2,3],[1,2,3]], '2D coordinate lists'); print g + 2D coordinated lists ['(1, 1)', '(2, 2)', '(3, 3)'] + >>> g = Group([[1,2],[1,2],[1,2]], '3D coordinate lists'); print g + 3D coordinated lists ['(1, 1, 1)', '(2, 2, 2)'] + ''' + # Initial values + self.__data_list = [] + self.__range = [] + self.__name = None + + + self.parent = parent + self.name = name + self.data_list = group + + # Name property + @apply + def name(): + doc = ''' + Name is a read/write property that controls the input of name. + - If passed an invalid value it cleans the name with None + + Usage: + >>> g = Group(13); g.name = 'name_test'; print g + name_test ['13'] + >>> g.name = 11; print g + ['13'] + >>> g.name = 'other_name'; print g + other_name ['13'] + >>> g.name = None; print g + ['13'] + >>> g.name = 'last_name'; print g + last_name ['13'] + >>> g.name = ''; print g + ['13'] + ''' + def fget(self): + ''' + Returns the name as a string + ''' + return self.__name + + def fset(self, name): + ''' + Sets the name of the Group + ''' + if type(name) in STRTYPES and len(name) > 0: + self.__name = name + else: + self.__name = None + + return property(**locals()) + + # data_list property + @apply + def data_list(): + doc = ''' + The data_list is a read/write property that can be a list of + numbers, a list of points or a list of 2 or 3 coordinate lists. This + property uses mainly the self.add_data method. + + Usage: + >>> g = Group(); g.data_list = 13; print g + ['13'] + >>> g.data_list = (1,2); print g + ['(1, 2)'] + >>> g.data_list = Data((1,2),'point a'); print g + ['point a: (1, 2)'] + >>> g.data_list = [1,2,3]; print g + ['1', '2', '3'] + >>> g.data_list = (1,2,3,4); print g + ['1', '2', '3', '4'] + >>> g.data_list = [(1,2),(2,3),(3,4)]; print g + ['(1, 2)', '(2, 3)', '(3, 4)'] + >>> g.data_list = [[1,2],[1,2]]; print g + ['(1, 1)', '(2, 2)'] + >>> g.data_list = [[1,2],[1,2],[1,2]]; print g + ['(1, 1, 1)', '(2, 2, 2)'] + >>> g.range = (10); g.data_list = lambda x:x**2; print g + ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 4.0)', '(3.0, 9.0)', '(4.0, 16.0)', '(5.0, 25.0)', '(6.0, 36.0)', '(7.0, 49.0)', '(8.0, 64.0)', '(9.0, 81.0)'] + ''' + def fget(self): + ''' + Returns the value of data_list + ''' + return self.__data_list + + def fset(self, group): + ''' + Ensures that group is valid. + ''' + # None + if group is None: + self.__data_list = [] + + # Int/float/long or Instance of Data + elif type(group) in NUMTYPES or isinstance(group, Data): + # Clean data_list + self.__data_list = [] + self.add_data(group) + + # One point + elif type(group) is tuple and len(group) in (2,3): + self.__data_list = [] + self.add_data(group) + + # list of items + elif type(group) in LISTTYPES and type(group[0]) is not list: + # Clean data_list + self.__data_list = [] + for item in group: + # try to append and catch an exception + self.add_data(item) + + # function lambda + elif callable(group): + # Explicit is better than implicit + function = group + # Has range + if len(self.range) is not 0: + # Clean data_list + self.__data_list = [] + # Generate values for the lambda function + for x in self.range: + #self.add_data((x,round(group(x),2))) + self.add_data((x,function(x))) + + # Only have range in parent + elif self.parent is not None and len(self.parent.range) is not 0: + # Copy parent range + self.__range = self.parent.range[:] + # Clean data_list + self.__data_list = [] + # Generate values for the lambda function + for x in self.range: + #self.add_data((x,round(group(x),2))) + self.add_data((x,function(x))) + + # Don't have range anywhere + else: + # x_data don't exist + raise Exception, "Data argument is valid but to use function type please set x_range first" + + # Coordinate Lists + elif type(group) in LISTTYPES and type(group[0]) is list: + # Clean data_list + self.__data_list = [] + data = [] + if len(group) == 3: + data = zip(group[0], group[1], group[2]) + elif len(group) == 2: + data = zip(group[0], group[1]) + else: + raise TypeError, "Only one list of coordinates was received." + + for item in data: + self.add_data(item) + + else: + raise TypeError, "Group type not supported" + + return property(**locals()) + + @apply + def range(): + doc = ''' + The range is a read/write property that generates a range of values + for the x axis of the functions. When passed a tuple it almost works + like the built-in range funtion: + - 1 item, represent the end of the range started from 0; + - 2 items, represents the start and the end, respectively; + - 3 items, the last one represents the step; + + When passed a list the range function understands as a valid range. + + Usage: + >>> g = Group(); g.range = 10; print g.range + [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] + >>> g = Group(); g.range = (5); print g.range + [0.0, 1.0, 2.0, 3.0, 4.0] + >>> g = Group(); g.range = (1,7); print g.range + [1.0, 2.0, 3.0, 4.0, 5.0, 6.0] + >>> g = Group(); g.range = (0,10,2); print g.range + [0.0, 2.0, 4.0, 6.0, 8.0] + >>> + >>> g = Group(); g.range = [0]; print g.range + [0.0] + >>> g = Group(); g.range = [0,10,20]; print g.range + [0.0, 10.0, 20.0] + ''' + def fget(self): + ''' + Returns the range + ''' + return self.__range + + def fset(self, x_range): + ''' + Controls the input of a valid type and generate the range + ''' + # if passed a simple number convert to tuple + if type(x_range) in NUMTYPES: + x_range = (x_range,) + + # A list, just convert to float + if type(x_range) is list and len(x_range) > 0: + # Convert all to float + x_range = map(float, x_range) + # Prevents repeated values and convert back to list + self.__range = list(set(x_range[:])) + # Sort the list to ascending order + self.__range.sort() + + # A tuple, must check the lengths and generate the values + elif type(x_range) is tuple and len(x_range) in (1,2,3): + # Convert all to float + x_range = map(float, x_range) + + # Inital values + start = 0.0 + step = 1.0 + end = 0.0 + + # Only the end and it can't be less or iqual to 0 + if len(x_range) is 1 and x_range > 0: + end = x_range[0] + + # The start and the end but the start must be less then the end + elif len(x_range) is 2 and x_range[0] < x_range[1]: + start = x_range[0] + end = x_range[1] + + # All 3, but the start must be less then the end + elif x_range[0] <= x_range[1]: + start = x_range[0] + end = x_range[1] + step = x_range[2] + + # Starts the range + self.__range = [] + # Generate the range + # Can't use the range function because it doesn't support float values + while start < end: + self.__range.append(start) + start += step + + # Incorrect type + else: + raise Exception, "x_range must be a list with one or more items or a tuple with 2 or 3 items" + + return property(**locals()) + + def add_data(self, data, name=None): + ''' + Append a new data to the data_list. + - If data is an instance of Data, append it + - If it's an int, float, tuple or list create an instance of Data and append it + + Usage: + >>> g = Group() + >>> g.add_data(12); print g + ['12'] + >>> g.add_data(7,'other'); print g + ['12', 'other: 7'] + >>> + >>> g = Group() + >>> g.add_data((1,1),'a'); print g + ['a: (1, 1)'] + >>> g.add_data((2,2),'b'); print g + ['a: (1, 1)', 'b: (2, 2)'] + >>> + >>> g.add_data(Data((1,2),'c')); print g + ['a: (1, 1)', 'b: (2, 2)', 'c: (1, 2)'] + ''' + if not isinstance(data, Data): + # Try to convert + data = Data(data,name,self) + + if data.content is not None: + self.__data_list.append(data.copy()) + self.__data_list[-1].parent = self + + + def to_list(self): + ''' + Returns the group as a list of numbers (int, float or long) or a + list of tuples (points 2D or 3D). + + Usage: + >>> g = Group([1,2,3,4],'g1'); g.to_list() + [1, 2, 3, 4] + >>> g = Group([(1,2),(2,3),(3,4)],'g2'); g.to_list() + [(1, 2), (2, 3), (3, 4)] + >>> g = Group([(1,2,3),(3,4,5)],'g2'); g.to_list() + [(1, 2, 3), (3, 4, 5)] + ''' + return [data.content for data in self] + + def copy(self): + ''' + Returns a copy of this group + ''' + new_group = Group() + new_group.__name = self.__name + if self.__range is not None: + new_group.__range = self.__range[:] + for data in self: + new_group.add_data(data.copy()) + return new_group + + def get_names(self): + ''' + Return a list with the names of all data in this group + ''' + names = [] + for data in self: + if data.name is None: + names.append('Data '+str(data.index()+1)) + else: + names.append(data.name) + return names + + + def __str__ (self): + ''' + Returns a string representing the Group + ''' + ret = "" + if self.name is not None: + ret += self.name + " " + if len(self) > 0: + list_str = [str(item) for item in self] + ret += str(list_str) + else: + ret += "[]" + return ret + + def __getitem__(self, key): + ''' + Makes a Group iterable, based in the data_list property + ''' + return self.data_list[key] + + def __len__(self): + ''' + Returns the length of the Group, based in the data_list property + ''' + return len(self.data_list) + + +class Colors(object): + ''' + Class that models the colors its labels (names) and its properties, RGB + and filling type. + + It can receive: + - A list where each item is a list with 3 or 4 items. The + first 3 items represent the RGB values and the last argument + defines the filling type. The list will be converted to a dict + and each color will receve a name based in its position in the + list. + - A dictionary where each key will be the color name and its item + can be a list with 3 or 4 items. The first 3 items represent + the RGB colors and the last argument defines the filling type. + ''' + def __init__(self, color_list=None): + ''' + Start the color_list property + @ color_list - the list or dict contaning the colors properties. + ''' + self.__color_list = None + + self.color_list = color_list + + @apply + def color_list(): + doc = ''' + >>> c = Colors([[1,1,1],[2,2,2,'linear'],[3,3,3,'gradient']]) + >>> print c.color_list + {'Color 2': [2, 2, 2, 'linear'], 'Color 3': [3, 3, 3, 'gradient'], 'Color 1': [1, 1, 1, 'solid']} + >>> c.color_list = [[1,1,1],(2,2,2,'solid'),(3,3,3,'linear')] + >>> print c.color_list + {'Color 2': [2, 2, 2, 'solid'], 'Color 3': [3, 3, 3, 'linear'], 'Color 1': [1, 1, 1, 'solid']} + >>> c.color_list = {'a':[1,1,1],'b':(2,2,2,'solid'),'c':(3,3,3,'linear'), 'd':(4,4,4)} + >>> print c.color_list + {'a': [1, 1, 1, 'solid'], 'c': [3, 3, 3, 'linear'], 'b': [2, 2, 2, 'solid'], 'd': [4, 4, 4, 'solid']} + ''' + def fget(self): + ''' + Return the color list + ''' + return self.__color_list + + def fset(self, color_list): + ''' + Format the color list to a dictionary + ''' + if color_list is None: + self.__color_list = None + return + + if type(color_list) in LISTTYPES and type(color_list[0]) in LISTTYPES: + old_color_list = color_list[:] + color_list = {} + for index, color in enumerate(old_color_list): + if len(color) is 3 and max(map(type, color)) in NUMTYPES: + color_list['Color '+str(index+1)] = list(color)+[DEFAULT_COLOR_FILLING] + elif len(color) is 4 and max(map(type, color[:-1])) in NUMTYPES and color[-1] in FILLING_TYPES: + color_list['Color '+str(index+1)] = list(color) + else: + raise TypeError, "Unsuported color format" + elif type(color_list) is not dict: + raise TypeError, "Unsuported color format" + + for name, color in color_list.items(): + if len(color) is 3: + if max(map(type, color)) in NUMTYPES: + color_list[name] = list(color)+[DEFAULT_COLOR_FILLING] + else: + raise TypeError, "Unsuported color format" + elif len(color) is 4: + if max(map(type, color[:-1])) in NUMTYPES and color[-1] in FILLING_TYPES: + color_list[name] = list(color) + else: + raise TypeError, "Unsuported color format" + self.__color_list = color_list.copy() + + return property(**locals()) + + +class Series(object): + ''' + Class that models a Series (group of groups). Every value (int, float, + long, tuple or list) passed is converted to a list of Group or Data. + It can receive: + - a single number or point, will be converted to a Group of one Data; + - a list of numbers, will be converted to a group of numbers; + - a list of tuples, will converted to a single Group of points; + - a list of lists of numbers, each 'sublist' will be converted to a + group of numbers; + - a list of lists of tuples, each 'sublist' will be converted to a + group of points; + - a list of lists of lists, the content of the 'sublist' will be + processed as coordinated lists and the result will be converted to + a group of points; + - a Dictionary where each item can be the same of the list: number, + point, list of numbers, list of points or list of lists (coordinated + lists); + - an instance of Data; + - an instance of group. + ''' + def __init__(self, series=None, name=None, property=[], colors=None): + ''' + Starts main atributes in Group instance. + @series - a list, dict of data of which the series is composed; + @name - name of the series; + @property - a list/dict of properties to be used in the plots of + this Series + + Usage: + >>> print Series([1,2,3,4]) + ["Group 1 ['1', '2', '3', '4']"] + >>> print Series([[1,2,3],[4,5,6]]) + ["Group 1 ['1', '2', '3']", "Group 2 ['4', '5', '6']"] + >>> print Series((1,2)) + ["Group 1 ['(1, 2)']"] + >>> print Series([(1,2),(2,3)]) + ["Group 1 ['(1, 2)', '(2, 3)']"] + >>> print Series([[(1,2),(2,3)],[(4,5),(5,6)]]) + ["Group 1 ['(1, 2)', '(2, 3)']", "Group 2 ['(4, 5)', '(5, 6)']"] + >>> print Series([[[1,2,3],[1,2,3],[1,2,3]]]) + ["Group 1 ['(1, 1, 1)', '(2, 2, 2)', '(3, 3, 3)']"] + >>> print Series({'g1':[1,2,3], 'g2':[4,5,6]}) + ["g1 ['1', '2', '3']", "g2 ['4', '5', '6']"] + >>> print Series({'g1':[(1,2),(2,3)], 'g2':[(4,5),(5,6)]}) + ["g1 ['(1, 2)', '(2, 3)']", "g2 ['(4, 5)', '(5, 6)']"] + >>> print Series({'g1':[[1,2],[1,2]], 'g2':[[4,5],[4,5]]}) + ["g1 ['(1, 1)', '(2, 2)']", "g2 ['(4, 4)', '(5, 5)']"] + >>> print Series(Data(1,'d1')) + ["Group 1 ['d1: 1']"] + >>> print Series(Group([(1,2),(2,3)],'g1')) + ["g1 ['(1, 2)', '(2, 3)']"] + ''' + # Intial values + self.__group_list = [] + self.__name = None + self.__range = None + + # TODO: Implement colors with filling + self.__colors = None + + self.name = name + self.group_list = series + self.colors = colors + + # Name property + @apply + def name(): + doc = ''' + Name is a read/write property that controls the input of name. + - If passed an invalid value it cleans the name with None + + Usage: + >>> s = Series(13); s.name = 'name_test'; print s + name_test ["Group 1 ['13']"] + >>> s.name = 11; print s + ["Group 1 ['13']"] + >>> s.name = 'other_name'; print s + other_name ["Group 1 ['13']"] + >>> s.name = None; print s + ["Group 1 ['13']"] + >>> s.name = 'last_name'; print s + last_name ["Group 1 ['13']"] + >>> s.name = ''; print s + ["Group 1 ['13']"] + ''' + def fget(self): + ''' + Returns the name as a string + ''' + return self.__name + + def fset(self, name): + ''' + Sets the name of the Group + ''' + if type(name) in STRTYPES and len(name) > 0: + self.__name = name + else: + self.__name = None + + return property(**locals()) + + + + # Colors property + @apply + def colors(): + doc = ''' + >>> s = Series() + >>> s.colors = [[1,1,1],[2,2,2,'linear'],[3,3,3,'gradient']] + >>> print s.colors + {'Color 2': [2, 2, 2, 'linear'], 'Color 3': [3, 3, 3, 'gradient'], 'Color 1': [1, 1, 1, 'solid']} + >>> s.colors = [[1,1,1],(2,2,2,'solid'),(3,3,3,'linear')] + >>> print s.colors + {'Color 2': [2, 2, 2, 'solid'], 'Color 3': [3, 3, 3, 'linear'], 'Color 1': [1, 1, 1, 'solid']} + >>> s.colors = {'a':[1,1,1],'b':(2,2,2,'solid'),'c':(3,3,3,'linear'), 'd':(4,4,4)} + >>> print s.colors + {'a': [1, 1, 1, 'solid'], 'c': [3, 3, 3, 'linear'], 'b': [2, 2, 2, 'solid'], 'd': [4, 4, 4, 'solid']} + ''' + def fget(self): + ''' + Return the color list + ''' + return self.__colors.color_list + + def fset(self, colors): + ''' + Format the color list to a dictionary + ''' + self.__colors = Colors(colors) + + return property(**locals()) + + @apply + def range(): + doc = ''' + The range is a read/write property that generates a range of values + for the x axis of the functions. When passed a tuple it almost works + like the built-in range funtion: + - 1 item, represent the end of the range started from 0; + - 2 items, represents the start and the end, respectively; + - 3 items, the last one represents the step; + + When passed a list the range function understands as a valid range. + + Usage: + >>> s = Series(); s.range = 10; print s.range + [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0] + >>> s = Series(); s.range = (5); print s.range + [0.0, 1.0, 2.0, 3.0, 4.0, 5.0] + >>> s = Series(); s.range = (1,7); print s.range + [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] + >>> s = Series(); s.range = (0,10,2); print s.range + [0.0, 2.0, 4.0, 6.0, 8.0, 10.0] + >>> + >>> s = Series(); s.range = [0]; print s.range + [0.0] + >>> s = Series(); s.range = [0,10,20]; print s.range + [0.0, 10.0, 20.0] + ''' + def fget(self): + ''' + Returns the range + ''' + return self.__range + + def fset(self, x_range): + ''' + Controls the input of a valid type and generate the range + ''' + # if passed a simple number convert to tuple + if type(x_range) in NUMTYPES: + x_range = (x_range,) + + # A list, just convert to float + if type(x_range) is list and len(x_range) > 0: + # Convert all to float + x_range = map(float, x_range) + # Prevents repeated values and convert back to list + self.__range = list(set(x_range[:])) + # Sort the list to ascending order + self.__range.sort() + + # A tuple, must check the lengths and generate the values + elif type(x_range) is tuple and len(x_range) in (1,2,3): + # Convert all to float + x_range = map(float, x_range) + + # Inital values + start = 0.0 + step = 1.0 + end = 0.0 + + # Only the end and it can't be less or iqual to 0 + if len(x_range) is 1 and x_range > 0: + end = x_range[0] + + # The start and the end but the start must be lesser then the end + elif len(x_range) is 2 and x_range[0] < x_range[1]: + start = x_range[0] + end = x_range[1] + + # All 3, but the start must be lesser then the end + elif x_range[0] < x_range[1]: + start = x_range[0] + end = x_range[1] + step = x_range[2] + + # Starts the range + self.__range = [] + # Generate the range + # Cnat use the range function becouse it don't suport float values + while start <= end: + self.__range.append(start) + start += step + + # Incorrect type + else: + raise Exception, "x_range must be a list with one or more item or a tuple with 2 or 3 items" + + return property(**locals()) + + @apply + def group_list(): + doc = ''' + The group_list is a read/write property used to pre-process the list + of Groups. + It can be: + - a single number, point or lambda, will be converted to a single + Group of one Data; + - a list of numbers, will be converted to a group of numbers; + - a list of tuples, will converted to a single Group of points; + - a list of lists of numbers, each 'sublist' will be converted to + a group of numbers; + - a list of lists of tuples, each 'sublist' will be converted to a + group of points; + - a list of lists of lists, the content of the 'sublist' will be + processed as coordinated lists and the result will be converted + to a group of points; + - a list of lambdas, each lambda represents a Group; + - a Dictionary where each item can be the same of the list: number, + point, list of numbers, list of points, list of lists + (coordinated lists) or lambdas + - an instance of Data; + - an instance of group. + + Usage: + >>> s = Series() + >>> s.group_list = [1,2,3,4]; print s + ["Group 1 ['1', '2', '3', '4']"] + >>> s.group_list = [[1,2,3],[4,5,6]]; print s + ["Group 1 ['1', '2', '3']", "Group 2 ['4', '5', '6']"] + >>> s.group_list = (1,2); print s + ["Group 1 ['(1, 2)']"] + >>> s.group_list = [(1,2),(2,3)]; print s + ["Group 1 ['(1, 2)', '(2, 3)']"] + >>> s.group_list = [[(1,2),(2,3)],[(4,5),(5,6)]]; print s + ["Group 1 ['(1, 2)', '(2, 3)']", "Group 2 ['(4, 5)', '(5, 6)']"] + >>> s.group_list = [[[1,2,3],[1,2,3],[1,2,3]]]; print s + ["Group 1 ['(1, 1, 1)', '(2, 2, 2)', '(3, 3, 3)']"] + >>> s.group_list = [(0.5,5.5) , [(0,4),(6,8)] , (5.5,7) , (7,9)]; print s + ["Group 1 ['(0.5, 5.5)']", "Group 2 ['(0, 4)', '(6, 8)']", "Group 3 ['(5.5, 7)']", "Group 4 ['(7, 9)']"] + >>> s.group_list = {'g1':[1,2,3], 'g2':[4,5,6]}; print s + ["g1 ['1', '2', '3']", "g2 ['4', '5', '6']"] + >>> s.group_list = {'g1':[(1,2),(2,3)], 'g2':[(4,5),(5,6)]}; print s + ["g1 ['(1, 2)', '(2, 3)']", "g2 ['(4, 5)', '(5, 6)']"] + >>> s.group_list = {'g1':[[1,2],[1,2]], 'g2':[[4,5],[4,5]]}; print s + ["g1 ['(1, 1)', '(2, 2)']", "g2 ['(4, 4)', '(5, 5)']"] + >>> s.range = 10 + >>> s.group_list = lambda x:x*2 + >>> s.group_list = [lambda x:x*2, lambda x:x**2, lambda x:x**3]; print s + ["Group 1 ['(0.0, 0.0)', '(1.0, 2.0)', '(2.0, 4.0)', '(3.0, 6.0)', '(4.0, 8.0)', '(5.0, 10.0)', '(6.0, 12.0)', '(7.0, 14.0)', '(8.0, 16.0)', '(9.0, 18.0)', '(10.0, 20.0)']", "Group 2 ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 4.0)', '(3.0, 9.0)', '(4.0, 16.0)', '(5.0, 25.0)', '(6.0, 36.0)', '(7.0, 49.0)', '(8.0, 64.0)', '(9.0, 81.0)', '(10.0, 100.0)']", "Group 3 ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 8.0)', '(3.0, 27.0)', '(4.0, 64.0)', '(5.0, 125.0)', '(6.0, 216.0)', '(7.0, 343.0)', '(8.0, 512.0)', '(9.0, 729.0)', '(10.0, 1000.0)']"] + >>> s.group_list = {'linear':lambda x:x*2, 'square':lambda x:x**2, 'cubic':lambda x:x**3}; print s + ["cubic ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 8.0)', '(3.0, 27.0)', '(4.0, 64.0)', '(5.0, 125.0)', '(6.0, 216.0)', '(7.0, 343.0)', '(8.0, 512.0)', '(9.0, 729.0)', '(10.0, 1000.0)']", "linear ['(0.0, 0.0)', '(1.0, 2.0)', '(2.0, 4.0)', '(3.0, 6.0)', '(4.0, 8.0)', '(5.0, 10.0)', '(6.0, 12.0)', '(7.0, 14.0)', '(8.0, 16.0)', '(9.0, 18.0)', '(10.0, 20.0)']", "square ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 4.0)', '(3.0, 9.0)', '(4.0, 16.0)', '(5.0, 25.0)', '(6.0, 36.0)', '(7.0, 49.0)', '(8.0, 64.0)', '(9.0, 81.0)', '(10.0, 100.0)']"] + >>> s.group_list = Data(1,'d1'); print s + ["Group 1 ['d1: 1']"] + >>> s.group_list = Group([(1,2),(2,3)],'g1'); print s + ["g1 ['(1, 2)', '(2, 3)']"] + ''' + def fget(self): + ''' + Return the group list. + ''' + return self.__group_list + + def fset(self, series): + ''' + Controls the input of a valid group list. + ''' + #TODO: Add support to the following strem of data: [ (0.5,5.5) , [(0,4),(6,8)] , (5.5,7) , (7,9)] + + # Type: None + if series is None: + self.__group_list = [] + + # List or Tuple + elif type(series) in LISTTYPES: + self.__group_list = [] + + is_function = lambda x: callable(x) + # Groups + if list in map(type, series) or max(map(is_function, series)): + for group in series: + self.add_group(group) + + # single group + else: + self.add_group(series) + + #old code + ## List of numbers + #if type(series[0]) in NUMTYPES or type(series[0]) is tuple: + # print series + # self.add_group(series) + # + ## List of anything else + #else: + # for group in series: + # self.add_group(group) + + # Dict representing series of groups + elif type(series) is dict: + self.__group_list = [] + names = series.keys() + names.sort() + for name in names: + self.add_group(Group(series[name],name,self)) + + # A single lambda + elif callable(series): + self.__group_list = [] + self.add_group(series) + + # Int/float, instance of Group or Data + elif type(series) in NUMTYPES or isinstance(series, Group) or isinstance(series, Data): + self.__group_list = [] + self.add_group(series) + + # Default + else: + raise TypeError, "Serie type not supported" + + return property(**locals()) + + def add_group(self, group, name=None): + ''' + Append a new group in group_list + ''' + if not isinstance(group, Group): + #Try to convert + group = Group(group, name, self) + + if len(group.data_list) is not 0: + # Auto naming groups + if group.name is None: + group.name = "Group "+str(len(self.__group_list)+1) + + self.__group_list.append(group) + self.__group_list[-1].parent = self + + def copy(self): + ''' + Returns a copy of the Series + ''' + new_series = Series() + new_series.__name = self.__name + if self.__range is not None: + new_series.__range = self.__range[:] + #Add color property in the copy method + #self.__colors = None + + for group in self: + new_series.add_group(group.copy()) + + return new_series + + def get_names(self): + ''' + Returns a list of the names of all groups in the Serie + ''' + names = [] + for group in self: + if group.name is None: + names.append('Group '+str(group.index()+1)) + else: + names.append(group.name) + + return names + + def to_list(self): + ''' + Returns a list with the content of all groups and data + ''' + big_list = [] + for group in self: + for data in group: + if type(data.content) in NUMTYPES: + big_list.append(data.content) + else: + big_list = big_list + list(data.content) + return big_list + + def __getitem__(self, key): + ''' + Makes the Series iterable, based in the group_list property + ''' + return self.__group_list[key] + + def __str__(self): + ''' + Returns a string that represents the Series + ''' + ret = "" + if self.name is not None: + ret += self.name + " " + if len(self) > 0: + list_str = [str(item) for item in self] + ret += str(list_str) + else: + ret += "[]" + return ret + + def __len__(self): + ''' + Returns the length of the Series, based in the group_lsit property + ''' + return len(self.group_list) + + +if __name__ == '__main__': + doctest.testmod() diff --git a/bindings/python/examples/python2/softirqtimes.py b/bindings/python/examples/python2/softirqtimes.py new file mode 100755 index 0000000..59905c1 --- /dev/null +++ b/bindings/python/examples/python2/softirqtimes.py @@ -0,0 +1,154 @@ +#!/usr/bin/env python2 +# softirqtimes.py +# +# Babeltrace time of softirqs example script +# +# Copyright 2012 EfficiOS Inc. +# +# Author: Danny Serres +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# The script checks the number of events in the trace +# and outputs a table and a .svg histogram for the specified +# range (microseconds) or the total trace if no range specified. +# The graph is generated using the cairoplot module. + +# The script checks the trace for the amount of time +# spent from each softirq_raise to softirq_exit. +# It prints out the min, max (with timestamp), +# average times, the standard deviation and the total count. +# Using the cairoplot module, a .svg graph is also outputted +# showing the taken time in function of the time since the +# beginning of the trace. + +import sys, math +from output_format_modules import cairoplot +from babeltrace import * + +if len(sys.argv) < 2: + raise TypeError("Usage: python softirqtimes.py path/to/trace") + +ctx = Context() +ret = ctx.add_trace(sys.argv[1], "ctf") +if ret is None: + raise IOError("Error adding trace") + +time_taken = [] +graph_data = [] +max_time = (0.0, 0.0) # (val, ts) + +# tmp template: {(cpu_id, vec):TS raise} +tmp = {} +largest_val = 0 + +# Setting iterator +bp = IterPos(SEEK_BEGIN) +ctf_it = ctf.Iterator(ctx, bp) + +# Reading events +event = ctf_it.read_event() +start_time = event.get_timestamp() +while(event is not None): + + event_name = event.get_name() + error = True + appendNext = False + + if event_name == 'softirq_raise' or event_name == 'softirq_exit': + # Recover cpu_id and vec values to make a key to tmp + error = False + scope = event.get_top_level_scope(ctf.scope.STREAM_PACKET_CONTEXT) + field = event.get_field(scope, "cpu_id") + cpu_id = field.get_uint64() + if ctf.field_error(): + print("ERROR: Missing cpu_id info for {}".format( + event.get_name())) + error = True + + scope = event.get_top_level_scope(ctf.scope.EVENT_FIELDS) + field = event.get_field(scope, "_vec") + vec = field.get_uint64() + if ctf.field_error(): + print("ERROR: Missing vec info for {}".format( + event.get_name())) + error = True + key = (cpu_id, vec) + + if event_name == 'softirq_raise' and not error: + # Add timestamp to tmp + if key in tmp: + # If key already exists + i = 0 + while True: + # Add index + key = (cpu_id, vec, i) + if key in tmp: + i += 1 + continue + if i > largest_val: + largest_val = i + break + + tmp[key] = event.get_timestamp() + + if event_name == 'softirq_exit' and not error: + # Saving data for output + # Key check + if not (key in tmp): + i = 0 + while i <= largest_val: + key = (key[0], key[1], i) + if key in tmp: + break + i += 1 + + raise_timestamp = tmp[key] + time_data = event.get_timestamp() - tmp.pop(key) + if time_data > max_time[0]: + # max_time = (val, ts) + max_time = (time_data, raise_timestamp) + time_taken.append(time_data) + graph_data.append((raise_timestamp - start_time, time_data)) + + # Next Event + ret = ctf_it.next() + if ret < 0: + break + event = ctf_it.read_event() + + +del ctf_it + +# Standard dev. calc. +try: + mean = sum(time_taken)/float(len(time_taken)) +except ZeroDivisionError: + raise TypeError("empty data") +deviations_squared = [] +for x in time_taken: + deviations_squared.append(math.pow((x - mean), 2)) +try: + stddev = math.sqrt(sum(deviations_squared) / (len(deviations_squared) - 1)) +except ZeroDivisionError: + stddev = '-' + +# Terminal output +print("AVG TIME: {} ns".format(mean)) +print("MIN TIME: {} ns".format(min(time_taken))) +print("MAX TIME: {} ns, TS: {}".format(max_time[0], max_time[1])) +print("STD DEV: {}".format(stddev)) +print("TOTAL COUNT: {}".format(len(time_taken))) + +# Graph output +cairoplot.scatter_plot ( 'softirqtimes.svg', data = graph_data, + width = 5000, height = 4000, border = 20, axis = True, + grid = True, series_colors = ["red"] ) diff --git a/bindings/python/examples/python2/syscalls_by_pid.py b/bindings/python/examples/python2/syscalls_by_pid.py new file mode 100755 index 0000000..cf1d581 --- /dev/null +++ b/bindings/python/examples/python2/syscalls_by_pid.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python2 +# syscall_by_pid.py +# +# Babeltrace syscall by pid example script +# +# Copyright 2012 EfficiOS Inc. +# +# Author: Danny Serres +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# The script checks the number of events in the trace +# and outputs a table and a .svg histogram for the specified +# range (microseconds) or the total trace if no range specified. +# The graph is generated using the cairoplot module. + +# The script checks all syscall in the trace and prints a list +# showing the number of systemcalls executed by each PID +# ordered from greatest to least number of syscalls. +# The trace needs PID context (lttng add-context -k -t pid) + +import sys +from babeltrace import * +from output_format_modules.pprint_table import pprint_table as pprint + +if len(sys.argv) < 2 : + raise TypeError("Usage: python syscalls_by_pid.py path/to/trace") + +ctx = Context() +ret = ctx.add_trace(sys.argv[1], "ctf") +if ret is None: + raise IOError("Error adding trace") + +data = {} + +# Setting iterator +bp = IterPos(SEEK_BEGIN) +ctf_it = ctf.Iterator(ctx, bp) + +# Reading events +event = ctf_it.read_event() +while event is not None: + if event.get_name().find("sys") >= 0: + # Getting scope definition + sco = event.get_top_level_scope(ctf.scope.STREAM_EVENT_CONTEXT) + if sco is None: + print("ERROR: Cannot get definition scope for {}".format( + event.get_name())) + else: + # Getting PID + pid_field = event.get_field(sco, "_pid") + pid = pid_field.get_int64() + + if ctf.field_error(): + print("ERROR: Missing PID info for sched_switch".format( + event.get_name())) + elif pid in data: + data[pid] += 1 + else: + data[pid] = 1 + # Next event + ret = ctf_it.next() + if ret < 0: + break + event = ctf_it.read_event() + +del ctf_it + +# Setting table for output +table = [] +for item in data: + table.append([data[item], item]) # [count, pid] +table.sort(reverse = True) # [big count first, pid] +for i in range(len(table)): + table[i].reverse() # [pid, big count first] +table.insert(0, ["PID", "SYSCALL COUNT"]) +pprint(table) diff --git a/bindings/python/examples/sched_switch.py b/bindings/python/examples/sched_switch.py old mode 100644 new mode 100755 index 7ae834b..d5ed25b --- a/bindings/python/examples/sched_switch.py +++ b/bindings/python/examples/sched_switch.py @@ -1,18 +1,19 @@ +#!/usr/bin/env python3 # sched_switch.py -# +# # Babeltrace example script with sched_switch events -# +# # Copyright 2012 EfficiOS Inc. -# +# # Author: Danny Serres -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. diff --git a/bindings/python/examples/softirqtimes.py b/bindings/python/examples/softirqtimes.py deleted file mode 100644 index 903bf3e..0000000 --- a/bindings/python/examples/softirqtimes.py +++ /dev/null @@ -1,153 +0,0 @@ -# softirqtimes.py -# -# Babeltrace time of softirqs example script -# -# Copyright 2012 EfficiOS Inc. -# -# Author: Danny Serres -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# The script checks the number of events in the trace -# and outputs a table and a .svg histogram for the specified -# range (microseconds) or the total trace if no range specified. -# The graph is generated using the cairoplot module. - -# The script checks the trace for the amount of time -# spent from each softirq_raise to softirq_exit. -# It prints out the min, max (with timestamp), -# average times, the standard deviation and the total count. -# Using the cairoplot module, a .svg graph is also outputted -# showing the taken time in function of the time since the -# beginning of the trace. - -import sys, math -from output_format_modules import cairoplot -from babeltrace import * - -if len(sys.argv) < 2: - raise TypeError("Usage: python softirqtimes.py path/to/trace") - -ctx = Context() -ret = ctx.add_trace(sys.argv[1], "ctf") -if ret is None: - raise IOError("Error adding trace") - -time_taken = [] -graph_data = [] -max_time = (0.0, 0.0) # (val, ts) - -# tmp template: {(cpu_id, vec):TS raise} -tmp = {} -largest_val = 0 - -# Setting iterator -bp = IterPos(SEEK_BEGIN) -ctf_it = ctf.Iterator(ctx, bp) - -# Reading events -event = ctf_it.read_event() -start_time = event.get_timestamp() -while(event is not None): - - event_name = event.get_name() - error = True - appendNext = False - - if event_name == 'softirq_raise' or event_name == 'softirq_exit': - # Recover cpu_id and vec values to make a key to tmp - error = False - scope = event.get_top_level_scope(ctf.scope.STREAM_PACKET_CONTEXT) - field = event.get_field(scope, "cpu_id") - cpu_id = field.get_uint64() - if ctf.field_error(): - print("ERROR: Missing cpu_id info for {}".format( - event.get_name())) - error = True - - scope = event.get_top_level_scope(ctf.scope.EVENT_FIELDS) - field = event.get_field(scope, "_vec") - vec = field.get_uint64() - if ctf.field_error(): - print("ERROR: Missing vec info for {}".format( - event.get_name())) - error = True - key = (cpu_id, vec) - - if event_name == 'softirq_raise' and not error: - # Add timestamp to tmp - if key in tmp: - # If key already exists - i = 0 - while True: - # Add index - key = (cpu_id, vec, i) - if key in tmp: - i += 1 - continue - if i > largest_val: - largest_val = i - break - - tmp[key] = event.get_timestamp() - - if event_name == 'softirq_exit' and not error: - # Saving data for output - # Key check - if not (key in tmp): - i = 0 - while i <= largest_val: - key = (key[0], key[1], i) - if key in tmp: - break - i += 1 - - raise_timestamp = tmp[key] - time_data = event.get_timestamp() - tmp.pop(key) - if time_data > max_time[0]: - # max_time = (val, ts) - max_time = (time_data, raise_timestamp) - time_taken.append(time_data) - graph_data.append((raise_timestamp - start_time, time_data)) - - # Next Event - ret = ctf_it.next() - if ret < 0: - break - event = ctf_it.read_event() - - -del ctf_it - -# Standard dev. calc. -try: - mean = sum(time_taken)/float(len(time_taken)) -except ZeroDivisionError: - raise TypeError("empty data") -deviations_squared = [] -for x in time_taken: - deviations_squared.append(math.pow((x - mean), 2)) -try: - stddev = math.sqrt(sum(deviations_squared) / (len(deviations_squared) - 1)) -except ZeroDivisionError: - stddev = '-' - -# Terminal output -print("AVG TIME: {} ns".format(mean)) -print("MIN TIME: {} ns".format(min(time_taken))) -print("MAX TIME: {} ns, TS: {}".format(max_time[0], max_time[1])) -print("STD DEV: {}".format(stddev)) -print("TOTAL COUNT: {}".format(len(time_taken))) - -# Graph output -cairoplot.scatter_plot ( 'softirqtimes.svg', data = graph_data, - width = 5000, height = 4000, border = 20, axis = True, - grid = True, series_colors = ["red"] ) diff --git a/bindings/python/examples/syscalls_by_pid.py b/bindings/python/examples/syscalls_by_pid.py deleted file mode 100644 index 3ae342e..0000000 --- a/bindings/python/examples/syscalls_by_pid.py +++ /dev/null @@ -1,84 +0,0 @@ -# syscall_by_pid.py -# -# Babeltrace syscall by pid example script -# -# Copyright 2012 EfficiOS Inc. -# -# Author: Danny Serres -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# The script checks the number of events in the trace -# and outputs a table and a .svg histogram for the specified -# range (microseconds) or the total trace if no range specified. -# The graph is generated using the cairoplot module. - -# The script checks all syscall in the trace and prints a list -# showing the number of systemcalls executed by each PID -# ordered from greatest to least number of syscalls. -# The trace needs PID context (lttng add-context -k -t pid) - -import sys -from babeltrace import * -from output_format_modules.pprint_table import pprint_table as pprint - -if len(sys.argv) < 2 : - raise TypeError("Usage: python syscalls_by_pid.py path/to/trace") - -ctx = Context() -ret = ctx.add_trace(sys.argv[1], "ctf") -if ret is None: - raise IOError("Error adding trace") - -data = {} - -# Setting iterator -bp = IterPos(SEEK_BEGIN) -ctf_it = ctf.Iterator(ctx, bp) - -# Reading events -event = ctf_it.read_event() -while event is not None: - if event.get_name().find("sys") >= 0: - # Getting scope definition - sco = event.get_top_level_scope(ctf.scope.STREAM_EVENT_CONTEXT) - if sco is None: - print("ERROR: Cannot get definition scope for {}".format( - event.get_name())) - else: - # Getting PID - pid_field = event.get_field(sco, "_pid") - pid = pid_field.get_int64() - - if ctf.field_error(): - print("ERROR: Missing PID info for sched_switch".format( - event.get_name())) - elif pid in data: - data[pid] += 1 - else: - data[pid] = 1 - # Next event - ret = ctf_it.next() - if ret < 0: - break - event = ctf_it.read_event() - -del ctf_it - -# Setting table for output -table = [] -for item in data: - table.append([data[item], item]) # [count, pid] -table.sort(reverse = True) # [big count first, pid] -for i in range(len(table)): - table[i].reverse() # [pid, big count first] -table.insert(0, ["PID", "SYSCALL COUNT"]) -pprint(table) diff --git a/tests/tests-python.py b/tests/tests-python.py old mode 100644 new mode 100755 index 0bd71c2..8695f61 --- a/tests/tests-python.py +++ b/tests/tests-python.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import unittest import sys from babeltrace import * -- 1.8.1.1 From mathieu.desnoyers at efficios.com Thu Jan 31 14:13:44 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 31 Jan 2013 14:13:44 -0500 Subject: [lttng-dev] [PATCH babeltrace 1/2] Added Python 3.0 or better requirement to the README file In-Reply-To: <1359640251-6133-1-git-send-email-jeremie.galarneau@efficios.com> References: <1359640251-6133-1-git-send-email-jeremie.galarneau@efficios.com> Message-ID: <20130131191344.GA15166@Krystal> * J?r?mie Galarneau (jeremie.galarneau at efficios.com) wrote: > > Signed-off-by: J?r?mie Galarneau merged, thanks! > --- > README | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/README b/README > index 9df02e7..ce98e24 100644 > --- a/README > +++ b/README > @@ -49,6 +49,8 @@ To compile Babeltrace, you will need: > (Debian/Ubuntu : python-dev) > swig >= 2.0 (optional) > (Debian/Ubuntu : swig2.0) > + python 3.0 or better (optional) > + (Debian/Ubuntu : python3) > > > For developers using the git tree: > -- > 1.8.1.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Thu Jan 31 14:16:15 2013 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 31 Jan 2013 14:16:15 -0500 Subject: [lttng-dev] [PATCH babeltrace 2/2] Added Python interpreter version directives and reorganized example scripts In-Reply-To: <1359640251-6133-2-git-send-email-jeremie.galarneau@efficios.com> References: <1359640251-6133-1-git-send-email-jeremie.galarneau@efficios.com> <1359640251-6133-2-git-send-email-jeremie.galarneau@efficios.com> Message-ID: <20130131191614.GB15166@Krystal> * J?r?mie Galarneau (jeremie.galarneau at efficios.com) wrote: > > Signed-off-by: J?r?mie Galarneau merged into bindings/python branch too. Thanks, Mathieu > --- > bindings/python/examples/babeltrace_and_lttng.py | 12 +- > bindings/python/examples/eventcount.py | 84 - > bindings/python/examples/eventcountlist.py | 83 - > bindings/python/examples/events_per_cpu.py | 99 - > bindings/python/examples/example-api-test.py | 11 +- > bindings/python/examples/histogram.py | 139 -- > .../examples/output_format_modules/cairoplot.py | 2336 -------------------- > .../examples/output_format_modules/pprint_table.py | 37 - > .../examples/output_format_modules/series.py | 1140 ---------- > bindings/python/examples/python2/eventcount.py | 85 + > bindings/python/examples/python2/eventcountlist.py | 84 + > bindings/python/examples/python2/events_per_cpu.py | 100 + > bindings/python/examples/python2/histogram.py | 140 ++ > .../python2/output_format_modules/cairoplot.py | 2336 ++++++++++++++++++++ > .../python2/output_format_modules/pprint_table.py | 37 + > .../python2/output_format_modules/series.py | 1140 ++++++++++ > bindings/python/examples/python2/softirqtimes.py | 154 ++ > .../python/examples/python2/syscalls_by_pid.py | 85 + > bindings/python/examples/sched_switch.py | 11 +- > bindings/python/examples/softirqtimes.py | 153 -- > bindings/python/examples/syscalls_by_pid.py | 84 - > tests/tests-python.py | 1 + > 22 files changed, 4183 insertions(+), 4168 deletions(-) > mode change 100644 => 100755 bindings/python/examples/babeltrace_and_lttng.py > delete mode 100644 bindings/python/examples/eventcount.py > delete mode 100644 bindings/python/examples/eventcountlist.py > delete mode 100644 bindings/python/examples/events_per_cpu.py > mode change 100644 => 100755 bindings/python/examples/example-api-test.py > delete mode 100644 bindings/python/examples/histogram.py > delete mode 100644 bindings/python/examples/output_format_modules/cairoplot.py > delete mode 100644 bindings/python/examples/output_format_modules/pprint_table.py > delete mode 100644 bindings/python/examples/output_format_modules/series.py > create mode 100755 bindings/python/examples/python2/eventcount.py > create mode 100755 bindings/python/examples/python2/eventcountlist.py > create mode 100755 bindings/python/examples/python2/events_per_cpu.py > create mode 100755 bindings/python/examples/python2/histogram.py > create mode 100644 bindings/python/examples/python2/output_format_modules/cairoplot.py > create mode 100644 bindings/python/examples/python2/output_format_modules/pprint_table.py > create mode 100644 bindings/python/examples/python2/output_format_modules/series.py > create mode 100755 bindings/python/examples/python2/softirqtimes.py > create mode 100755 bindings/python/examples/python2/syscalls_by_pid.py > mode change 100644 => 100755 bindings/python/examples/sched_switch.py > delete mode 100644 bindings/python/examples/softirqtimes.py > delete mode 100644 bindings/python/examples/syscalls_by_pid.py > mode change 100644 => 100755 tests/tests-python.py > > diff --git a/bindings/python/examples/babeltrace_and_lttng.py b/bindings/python/examples/babeltrace_and_lttng.py > old mode 100644 > new mode 100755 > index cb44796..cfd611f > --- a/bindings/python/examples/babeltrace_and_lttng.py > +++ b/bindings/python/examples/babeltrace_and_lttng.py > @@ -1,3 +1,4 @@ > +#!/usr/bin/env python3 > # babeltrace_and_lttng.py > # > # Babeltrace and LTTng example script > @@ -59,18 +60,23 @@ ret = lttng.create(ses_name,trace_path) > if ret < 0: > raise LTTngError(lttng.strerror(ret)) > > +domain = lttng.Domain() > +domain.type = lttng.DOMAIN_KERNEL > + > han = None > -han = lttng.Handle(ses_name, lttng.Domain()) > +han = lttng.Handle(ses_name, domain) > if han is None: > raise LTTngError("Handle not created") > > > # Enabling all events > -ret = lttng.enable_event(han, lttng.Event(), None) > +event = lttng.Event() > +event.type = lttng.EVENT_ALL > +event.loglevel_type = lttng.EVENT_LOGLEVEL_ALL > +ret = lttng.enable_event(han, event, None) > if ret < 0: > raise LTTngError(lttng.strerror(ret)) > > - > # Start, wait, stop > ret = lttng.start(ses_name) > if ret < 0: > diff --git a/bindings/python/examples/eventcount.py b/bindings/python/examples/eventcount.py > deleted file mode 100644 > index 5e96a43..0000000 > --- a/bindings/python/examples/eventcount.py > +++ /dev/null > @@ -1,84 +0,0 @@ > -# eventcount.py > -# > -# Babeltrace event count example script > -# > -# Copyright 2012 EfficiOS Inc. > -# > -# Author: Danny Serres > -# > -# Permission is hereby granted, free of charge, to any person obtaining a copy > -# of this software and associated documentation files (the "Software"), to deal > -# in the Software without restriction, including without limitation the rights > -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > -# copies of the Software, and to permit persons to whom the Software is > -# furnished to do so, subject to the following conditions: > -# > -# The above copyright notice and this permission notice shall be included in > -# all copies or substantial portions of the Software. > - > -# The script prints a count of specified events and > -# their related tid's in a given trace. > -# The trace needs TID context (lttng add-context -k -t tid) > - > -import sys > -from babeltrace import * > -from output_format_modules.pprint_table import pprint_table as pprint > - > -if len(sys.argv) < 3: > - raise TypeError("Usage: python eventcount.py event1 [event2 ...] path/to/trace") > - > -ctx = Context() > -ret = ctx.add_trace(sys.argv[len(sys.argv)-1], "ctf") > -if ret is None: > - raise IOError("Error adding trace") > - > -counts = {} > - > -# Setting iterator > -bp = IterPos(SEEK_BEGIN) > -ctf_it = ctf.Iterator(ctx, bp) > - > -# Reading events > -event = ctf_it.read_event() > -while(event is not None): > - for event_type in sys.argv[1:len(sys.argv)-1]: > - if event_type == event.get_name(): > - > - # Getting scope definition > - sco = event.get_top_level_scope(ctf.scope.STREAM_EVENT_CONTEXT) > - if sco is None: > - print("ERROR: Cannot get definition scope for {}".format( > - event.get_name())) > - continue > - > - # Getting TID > - tid_field = event.get_field(sco, "_tid") > - tid = tid_field.get_int64() > - > - if ctf.field_error(): > - print("ERROR: Missing TID info for {}".format( > - event.get_name())) > - continue > - > - tmp = (tid, event.get_name()) > - > - if tmp in counts: > - counts[tmp] += 1 > - else: > - counts[tmp] = 1 > - > - # Next event > - ret = ctf_it.next() > - if ret < 0: > - break > - event = ctf_it.read_event() > - > -del ctf_it > - > -# Appending data to table for output > -table = [] > -for item in counts: > - table.append([item[0], item[1], counts[item]]) > -table = sorted(table) > -table.insert(0,["TID", "EVENT", "COUNT"]) > -pprint(table, 2) > diff --git a/bindings/python/examples/eventcountlist.py b/bindings/python/examples/eventcountlist.py > deleted file mode 100644 > index 945a960..0000000 > --- a/bindings/python/examples/eventcountlist.py > +++ /dev/null > @@ -1,83 +0,0 @@ > -# eventcountlist.py > -# > -# Babeltrace event count list example script > -# > -# Copyright 2012 EfficiOS Inc. > -# > -# Author: Danny Serres > -# > -# Permission is hereby granted, free of charge, to any person obtaining a copy > -# of this software and associated documentation files (the "Software"), to deal > -# in the Software without restriction, including without limitation the rights > -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > -# copies of the Software, and to permit persons to whom the Software is > -# furnished to do so, subject to the following conditions: > -# > -# The above copyright notice and this permission notice shall be included in > -# all copies or substantial portions of the Software. > - > -# The script prints a count and rate of events. > -# It also outputs a bar graph of count per event, using the cairoplot module. > - > -import sys > -from babeltrace import * > -from output_format_modules import cairoplot > -from output_format_modules.pprint_table import pprint_table as pprint > - > -# Check for path arg: > -if len(sys.argv) < 2: > - raise TypeError("Usage: python eventcountlist.py path/to/trace") > - > -ctx = Context() > -ret = ctx.add_trace(sys.argv[1], "ctf") > -if ret is None: > - raise IOError("Error adding trace") > - > -# Events and their assossiated count > -# will be stored as a dict: > -events_count = {} > - > -# Setting iterator: > -bp = IterPos(SEEK_BEGIN) > -ctf_it = ctf.Iterator(ctx,bp) > - > -prev_event = None > -event = ctf_it.read_event() > - > -start_time = event.get_timestamp() > - > -# Reading events: > -while(event is not None): > - if event.get_name() in events_count: > - events_count[event.get_name()] += 1 > - else: > - events_count[event.get_name()] = 1 > - > - ret = ctf_it.next() > - if ret < 0: > - break > - else: > - prev_event = event > - event = ctf_it.read_event() > - > -if event: > - total_time = event.get_timestamp() - start_time > -else: > - total_time = prev_event.get_timestamp() - start_time > - > -del ctf_it > - > -# Printing encountered events with respective count and rate: > -print("Total time: {} ns".format(total_time)) > -table = [["EVENT", "COUNT", "RATE (Hz)"]] > -for item in sorted(events_count.iterkeys()): > - tmp = [item, events_count[item], > - events_count[item]/(total_time/1000000000.0)] > - table.append(tmp) > -pprint(table) > - > -# Exporting data as bar graph > -cairoplot.vertical_bar_plot ( 'eventcountlist.svg', events_count, 50+85*len(events_count), > - 800, border = 20, display_values = True, grid = True, > - rounded_corners = True, > - x_labels = sorted(events_count.keys()) ) > diff --git a/bindings/python/examples/events_per_cpu.py b/bindings/python/examples/events_per_cpu.py > deleted file mode 100644 > index be497ec..0000000 > --- a/bindings/python/examples/events_per_cpu.py > +++ /dev/null > @@ -1,99 +0,0 @@ > -# events_per_cpu.py > -# > -# Babeltrace events per cpu example script > -# > -# Copyright 2012 EfficiOS Inc. > -# > -# Author: Danny Serres > -# > -# Permission is hereby granted, free of charge, to any person obtaining a copy > -# of this software and associated documentation files (the "Software"), to deal > -# in the Software without restriction, including without limitation the rights > -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > -# copies of the Software, and to permit persons to whom the Software is > -# furnished to do so, subject to the following conditions: > -# > -# The above copyright notice and this permission notice shall be included in > -# all copies or substantial portions of the Software. > - > -# The script opens a trace and prints out CPU statistics > -# for the given trace (event count per CPU, total active > -# time and % of time processing events). > -# It also outputs a .txt file showing each time interval > -# (since the beginning of the trace) in which each CPU > -# was active and the corresponding event. > - > -import sys, multiprocessing > -from output_format_modules.pprint_table import pprint_table as pprint > -from babeltrace import * > - > -if len(sys.argv) < 2: > - raise TypeError("Usage: python events_per_cpu.py path/to/trace") > - > -# Adding trace > -ctx = Context() > -ret = ctx.add_trace(sys.argv[1], "ctf") > -if ret is None: > - raise IOError("Error adding trace") > - > -cpu_usage = [] > -nbEvents = 0 > -i = 0 > -while i < multiprocessing.cpu_count(): > - cpu_usage.append([]) > - i += 1 > - > -# Setting iterator > -bp = IterPos(SEEK_BEGIN) > -ctf_it = ctf.Iterator(ctx, bp) > - > -# Reading events > -event = ctf_it.read_event() > -start_time = event.get_timestamp() > - > -while(event is not None): > - > - event_name = event.get_name() > - ts = event.get_timestamp() > - > - # Getting cpu_id > - scope = event.get_top_level_scope(ctf.scope.STREAM_PACKET_CONTEXT) > - field = event.get_field(scope, "cpu_id") > - cpu_id = field.get_uint64() > - if ctf.field_error(): > - print("ERROR: Missing cpu_id info for {}".format(event.get_name())) > - else: > - cpu_usage[cpu_id].append( (int(ts), event_name) ) > - nbEvents += 1 > - > - # Next Event > - ret = ctf_it.next() > - if ret < 0: > - break > - event = ctf_it.read_event() > - > - > -# Outputting > -table = [] > -output = open("events_per_cpu.txt", "wt") > -output.write("(timestamp, event)\n") > - > -for cpu in range(len(cpu_usage)): > - # Setting table > - event_str = str(100.0 * len(cpu_usage[cpu]) / nbEvents) + '000' > - # % is printed with 2 decimals > - table.append([cpu, len(cpu_usage[cpu]), event_str[0:event_str.find('.') + 3] + ' %']) > - > - # Writing to file > - output.write("\n\n\n----------------------\n") > - output.write("CPU {}\n\n".format(cpu)) > - for event in cpu_usage[cpu]: > - output.write(str(event) + '\n') > - > -# Printing table > -table.insert(0, ["CPU ID", "EVENT COUNT", "TRACE EVENT %"]) > -pprint(table) > -print("Total event count: {}".format(nbEvents)) > -print("Total trace time: {} ns".format(ts - start_time)) > - > -output.close() > diff --git a/bindings/python/examples/example-api-test.py b/bindings/python/examples/example-api-test.py > old mode 100644 > new mode 100755 > index 104f2d5..fc59e24 > --- a/bindings/python/examples/example-api-test.py > +++ b/bindings/python/examples/example-api-test.py > @@ -1,18 +1,19 @@ > +#!/usr/bin/env python3 > # example_api_test.py > -# > +# > # Babeltrace example script based on the Babeltrace API test script > -# > +# > # Copyright 2012 EfficiOS Inc. > -# > +# > # Author: Danny Serres > -# > +# > # Permission is hereby granted, free of charge, to any person obtaining a copy > # of this software and associated documentation files (the "Software"), to deal > # in the Software without restriction, including without limitation the rights > # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > # copies of the Software, and to permit persons to whom the Software is > # furnished to do so, subject to the following conditions: > -# > +# > # The above copyright notice and this permission notice shall be included in > # all copies or substantial portions of the Software. > > diff --git a/bindings/python/examples/histogram.py b/bindings/python/examples/histogram.py > deleted file mode 100644 > index 44616a6..0000000 > --- a/bindings/python/examples/histogram.py > +++ /dev/null > @@ -1,139 +0,0 @@ > -# histogram.py > -# > -# Babeltrace histogram example script > -# > -# Copyright 2012 EfficiOS Inc. > -# > -# Author: Danny Serres > -# > -# Permission is hereby granted, free of charge, to any person obtaining a copy > -# of this software and associated documentation files (the "Software"), to deal > -# in the Software without restriction, including without limitation the rights > -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > -# copies of the Software, and to permit persons to whom the Software is > -# furnished to do so, subject to the following conditions: > -# > -# The above copyright notice and this permission notice shall be included in > -# all copies or substantial portions of the Software. > - > -# The script checks the number of events in the trace > -# and outputs a table and a .svg histogram for the specified > -# range (microseconds) or the total trace if no range specified. > -# The graph is generated using the cairoplot module. > - > -import sys > -from babeltrace import * > -from output_format_modules import cairoplot > -from output_format_modules.pprint_table import pprint_table as pprint > - > -# ------------------------------------------------ > -# Output settings > - > -# number of intervals: > -nbDiv = 25 # Should not be over 150 > - # for usable graph output > - > -# table output stream (file-like object): > -out = sys.stdout > -# ------------------------------------------------- > - > -if len(sys.argv) < 2 or len(sys.argv) > 4: > - raise TypeError("Usage: python histogram.py [ start_time [end_time] ] path/to/trace") > - > -ctx = Context() > -ret = ctx.add_trace(sys.argv[len(sys.argv)-1], "ctf") > -if ret is None: > - raise IOError("Error adding trace") > - > -# Check when to start/stop graphing > -sinceBegin = True > -beginTime = 0.0 > -if len(sys.argv) > 2: > - sinceBegin = False > - beginTime = float(sys.argv[1]) > -untilEnd = True > -if len(sys.argv) == 4: > - untilEnd = False > - > -# Setting iterator > -bp = IterPos(SEEK_BEGIN) > -ctf_it = ctf.Iterator(ctx, bp) > - > -# Reading events > -event = ctf_it.read_event() > -start_time = event.get_timestamp() > -time = 0 > -count = {} > - > -while(event is not None): > - # Microsec. > - time = (event.get_timestamp() - start_time)/1000.0 > - > - # Check if in range > - if not sinceBegin: > - if time < beginTime: > - # Next Event > - ret = ctf_it.next() > - if ret < 0: > - break > - event = ctf_it.read_event() > - continue > - if not untilEnd: > - if time > float(sys.argv[2]): > - break > - > - # Counting events per timestamp: > - if time in count: > - count[time] += 1 > - else: > - count[time] = 1 > - > - # Next Event > - ret = ctf_it.next() > - if ret < 0: > - break > - event = ctf_it.read_event() > - > -del ctf_it > - > -# Setting data for output > -interval = (time - beginTime)/nbDiv > -div_begin_time = beginTime > -div_end_time = beginTime + interval > -data = {} > - > -# Prefix for string sorting, considering > -# there should not be over 150 intervals. > -# This would work up to 9999 intervals. > -# If needed, add zeros. > -prefix = 0.0001 > - > -while div_end_time <= time: > - key = str(prefix) + '[' + str(div_begin_time) + ';' + str(div_end_time) + '[' > - for tmp in count: > - if tmp >= div_begin_time and tmp < div_end_time: > - if key in data: > - data[key] += count[tmp] > - else: > - data[key] = count[tmp] > - if not key in data: > - data[key] = 0 > - div_begin_time = div_end_time > - div_end_time += interval > - # Prefix increment > - prefix += 0.001 > - > -table = [] > -x_labels = [] > -for key in sorted(data): > - table.append([key[key.find('['):], data[key]]) > - x_labels.append(key[key.find('['):]) > - > -# Table output > -table.insert(0, ["INTERVAL (us)", "COUNT"]) > -pprint(table, 1, out) > - > -# Graph output > -cairoplot.vertical_bar_plot ( 'histogram.svg', data, 50 + 150*nbDiv, 50*nbDiv, > - border = 20, display_values = True, grid = True, > - x_labels = x_labels, rounded_corners = True ) > diff --git a/bindings/python/examples/output_format_modules/cairoplot.py b/bindings/python/examples/output_format_modules/cairoplot.py > deleted file mode 100644 > index a27113f..0000000 > --- a/bindings/python/examples/output_format_modules/cairoplot.py > +++ /dev/null > @@ -1,2336 +0,0 @@ > -?#!/usr/bin/env python > -# -*- coding: utf-8 -*- > - > -# CairoPlot.py > -# > -# Copyright (c) 2008 Rodrigo Moreira Ara?jo > -# > -# Author: Rodrigo Moreiro Araujo > -# > -# This program is free software; you can redistribute it and/or > -# modify it under the terms of the GNU Lesser 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 Lesser 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 > - > -#Contributor: Jo?o S. O. Bueno > - > -#TODO: review BarPlot Code > -#TODO: x_label colision problem on Horizontal Bar Plot > -#TODO: y_label's eat too much space on HBP > - > - > -__version__ = 1.2 > - > -import cairo > -import math > -import random > -from series import Series, Group, Data > - > -HORZ = 0 > -VERT = 1 > -NORM = 2 > - > -COLORS = {"red" : (1.0,0.0,0.0,1.0), "lime" : (0.0,1.0,0.0,1.0), "blue" : (0.0,0.0,1.0,1.0), > - "maroon" : (0.5,0.0,0.0,1.0), "green" : (0.0,0.5,0.0,1.0), "navy" : (0.0,0.0,0.5,1.0), > - "yellow" : (1.0,1.0,0.0,1.0), "magenta" : (1.0,0.0,1.0,1.0), "cyan" : (0.0,1.0,1.0,1.0), > - "orange" : (1.0,0.5,0.0,1.0), "white" : (1.0,1.0,1.0,1.0), "black" : (0.0,0.0,0.0,1.0), > - "gray" : (0.5,0.5,0.5,1.0), "light_gray" : (0.9,0.9,0.9,1.0), > - "transparent" : (0.0,0.0,0.0,0.0)} > - > -THEMES = {"black_red" : [(0.0,0.0,0.0,1.0), (1.0,0.0,0.0,1.0)], > - "red_green_blue" : [(1.0,0.0,0.0,1.0), (0.0,1.0,0.0,1.0), (0.0,0.0,1.0,1.0)], > - "red_orange_yellow" : [(1.0,0.2,0.0,1.0), (1.0,0.7,0.0,1.0), (1.0,1.0,0.0,1.0)], > - "yellow_orange_red" : [(1.0,1.0,0.0,1.0), (1.0,0.7,0.0,1.0), (1.0,0.2,0.0,1.0)], > - "rainbow" : [(1.0,0.0,0.0,1.0), (1.0,0.5,0.0,1.0), (1.0,1.0,0.0,1.0), (0.0,1.0,0.0,1.0), (0.0,0.0,1.0,1.0), (0.3, 0.0, 0.5,1.0), (0.5, 0.0, 1.0, 1.0)]} > - > -def colors_from_theme( theme, series_length, mode = 'solid' ): > - colors = [] > - if theme not in THEMES.keys() : > - raise Exception, "Theme not defined" > - color_steps = THEMES[theme] > - n_colors = len(color_steps) > - if series_length <= n_colors: > - colors = [color + tuple([mode]) for color in color_steps[0:n_colors]] > - else: > - iterations = [(series_length - n_colors)/(n_colors - 1) for i in color_steps[:-1]] > - over_iterations = (series_length - n_colors) % (n_colors - 1) > - for i in range(n_colors - 1): > - if over_iterations <= 0: > - break > - iterations[i] += 1 > - over_iterations -= 1 > - for index,color in enumerate(color_steps[:-1]): > - colors.append(color + tuple([mode])) > - if iterations[index] == 0: > - continue > - next_color = color_steps[index+1] > - color_step = ((next_color[0] - color[0])/(iterations[index] + 1), > - (next_color[1] - color[1])/(iterations[index] + 1), > - (next_color[2] - color[2])/(iterations[index] + 1), > - (next_color[3] - color[3])/(iterations[index] + 1)) > - for i in range( iterations[index] ): > - colors.append((color[0] + color_step[0]*(i+1), > - color[1] + color_step[1]*(i+1), > - color[2] + color_step[2]*(i+1), > - color[3] + color_step[3]*(i+1), > - mode)) > - colors.append(color_steps[-1] + tuple([mode])) > - return colors > - > - > -def other_direction(direction): > - "explicit is better than implicit" > - if direction == HORZ: > - return VERT > - else: > - return HORZ > - > -#Class definition > - > -class Plot(object): > - def __init__(self, > - surface=None, > - data=None, > - width=640, > - height=480, > - background=None, > - border = 0, > - x_labels = None, > - y_labels = None, > - series_colors = None): > - random.seed(2) > - self.create_surface(surface, width, height) > - self.dimensions = {} > - self.dimensions[HORZ] = width > - self.dimensions[VERT] = height > - self.context = cairo.Context(self.surface) > - self.labels={} > - self.labels[HORZ] = x_labels > - self.labels[VERT] = y_labels > - self.load_series(data, x_labels, y_labels, series_colors) > - self.font_size = 10 > - self.set_background (background) > - self.border = border > - self.borders = {} > - self.line_color = (0.5, 0.5, 0.5) > - self.line_width = 0.5 > - self.label_color = (0.0, 0.0, 0.0) > - self.grid_color = (0.8, 0.8, 0.8) > - > - def create_surface(self, surface, width=None, height=None): > - self.filename = None > - if isinstance(surface, cairo.Surface): > - self.surface = surface > - return > - if not type(surface) in (str, unicode): > - raise TypeError("Surface should be either a Cairo surface or a filename, not %s" % surface) > - sufix = surface.rsplit(".")[-1].lower() > - self.filename = surface > - if sufix == "png": > - self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) > - elif sufix == "ps": > - self.surface = cairo.PSSurface(surface, width, height) > - elif sufix == "pdf": > - self.surface = cairo.PSSurface(surface, width, height) > - else: > - if sufix != "svg": > - self.filename += ".svg" > - self.surface = cairo.SVGSurface(self.filename, width, height) > - > - def commit(self): > - try: > - self.context.show_page() > - if self.filename and self.filename.endswith(".png"): > - self.surface.write_to_png(self.filename) > - else: > - self.surface.finish() > - except cairo.Error: > - pass > - > - def load_series (self, data, x_labels=None, y_labels=None, series_colors=None): > - self.series_labels = [] > - self.series = None > - > - #The pretty way > - #if not isinstance(data, Series): > - # # Not an instance of Series > - # self.series = Series(data) > - #else: > - # self.series = data > - # > - #self.series_labels = self.series.get_names() > - > - #TODO: Remove on next version > - # The ugly way, keeping retrocompatibility... > - if callable(data) or type(data) is list and callable(data[0]): # Lambda or List of lambdas > - self.series = data > - self.series_labels = None > - elif isinstance(data, Series): # Instance of Series > - self.series = data > - self.series_labels = data.get_names() > - else: # Anything else > - self.series = Series(data) > - self.series_labels = self.series.get_names() > - > - #TODO: allow user passed series_widths > - self.series_widths = [1.0 for group in self.series] > - > - #TODO: Remove on next version > - self.process_colors( series_colors ) > - > - def process_colors( self, series_colors, length = None, mode = 'solid' ): > - #series_colors might be None, a theme, a string of colors names or a list of color tuples > - if length is None : > - length = len( self.series.to_list() ) > - > - #no colors passed > - if not series_colors: > - #Randomize colors > - self.series_colors = [ [random.random() for i in range(3)] + [1.0, mode] for series in range( length ) ] > - else: > - #Just theme pattern > - if not hasattr( series_colors, "__iter__" ): > - theme = series_colors > - self.series_colors = colors_from_theme( theme.lower(), length ) > - > - #Theme pattern and mode > - elif not hasattr(series_colors, '__delitem__') and not hasattr( series_colors[0], "__iter__" ): > - theme = series_colors[0] > - mode = series_colors[1] > - self.series_colors = colors_from_theme( theme.lower(), length, mode ) > - > - #List > - else: > - self.series_colors = series_colors > - for index, color in enumerate( self.series_colors ): > - #element is a color name > - if not hasattr(color, "__iter__"): > - self.series_colors[index] = COLORS[color.lower()] + tuple([mode]) > - #element is rgb tuple instead of rgba > - elif len( color ) == 3 : > - self.series_colors[index] += (1.0,mode) > - #element has 4 elements, might be rgba tuple or rgb tuple with mode > - elif len( color ) == 4 : > - #last element is mode > - if not hasattr(color[3], "__iter__"): > - self.series_colors[index] += tuple([color[3]]) > - self.series_colors[index][3] = 1.0 > - #last element is alpha > - else: > - self.series_colors[index] += tuple([mode]) > - > - def get_width(self): > - return self.surface.get_width() > - > - def get_height(self): > - return self.surface.get_height() > - > - def set_background(self, background): > - if background is None: > - self.background = (0.0,0.0,0.0,0.0) > - elif type(background) in (cairo.LinearGradient, tuple): > - self.background = background > - elif not hasattr(background,"__iter__"): > - colors = background.split(" ") > - if len(colors) == 1 and colors[0] in COLORS: > - self.background = COLORS[background] > - elif len(colors) > 1: > - self.background = cairo.LinearGradient(self.dimensions[HORZ] / 2, 0, self.dimensions[HORZ] / 2, self.dimensions[VERT]) > - for index,color in enumerate(colors): > - self.background.add_color_stop_rgba(float(index)/(len(colors)-1),*COLORS[color]) > - else: > - raise TypeError ("Background should be either cairo.LinearGradient or a 3/4-tuple, not %s" % type(background)) > - > - def render_background(self): > - if isinstance(self.background, cairo.LinearGradient): > - self.context.set_source(self.background) > - else: > - self.context.set_source_rgba(*self.background) > - self.context.rectangle(0,0, self.dimensions[HORZ], self.dimensions[VERT]) > - self.context.fill() > - > - def render_bounding_box(self): > - self.context.set_source_rgba(*self.line_color) > - self.context.set_line_width(self.line_width) > - self.context.rectangle(self.border, self.border, > - self.dimensions[HORZ] - 2 * self.border, > - self.dimensions[VERT] - 2 * self.border) > - self.context.stroke() > - > - def render(self): > - pass > - > -class ScatterPlot( Plot ): > - def __init__(self, > - surface=None, > - data=None, > - errorx=None, > - errory=None, > - width=640, > - height=480, > - background=None, > - border=0, > - axis = False, > - dash = False, > - discrete = False, > - dots = 0, > - grid = False, > - series_legend = False, > - x_labels = None, > - y_labels = None, > - x_bounds = None, > - y_bounds = None, > - z_bounds = None, > - x_title = None, > - y_title = None, > - series_colors = None, > - circle_colors = None ): > - > - self.bounds = {} > - self.bounds[HORZ] = x_bounds > - self.bounds[VERT] = y_bounds > - self.bounds[NORM] = z_bounds > - self.titles = {} > - self.titles[HORZ] = x_title > - self.titles[VERT] = y_title > - self.max_value = {} > - self.axis = axis > - self.discrete = discrete > - self.dots = dots > - self.grid = grid > - self.series_legend = series_legend > - self.variable_radius = False > - self.x_label_angle = math.pi / 2.5 > - self.circle_colors = circle_colors > - > - Plot.__init__(self, surface, data, width, height, background, border, x_labels, y_labels, series_colors) > - > - self.dash = None > - if dash: > - if hasattr(dash, "keys"): > - self.dash = [dash[key] for key in self.series_labels] > - elif max([hasattr(item,'__delitem__') for item in data]) : > - self.dash = dash > - else: > - self.dash = [dash] > - > - self.load_errors(errorx, errory) > - > - def convert_list_to_tuple(self, data): > - #Data must be converted from lists of coordinates to a single > - # list of tuples > - out_data = zip(*data) > - if len(data) == 3: > - self.variable_radius = True > - return out_data > - > - def load_series(self, data, x_labels = None, y_labels = None, series_colors=None): > - #TODO: In cairoplot 2.0 keep only the Series instances > - > - # Convert Data and Group to Series > - if isinstance(data, Data) or isinstance(data, Group): > - data = Series(data) > - > - # Series > - if isinstance(data, Series): > - for group in data: > - for item in group: > - if len(item) is 3: > - self.variable_radius = True > - > - #Dictionary with lists > - if hasattr(data, "keys") : > - if hasattr( data.values()[0][0], "__delitem__" ) : > - for key in data.keys() : > - data[key] = self.convert_list_to_tuple(data[key]) > - elif len(data.values()[0][0]) == 3: > - self.variable_radius = True > - #List > - elif hasattr(data[0], "__delitem__") : > - #List of lists > - if hasattr(data[0][0], "__delitem__") : > - for index,value in enumerate(data) : > - data[index] = self.convert_list_to_tuple(value) > - #List > - elif type(data[0][0]) != type((0,0)): > - data = self.convert_list_to_tuple(data) > - #Three dimensional data > - elif len(data[0][0]) == 3: > - self.variable_radius = True > - > - #List with three dimensional tuples > - elif len(data[0]) == 3: > - self.variable_radius = True > - Plot.load_series(self, data, x_labels, y_labels, series_colors) > - self.calc_boundaries() > - self.calc_labels() > - > - def load_errors(self, errorx, errory): > - self.errors = None > - if errorx == None and errory == None: > - return > - self.errors = {} > - self.errors[HORZ] = None > - self.errors[VERT] = None > - #asimetric errors > - if errorx and hasattr(errorx[0], "__delitem__"): > - self.errors[HORZ] = errorx > - #simetric errors > - elif errorx: > - self.errors[HORZ] = [errorx] > - #asimetric errors > - if errory and hasattr(errory[0], "__delitem__"): > - self.errors[VERT] = errory > - #simetric errors > - elif errory: > - self.errors[VERT] = [errory] > - > - def calc_labels(self): > - if not self.labels[HORZ]: > - amplitude = self.bounds[HORZ][1] - self.bounds[HORZ][0] > - if amplitude % 10: #if horizontal labels need floating points > - self.labels[HORZ] = ["%.2lf" % (float(self.bounds[HORZ][0] + (amplitude * i / 10.0))) for i in range(11) ] > - else: > - self.labels[HORZ] = ["%d" % (int(self.bounds[HORZ][0] + (amplitude * i / 10.0))) for i in range(11) ] > - if not self.labels[VERT]: > - amplitude = self.bounds[VERT][1] - self.bounds[VERT][0] > - if amplitude % 10: #if vertical labels need floating points > - self.labels[VERT] = ["%.2lf" % (float(self.bounds[VERT][0] + (amplitude * i / 10.0))) for i in range(11) ] > - else: > - self.labels[VERT] = ["%d" % (int(self.bounds[VERT][0] + (amplitude * i / 10.0))) for i in range(11) ] > - > - def calc_extents(self, direction): > - self.context.set_font_size(self.font_size * 0.8) > - self.max_value[direction] = max(self.context.text_extents(item)[2] for item in self.labels[direction]) > - self.borders[other_direction(direction)] = self.max_value[direction] + self.border + 20 > - > - def calc_boundaries(self): > - #HORZ = 0, VERT = 1, NORM = 2 > - min_data_value = [0,0,0] > - max_data_value = [0,0,0] > - > - for group in self.series: > - if type(group[0].content) in (int, float, long): > - group = [Data((index, item.content)) for index,item in enumerate(group)] > - > - for point in group: > - for index, item in enumerate(point.content): > - if item > max_data_value[index]: > - max_data_value[index] = item > - elif item < min_data_value[index]: > - min_data_value[index] = item > - > - if not self.bounds[HORZ]: > - self.bounds[HORZ] = (min_data_value[HORZ], max_data_value[HORZ]) > - if not self.bounds[VERT]: > - self.bounds[VERT] = (min_data_value[VERT], max_data_value[VERT]) > - if not self.bounds[NORM]: > - self.bounds[NORM] = (min_data_value[NORM], max_data_value[NORM]) > - > - def calc_all_extents(self): > - self.calc_extents(HORZ) > - self.calc_extents(VERT) > - > - self.plot_height = self.dimensions[VERT] - 2 * self.borders[VERT] > - self.plot_width = self.dimensions[HORZ] - 2* self.borders[HORZ] > - > - self.plot_top = self.dimensions[VERT] - self.borders[VERT] > - > - def calc_steps(self): > - #Calculates all the x, y, z and color steps > - series_amplitude = [self.bounds[index][1] - self.bounds[index][0] for index in range(3)] > - > - if series_amplitude[HORZ]: > - self.horizontal_step = float (self.plot_width) / series_amplitude[HORZ] > - else: > - self.horizontal_step = 0.00 > - > - if series_amplitude[VERT]: > - self.vertical_step = float (self.plot_height) / series_amplitude[VERT] > - else: > - self.vertical_step = 0.00 > - > - if series_amplitude[NORM]: > - if self.variable_radius: > - self.z_step = float (self.bounds[NORM][1]) / series_amplitude[NORM] > - if self.circle_colors: > - self.circle_color_step = tuple([float(self.circle_colors[1][i]-self.circle_colors[0][i])/series_amplitude[NORM] for i in range(4)]) > - else: > - self.z_step = 0.00 > - self.circle_color_step = ( 0.0, 0.0, 0.0, 0.0 ) > - > - def get_circle_color(self, value): > - return tuple( [self.circle_colors[0][i] + value*self.circle_color_step[i] for i in range(4)] ) > - > - def render(self): > - self.calc_all_extents() > - self.calc_steps() > - self.render_background() > - self.render_bounding_box() > - if self.axis: > - self.render_axis() > - if self.grid: > - self.render_grid() > - self.render_labels() > - self.render_plot() > - if self.errors: > - self.render_errors() > - if self.series_legend and self.series_labels: > - self.render_legend() > - > - def render_axis(self): > - #Draws both the axis lines and their titles > - cr = self.context > - cr.set_source_rgba(*self.line_color) > - cr.move_to(self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT]) > - cr.line_to(self.borders[HORZ], self.borders[VERT]) > - cr.stroke() > - > - cr.move_to(self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT]) > - cr.line_to(self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT]) > - cr.stroke() > - > - cr.set_source_rgba(*self.label_color) > - self.context.set_font_size( 1.2 * self.font_size ) > - if self.titles[HORZ]: > - title_width,title_height = cr.text_extents(self.titles[HORZ])[2:4] > - cr.move_to( self.dimensions[HORZ]/2 - title_width/2, self.borders[VERT] - title_height/2 ) > - cr.show_text( self.titles[HORZ] ) > - > - if self.titles[VERT]: > - title_width,title_height = cr.text_extents(self.titles[VERT])[2:4] > - cr.move_to( self.dimensions[HORZ] - self.borders[HORZ] + title_height/2, self.dimensions[VERT]/2 - title_width/2) > - cr.save() > - cr.rotate( math.pi/2 ) > - cr.show_text( self.titles[VERT] ) > - cr.restore() > - > - def render_grid(self): > - cr = self.context > - horizontal_step = float( self.plot_height ) / ( len( self.labels[VERT] ) - 1 ) > - vertical_step = float( self.plot_width ) / ( len( self.labels[HORZ] ) - 1 ) > - > - x = self.borders[HORZ] + vertical_step > - y = self.plot_top - horizontal_step > - > - for label in self.labels[HORZ][:-1]: > - cr.set_source_rgba(*self.grid_color) > - cr.move_to(x, self.dimensions[VERT] - self.borders[VERT]) > - cr.line_to(x, self.borders[VERT]) > - cr.stroke() > - x += vertical_step > - for label in self.labels[VERT][:-1]: > - cr.set_source_rgba(*self.grid_color) > - cr.move_to(self.borders[HORZ], y) > - cr.line_to(self.dimensions[HORZ] - self.borders[HORZ], y) > - cr.stroke() > - y -= horizontal_step > - > - def render_labels(self): > - self.context.set_font_size(self.font_size * 0.8) > - self.render_horz_labels() > - self.render_vert_labels() > - > - def render_horz_labels(self): > - cr = self.context > - step = float( self.plot_width ) / ( len( self.labels[HORZ] ) - 1 ) > - x = self.borders[HORZ] > - y = self.dimensions[VERT] - self.borders[VERT] + 5 > - > - # store rotation matrix from the initial state > - rotation_matrix = cr.get_matrix() > - rotation_matrix.rotate(self.x_label_angle) > - > - cr.set_source_rgba(*self.label_color) > - > - for item in self.labels[HORZ]: > - width = cr.text_extents(item)[2] > - cr.move_to(x, y) > - cr.save() > - cr.set_matrix(rotation_matrix) > - cr.show_text(item) > - cr.restore() > - x += step > - > - def render_vert_labels(self): > - cr = self.context > - step = ( self.plot_height ) / ( len( self.labels[VERT] ) - 1 ) > - y = self.plot_top > - cr.set_source_rgba(*self.label_color) > - for item in self.labels[VERT]: > - width = cr.text_extents(item)[2] > - cr.move_to(self.borders[HORZ] - width - 5,y) > - cr.show_text(item) > - y -= step > - > - def render_legend(self): > - cr = self.context > - cr.set_font_size(self.font_size) > - cr.set_line_width(self.line_width) > - > - widest_word = max(self.series_labels, key = lambda item: self.context.text_extents(item)[2]) > - tallest_word = max(self.series_labels, key = lambda item: self.context.text_extents(item)[3]) > - max_width = self.context.text_extents(widest_word)[2] > - max_height = self.context.text_extents(tallest_word)[3] * 1.1 > - > - color_box_height = max_height / 2 > - color_box_width = color_box_height * 2 > - > - #Draw a bounding box > - bounding_box_width = max_width + color_box_width + 15 > - bounding_box_height = (len(self.series_labels)+0.5) * max_height > - cr.set_source_rgba(1,1,1) > - cr.rectangle(self.dimensions[HORZ] - self.borders[HORZ] - bounding_box_width, self.borders[VERT], > - bounding_box_width, bounding_box_height) > - cr.fill() > - > - cr.set_source_rgba(*self.line_color) > - cr.set_line_width(self.line_width) > - cr.rectangle(self.dimensions[HORZ] - self.borders[HORZ] - bounding_box_width, self.borders[VERT], > - bounding_box_width, bounding_box_height) > - cr.stroke() > - > - for idx,key in enumerate(self.series_labels): > - #Draw color box > - cr.set_source_rgba(*self.series_colors[idx][:4]) > - cr.rectangle(self.dimensions[HORZ] - self.borders[HORZ] - max_width - color_box_width - 10, > - self.borders[VERT] + color_box_height + (idx*max_height) , > - color_box_width, color_box_height) > - cr.fill() > - > - cr.set_source_rgba(0, 0, 0) > - cr.rectangle(self.dimensions[HORZ] - self.borders[HORZ] - max_width - color_box_width - 10, > - self.borders[VERT] + color_box_height + (idx*max_height), > - color_box_width, color_box_height) > - cr.stroke() > - > - #Draw series labels > - cr.set_source_rgba(0, 0, 0) > - cr.move_to(self.dimensions[HORZ] - self.borders[HORZ] - max_width - 5, self.borders[VERT] + ((idx+1)*max_height)) > - cr.show_text(key) > - > - def render_errors(self): > - cr = self.context > - cr.rectangle(self.borders[HORZ], self.borders[VERT], self.plot_width, self.plot_height) > - cr.clip() > - radius = self.dots > - x0 = self.borders[HORZ] - self.bounds[HORZ][0]*self.horizontal_step > - y0 = self.borders[VERT] - self.bounds[VERT][0]*self.vertical_step > - for index, group in enumerate(self.series): > - cr.set_source_rgba(*self.series_colors[index][:4]) > - for number, data in enumerate(group): > - x = x0 + self.horizontal_step * data.content[0] > - y = self.dimensions[VERT] - y0 - self.vertical_step * data.content[1] > - if self.errors[HORZ]: > - cr.move_to(x, y) > - x1 = x - self.horizontal_step * self.errors[HORZ][0][number] > - cr.line_to(x1, y) > - cr.line_to(x1, y - radius) > - cr.line_to(x1, y + radius) > - cr.stroke() > - if self.errors[HORZ] and len(self.errors[HORZ]) == 2: > - cr.move_to(x, y) > - x1 = x + self.horizontal_step * self.errors[HORZ][1][number] > - cr.line_to(x1, y) > - cr.line_to(x1, y - radius) > - cr.line_to(x1, y + radius) > - cr.stroke() > - if self.errors[VERT]: > - cr.move_to(x, y) > - y1 = y + self.vertical_step * self.errors[VERT][0][number] > - cr.line_to(x, y1) > - cr.line_to(x - radius, y1) > - cr.line_to(x + radius, y1) > - cr.stroke() > - if self.errors[VERT] and len(self.errors[VERT]) == 2: > - cr.move_to(x, y) > - y1 = y - self.vertical_step * self.errors[VERT][1][number] > - cr.line_to(x, y1) > - cr.line_to(x - radius, y1) > - cr.line_to(x + radius, y1) > - cr.stroke() > - > - > - def render_plot(self): > - cr = self.context > - if self.discrete: > - cr.rectangle(self.borders[HORZ], self.borders[VERT], self.plot_width, self.plot_height) > - cr.clip() > - x0 = self.borders[HORZ] - self.bounds[HORZ][0]*self.horizontal_step > - y0 = self.borders[VERT] - self.bounds[VERT][0]*self.vertical_step > - radius = self.dots > - for number, group in enumerate (self.series): > - cr.set_source_rgba(*self.series_colors[number][:4]) > - for data in group : > - if self.variable_radius: > - radius = data.content[2]*self.z_step > - if self.circle_colors: > - cr.set_source_rgba( *self.get_circle_color( data.content[2]) ) > - x = x0 + self.horizontal_step*data.content[0] > - y = y0 + self.vertical_step*data.content[1] > - cr.arc(x, self.dimensions[VERT] - y, radius, 0, 2*math.pi) > - cr.fill() > - else: > - cr.rectangle(self.borders[HORZ], self.borders[VERT], self.plot_width, self.plot_height) > - cr.clip() > - x0 = self.borders[HORZ] - self.bounds[HORZ][0]*self.horizontal_step > - y0 = self.borders[VERT] - self.bounds[VERT][0]*self.vertical_step > - radius = self.dots > - for number, group in enumerate (self.series): > - last_data = None > - cr.set_source_rgba(*self.series_colors[number][:4]) > - for data in group : > - x = x0 + self.horizontal_step*data.content[0] > - y = y0 + self.vertical_step*data.content[1] > - if self.dots: > - if self.variable_radius: > - radius = data.content[2]*self.z_step > - cr.arc(x, self.dimensions[VERT] - y, radius, 0, 2*math.pi) > - cr.fill() > - if last_data : > - old_x = x0 + self.horizontal_step*last_data.content[0] > - old_y = y0 + self.vertical_step*last_data.content[1] > - cr.move_to( old_x, self.dimensions[VERT] - old_y ) > - cr.line_to( x, self.dimensions[VERT] - y) > - cr.set_line_width(self.series_widths[number]) > - > - #?Display line as dash line > - if self.dash and self.dash[number]: > - s = self.series_widths[number] > - cr.set_dash([s*3, s*3], 0) > - > - cr.stroke() > - cr.set_dash([]) > - last_data = data > - > -class DotLinePlot(ScatterPlot): > - def __init__(self, > - surface=None, > - data=None, > - width=640, > - height=480, > - background=None, > - border=0, > - axis = False, > - dash = False, > - dots = 0, > - grid = False, > - series_legend = False, > - x_labels = None, > - y_labels = None, > - x_bounds = None, > - y_bounds = None, > - x_title = None, > - y_title = None, > - series_colors = None): > - > - ScatterPlot.__init__(self, surface, data, None, None, width, height, background, border, > - axis, dash, False, dots, grid, series_legend, x_labels, y_labels, > - x_bounds, y_bounds, None, x_title, y_title, series_colors, None ) > - > - > - def load_series(self, data, x_labels = None, y_labels = None, series_colors=None): > - Plot.load_series(self, data, x_labels, y_labels, series_colors) > - for group in self.series : > - for index,data in enumerate(group): > - group[index].content = (index, data.content) > - > - self.calc_boundaries() > - self.calc_labels() > - > -class FunctionPlot(ScatterPlot): > - def __init__(self, > - surface=None, > - data=None, > - width=640, > - height=480, > - background=None, > - border=0, > - axis = False, > - discrete = False, > - dots = 0, > - grid = False, > - series_legend = False, > - x_labels = None, > - y_labels = None, > - x_bounds = None, > - y_bounds = None, > - x_title = None, > - y_title = None, > - series_colors = None, > - step = 1): > - > - self.function = data > - self.step = step > - self.discrete = discrete > - > - data, x_bounds = self.load_series_from_function( self.function, x_bounds ) > - > - ScatterPlot.__init__(self, surface, data, None, None, width, height, background, border, > - axis, False, discrete, dots, grid, series_legend, x_labels, y_labels, > - x_bounds, y_bounds, None, x_title, y_title, series_colors, None ) > - > - def load_series(self, data, x_labels = None, y_labels = None, series_colors=None): > - Plot.load_series(self, data, x_labels, y_labels, series_colors) > - > - if len(self.series[0][0]) is 1: > - for group_id, group in enumerate(self.series) : > - for index,data in enumerate(group): > - group[index].content = (self.bounds[HORZ][0] + self.step*index, data.content) > - > - self.calc_boundaries() > - self.calc_labels() > - > - def load_series_from_function( self, function, x_bounds ): > - #TODO: Add the possibility for the user to define multiple functions with different discretization parameters > - > - #This function converts a function, a list of functions or a dictionary > - #of functions into its corresponding array of data > - series = Series() > - > - if isinstance(function, Group) or isinstance(function, Data): > - function = Series(function) > - > - # If is instance of Series > - if isinstance(function, Series): > - # Overwrite any bounds passed by the function > - x_bounds = (function.range[0],function.range[-1]) > - > - #if no bounds are provided > - if x_bounds == None: > - x_bounds = (0,10) > - > - > - #TODO: Finish the dict translation > - if hasattr(function, "keys"): #dictionary: > - for key in function.keys(): > - group = Group(name=key) > - #data[ key ] = [] > - i = x_bounds[0] > - while i <= x_bounds[1] : > - group.add_data(function[ key ](i)) > - #data[ key ].append( function[ key ](i) ) > - i += self.step > - series.add_group(group) > - > - elif hasattr(function, "__delitem__"): #list of functions > - for index,f in enumerate( function ) : > - group = Group() > - #data.append( [] ) > - i = x_bounds[0] > - while i <= x_bounds[1] : > - group.add_data(f(i)) > - #data[ index ].append( f(i) ) > - i += self.step > - series.add_group(group) > - > - elif isinstance(function, Series): # instance of Series > - series = function > - > - else: #function > - group = Group() > - i = x_bounds[0] > - while i <= x_bounds[1] : > - group.add_data(function(i)) > - i += self.step > - series.add_group(group) > - > - > - return series, x_bounds > - > - def calc_labels(self): > - if not self.labels[HORZ]: > - self.labels[HORZ] = [] > - i = self.bounds[HORZ][0] > - while i<=self.bounds[HORZ][1]: > - self.labels[HORZ].append(str(i)) > - i += float(self.bounds[HORZ][1] - self.bounds[HORZ][0])/10 > - ScatterPlot.calc_labels(self) > - > - def render_plot(self): > - if not self.discrete: > - ScatterPlot.render_plot(self) > - else: > - last = None > - cr = self.context > - for number, group in enumerate (self.series): > - cr.set_source_rgba(*self.series_colors[number][:4]) > - x0 = self.borders[HORZ] - self.bounds[HORZ][0]*self.horizontal_step > - y0 = self.borders[VERT] - self.bounds[VERT][0]*self.vertical_step > - for data in group: > - x = x0 + self.horizontal_step * data.content[0] > - y = y0 + self.vertical_step * data.content[1] > - cr.move_to(x, self.dimensions[VERT] - y) > - cr.line_to(x, self.plot_top) > - cr.set_line_width(self.series_widths[number]) > - cr.stroke() > - if self.dots: > - cr.new_path() > - cr.arc(x, self.dimensions[VERT] - y, 3, 0, 2.1 * math.pi) > - cr.close_path() > - cr.fill() > - > -class BarPlot(Plot): > - def __init__(self, > - surface = None, > - data = None, > - width = 640, > - height = 480, > - background = "white light_gray", > - border = 0, > - display_values = False, > - grid = False, > - rounded_corners = False, > - stack = False, > - three_dimension = False, > - x_labels = None, > - y_labels = None, > - x_bounds = None, > - y_bounds = None, > - series_colors = None, > - main_dir = None): > - > - self.bounds = {} > - self.bounds[HORZ] = x_bounds > - self.bounds[VERT] = y_bounds > - self.display_values = display_values > - self.grid = grid > - self.rounded_corners = rounded_corners > - self.stack = stack > - self.three_dimension = three_dimension > - self.x_label_angle = math.pi / 2.5 > - self.main_dir = main_dir > - self.max_value = {} > - self.plot_dimensions = {} > - self.steps = {} > - self.value_label_color = (0.5,0.5,0.5,1.0) > - > - Plot.__init__(self, surface, data, width, height, background, border, x_labels, y_labels, series_colors) > - > - def load_series(self, data, x_labels = None, y_labels = None, series_colors = None): > - Plot.load_series(self, data, x_labels, y_labels, series_colors) > - self.calc_boundaries() > - > - def process_colors(self, series_colors): > - #Data for a BarPlot might be a List or a List of Lists. > - #On the first case, colors must be generated for all bars, > - #On the second, colors must be generated for each of the inner lists. > - > - #TODO: Didn't get it... > - #if hasattr(self.data[0], '__getitem__'): > - # length = max(len(series) for series in self.data) > - #else: > - # length = len( self.data ) > - > - length = max(len(group) for group in self.series) > - > - Plot.process_colors( self, series_colors, length, 'linear') > - > - def calc_boundaries(self): > - if not self.bounds[self.main_dir]: > - if self.stack: > - max_data_value = max(sum(group.to_list()) for group in self.series) > - else: > - max_data_value = max(max(group.to_list()) for group in self.series) > - self.bounds[self.main_dir] = (0, max_data_value) > - if not self.bounds[other_direction(self.main_dir)]: > - self.bounds[other_direction(self.main_dir)] = (0, len(self.series)) > - > - def calc_extents(self, direction): > - self.max_value[direction] = 0 > - if self.labels[direction]: > - widest_word = max(self.labels[direction], key = lambda item: self.context.text_extents(item)[2]) > - self.max_value[direction] = self.context.text_extents(widest_word)[3 - direction] > - self.borders[other_direction(direction)] = (2-direction)*self.max_value[direction] + self.border + direction*(5) > - else: > - self.borders[other_direction(direction)] = self.border > - > - def calc_horz_extents(self): > - self.calc_extents(HORZ) > - > - def calc_vert_extents(self): > - self.calc_extents(VERT) > - > - def calc_all_extents(self): > - self.calc_horz_extents() > - self.calc_vert_extents() > - other_dir = other_direction(self.main_dir) > - self.value_label = 0 > - if self.display_values: > - if self.stack: > - self.value_label = self.context.text_extents(str(max(sum(group.to_list()) for group in self.series)))[2 + self.main_dir] > - else: > - self.value_label = self.context.text_extents(str(max(max(group.to_list()) for group in self.series)))[2 + self.main_dir] > - if self.labels[self.main_dir]: > - self.plot_dimensions[self.main_dir] = self.dimensions[self.main_dir] - 2*self.borders[self.main_dir] - self.value_label > - else: > - self.plot_dimensions[self.main_dir] = self.dimensions[self.main_dir] - self.borders[self.main_dir] - 1.2*self.border - self.value_label > - self.plot_dimensions[other_dir] = self.dimensions[other_dir] - self.borders[other_dir] - self.border > - self.plot_top = self.dimensions[VERT] - self.borders[VERT] > - > - def calc_steps(self): > - other_dir = other_direction(self.main_dir) > - self.series_amplitude = self.bounds[self.main_dir][1] - self.bounds[self.main_dir][0] > - if self.series_amplitude: > - self.steps[self.main_dir] = float(self.plot_dimensions[self.main_dir])/self.series_amplitude > - else: > - self.steps[self.main_dir] = 0.00 > - series_length = len(self.series) > - self.steps[other_dir] = float(self.plot_dimensions[other_dir])/(series_length + 0.1*(series_length + 1)) > - self.space = 0.1*self.steps[other_dir] > - > - def render(self): > - self.calc_all_extents() > - self.calc_steps() > - self.render_background() > - self.render_bounding_box() > - if self.grid: > - self.render_grid() > - if self.three_dimension: > - self.render_ground() > - if self.display_values: > - self.render_values() > - self.render_labels() > - self.render_plot() > - if self.series_labels: > - self.render_legend() > - > - def draw_3d_rectangle_front(self, x0, y0, x1, y1, shift): > - self.context.rectangle(x0-shift, y0+shift, x1-x0, y1-y0) > - > - def draw_3d_rectangle_side(self, x0, y0, x1, y1, shift): > - self.context.move_to(x1-shift,y0+shift) > - self.context.line_to(x1, y0) > - self.context.line_to(x1, y1) > - self.context.line_to(x1-shift, y1+shift) > - self.context.line_to(x1-shift, y0+shift) > - self.context.close_path() > - > - def draw_3d_rectangle_top(self, x0, y0, x1, y1, shift): > - self.context.move_to(x0-shift,y0+shift) > - self.context.line_to(x0, y0) > - self.context.line_to(x1, y0) > - self.context.line_to(x1-shift, y0+shift) > - self.context.line_to(x0-shift, y0+shift) > - self.context.close_path() > - > - def draw_round_rectangle(self, x0, y0, x1, y1): > - self.context.arc(x0+5, y0+5, 5, -math.pi, -math.pi/2) > - self.context.line_to(x1-5, y0) > - self.context.arc(x1-5, y0+5, 5, -math.pi/2, 0) > - self.context.line_to(x1, y1-5) > - self.context.arc(x1-5, y1-5, 5, 0, math.pi/2) > - self.context.line_to(x0+5, y1) > - self.context.arc(x0+5, y1-5, 5, math.pi/2, math.pi) > - self.context.line_to(x0, y0+5) > - self.context.close_path() > - > - def render_ground(self): > - self.draw_3d_rectangle_front(self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], > - self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) > - self.context.fill() > - > - self.draw_3d_rectangle_side (self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], > - self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) > - self.context.fill() > - > - self.draw_3d_rectangle_top (self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], > - self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) > - self.context.fill() > - > - def render_labels(self): > - self.context.set_font_size(self.font_size * 0.8) > - if self.labels[HORZ]: > - self.render_horz_labels() > - if self.labels[VERT]: > - self.render_vert_labels() > - > - def render_legend(self): > - cr = self.context > - cr.set_font_size(self.font_size) > - cr.set_line_width(self.line_width) > - > - widest_word = max(self.series_labels, key = lambda item: self.context.text_extents(item)[2]) > - tallest_word = max(self.series_labels, key = lambda item: self.context.text_extents(item)[3]) > - max_width = self.context.text_extents(widest_word)[2] > - max_height = self.context.text_extents(tallest_word)[3] * 1.1 + 5 > - > - color_box_height = max_height / 2 > - color_box_width = color_box_height * 2 > - > - #Draw a bounding box > - bounding_box_width = max_width + color_box_width + 15 > - bounding_box_height = (len(self.series_labels)+0.5) * max_height > - cr.set_source_rgba(1,1,1) > - cr.rectangle(self.dimensions[HORZ] - self.border - bounding_box_width, self.border, > - bounding_box_width, bounding_box_height) > - cr.fill() > - > - cr.set_source_rgba(*self.line_color) > - cr.set_line_width(self.line_width) > - cr.rectangle(self.dimensions[HORZ] - self.border - bounding_box_width, self.border, > - bounding_box_width, bounding_box_height) > - cr.stroke() > - > - for idx,key in enumerate(self.series_labels): > - #Draw color box > - cr.set_source_rgba(*self.series_colors[idx][:4]) > - cr.rectangle(self.dimensions[HORZ] - self.border - max_width - color_box_width - 10, > - self.border + color_box_height + (idx*max_height) , > - color_box_width, color_box_height) > - cr.fill() > - > - cr.set_source_rgba(0, 0, 0) > - cr.rectangle(self.dimensions[HORZ] - self.border - max_width - color_box_width - 10, > - self.border + color_box_height + (idx*max_height), > - color_box_width, color_box_height) > - cr.stroke() > - > - #Draw series labels > - cr.set_source_rgba(0, 0, 0) > - cr.move_to(self.dimensions[HORZ] - self.border - max_width - 5, self.border + ((idx+1)*max_height)) > - cr.show_text(key) > - > - > -class HorizontalBarPlot(BarPlot): > - def __init__(self, > - surface = None, > - data = None, > - width = 640, > - height = 480, > - background = "white light_gray", > - border = 0, > - display_values = False, > - grid = False, > - rounded_corners = False, > - stack = False, > - three_dimension = False, > - series_labels = None, > - x_labels = None, > - y_labels = None, > - x_bounds = None, > - y_bounds = None, > - series_colors = None): > - > - BarPlot.__init__(self, surface, data, width, height, background, border, > - display_values, grid, rounded_corners, stack, three_dimension, > - x_labels, y_labels, x_bounds, y_bounds, series_colors, HORZ) > - self.series_labels = series_labels > - > - def calc_vert_extents(self): > - self.calc_extents(VERT) > - if self.labels[HORZ] and not self.labels[VERT]: > - self.borders[HORZ] += 10 > - > - def draw_rectangle_bottom(self, x0, y0, x1, y1): > - self.context.arc(x0+5, y1-5, 5, math.pi/2, math.pi) > - self.context.line_to(x0, y0+5) > - self.context.arc(x0+5, y0+5, 5, -math.pi, -math.pi/2) > - self.context.line_to(x1, y0) > - self.context.line_to(x1, y1) > - self.context.line_to(x0+5, y1) > - self.context.close_path() > - > - def draw_rectangle_top(self, x0, y0, x1, y1): > - self.context.arc(x1-5, y0+5, 5, -math.pi/2, 0) > - self.context.line_to(x1, y1-5) > - self.context.arc(x1-5, y1-5, 5, 0, math.pi/2) > - self.context.line_to(x0, y1) > - self.context.line_to(x0, y0) > - self.context.line_to(x1, y0) > - self.context.close_path() > - > - def draw_rectangle(self, index, length, x0, y0, x1, y1): > - if length == 1: > - BarPlot.draw_rectangle(self, x0, y0, x1, y1) > - elif index == 0: > - self.draw_rectangle_bottom(x0, y0, x1, y1) > - elif index == length-1: > - self.draw_rectangle_top(x0, y0, x1, y1) > - else: > - self.context.rectangle(x0, y0, x1-x0, y1-y0) > - > - #TODO: Review BarPlot.render_grid code > - def render_grid(self): > - self.context.set_source_rgba(0.8, 0.8, 0.8) > - if self.labels[HORZ]: > - self.context.set_font_size(self.font_size * 0.8) > - step = (self.dimensions[HORZ] - 2*self.borders[HORZ] - self.value_label)/(len(self.labels[HORZ])-1) > - x = self.borders[HORZ] > - next_x = 0 > - for item in self.labels[HORZ]: > - width = self.context.text_extents(item)[2] > - if x - width/2 > next_x and x - width/2 > self.border: > - self.context.move_to(x, self.border) > - self.context.line_to(x, self.dimensions[VERT] - self.borders[VERT]) > - self.context.stroke() > - next_x = x + width/2 > - x += step > - else: > - lines = 11 > - horizontal_step = float(self.plot_dimensions[HORZ])/(lines-1) > - x = self.borders[HORZ] > - for y in xrange(0, lines): > - self.context.move_to(x, self.border) > - self.context.line_to(x, self.dimensions[VERT] - self.borders[VERT]) > - self.context.stroke() > - x += horizontal_step > - > - def render_horz_labels(self): > - step = (self.dimensions[HORZ] - 2*self.borders[HORZ])/(len(self.labels[HORZ])-1) > - x = self.borders[HORZ] > - next_x = 0 > - > - for item in self.labels[HORZ]: > - self.context.set_source_rgba(*self.label_color) > - width = self.context.text_extents(item)[2] > - if x - width/2 > next_x and x - width/2 > self.border: > - self.context.move_to(x - width/2, self.dimensions[VERT] - self.borders[VERT] + self.max_value[HORZ] + 3) > - self.context.show_text(item) > - next_x = x + width/2 > - x += step > - > - def render_vert_labels(self): > - series_length = len(self.labels[VERT]) > - step = (self.plot_dimensions[VERT] - (series_length + 1)*self.space)/(len(self.labels[VERT])) > - y = self.border + step/2 + self.space > - > - for item in self.labels[VERT]: > - self.context.set_source_rgba(*self.label_color) > - width, height = self.context.text_extents(item)[2:4] > - self.context.move_to(self.borders[HORZ] - width - 5, y + height/2) > - self.context.show_text(item) > - y += step + self.space > - self.labels[VERT].reverse() > - > - def render_values(self): > - self.context.set_source_rgba(*self.value_label_color) > - self.context.set_font_size(self.font_size * 0.8) > - if self.stack: > - for i,group in enumerate(self.series): > - value = sum(group.to_list()) > - height = self.context.text_extents(str(value))[3] > - x = self.borders[HORZ] + value*self.steps[HORZ] + 2 > - y = self.borders[VERT] + (i+0.5)*self.steps[VERT] + (i+1)*self.space + height/2 > - self.context.move_to(x, y) > - self.context.show_text(str(value)) > - else: > - for i,group in enumerate(self.series): > - inner_step = self.steps[VERT]/len(group) > - y0 = self.border + i*self.steps[VERT] + (i+1)*self.space > - for number,data in enumerate(group): > - height = self.context.text_extents(str(data.content))[3] > - self.context.move_to(self.borders[HORZ] + data.content*self.steps[HORZ] + 2, y0 + 0.5*inner_step + height/2, ) > - self.context.show_text(str(data.content)) > - y0 += inner_step > - > - def render_plot(self): > - if self.stack: > - for i,group in enumerate(self.series): > - x0 = self.borders[HORZ] > - y0 = self.borders[VERT] + i*self.steps[VERT] + (i+1)*self.space > - for number,data in enumerate(group): > - if self.series_colors[number][4] in ('radial','linear') : > - linear = cairo.LinearGradient( data.content*self.steps[HORZ]/2, y0, data.content*self.steps[HORZ]/2, y0 + self.steps[VERT] ) > - color = self.series_colors[number] > - linear.add_color_stop_rgba(0.0, 3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) > - linear.add_color_stop_rgba(1.0, *color[:4]) > - self.context.set_source(linear) > - elif self.series_colors[number][4] == 'solid': > - self.context.set_source_rgba(*self.series_colors[number][:4]) > - if self.rounded_corners: > - self.draw_rectangle(number, len(group), x0, y0, x0+data.content*self.steps[HORZ], y0+self.steps[VERT]) > - self.context.fill() > - else: > - self.context.rectangle(x0, y0, data.content*self.steps[HORZ], self.steps[VERT]) > - self.context.fill() > - x0 += data.content*self.steps[HORZ] > - else: > - for i,group in enumerate(self.series): > - inner_step = self.steps[VERT]/len(group) > - x0 = self.borders[HORZ] > - y0 = self.border + i*self.steps[VERT] + (i+1)*self.space > - for number,data in enumerate(group): > - linear = cairo.LinearGradient(data.content*self.steps[HORZ]/2, y0, data.content*self.steps[HORZ]/2, y0 + inner_step) > - color = self.series_colors[number] > - linear.add_color_stop_rgba(0.0, 3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) > - linear.add_color_stop_rgba(1.0, *color[:4]) > - self.context.set_source(linear) > - if self.rounded_corners and data.content != 0: > - BarPlot.draw_round_rectangle(self,x0, y0, x0 + data.content*self.steps[HORZ], y0 + inner_step) > - self.context.fill() > - else: > - self.context.rectangle(x0, y0, data.content*self.steps[HORZ], inner_step) > - self.context.fill() > - y0 += inner_step > - > -class VerticalBarPlot(BarPlot): > - def __init__(self, > - surface = None, > - data = None, > - width = 640, > - height = 480, > - background = "white light_gray", > - border = 0, > - display_values = False, > - grid = False, > - rounded_corners = False, > - stack = False, > - three_dimension = False, > - series_labels = None, > - x_labels = None, > - y_labels = None, > - x_bounds = None, > - y_bounds = None, > - series_colors = None): > - > - BarPlot.__init__(self, surface, data, width, height, background, border, > - display_values, grid, rounded_corners, stack, three_dimension, > - x_labels, y_labels, x_bounds, y_bounds, series_colors, VERT) > - self.series_labels = series_labels > - > - def calc_vert_extents(self): > - self.calc_extents(VERT) > - if self.labels[VERT] and not self.labels[HORZ]: > - self.borders[VERT] += 10 > - > - def draw_rectangle_bottom(self, x0, y0, x1, y1): > - self.context.move_to(x1,y1) > - self.context.arc(x1-5, y1-5, 5, 0, math.pi/2) > - self.context.line_to(x0+5, y1) > - self.context.arc(x0+5, y1-5, 5, math.pi/2, math.pi) > - self.context.line_to(x0, y0) > - self.context.line_to(x1, y0) > - self.context.line_to(x1, y1) > - self.context.close_path() > - > - def draw_rectangle_top(self, x0, y0, x1, y1): > - self.context.arc(x0+5, y0+5, 5, -math.pi, -math.pi/2) > - self.context.line_to(x1-5, y0) > - self.context.arc(x1-5, y0+5, 5, -math.pi/2, 0) > - self.context.line_to(x1, y1) > - self.context.line_to(x0, y1) > - self.context.line_to(x0, y0) > - self.context.close_path() > - > - def draw_rectangle(self, index, length, x0, y0, x1, y1): > - if length == 1: > - BarPlot.draw_rectangle(self, x0, y0, x1, y1) > - elif index == 0: > - self.draw_rectangle_bottom(x0, y0, x1, y1) > - elif index == length-1: > - self.draw_rectangle_top(x0, y0, x1, y1) > - else: > - self.context.rectangle(x0, y0, x1-x0, y1-y0) > - > - def render_grid(self): > - self.context.set_source_rgba(0.8, 0.8, 0.8) > - if self.labels[VERT]: > - lines = len(self.labels[VERT]) > - vertical_step = float(self.plot_dimensions[self.main_dir])/(lines-1) > - y = self.borders[VERT] + self.value_label > - else: > - lines = 11 > - vertical_step = float(self.plot_dimensions[self.main_dir])/(lines-1) > - y = 1.2*self.border + self.value_label > - for x in xrange(0, lines): > - self.context.move_to(self.borders[HORZ], y) > - self.context.line_to(self.dimensions[HORZ] - self.border, y) > - self.context.stroke() > - y += vertical_step > - > - def render_ground(self): > - self.draw_3d_rectangle_front(self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], > - self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) > - self.context.fill() > - > - self.draw_3d_rectangle_side (self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], > - self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) > - self.context.fill() > - > - self.draw_3d_rectangle_top (self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], > - self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) > - self.context.fill() > - > - def render_horz_labels(self): > - series_length = len(self.labels[HORZ]) > - step = float (self.plot_dimensions[HORZ] - (series_length + 1)*self.space)/len(self.labels[HORZ]) > - x = self.borders[HORZ] + step/2 + self.space > - next_x = 0 > - > - for item in self.labels[HORZ]: > - self.context.set_source_rgba(*self.label_color) > - width = self.context.text_extents(item)[2] > - if x - width/2 > next_x and x - width/2 > self.borders[HORZ]: > - self.context.move_to(x - width/2, self.dimensions[VERT] - self.borders[VERT] + self.max_value[HORZ] + 3) > - self.context.show_text(item) > - next_x = x + width/2 > - x += step + self.space > - > - def render_vert_labels(self): > - self.context.set_source_rgba(*self.label_color) > - y = self.borders[VERT] + self.value_label > - step = (self.dimensions[VERT] - 2*self.borders[VERT] - self.value_label)/(len(self.labels[VERT]) - 1) > - self.labels[VERT].reverse() > - for item in self.labels[VERT]: > - width, height = self.context.text_extents(item)[2:4] > - self.context.move_to(self.borders[HORZ] - width - 5, y + height/2) > - self.context.show_text(item) > - y += step > - self.labels[VERT].reverse() > - > - def render_values(self): > - self.context.set_source_rgba(*self.value_label_color) > - self.context.set_font_size(self.font_size * 0.8) > - if self.stack: > - for i,group in enumerate(self.series): > - value = sum(group.to_list()) > - width = self.context.text_extents(str(value))[2] > - x = self.borders[HORZ] + (i+0.5)*self.steps[HORZ] + (i+1)*self.space - width/2 > - y = value*self.steps[VERT] + 2 > - self.context.move_to(x, self.plot_top-y) > - self.context.show_text(str(value)) > - else: > - for i,group in enumerate(self.series): > - inner_step = self.steps[HORZ]/len(group) > - x0 = self.borders[HORZ] + i*self.steps[HORZ] + (i+1)*self.space > - for number,data in enumerate(group): > - width = self.context.text_extents(str(data.content))[2] > - self.context.move_to(x0 + 0.5*inner_step - width/2, self.plot_top - data.content*self.steps[VERT] - 2) > - self.context.show_text(str(data.content)) > - x0 += inner_step > - > - def render_plot(self): > - if self.stack: > - for i,group in enumerate(self.series): > - x0 = self.borders[HORZ] + i*self.steps[HORZ] + (i+1)*self.space > - y0 = 0 > - for number,data in enumerate(group): > - if self.series_colors[number][4] in ('linear','radial'): > - linear = cairo.LinearGradient( x0, data.content*self.steps[VERT]/2, x0 + self.steps[HORZ], data.content*self.steps[VERT]/2 ) > - color = self.series_colors[number] > - linear.add_color_stop_rgba(0.0, 3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) > - linear.add_color_stop_rgba(1.0, *color[:4]) > - self.context.set_source(linear) > - elif self.series_colors[number][4] == 'solid': > - self.context.set_source_rgba(*self.series_colors[number][:4]) > - if self.rounded_corners: > - self.draw_rectangle(number, len(group), x0, self.plot_top - y0 - data.content*self.steps[VERT], x0 + self.steps[HORZ], self.plot_top - y0) > - self.context.fill() > - else: > - self.context.rectangle(x0, self.plot_top - y0 - data.content*self.steps[VERT], self.steps[HORZ], data.content*self.steps[VERT]) > - self.context.fill() > - y0 += data.content*self.steps[VERT] > - else: > - for i,group in enumerate(self.series): > - inner_step = self.steps[HORZ]/len(group) > - y0 = self.borders[VERT] > - x0 = self.borders[HORZ] + i*self.steps[HORZ] + (i+1)*self.space > - for number,data in enumerate(group): > - if self.series_colors[number][4] == 'linear': > - linear = cairo.LinearGradient( x0, data.content*self.steps[VERT]/2, x0 + inner_step, data.content*self.steps[VERT]/2 ) > - color = self.series_colors[number] > - linear.add_color_stop_rgba(0.0, 3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) > - linear.add_color_stop_rgba(1.0, *color[:4]) > - self.context.set_source(linear) > - elif self.series_colors[number][4] == 'solid': > - self.context.set_source_rgba(*self.series_colors[number][:4]) > - if self.rounded_corners and data.content != 0: > - BarPlot.draw_round_rectangle(self, x0, self.plot_top - data.content*self.steps[VERT], x0+inner_step, self.plot_top) > - self.context.fill() > - elif self.three_dimension: > - self.draw_3d_rectangle_front(x0, self.plot_top - data.content*self.steps[VERT], x0+inner_step, self.plot_top, 5) > - self.context.fill() > - self.draw_3d_rectangle_side(x0, self.plot_top - data.content*self.steps[VERT], x0+inner_step, self.plot_top, 5) > - self.context.fill() > - self.draw_3d_rectangle_top(x0, self.plot_top - data.content*self.steps[VERT], x0+inner_step, self.plot_top, 5) > - self.context.fill() > - else: > - self.context.rectangle(x0, self.plot_top - data.content*self.steps[VERT], inner_step, data.content*self.steps[VERT]) > - self.context.fill() > - > - x0 += inner_step > - > -class StreamChart(VerticalBarPlot): > - def __init__(self, > - surface = None, > - data = None, > - width = 640, > - height = 480, > - background = "white light_gray", > - border = 0, > - grid = False, > - series_legend = None, > - x_labels = None, > - x_bounds = None, > - y_bounds = None, > - series_colors = None): > - > - VerticalBarPlot.__init__(self, surface, data, width, height, background, border, > - False, grid, False, True, False, > - None, x_labels, None, x_bounds, y_bounds, series_colors) > - > - def calc_steps(self): > - other_dir = other_direction(self.main_dir) > - self.series_amplitude = self.bounds[self.main_dir][1] - self.bounds[self.main_dir][0] > - if self.series_amplitude: > - self.steps[self.main_dir] = float(self.plot_dimensions[self.main_dir])/self.series_amplitude > - else: > - self.steps[self.main_dir] = 0.00 > - series_length = len(self.data) > - self.steps[other_dir] = float(self.plot_dimensions[other_dir])/series_length > - > - def render_legend(self): > - pass > - > - def ground(self, index): > - sum_values = sum(self.data[index]) > - return -0.5*sum_values > - > - def calc_angles(self): > - middle = self.plot_top - self.plot_dimensions[VERT]/2.0 > - self.angles = [tuple([0.0 for x in range(len(self.data)+1)])] > - for x_index in range(1, len(self.data)-1): > - t = [] > - x0 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ] > - x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ] > - y0 = middle - self.ground(x_index-1)*self.steps[VERT] > - y2 = middle - self.ground(x_index+1)*self.steps[VERT] > - t.append(math.atan(float(y0-y2)/(x0-x2))) > - for data_index in range(len(self.data[x_index])): > - x0 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ] > - x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ] > - y0 = middle - self.ground(x_index-1)*self.steps[VERT] - self.data[x_index-1][data_index]*self.steps[VERT] > - y2 = middle - self.ground(x_index+1)*self.steps[VERT] - self.data[x_index+1][data_index]*self.steps[VERT] > - > - for i in range(0,data_index): > - y0 -= self.data[x_index-1][i]*self.steps[VERT] > - y2 -= self.data[x_index+1][i]*self.steps[VERT] > - > - if data_index == len(self.data[0])-1 and False: > - self.context.set_source_rgba(0.0,0.0,0.0,0.3) > - self.context.move_to(x0,y0) > - self.context.line_to(x2,y2) > - self.context.stroke() > - self.context.arc(x0,y0,2,0,2*math.pi) > - self.context.fill() > - t.append(math.atan(float(y0-y2)/(x0-x2))) > - self.angles.append(tuple(t)) > - self.angles.append(tuple([0.0 for x in range(len(self.data)+1)])) > - > - def render_plot(self): > - self.calc_angles() > - middle = self.plot_top - self.plot_dimensions[VERT]/2.0 > - p = 0.4*self.steps[HORZ] > - for data_index in range(len(self.data[0])-1,-1,-1): > - self.context.set_source_rgba(*self.series_colors[data_index][:4]) > - > - #draw the upper line > - for x_index in range(len(self.data)-1) : > - x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ] > - y1 = middle - self.ground(x_index)*self.steps[VERT] - self.data[x_index][data_index]*self.steps[VERT] > - x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ] > - y2 = middle - self.ground(x_index + 1)*self.steps[VERT] - self.data[x_index + 1][data_index]*self.steps[VERT] > - > - for i in range(0,data_index): > - y1 -= self.data[x_index][i]*self.steps[VERT] > - y2 -= self.data[x_index+1][i]*self.steps[VERT] > - > - if x_index == 0: > - self.context.move_to(x1,y1) > - > - ang1 = self.angles[x_index][data_index+1] > - ang2 = self.angles[x_index+1][data_index+1] + math.pi > - self.context.curve_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1), > - x2+p*math.cos(ang2),y2+p*math.sin(ang2), > - x2,y2) > - > - for x_index in range(len(self.data)-1,0,-1) : > - x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ] > - y1 = middle - self.ground(x_index)*self.steps[VERT] > - x2 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ] > - y2 = middle - self.ground(x_index - 1)*self.steps[VERT] > - > - for i in range(0,data_index): > - y1 -= self.data[x_index][i]*self.steps[VERT] > - y2 -= self.data[x_index-1][i]*self.steps[VERT] > - > - if x_index == len(self.data)-1: > - self.context.line_to(x1,y1+2) > - > - #revert angles by pi degrees to take the turn back > - ang1 = self.angles[x_index][data_index] + math.pi > - ang2 = self.angles[x_index-1][data_index] > - self.context.curve_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1), > - x2+p*math.cos(ang2),y2+p*math.sin(ang2), > - x2,y2+2) > - > - self.context.close_path() > - self.context.fill() > - > - if False: > - self.context.move_to(self.borders[HORZ] + 0.5*self.steps[HORZ], middle) > - for x_index in range(len(self.data)-1) : > - x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ] > - y1 = middle - self.ground(x_index)*self.steps[VERT] - self.data[x_index][data_index]*self.steps[VERT] > - x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ] > - y2 = middle - self.ground(x_index + 1)*self.steps[VERT] - self.data[x_index + 1][data_index]*self.steps[VERT] > - > - for i in range(0,data_index): > - y1 -= self.data[x_index][i]*self.steps[VERT] > - y2 -= self.data[x_index+1][i]*self.steps[VERT] > - > - ang1 = self.angles[x_index][data_index+1] > - ang2 = self.angles[x_index+1][data_index+1] + math.pi > - self.context.set_source_rgba(1.0,0.0,0.0) > - self.context.arc(x1+p*math.cos(ang1),y1+p*math.sin(ang1),2,0,2*math.pi) > - self.context.fill() > - self.context.set_source_rgba(0.0,0.0,0.0) > - self.context.arc(x2+p*math.cos(ang2),y2+p*math.sin(ang2),2,0,2*math.pi) > - self.context.fill() > - '''self.context.set_source_rgba(0.0,0.0,0.0,0.3) > - self.context.arc(x2,y2,2,0,2*math.pi) > - self.context.fill()''' > - self.context.move_to(x1,y1) > - self.context.line_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1)) > - self.context.stroke() > - self.context.move_to(x2,y2) > - self.context.line_to(x2+p*math.cos(ang2),y2+p*math.sin(ang2)) > - self.context.stroke() > - if False: > - for x_index in range(len(self.data)-1,0,-1) : > - x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ] > - y1 = middle - self.ground(x_index)*self.steps[VERT] > - x2 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ] > - y2 = middle - self.ground(x_index - 1)*self.steps[VERT] > - > - for i in range(0,data_index): > - y1 -= self.data[x_index][i]*self.steps[VERT] > - y2 -= self.data[x_index-1][i]*self.steps[VERT] > - > - #revert angles by pi degrees to take the turn back > - ang1 = self.angles[x_index][data_index] + math.pi > - ang2 = self.angles[x_index-1][data_index] > - self.context.set_source_rgba(0.0,1.0,0.0) > - self.context.arc(x1+p*math.cos(ang1),y1+p*math.sin(ang1),2,0,2*math.pi) > - self.context.fill() > - self.context.set_source_rgba(0.0,0.0,1.0) > - self.context.arc(x2+p*math.cos(ang2),y2+p*math.sin(ang2),2,0,2*math.pi) > - self.context.fill() > - '''self.context.set_source_rgba(0.0,0.0,0.0,0.3) > - self.context.arc(x2,y2,2,0,2*math.pi) > - self.context.fill()''' > - self.context.move_to(x1,y1) > - self.context.line_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1)) > - self.context.stroke() > - self.context.move_to(x2,y2) > - self.context.line_to(x2+p*math.cos(ang2),y2+p*math.sin(ang2)) > - self.context.stroke() > - #break > - > - #self.context.arc(self.dimensions[HORZ]/2, self.dimensions[VERT]/2,50,0,3*math.pi/2) > - #self.context.fill() > - > - > -class PiePlot(Plot): > - #TODO: Check the old cairoplot, graphs aren't matching > - def __init__ (self, > - surface = None, > - data = None, > - width = 640, > - height = 480, > - background = "white light_gray", > - gradient = False, > - shadow = False, > - colors = None): > - > - Plot.__init__( self, surface, data, width, height, background, series_colors = colors ) > - self.center = (self.dimensions[HORZ]/2, self.dimensions[VERT]/2) > - self.total = sum( self.series.to_list() ) > - self.radius = min(self.dimensions[HORZ]/3,self.dimensions[VERT]/3) > - self.gradient = gradient > - self.shadow = shadow > - > - def sort_function(x,y): > - return x.content - y.content > - > - def load_series(self, data, x_labels=None, y_labels=None, series_colors=None): > - Plot.load_series(self, data, x_labels, y_labels, series_colors) > - # Already done inside series > - #self.data = sorted(self.data) > - > - def draw_piece(self, angle, next_angle): > - self.context.move_to(self.center[0],self.center[1]) > - self.context.line_to(self.center[0] + self.radius*math.cos(angle), self.center[1] + self.radius*math.sin(angle)) > - self.context.arc(self.center[0], self.center[1], self.radius, angle, next_angle) > - self.context.line_to(self.center[0], self.center[1]) > - self.context.close_path() > - > - def render(self): > - self.render_background() > - self.render_bounding_box() > - if self.shadow: > - self.render_shadow() > - self.render_plot() > - self.render_series_labels() > - > - def render_shadow(self): > - horizontal_shift = 3 > - vertical_shift = 3 > - self.context.set_source_rgba(0, 0, 0, 0.5) > - self.context.arc(self.center[0] + horizontal_shift, self.center[1] + vertical_shift, self.radius, 0, 2*math.pi) > - self.context.fill() > - > - def render_series_labels(self): > - angle = 0 > - next_angle = 0 > - x0,y0 = self.center > - cr = self.context > - for number,key in enumerate(self.series_labels): > - # self.data[number] should be just a number > - data = sum(self.series[number].to_list()) > - > - next_angle = angle + 2.0*math.pi*data/self.total > - cr.set_source_rgba(*self.series_colors[number][:4]) > - w = cr.text_extents(key)[2] > - if (angle + next_angle)/2 < math.pi/2 or (angle + next_angle)/2 > 3*math.pi/2: > - cr.move_to(x0 + (self.radius+10)*math.cos((angle+next_angle)/2), y0 + (self.radius+10)*math.sin((angle+next_angle)/2) ) > - else: > - cr.move_to(x0 + (self.radius+10)*math.cos((angle+next_angle)/2) - w, y0 + (self.radius+10)*math.sin((angle+next_angle)/2) ) > - cr.show_text(key) > - angle = next_angle > - > - def render_plot(self): > - angle = 0 > - next_angle = 0 > - x0,y0 = self.center > - cr = self.context > - for number,group in enumerate(self.series): > - # Group should be just a number > - data = sum(group.to_list()) > - next_angle = angle + 2.0*math.pi*data/self.total > - if self.gradient or self.series_colors[number][4] in ('linear','radial'): > - gradient_color = cairo.RadialGradient(self.center[0], self.center[1], 0, self.center[0], self.center[1], self.radius) > - gradient_color.add_color_stop_rgba(0.3, *self.series_colors[number][:4]) > - gradient_color.add_color_stop_rgba(1, self.series_colors[number][0]*0.7, > - self.series_colors[number][1]*0.7, > - self.series_colors[number][2]*0.7, > - self.series_colors[number][3]) > - cr.set_source(gradient_color) > - else: > - cr.set_source_rgba(*self.series_colors[number][:4]) > - > - self.draw_piece(angle, next_angle) > - cr.fill() > - > - cr.set_source_rgba(1.0, 1.0, 1.0) > - self.draw_piece(angle, next_angle) > - cr.stroke() > - > - angle = next_angle > - > -class DonutPlot(PiePlot): > - def __init__ (self, > - surface = None, > - data = None, > - width = 640, > - height = 480, > - background = "white light_gray", > - gradient = False, > - shadow = False, > - colors = None, > - inner_radius=-1): > - > - Plot.__init__( self, surface, data, width, height, background, series_colors = colors ) > - > - self.center = ( self.dimensions[HORZ]/2, self.dimensions[VERT]/2 ) > - self.total = sum( self.series.to_list() ) > - self.radius = min( self.dimensions[HORZ]/3,self.dimensions[VERT]/3 ) > - self.inner_radius = inner_radius*self.radius > - > - if inner_radius == -1: > - self.inner_radius = self.radius/3 > - > - self.gradient = gradient > - self.shadow = shadow > - > - def draw_piece(self, angle, next_angle): > - self.context.move_to(self.center[0] + (self.inner_radius)*math.cos(angle), self.center[1] + (self.inner_radius)*math.sin(angle)) > - self.context.line_to(self.center[0] + self.radius*math.cos(angle), self.center[1] + self.radius*math.sin(angle)) > - self.context.arc(self.center[0], self.center[1], self.radius, angle, next_angle) > - self.context.line_to(self.center[0] + (self.inner_radius)*math.cos(next_angle), self.center[1] + (self.inner_radius)*math.sin(next_angle)) > - self.context.arc_negative(self.center[0], self.center[1], self.inner_radius, next_angle, angle) > - self.context.close_path() > - > - def render_shadow(self): > - horizontal_shift = 3 > - vertical_shift = 3 > - self.context.set_source_rgba(0, 0, 0, 0.5) > - self.context.arc(self.center[0] + horizontal_shift, self.center[1] + vertical_shift, self.inner_radius, 0, 2*math.pi) > - self.context.arc_negative(self.center[0] + horizontal_shift, self.center[1] + vertical_shift, self.radius, 0, -2*math.pi) > - self.context.fill() > - > -class GanttChart (Plot) : > - def __init__(self, > - surface = None, > - data = None, > - width = 640, > - height = 480, > - x_labels = None, > - y_labels = None, > - colors = None): > - self.bounds = {} > - self.max_value = {} > - Plot.__init__(self, surface, data, width, height, x_labels = x_labels, y_labels = y_labels, series_colors = colors) > - > - def load_series(self, data, x_labels=None, y_labels=None, series_colors=None): > - Plot.load_series(self, data, x_labels, y_labels, series_colors) > - self.calc_boundaries() > - > - def calc_boundaries(self): > - self.bounds[HORZ] = (0,len(self.series)) > - end_pos = max(self.series.to_list()) > - > - #for group in self.series: > - # if hasattr(item, "__delitem__"): > - # for sub_item in item: > - # end_pos = max(sub_item) > - # else: > - # end_pos = max(item) > - self.bounds[VERT] = (0,end_pos) > - > - def calc_extents(self, direction): > - self.max_value[direction] = 0 > - if self.labels[direction]: > - self.max_value[direction] = max(self.context.text_extents(item)[2] for item in self.labels[direction]) > - else: > - self.max_value[direction] = self.context.text_extents( str(self.bounds[direction][1] + 1) )[2] > - > - def calc_horz_extents(self): > - self.calc_extents(HORZ) > - self.borders[HORZ] = 100 + self.max_value[HORZ] > - > - def calc_vert_extents(self): > - self.calc_extents(VERT) > - self.borders[VERT] = self.dimensions[VERT]/(self.bounds[HORZ][1] + 1) > - > - def calc_steps(self): > - self.horizontal_step = (self.dimensions[HORZ] - self.borders[HORZ])/(len(self.labels[VERT])) > - self.vertical_step = self.borders[VERT] > - > - def render(self): > - self.calc_horz_extents() > - self.calc_vert_extents() > - self.calc_steps() > - self.render_background() > - > - self.render_labels() > - self.render_grid() > - self.render_plot() > - > - def render_background(self): > - cr = self.context > - cr.set_source_rgba(255,255,255) > - cr.rectangle(0,0,self.dimensions[HORZ], self.dimensions[VERT]) > - cr.fill() > - for number,group in enumerate(self.series): > - linear = cairo.LinearGradient(self.dimensions[HORZ]/2, self.borders[VERT] + number*self.vertical_step, > - self.dimensions[HORZ]/2, self.borders[VERT] + (number+1)*self.vertical_step) > - linear.add_color_stop_rgba(0,1.0,1.0,1.0,1.0) > - linear.add_color_stop_rgba(1.0,0.9,0.9,0.9,1.0) > - cr.set_source(linear) > - cr.rectangle(0,self.borders[VERT] + number*self.vertical_step,self.dimensions[HORZ],self.vertical_step) > - cr.fill() > - > - def render_grid(self): > - cr = self.context > - cr.set_source_rgba(0.7, 0.7, 0.7) > - cr.set_dash((1,0,0,0,0,0,1)) > - cr.set_line_width(0.5) > - for number,label in enumerate(self.labels[VERT]): > - h = cr.text_extents(label)[3] > - cr.move_to(self.borders[HORZ] + number*self.horizontal_step, self.vertical_step/2 + h) > - cr.line_to(self.borders[HORZ] + number*self.horizontal_step, self.dimensions[VERT]) > - cr.stroke() > - > - def render_labels(self): > - self.context.set_font_size(0.02 * self.dimensions[HORZ]) > - > - self.render_horz_labels() > - self.render_vert_labels() > - > - def render_horz_labels(self): > - cr = self.context > - labels = self.labels[HORZ] > - if not labels: > - labels = [str(i) for i in range(1, self.bounds[HORZ][1] + 1) ] > - for number,label in enumerate(labels): > - if label != None: > - cr.set_source_rgba(0.5, 0.5, 0.5) > - w,h = cr.text_extents(label)[2], cr.text_extents(label)[3] > - cr.move_to(40,self.borders[VERT] + number*self.vertical_step + self.vertical_step/2 + h/2) > - cr.show_text(label) > - > - def render_vert_labels(self): > - cr = self.context > - labels = self.labels[VERT] > - if not labels: > - labels = [str(i) for i in range(1, self.bounds[VERT][1] + 1) ] > - for number,label in enumerate(labels): > - w,h = cr.text_extents(label)[2], cr.text_extents(label)[3] > - cr.move_to(self.borders[HORZ] + number*self.horizontal_step - w/2, self.vertical_step/2) > - cr.show_text(label) > - > - def render_rectangle(self, x0, y0, x1, y1, color): > - self.draw_shadow(x0, y0, x1, y1) > - self.draw_rectangle(x0, y0, x1, y1, color) > - > - def draw_rectangular_shadow(self, gradient, x0, y0, w, h): > - self.context.set_source(gradient) > - self.context.rectangle(x0,y0,w,h) > - self.context.fill() > - > - def draw_circular_shadow(self, x, y, radius, ang_start, ang_end, mult, shadow): > - gradient = cairo.RadialGradient(x, y, 0, x, y, 2*radius) > - gradient.add_color_stop_rgba(0, 0, 0, 0, shadow) > - gradient.add_color_stop_rgba(1, 0, 0, 0, 0) > - self.context.set_source(gradient) > - self.context.move_to(x,y) > - self.context.line_to(x + mult[0]*radius,y + mult[1]*radius) > - self.context.arc(x, y, 8, ang_start, ang_end) > - self.context.line_to(x,y) > - self.context.close_path() > - self.context.fill() > - > - def draw_rectangle(self, x0, y0, x1, y1, color): > - cr = self.context > - middle = (x0+x1)/2 > - linear = cairo.LinearGradient(middle,y0,middle,y1) > - linear.add_color_stop_rgba(0,3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) > - linear.add_color_stop_rgba(1,*color[:4]) > - cr.set_source(linear) > - > - cr.arc(x0+5, y0+5, 5, 0, 2*math.pi) > - cr.arc(x1-5, y0+5, 5, 0, 2*math.pi) > - cr.arc(x0+5, y1-5, 5, 0, 2*math.pi) > - cr.arc(x1-5, y1-5, 5, 0, 2*math.pi) > - cr.rectangle(x0+5,y0,x1-x0-10,y1-y0) > - cr.rectangle(x0,y0+5,x1-x0,y1-y0-10) > - cr.fill() > - > - def draw_shadow(self, x0, y0, x1, y1): > - shadow = 0.4 > - h_mid = (x0+x1)/2 > - v_mid = (y0+y1)/2 > - h_linear_1 = cairo.LinearGradient(h_mid,y0-4,h_mid,y0+4) > - h_linear_2 = cairo.LinearGradient(h_mid,y1-4,h_mid,y1+4) > - v_linear_1 = cairo.LinearGradient(x0-4,v_mid,x0+4,v_mid) > - v_linear_2 = cairo.LinearGradient(x1-4,v_mid,x1+4,v_mid) > - > - h_linear_1.add_color_stop_rgba( 0, 0, 0, 0, 0) > - h_linear_1.add_color_stop_rgba( 1, 0, 0, 0, shadow) > - h_linear_2.add_color_stop_rgba( 0, 0, 0, 0, shadow) > - h_linear_2.add_color_stop_rgba( 1, 0, 0, 0, 0) > - v_linear_1.add_color_stop_rgba( 0, 0, 0, 0, 0) > - v_linear_1.add_color_stop_rgba( 1, 0, 0, 0, shadow) > - v_linear_2.add_color_stop_rgba( 0, 0, 0, 0, shadow) > - v_linear_2.add_color_stop_rgba( 1, 0, 0, 0, 0) > - > - self.draw_rectangular_shadow(h_linear_1,x0+4,y0-4,x1-x0-8,8) > - self.draw_rectangular_shadow(h_linear_2,x0+4,y1-4,x1-x0-8,8) > - self.draw_rectangular_shadow(v_linear_1,x0-4,y0+4,8,y1-y0-8) > - self.draw_rectangular_shadow(v_linear_2,x1-4,y0+4,8,y1-y0-8) > - > - self.draw_circular_shadow(x0+4, y0+4, 4, math.pi, 3*math.pi/2, (-1,0), shadow) > - self.draw_circular_shadow(x1-4, y0+4, 4, 3*math.pi/2, 2*math.pi, (0,-1), shadow) > - self.draw_circular_shadow(x0+4, y1-4, 4, math.pi/2, math.pi, (0,1), shadow) > - self.draw_circular_shadow(x1-4, y1-4, 4, 0, math.pi/2, (1,0), shadow) > - > - def render_plot(self): > - for index,group in enumerate(self.series): > - for data in group: > - self.render_rectangle(self.borders[HORZ] + data.content[0]*self.horizontal_step, > - self.borders[VERT] + index*self.vertical_step + self.vertical_step/4.0, > - self.borders[HORZ] + data.content[1]*self.horizontal_step, > - self.borders[VERT] + index*self.vertical_step + 3.0*self.vertical_step/4.0, > - self.series_colors[index]) > - > -# Function definition > - > -def scatter_plot(name, > - data = None, > - errorx = None, > - errory = None, > - width = 640, > - height = 480, > - background = "white light_gray", > - border = 0, > - axis = False, > - dash = False, > - discrete = False, > - dots = False, > - grid = False, > - series_legend = False, > - x_labels = None, > - y_labels = None, > - x_bounds = None, > - y_bounds = None, > - z_bounds = None, > - x_title = None, > - y_title = None, > - series_colors = None, > - circle_colors = None): > - > - ''' > - - Function to plot scatter data. > - > - - Parameters > - > - data - The values to be ploted might be passed in a two basic: > - list of points: [(0,0), (0,1), (0,2)] or [(0,0,1), (0,1,4), (0,2,1)] > - lists of coordinates: [ [0,0,0] , [0,1,2] ] or [ [0,0,0] , [0,1,2] , [1,4,1] ] > - Notice that these kinds of that can be grouped in order to form more complex data > - using lists of lists or dictionaries; > - series_colors - Define color values for each of the series > - circle_colors - Define a lower and an upper bound for the circle colors for variable radius > - (3 dimensions) series > - ''' > - > - plot = ScatterPlot( name, data, errorx, errory, width, height, background, border, > - axis, dash, discrete, dots, grid, series_legend, x_labels, y_labels, > - x_bounds, y_bounds, z_bounds, x_title, y_title, series_colors, circle_colors ) > - plot.render() > - plot.commit() > - > -def dot_line_plot(name, > - data, > - width, > - height, > - background = "white light_gray", > - border = 0, > - axis = False, > - dash = False, > - dots = False, > - grid = False, > - series_legend = False, > - x_labels = None, > - y_labels = None, > - x_bounds = None, > - y_bounds = None, > - x_title = None, > - y_title = None, > - series_colors = None): > - ''' > - - Function to plot graphics using dots and lines. > - > - dot_line_plot (name, data, width, height, background = "white light_gray", border = 0, axis = False, grid = False, x_labels = None, y_labels = None, x_bounds = None, y_bounds = None) > - > - - Parameters > - > - name - Name of the desired output file, no need to input the .svg as it will be added at runtim; > - data - The list, list of lists or dictionary holding the data to be plotted; > - width, height - Dimensions of the output image; > - background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. > - If left None, a gray to white gradient will be generated; > - border - Distance in pixels of a square border into which the graphics will be drawn; > - axis - Whether or not the axis are to be drawn; > - dash - Boolean or a list or a dictionary of booleans indicating whether or not the associated series should be drawn in dashed mode; > - dots - Whether or not dots should be drawn on each point; > - grid - Whether or not the gris is to be drawn; > - series_legend - Whether or not the legend is to be drawn; > - x_labels, y_labels - lists of strings containing the horizontal and vertical labels for the axis; > - x_bounds, y_bounds - tuples containing the lower and upper value bounds for the data to be plotted; > - x_title - Whether or not to plot a title over the x axis. > - y_title - Whether or not to plot a title over the y axis. > - > - - Examples of use > - > - data = [0, 1, 3, 8, 9, 0, 10, 10, 2, 1] > - CairoPlot.dot_line_plot('teste', data, 400, 300) > - > - data = { "john" : [10, 10, 10, 10, 30], "mary" : [0, 0, 3, 5, 15], "philip" : [13, 32, 11, 25, 2] } > - x_labels = ["jan/2008", "feb/2008", "mar/2008", "apr/2008", "may/2008" ] > - CairoPlot.dot_line_plot( 'test', data, 400, 300, axis = True, grid = True, > - series_legend = True, x_labels = x_labels ) > - ''' > - plot = DotLinePlot( name, data, width, height, background, border, > - axis, dash, dots, grid, series_legend, x_labels, y_labels, > - x_bounds, y_bounds, x_title, y_title, series_colors ) > - plot.render() > - plot.commit() > - > -def function_plot(name, > - data, > - width, > - height, > - background = "white light_gray", > - border = 0, > - axis = True, > - dots = False, > - discrete = False, > - grid = False, > - series_legend = False, > - x_labels = None, > - y_labels = None, > - x_bounds = None, > - y_bounds = None, > - x_title = None, > - y_title = None, > - series_colors = None, > - step = 1): > - > - ''' > - - Function to plot functions. > - > - function_plot(name, data, width, height, background = "white light_gray", border = 0, axis = True, grid = False, dots = False, x_labels = None, y_labels = None, x_bounds = None, y_bounds = None, step = 1, discrete = False) > - > - - Parameters > - > - name - Name of the desired output file, no need to input the .svg as it will be added at runtim; > - data - The list, list of lists or dictionary holding the data to be plotted; > - width, height - Dimensions of the output image; > - background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. > - If left None, a gray to white gradient will be generated; > - border - Distance in pixels of a square border into which the graphics will be drawn; > - axis - Whether or not the axis are to be drawn; > - grid - Whether or not the gris is to be drawn; > - dots - Whether or not dots should be shown at each point; > - x_labels, y_labels - lists of strings containing the horizontal and vertical labels for the axis; > - x_bounds, y_bounds - tuples containing the lower and upper value bounds for the data to be plotted; > - step - the horizontal distance from one point to the other. The smaller, the smoother the curve will be; > - discrete - whether or not the function should be plotted in discrete format. > - > - - Example of use > - > - data = lambda x : x**2 > - CairoPlot.function_plot('function4', data, 400, 300, grid = True, x_bounds=(-10,10), step = 0.1) > - ''' > - > - plot = FunctionPlot( name, data, width, height, background, border, > - axis, discrete, dots, grid, series_legend, x_labels, y_labels, > - x_bounds, y_bounds, x_title, y_title, series_colors, step ) > - plot.render() > - plot.commit() > - > -def pie_plot( name, data, width, height, background = "white light_gray", gradient = False, shadow = False, colors = None ): > - > - ''' > - - Function to plot pie graphics. > - > - pie_plot(name, data, width, height, background = "white light_gray", gradient = False, colors = None) > - > - - Parameters > - > - name - Name of the desired output file, no need to input the .svg as it will be added at runtim; > - data - The list, list of lists or dictionary holding the data to be plotted; > - width, height - Dimensions of the output image; > - background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. > - If left None, a gray to white gradient will be generated; > - gradient - Whether or not the pie color will be painted with a gradient; > - shadow - Whether or not there will be a shadow behind the pie; > - colors - List of slices colors. > - > - - Example of use > - > - teste_data = {"john" : 123, "mary" : 489, "philip" : 890 , "suzy" : 235} > - CairoPlot.pie_plot("pie_teste", teste_data, 500, 500) > - ''' > - > - plot = PiePlot( name, data, width, height, background, gradient, shadow, colors ) > - plot.render() > - plot.commit() > - > -def donut_plot(name, data, width, height, background = "white light_gray", gradient = False, shadow = False, colors = None, inner_radius = -1): > - > - ''' > - - Function to plot donut graphics. > - > - donut_plot(name, data, width, height, background = "white light_gray", gradient = False, inner_radius = -1) > - > - - Parameters > - > - name - Name of the desired output file, no need to input the .svg as it will be added at runtim; > - data - The list, list of lists or dictionary holding the data to be plotted; > - width, height - Dimensions of the output image; > - background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. > - If left None, a gray to white gradient will be generated; > - shadow - Whether or not there will be a shadow behind the donut; > - gradient - Whether or not the donut color will be painted with a gradient; > - colors - List of slices colors; > - inner_radius - The radius of the donut's inner circle. > - > - - Example of use > - > - teste_data = {"john" : 123, "mary" : 489, "philip" : 890 , "suzy" : 235} > - CairoPlot.donut_plot("donut_teste", teste_data, 500, 500) > - ''' > - > - plot = DonutPlot(name, data, width, height, background, gradient, shadow, colors, inner_radius) > - plot.render() > - plot.commit() > - > -def gantt_chart(name, pieces, width, height, x_labels, y_labels, colors): > - > - ''' > - - Function to generate Gantt Charts. > - > - gantt_chart(name, pieces, width, height, x_labels, y_labels, colors): > - > - - Parameters > - > - name - Name of the desired output file, no need to input the .svg as it will be added at runtim; > - pieces - A list defining the spaces to be drawn. The user must pass, for each line, the index of its start and the index of its end. If a line must have two or more spaces, they must be passed inside a list; > - width, height - Dimensions of the output image; > - x_labels - A list of names for each of the vertical lines; > - y_labels - A list of names for each of the horizontal spaces; > - colors - List containing the colors expected for each of the horizontal spaces > - > - - Example of use > - > - pieces = [ (0.5,5.5) , [(0,4),(6,8)] , (5.5,7) , (7,8)] > - x_labels = [ 'teste01', 'teste02', 'teste03', 'teste04'] > - y_labels = [ '0001', '0002', '0003', '0004', '0005', '0006', '0007', '0008', '0009', '0010' ] > - colors = [ (1.0, 0.0, 0.0), (1.0, 0.7, 0.0), (1.0, 1.0, 0.0), (0.0, 1.0, 0.0) ] > - CairoPlot.gantt_chart('gantt_teste', pieces, 600, 300, x_labels, y_labels, colors) > - ''' > - > - plot = GanttChart(name, pieces, width, height, x_labels, y_labels, colors) > - plot.render() > - plot.commit() > - > -def vertical_bar_plot(name, > - data, > - width, > - height, > - background = "white light_gray", > - border = 0, > - display_values = False, > - grid = False, > - rounded_corners = False, > - stack = False, > - three_dimension = False, > - series_labels = None, > - x_labels = None, > - y_labels = None, > - x_bounds = None, > - y_bounds = None, > - colors = None): > - #TODO: Fix docstring for vertical_bar_plot > - ''' > - - Function to generate vertical Bar Plot Charts. > - > - bar_plot(name, data, width, height, background, border, grid, rounded_corners, three_dimension, > - x_labels, y_labels, x_bounds, y_bounds, colors): > - > - - Parameters > - > - name - Name of the desired output file, no need to input the .svg as it will be added at runtime; > - data - The list, list of lists or dictionary holding the data to be plotted; > - width, height - Dimensions of the output image; > - background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. > - If left None, a gray to white gradient will be generated; > - border - Distance in pixels of a square border into which the graphics will be drawn; > - grid - Whether or not the gris is to be drawn; > - rounded_corners - Whether or not the bars should have rounded corners; > - three_dimension - Whether or not the bars should be drawn in pseudo 3D; > - x_labels, y_labels - lists of strings containing the horizontal and vertical labels for the axis; > - x_bounds, y_bounds - tuples containing the lower and upper value bounds for the data to be plotted; > - colors - List containing the colors expected for each of the bars. > - > - - Example of use > - > - data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] > - CairoPlot.vertical_bar_plot ('bar2', data, 400, 300, border = 20, grid = True, rounded_corners = False) > - ''' > - > - plot = VerticalBarPlot(name, data, width, height, background, border, > - display_values, grid, rounded_corners, stack, three_dimension, > - series_labels, x_labels, y_labels, x_bounds, y_bounds, colors) > - plot.render() > - plot.commit() > - > -def horizontal_bar_plot(name, > - data, > - width, > - height, > - background = "white light_gray", > - border = 0, > - display_values = False, > - grid = False, > - rounded_corners = False, > - stack = False, > - three_dimension = False, > - series_labels = None, > - x_labels = None, > - y_labels = None, > - x_bounds = None, > - y_bounds = None, > - colors = None): > - > - #TODO: Fix docstring for horizontal_bar_plot > - ''' > - - Function to generate Horizontal Bar Plot Charts. > - > - bar_plot(name, data, width, height, background, border, grid, rounded_corners, three_dimension, > - x_labels, y_labels, x_bounds, y_bounds, colors): > - > - - Parameters > - > - name - Name of the desired output file, no need to input the .svg as it will be added at runtime; > - data - The list, list of lists or dictionary holding the data to be plotted; > - width, height - Dimensions of the output image; > - background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. > - If left None, a gray to white gradient will be generated; > - border - Distance in pixels of a square border into which the graphics will be drawn; > - grid - Whether or not the gris is to be drawn; > - rounded_corners - Whether or not the bars should have rounded corners; > - three_dimension - Whether or not the bars should be drawn in pseudo 3D; > - x_labels, y_labels - lists of strings containing the horizontal and vertical labels for the axis; > - x_bounds, y_bounds - tuples containing the lower and upper value bounds for the data to be plotted; > - colors - List containing the colors expected for each of the bars. > - > - - Example of use > - > - data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] > - CairoPlot.bar_plot ('bar2', data, 400, 300, border = 20, grid = True, rounded_corners = False) > - ''' > - > - plot = HorizontalBarPlot(name, data, width, height, background, border, > - display_values, grid, rounded_corners, stack, three_dimension, > - series_labels, x_labels, y_labels, x_bounds, y_bounds, colors) > - plot.render() > - plot.commit() > - > -def stream_chart(name, > - data, > - width, > - height, > - background = "white light_gray", > - border = 0, > - grid = False, > - series_legend = None, > - x_labels = None, > - x_bounds = None, > - y_bounds = None, > - colors = None): > - > - #TODO: Fix docstring for horizontal_bar_plot > - plot = StreamChart(name, data, width, height, background, border, > - grid, series_legend, x_labels, x_bounds, y_bounds, colors) > - plot.render() > - plot.commit() > - > - > -if __name__ == "__main__": > - import tests > - import seriestests > diff --git a/bindings/python/examples/output_format_modules/pprint_table.py b/bindings/python/examples/output_format_modules/pprint_table.py > deleted file mode 100644 > index a7e8255..0000000 > --- a/bindings/python/examples/output_format_modules/pprint_table.py > +++ /dev/null > @@ -1,37 +0,0 @@ > -# pprint_table.py > -# > -# This module is used to pretty-print a table > -# Adapted from > -# http://ginstrom.com/scribbles/2007/09/04/pretty-printing-a-table-in-python/ > - > -import sys > - > -def get_max_width(table, index): > - """Get the maximum width of the given column index""" > - > - return max([len(str(row[index])) for row in table]) > - > - > -def pprint_table(table, nbLeft=1, out=sys.stdout): > - """ > - Prints out a table of data, padded for alignment > - @param table: The table to print. A list of lists. > - Each row must have the same number of columns. > - @param nbLeft: The number of columns aligned left > - @param out: Output stream (file-like object) > - """ > - > - col_paddings = [] > - > - for i in range(len(table[0])): > - col_paddings.append(get_max_width(table, i)) > - > - for row in table: > - # left cols > - for i in range(nbLeft): > - print >> out, str(row[i]).ljust(col_paddings[i] + 1), > - # rest of the cols > - for i in range(nbLeft, len(row)): > - col = str(row[i]).rjust(col_paddings[i] + 2) > - print >> out, col, > - print >> out > diff --git a/bindings/python/examples/output_format_modules/series.py b/bindings/python/examples/output_format_modules/series.py > deleted file mode 100644 > index 8e8b236..0000000 > --- a/bindings/python/examples/output_format_modules/series.py > +++ /dev/null > @@ -1,1140 +0,0 @@ > -#!/usr/bin/env python > -# -*- coding: utf-8 -*- > - > -# Serie.py > -# > -# Copyright (c) 2008 Magnun Leno da Silva > -# > -# Author: Magnun Leno da Silva > -# > -# This program is free software; you can redistribute it and/or > -# modify it under the terms of the GNU Lesser 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 Lesser 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 > - > -# Contributor: Rodrigo Moreiro Araujo > - > -#import cairoplot > -import doctest > - > -NUMTYPES = (int, float, long) > -LISTTYPES = (list, tuple) > -STRTYPES = (str, unicode) > -FILLING_TYPES = ['linear', 'solid', 'gradient'] > -DEFAULT_COLOR_FILLING = 'solid' > -#TODO: Define default color list > -DEFAULT_COLOR_LIST = None > - > -class Data(object): > - ''' > - Class that models the main data structure. > - It can hold: > - - a number type (int, float or long) > - - a tuple, witch represents a point and can have 2 or 3 items (x,y,z) > - - if a list is passed it will be converted to a tuple. > - > - obs: In case a tuple is passed it will convert to tuple > - ''' > - def __init__(self, data=None, name=None, parent=None): > - ''' > - Starts main atributes from the Data class > - @name - Name for each point; > - @content - The real data, can be an int, float, long or tuple, which > - represents a point (x,y) or (x,y,z); > - @parent - A pointer that give the data access to it's parent. > - > - Usage: > - >>> d = Data(name='empty'); print d > - empty: () > - >>> d = Data((1,1),'point a'); print d > - point a: (1, 1) > - >>> d = Data((1,2,3),'point b'); print d > - point b: (1, 2, 3) > - >>> d = Data([2,3],'point c'); print d > - point c: (2, 3) > - >>> d = Data(12, 'simple value'); print d > - simple value: 12 > - ''' > - # Initial values > - self.__content = None > - self.__name = None > - > - # Setting passed values > - self.parent = parent > - self.name = name > - self.content = data > - > - # Name property > - @apply > - def name(): > - doc = ''' > - Name is a read/write property that controls the input of name. > - - If passed an invalid value it cleans the name with None > - > - Usage: > - >>> d = Data(13); d.name = 'name_test'; print d > - name_test: 13 > - >>> d.name = 11; print d > - 13 > - >>> d.name = 'other_name'; print d > - other_name: 13 > - >>> d.name = None; print d > - 13 > - >>> d.name = 'last_name'; print d > - last_name: 13 > - >>> d.name = ''; print d > - 13 > - ''' > - def fget(self): > - ''' > - returns the name as a string > - ''' > - return self.__name > - > - def fset(self, name): > - ''' > - Sets the name of the Data > - ''' > - if type(name) in STRTYPES and len(name) > 0: > - self.__name = name > - else: > - self.__name = None > - > - > - > - return property(**locals()) > - > - # Content property > - @apply > - def content(): > - doc = ''' > - Content is a read/write property that validate the data passed > - and return it. > - > - Usage: > - >>> d = Data(); d.content = 13; d.content > - 13 > - >>> d = Data(); d.content = (1,2); d.content > - (1, 2) > - >>> d = Data(); d.content = (1,2,3); d.content > - (1, 2, 3) > - >>> d = Data(); d.content = [1,2,3]; d.content > - (1, 2, 3) > - >>> d = Data(); d.content = [1.5,.2,3.3]; d.content > - (1.5, 0.20000000000000001, 3.2999999999999998) > - ''' > - def fget(self): > - ''' > - Return the content of Data > - ''' > - return self.__content > - > - def fset(self, data): > - ''' > - Ensures that data is a valid tuple/list or a number (int, float > - or long) > - ''' > - # Type: None > - if data is None: > - self.__content = None > - return > - > - # Type: Int or Float > - elif type(data) in NUMTYPES: > - self.__content = data > - > - # Type: List or Tuple > - elif type(data) in LISTTYPES: > - # Ensures the correct size > - if len(data) not in (2, 3): > - raise TypeError, "Data (as list/tuple) must have 2 or 3 items" > - return > - > - # Ensures that all items in list/tuple is a number > - isnum = lambda x : type(x) not in NUMTYPES > - > - if max(map(isnum, data)): > - # An item in data isn't an int or a float > - raise TypeError, "All content of data must be a number (int or float)" > - > - # Convert the tuple to list > - if type(data) is list: > - data = tuple(data) > - > - # Append a copy and sets the type > - self.__content = data[:] > - > - # Unknown type! > - else: > - self.__content = None > - raise TypeError, "Data must be an int, float or a tuple with two or three items" > - return > - > - return property(**locals()) > - > - > - def clear(self): > - ''' > - Clear the all Data (content, name and parent) > - ''' > - self.content = None > - self.name = None > - self.parent = None > - > - def copy(self): > - ''' > - Returns a copy of the Data structure > - ''' > - # The copy > - new_data = Data() > - if self.content is not None: > - # If content is a point > - if type(self.content) is tuple: > - new_data.__content = self.content[:] > - > - # If content is a number > - else: > - new_data.__content = self.content > - > - # If it has a name > - if self.name is not None: > - new_data.__name = self.name > - > - return new_data > - > - def __str__(self): > - ''' > - Return a string representation of the Data structure > - ''' > - if self.name is None: > - if self.content is None: > - return '' > - return str(self.content) > - else: > - if self.content is None: > - return self.name+": ()" > - return self.name+": "+str(self.content) > - > - def __len__(self): > - ''' > - Return the length of the Data. > - - If it's a number return 1; > - - If it's a list return it's length; > - - If its None return 0. > - ''' > - if self.content is None: > - return 0 > - elif type(self.content) in NUMTYPES: > - return 1 > - return len(self.content) > - > - > - > - > -class Group(object): > - ''' > - Class that models a group of data. Every value (int, float, long, tuple > - or list) passed is converted to a list of Data. > - It can receive: > - - A single number (int, float, long); > - - A list of numbers; > - - A tuple of numbers; > - - An instance of Data; > - - A list of Data; > - > - Obs: If a tuple with 2 or 3 items is passed it is converted to a point. > - If a tuple with only 1 item is passed it's converted to a number; > - If a tuple with more than 2 items is passed it's converted to a > - list of numbers > - ''' > - def __init__(self, group=None, name=None, parent=None): > - ''' > - Starts main atributes in Group instance. > - @data_list - a list of data which forms the group; > - @range - a range that represent the x axis of possible functions; > - @name - name of the data group; > - @parent - the Serie parent of this group. > - > - Usage: > - >>> g = Group(13, 'simple number'); print g > - simple number ['13'] > - >>> g = Group((1,2), 'simple point'); print g > - simple point ['(1, 2)'] > - >>> g = Group([1,2,3,4], 'list of numbers'); print g > - list of numbers ['1', '2', '3', '4'] > - >>> g = Group((1,2,3,4),'int in tuple'); print g > - int in tuple ['1', '2', '3', '4'] > - >>> g = Group([(1,2),(2,3),(3,4)], 'list of points'); print g > - list of points ['(1, 2)', '(2, 3)', '(3, 4)'] > - >>> g = Group([[1,2,3],[1,2,3]], '2D coordinate lists'); print g > - 2D coordinated lists ['(1, 1)', '(2, 2)', '(3, 3)'] > - >>> g = Group([[1,2],[1,2],[1,2]], '3D coordinate lists'); print g > - 3D coordinated lists ['(1, 1, 1)', '(2, 2, 2)'] > - ''' > - # Initial values > - self.__data_list = [] > - self.__range = [] > - self.__name = None > - > - > - self.parent = parent > - self.name = name > - self.data_list = group > - > - # Name property > - @apply > - def name(): > - doc = ''' > - Name is a read/write property that controls the input of name. > - - If passed an invalid value it cleans the name with None > - > - Usage: > - >>> g = Group(13); g.name = 'name_test'; print g > - name_test ['13'] > - >>> g.name = 11; print g > - ['13'] > - >>> g.name = 'other_name'; print g > - other_name ['13'] > - >>> g.name = None; print g > - ['13'] > - >>> g.name = 'last_name'; print g > - last_name ['13'] > - >>> g.name = ''; print g > - ['13'] > - ''' > - def fget(self): > - ''' > - Returns the name as a string > - ''' > - return self.__name > - > - def fset(self, name): > - ''' > - Sets the name of the Group > - ''' > - if type(name) in STRTYPES and len(name) > 0: > - self.__name = name > - else: > - self.__name = None > - > - return property(**locals()) > - > - # data_list property > - @apply > - def data_list(): > - doc = ''' > - The data_list is a read/write property that can be a list of > - numbers, a list of points or a list of 2 or 3 coordinate lists. This > - property uses mainly the self.add_data method. > - > - Usage: > - >>> g = Group(); g.data_list = 13; print g > - ['13'] > - >>> g.data_list = (1,2); print g > - ['(1, 2)'] > - >>> g.data_list = Data((1,2),'point a'); print g > - ['point a: (1, 2)'] > - >>> g.data_list = [1,2,3]; print g > - ['1', '2', '3'] > - >>> g.data_list = (1,2,3,4); print g > - ['1', '2', '3', '4'] > - >>> g.data_list = [(1,2),(2,3),(3,4)]; print g > - ['(1, 2)', '(2, 3)', '(3, 4)'] > - >>> g.data_list = [[1,2],[1,2]]; print g > - ['(1, 1)', '(2, 2)'] > - >>> g.data_list = [[1,2],[1,2],[1,2]]; print g > - ['(1, 1, 1)', '(2, 2, 2)'] > - >>> g.range = (10); g.data_list = lambda x:x**2; print g > - ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 4.0)', '(3.0, 9.0)', '(4.0, 16.0)', '(5.0, 25.0)', '(6.0, 36.0)', '(7.0, 49.0)', '(8.0, 64.0)', '(9.0, 81.0)'] > - ''' > - def fget(self): > - ''' > - Returns the value of data_list > - ''' > - return self.__data_list > - > - def fset(self, group): > - ''' > - Ensures that group is valid. > - ''' > - # None > - if group is None: > - self.__data_list = [] > - > - # Int/float/long or Instance of Data > - elif type(group) in NUMTYPES or isinstance(group, Data): > - # Clean data_list > - self.__data_list = [] > - self.add_data(group) > - > - # One point > - elif type(group) is tuple and len(group) in (2,3): > - self.__data_list = [] > - self.add_data(group) > - > - # list of items > - elif type(group) in LISTTYPES and type(group[0]) is not list: > - # Clean data_list > - self.__data_list = [] > - for item in group: > - # try to append and catch an exception > - self.add_data(item) > - > - # function lambda > - elif callable(group): > - # Explicit is better than implicit > - function = group > - # Has range > - if len(self.range) is not 0: > - # Clean data_list > - self.__data_list = [] > - # Generate values for the lambda function > - for x in self.range: > - #self.add_data((x,round(group(x),2))) > - self.add_data((x,function(x))) > - > - # Only have range in parent > - elif self.parent is not None and len(self.parent.range) is not 0: > - # Copy parent range > - self.__range = self.parent.range[:] > - # Clean data_list > - self.__data_list = [] > - # Generate values for the lambda function > - for x in self.range: > - #self.add_data((x,round(group(x),2))) > - self.add_data((x,function(x))) > - > - # Don't have range anywhere > - else: > - # x_data don't exist > - raise Exception, "Data argument is valid but to use function type please set x_range first" > - > - # Coordinate Lists > - elif type(group) in LISTTYPES and type(group[0]) is list: > - # Clean data_list > - self.__data_list = [] > - data = [] > - if len(group) == 3: > - data = zip(group[0], group[1], group[2]) > - elif len(group) == 2: > - data = zip(group[0], group[1]) > - else: > - raise TypeError, "Only one list of coordinates was received." > - > - for item in data: > - self.add_data(item) > - > - else: > - raise TypeError, "Group type not supported" > - > - return property(**locals()) > - > - @apply > - def range(): > - doc = ''' > - The range is a read/write property that generates a range of values > - for the x axis of the functions. When passed a tuple it almost works > - like the built-in range funtion: > - - 1 item, represent the end of the range started from 0; > - - 2 items, represents the start and the end, respectively; > - - 3 items, the last one represents the step; > - > - When passed a list the range function understands as a valid range. > - > - Usage: > - >>> g = Group(); g.range = 10; print g.range > - [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] > - >>> g = Group(); g.range = (5); print g.range > - [0.0, 1.0, 2.0, 3.0, 4.0] > - >>> g = Group(); g.range = (1,7); print g.range > - [1.0, 2.0, 3.0, 4.0, 5.0, 6.0] > - >>> g = Group(); g.range = (0,10,2); print g.range > - [0.0, 2.0, 4.0, 6.0, 8.0] > - >>> > - >>> g = Group(); g.range = [0]; print g.range > - [0.0] > - >>> g = Group(); g.range = [0,10,20]; print g.range > - [0.0, 10.0, 20.0] > - ''' > - def fget(self): > - ''' > - Returns the range > - ''' > - return self.__range > - > - def fset(self, x_range): > - ''' > - Controls the input of a valid type and generate the range > - ''' > - # if passed a simple number convert to tuple > - if type(x_range) in NUMTYPES: > - x_range = (x_range,) > - > - # A list, just convert to float > - if type(x_range) is list and len(x_range) > 0: > - # Convert all to float > - x_range = map(float, x_range) > - # Prevents repeated values and convert back to list > - self.__range = list(set(x_range[:])) > - # Sort the list to ascending order > - self.__range.sort() > - > - # A tuple, must check the lengths and generate the values > - elif type(x_range) is tuple and len(x_range) in (1,2,3): > - # Convert all to float > - x_range = map(float, x_range) > - > - # Inital values > - start = 0.0 > - step = 1.0 > - end = 0.0 > - > - # Only the end and it can't be less or iqual to 0 > - if len(x_range) is 1 and x_range > 0: > - end = x_range[0] > - > - # The start and the end but the start must be less then the end > - elif len(x_range) is 2 and x_range[0] < x_range[1]: > - start = x_range[0] > - end = x_range[1] > - > - # All 3, but the start must be less then the end > - elif x_range[0] <= x_range[1]: > - start = x_range[0] > - end = x_range[1] > - step = x_range[2] > - > - # Starts the range > - self.__range = [] > - # Generate the range > - # Can't use the range function because it doesn't support float values > - while start < end: > - self.__range.append(start) > - start += step > - > - # Incorrect type > - else: > - raise Exception, "x_range must be a list with one or more items or a tuple with 2 or 3 items" > - > - return property(**locals()) > - > - def add_data(self, data, name=None): > - ''' > - Append a new data to the data_list. > - - If data is an instance of Data, append it > - - If it's an int, float, tuple or list create an instance of Data and append it > - > - Usage: > - >>> g = Group() > - >>> g.add_data(12); print g > - ['12'] > - >>> g.add_data(7,'other'); print g > - ['12', 'other: 7'] > - >>> > - >>> g = Group() > - >>> g.add_data((1,1),'a'); print g > - ['a: (1, 1)'] > - >>> g.add_data((2,2),'b'); print g > - ['a: (1, 1)', 'b: (2, 2)'] > - >>> > - >>> g.add_data(Data((1,2),'c')); print g > - ['a: (1, 1)', 'b: (2, 2)', 'c: (1, 2)'] > - ''' > - if not isinstance(data, Data): > - # Try to convert > - data = Data(data,name,self) > - > - if data.content is not None: > - self.__data_list.append(data.copy()) > - self.__data_list[-1].parent = self > - > - > - def to_list(self): > - ''' > - Returns the group as a list of numbers (int, float or long) or a > - list of tuples (points 2D or 3D). > - > - Usage: > - >>> g = Group([1,2,3,4],'g1'); g.to_list() > - [1, 2, 3, 4] > - >>> g = Group([(1,2),(2,3),(3,4)],'g2'); g.to_list() > - [(1, 2), (2, 3), (3, 4)] > - >>> g = Group([(1,2,3),(3,4,5)],'g2'); g.to_list() > - [(1, 2, 3), (3, 4, 5)] > - ''' > - return [data.content for data in self] > - > - def copy(self): > - ''' > - Returns a copy of this group > - ''' > - new_group = Group() > - new_group.__name = self.__name > - if self.__range is not None: > - new_group.__range = self.__range[:] > - for data in self: > - new_group.add_data(data.copy()) > - return new_group > - > - def get_names(self): > - ''' > - Return a list with the names of all data in this group > - ''' > - names = [] > - for data in self: > - if data.name is None: > - names.append('Data '+str(data.index()+1)) > - else: > - names.append(data.name) > - return names > - > - > - def __str__ (self): > - ''' > - Returns a string representing the Group > - ''' > - ret = "" > - if self.name is not None: > - ret += self.name + " " > - if len(self) > 0: > - list_str = [str(item) for item in self] > - ret += str(list_str) > - else: > - ret += "[]" > - return ret > - > - def __getitem__(self, key): > - ''' > - Makes a Group iterable, based in the data_list property > - ''' > - return self.data_list[key] > - > - def __len__(self): > - ''' > - Returns the length of the Group, based in the data_list property > - ''' > - return len(self.data_list) > - > - > -class Colors(object): > - ''' > - Class that models the colors its labels (names) and its properties, RGB > - and filling type. > - > - It can receive: > - - A list where each item is a list with 3 or 4 items. The > - first 3 items represent the RGB values and the last argument > - defines the filling type. The list will be converted to a dict > - and each color will receve a name based in its position in the > - list. > - - A dictionary where each key will be the color name and its item > - can be a list with 3 or 4 items. The first 3 items represent > - the RGB colors and the last argument defines the filling type. > - ''' > - def __init__(self, color_list=None): > - ''' > - Start the color_list property > - @ color_list - the list or dict contaning the colors properties. > - ''' > - self.__color_list = None > - > - self.color_list = color_list > - > - @apply > - def color_list(): > - doc = ''' > - >>> c = Colors([[1,1,1],[2,2,2,'linear'],[3,3,3,'gradient']]) > - >>> print c.color_list > - {'Color 2': [2, 2, 2, 'linear'], 'Color 3': [3, 3, 3, 'gradient'], 'Color 1': [1, 1, 1, 'solid']} > - >>> c.color_list = [[1,1,1],(2,2,2,'solid'),(3,3,3,'linear')] > - >>> print c.color_list > - {'Color 2': [2, 2, 2, 'solid'], 'Color 3': [3, 3, 3, 'linear'], 'Color 1': [1, 1, 1, 'solid']} > - >>> c.color_list = {'a':[1,1,1],'b':(2,2,2,'solid'),'c':(3,3,3,'linear'), 'd':(4,4,4)} > - >>> print c.color_list > - {'a': [1, 1, 1, 'solid'], 'c': [3, 3, 3, 'linear'], 'b': [2, 2, 2, 'solid'], 'd': [4, 4, 4, 'solid']} > - ''' > - def fget(self): > - ''' > - Return the color list > - ''' > - return self.__color_list > - > - def fset(self, color_list): > - ''' > - Format the color list to a dictionary > - ''' > - if color_list is None: > - self.__color_list = None > - return > - > - if type(color_list) in LISTTYPES and type(color_list[0]) in LISTTYPES: > - old_color_list = color_list[:] > - color_list = {} > - for index, color in enumerate(old_color_list): > - if len(color) is 3 and max(map(type, color)) in NUMTYPES: > - color_list['Color '+str(index+1)] = list(color)+[DEFAULT_COLOR_FILLING] > - elif len(color) is 4 and max(map(type, color[:-1])) in NUMTYPES and color[-1] in FILLING_TYPES: > - color_list['Color '+str(index+1)] = list(color) > - else: > - raise TypeError, "Unsuported color format" > - elif type(color_list) is not dict: > - raise TypeError, "Unsuported color format" > - > - for name, color in color_list.items(): > - if len(color) is 3: > - if max(map(type, color)) in NUMTYPES: > - color_list[name] = list(color)+[DEFAULT_COLOR_FILLING] > - else: > - raise TypeError, "Unsuported color format" > - elif len(color) is 4: > - if max(map(type, color[:-1])) in NUMTYPES and color[-1] in FILLING_TYPES: > - color_list[name] = list(color) > - else: > - raise TypeError, "Unsuported color format" > - self.__color_list = color_list.copy() > - > - return property(**locals()) > - > - > -class Series(object): > - ''' > - Class that models a Series (group of groups). Every value (int, float, > - long, tuple or list) passed is converted to a list of Group or Data. > - It can receive: > - - a single number or point, will be converted to a Group of one Data; > - - a list of numbers, will be converted to a group of numbers; > - - a list of tuples, will converted to a single Group of points; > - - a list of lists of numbers, each 'sublist' will be converted to a > - group of numbers; > - - a list of lists of tuples, each 'sublist' will be converted to a > - group of points; > - - a list of lists of lists, the content of the 'sublist' will be > - processed as coordinated lists and the result will be converted to > - a group of points; > - - a Dictionary where each item can be the same of the list: number, > - point, list of numbers, list of points or list of lists (coordinated > - lists); > - - an instance of Data; > - - an instance of group. > - ''' > - def __init__(self, series=None, name=None, property=[], colors=None): > - ''' > - Starts main atributes in Group instance. > - @series - a list, dict of data of which the series is composed; > - @name - name of the series; > - @property - a list/dict of properties to be used in the plots of > - this Series > - > - Usage: > - >>> print Series([1,2,3,4]) > - ["Group 1 ['1', '2', '3', '4']"] > - >>> print Series([[1,2,3],[4,5,6]]) > - ["Group 1 ['1', '2', '3']", "Group 2 ['4', '5', '6']"] > - >>> print Series((1,2)) > - ["Group 1 ['(1, 2)']"] > - >>> print Series([(1,2),(2,3)]) > - ["Group 1 ['(1, 2)', '(2, 3)']"] > - >>> print Series([[(1,2),(2,3)],[(4,5),(5,6)]]) > - ["Group 1 ['(1, 2)', '(2, 3)']", "Group 2 ['(4, 5)', '(5, 6)']"] > - >>> print Series([[[1,2,3],[1,2,3],[1,2,3]]]) > - ["Group 1 ['(1, 1, 1)', '(2, 2, 2)', '(3, 3, 3)']"] > - >>> print Series({'g1':[1,2,3], 'g2':[4,5,6]}) > - ["g1 ['1', '2', '3']", "g2 ['4', '5', '6']"] > - >>> print Series({'g1':[(1,2),(2,3)], 'g2':[(4,5),(5,6)]}) > - ["g1 ['(1, 2)', '(2, 3)']", "g2 ['(4, 5)', '(5, 6)']"] > - >>> print Series({'g1':[[1,2],[1,2]], 'g2':[[4,5],[4,5]]}) > - ["g1 ['(1, 1)', '(2, 2)']", "g2 ['(4, 4)', '(5, 5)']"] > - >>> print Series(Data(1,'d1')) > - ["Group 1 ['d1: 1']"] > - >>> print Series(Group([(1,2),(2,3)],'g1')) > - ["g1 ['(1, 2)', '(2, 3)']"] > - ''' > - # Intial values > - self.__group_list = [] > - self.__name = None > - self.__range = None > - > - # TODO: Implement colors with filling > - self.__colors = None > - > - self.name = name > - self.group_list = series > - self.colors = colors > - > - # Name property > - @apply > - def name(): > - doc = ''' > - Name is a read/write property that controls the input of name. > - - If passed an invalid value it cleans the name with None > - > - Usage: > - >>> s = Series(13); s.name = 'name_test'; print s > - name_test ["Group 1 ['13']"] > - >>> s.name = 11; print s > - ["Group 1 ['13']"] > - >>> s.name = 'other_name'; print s > - other_name ["Group 1 ['13']"] > - >>> s.name = None; print s > - ["Group 1 ['13']"] > - >>> s.name = 'last_name'; print s > - last_name ["Group 1 ['13']"] > - >>> s.name = ''; print s > - ["Group 1 ['13']"] > - ''' > - def fget(self): > - ''' > - Returns the name as a string > - ''' > - return self.__name > - > - def fset(self, name): > - ''' > - Sets the name of the Group > - ''' > - if type(name) in STRTYPES and len(name) > 0: > - self.__name = name > - else: > - self.__name = None > - > - return property(**locals()) > - > - > - > - # Colors property > - @apply > - def colors(): > - doc = ''' > - >>> s = Series() > - >>> s.colors = [[1,1,1],[2,2,2,'linear'],[3,3,3,'gradient']] > - >>> print s.colors > - {'Color 2': [2, 2, 2, 'linear'], 'Color 3': [3, 3, 3, 'gradient'], 'Color 1': [1, 1, 1, 'solid']} > - >>> s.colors = [[1,1,1],(2,2,2,'solid'),(3,3,3,'linear')] > - >>> print s.colors > - {'Color 2': [2, 2, 2, 'solid'], 'Color 3': [3, 3, 3, 'linear'], 'Color 1': [1, 1, 1, 'solid']} > - >>> s.colors = {'a':[1,1,1],'b':(2,2,2,'solid'),'c':(3,3,3,'linear'), 'd':(4,4,4)} > - >>> print s.colors > - {'a': [1, 1, 1, 'solid'], 'c': [3, 3, 3, 'linear'], 'b': [2, 2, 2, 'solid'], 'd': [4, 4, 4, 'solid']} > - ''' > - def fget(self): > - ''' > - Return the color list > - ''' > - return self.__colors.color_list > - > - def fset(self, colors): > - ''' > - Format the color list to a dictionary > - ''' > - self.__colors = Colors(colors) > - > - return property(**locals()) > - > - @apply > - def range(): > - doc = ''' > - The range is a read/write property that generates a range of values > - for the x axis of the functions. When passed a tuple it almost works > - like the built-in range funtion: > - - 1 item, represent the end of the range started from 0; > - - 2 items, represents the start and the end, respectively; > - - 3 items, the last one represents the step; > - > - When passed a list the range function understands as a valid range. > - > - Usage: > - >>> s = Series(); s.range = 10; print s.range > - [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0] > - >>> s = Series(); s.range = (5); print s.range > - [0.0, 1.0, 2.0, 3.0, 4.0, 5.0] > - >>> s = Series(); s.range = (1,7); print s.range > - [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] > - >>> s = Series(); s.range = (0,10,2); print s.range > - [0.0, 2.0, 4.0, 6.0, 8.0, 10.0] > - >>> > - >>> s = Series(); s.range = [0]; print s.range > - [0.0] > - >>> s = Series(); s.range = [0,10,20]; print s.range > - [0.0, 10.0, 20.0] > - ''' > - def fget(self): > - ''' > - Returns the range > - ''' > - return self.__range > - > - def fset(self, x_range): > - ''' > - Controls the input of a valid type and generate the range > - ''' > - # if passed a simple number convert to tuple > - if type(x_range) in NUMTYPES: > - x_range = (x_range,) > - > - # A list, just convert to float > - if type(x_range) is list and len(x_range) > 0: > - # Convert all to float > - x_range = map(float, x_range) > - # Prevents repeated values and convert back to list > - self.__range = list(set(x_range[:])) > - # Sort the list to ascending order > - self.__range.sort() > - > - # A tuple, must check the lengths and generate the values > - elif type(x_range) is tuple and len(x_range) in (1,2,3): > - # Convert all to float > - x_range = map(float, x_range) > - > - # Inital values > - start = 0.0 > - step = 1.0 > - end = 0.0 > - > - # Only the end and it can't be less or iqual to 0 > - if len(x_range) is 1 and x_range > 0: > - end = x_range[0] > - > - # The start and the end but the start must be lesser then the end > - elif len(x_range) is 2 and x_range[0] < x_range[1]: > - start = x_range[0] > - end = x_range[1] > - > - # All 3, but the start must be lesser then the end > - elif x_range[0] < x_range[1]: > - start = x_range[0] > - end = x_range[1] > - step = x_range[2] > - > - # Starts the range > - self.__range = [] > - # Generate the range > - # Cnat use the range function becouse it don't suport float values > - while start <= end: > - self.__range.append(start) > - start += step > - > - # Incorrect type > - else: > - raise Exception, "x_range must be a list with one or more item or a tuple with 2 or 3 items" > - > - return property(**locals()) > - > - @apply > - def group_list(): > - doc = ''' > - The group_list is a read/write property used to pre-process the list > - of Groups. > - It can be: > - - a single number, point or lambda, will be converted to a single > - Group of one Data; > - - a list of numbers, will be converted to a group of numbers; > - - a list of tuples, will converted to a single Group of points; > - - a list of lists of numbers, each 'sublist' will be converted to > - a group of numbers; > - - a list of lists of tuples, each 'sublist' will be converted to a > - group of points; > - - a list of lists of lists, the content of the 'sublist' will be > - processed as coordinated lists and the result will be converted > - to a group of points; > - - a list of lambdas, each lambda represents a Group; > - - a Dictionary where each item can be the same of the list: number, > - point, list of numbers, list of points, list of lists > - (coordinated lists) or lambdas > - - an instance of Data; > - - an instance of group. > - > - Usage: > - >>> s = Series() > - >>> s.group_list = [1,2,3,4]; print s > - ["Group 1 ['1', '2', '3', '4']"] > - >>> s.group_list = [[1,2,3],[4,5,6]]; print s > - ["Group 1 ['1', '2', '3']", "Group 2 ['4', '5', '6']"] > - >>> s.group_list = (1,2); print s > - ["Group 1 ['(1, 2)']"] > - >>> s.group_list = [(1,2),(2,3)]; print s > - ["Group 1 ['(1, 2)', '(2, 3)']"] > - >>> s.group_list = [[(1,2),(2,3)],[(4,5),(5,6)]]; print s > - ["Group 1 ['(1, 2)', '(2, 3)']", "Group 2 ['(4, 5)', '(5, 6)']"] > - >>> s.group_list = [[[1,2,3],[1,2,3],[1,2,3]]]; print s > - ["Group 1 ['(1, 1, 1)', '(2, 2, 2)', '(3, 3, 3)']"] > - >>> s.group_list = [(0.5,5.5) , [(0,4),(6,8)] , (5.5,7) , (7,9)]; print s > - ["Group 1 ['(0.5, 5.5)']", "Group 2 ['(0, 4)', '(6, 8)']", "Group 3 ['(5.5, 7)']", "Group 4 ['(7, 9)']"] > - >>> s.group_list = {'g1':[1,2,3], 'g2':[4,5,6]}; print s > - ["g1 ['1', '2', '3']", "g2 ['4', '5', '6']"] > - >>> s.group_list = {'g1':[(1,2),(2,3)], 'g2':[(4,5),(5,6)]}; print s > - ["g1 ['(1, 2)', '(2, 3)']", "g2 ['(4, 5)', '(5, 6)']"] > - >>> s.group_list = {'g1':[[1,2],[1,2]], 'g2':[[4,5],[4,5]]}; print s > - ["g1 ['(1, 1)', '(2, 2)']", "g2 ['(4, 4)', '(5, 5)']"] > - >>> s.range = 10 > - >>> s.group_list = lambda x:x*2 > - >>> s.group_list = [lambda x:x*2, lambda x:x**2, lambda x:x**3]; print s > - ["Group 1 ['(0.0, 0.0)', '(1.0, 2.0)', '(2.0, 4.0)', '(3.0, 6.0)', '(4.0, 8.0)', '(5.0, 10.0)', '(6.0, 12.0)', '(7.0, 14.0)', '(8.0, 16.0)', '(9.0, 18.0)', '(10.0, 20.0)']", "Group 2 ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 4.0)', '(3.0, 9.0)', '(4.0, 16.0)', '(5.0, 25.0)', '(6.0, 36.0)', '(7.0, 49.0)', '(8.0, 64.0)', '(9.0, 81.0)', '(10.0, 100.0)']", "Group 3 ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 8.0)', '(3.0, 27.0)', '(4.0, 64.0)', '(5.0, 125.0)', '(6.0, 216.0)', '(7.0, 343.0)', '(8.0, 512.0)', '(9.0, 729.0)', '(10.0, 1000.0)']"] > - >>> s.group_list = {'linear':lambda x:x*2, 'square':lambda x:x**2, 'cubic':lambda x:x**3}; print s > - ["cubic ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 8.0)', '(3.0, 27.0)', '(4.0, 64.0)', '(5.0, 125.0)', '(6.0, 216.0)', '(7.0, 343.0)', '(8.0, 512.0)', '(9.0, 729.0)', '(10.0, 1000.0)']", "linear ['(0.0, 0.0)', '(1.0, 2.0)', '(2.0, 4.0)', '(3.0, 6.0)', '(4.0, 8.0)', '(5.0, 10.0)', '(6.0, 12.0)', '(7.0, 14.0)', '(8.0, 16.0)', '(9.0, 18.0)', '(10.0, 20.0)']", "square ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 4.0)', '(3.0, 9.0)', '(4.0, 16.0)', '(5.0, 25.0)', '(6.0, 36.0)', '(7.0, 49.0)', '(8.0, 64.0)', '(9.0, 81.0)', '(10.0, 100.0)']"] > - >>> s.group_list = Data(1,'d1'); print s > - ["Group 1 ['d1: 1']"] > - >>> s.group_list = Group([(1,2),(2,3)],'g1'); print s > - ["g1 ['(1, 2)', '(2, 3)']"] > - ''' > - def fget(self): > - ''' > - Return the group list. > - ''' > - return self.__group_list > - > - def fset(self, series): > - ''' > - Controls the input of a valid group list. > - ''' > - #TODO: Add support to the following strem of data: [ (0.5,5.5) , [(0,4),(6,8)] , (5.5,7) , (7,9)] > - > - # Type: None > - if series is None: > - self.__group_list = [] > - > - # List or Tuple > - elif type(series) in LISTTYPES: > - self.__group_list = [] > - > - is_function = lambda x: callable(x) > - # Groups > - if list in map(type, series) or max(map(is_function, series)): > - for group in series: > - self.add_group(group) > - > - # single group > - else: > - self.add_group(series) > - > - #old code > - ## List of numbers > - #if type(series[0]) in NUMTYPES or type(series[0]) is tuple: > - # print series > - # self.add_group(series) > - # > - ## List of anything else > - #else: > - # for group in series: > - # self.add_group(group) > - > - # Dict representing series of groups > - elif type(series) is dict: > - self.__group_list = [] > - names = series.keys() > - names.sort() > - for name in names: > - self.add_group(Group(series[name],name,self)) > - > - # A single lambda > - elif callable(series): > - self.__group_list = [] > - self.add_group(series) > - > - # Int/float, instance of Group or Data > - elif type(series) in NUMTYPES or isinstance(series, Group) or isinstance(series, Data): > - self.__group_list = [] > - self.add_group(series) > - > - # Default > - else: > - raise TypeError, "Serie type not supported" > - > - return property(**locals()) > - > - def add_group(self, group, name=None): > - ''' > - Append a new group in group_list > - ''' > - if not isinstance(group, Group): > - #Try to convert > - group = Group(group, name, self) > - > - if len(group.data_list) is not 0: > - # Auto naming groups > - if group.name is None: > - group.name = "Group "+str(len(self.__group_list)+1) > - > - self.__group_list.append(group) > - self.__group_list[-1].parent = self > - > - def copy(self): > - ''' > - Returns a copy of the Series > - ''' > - new_series = Series() > - new_series.__name = self.__name > - if self.__range is not None: > - new_series.__range = self.__range[:] > - #Add color property in the copy method > - #self.__colors = None > - > - for group in self: > - new_series.add_group(group.copy()) > - > - return new_series > - > - def get_names(self): > - ''' > - Returns a list of the names of all groups in the Serie > - ''' > - names = [] > - for group in self: > - if group.name is None: > - names.append('Group '+str(group.index()+1)) > - else: > - names.append(group.name) > - > - return names > - > - def to_list(self): > - ''' > - Returns a list with the content of all groups and data > - ''' > - big_list = [] > - for group in self: > - for data in group: > - if type(data.content) in NUMTYPES: > - big_list.append(data.content) > - else: > - big_list = big_list + list(data.content) > - return big_list > - > - def __getitem__(self, key): > - ''' > - Makes the Series iterable, based in the group_list property > - ''' > - return self.__group_list[key] > - > - def __str__(self): > - ''' > - Returns a string that represents the Series > - ''' > - ret = "" > - if self.name is not None: > - ret += self.name + " " > - if len(self) > 0: > - list_str = [str(item) for item in self] > - ret += str(list_str) > - else: > - ret += "[]" > - return ret > - > - def __len__(self): > - ''' > - Returns the length of the Series, based in the group_lsit property > - ''' > - return len(self.group_list) > - > - > -if __name__ == '__main__': > - doctest.testmod() > diff --git a/bindings/python/examples/python2/eventcount.py b/bindings/python/examples/python2/eventcount.py > new file mode 100755 > index 0000000..079633c > --- /dev/null > +++ b/bindings/python/examples/python2/eventcount.py > @@ -0,0 +1,85 @@ > +#!/usr/bin/env python2 > +# eventcount.py > +# > +# Babeltrace event count example script > +# > +# Copyright 2012 EfficiOS Inc. > +# > +# Author: Danny Serres > +# > +# Permission is hereby granted, free of charge, to any person obtaining a copy > +# of this software and associated documentation files (the "Software"), to deal > +# in the Software without restriction, including without limitation the rights > +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > +# copies of the Software, and to permit persons to whom the Software is > +# furnished to do so, subject to the following conditions: > +# > +# The above copyright notice and this permission notice shall be included in > +# all copies or substantial portions of the Software. > + > +# The script prints a count of specified events and > +# their related tid's in a given trace. > +# The trace needs TID context (lttng add-context -k -t tid) > + > +import sys > +from babeltrace import * > +from output_format_modules.pprint_table import pprint_table as pprint > + > +if len(sys.argv) < 3: > + raise TypeError("Usage: python eventcount.py event1 [event2 ...] path/to/trace") > + > +ctx = Context() > +ret = ctx.add_trace(sys.argv[len(sys.argv)-1], "ctf") > +if ret is None: > + raise IOError("Error adding trace") > + > +counts = {} > + > +# Setting iterator > +bp = IterPos(SEEK_BEGIN) > +ctf_it = ctf.Iterator(ctx, bp) > + > +# Reading events > +event = ctf_it.read_event() > +while(event is not None): > + for event_type in sys.argv[1:len(sys.argv)-1]: > + if event_type == event.get_name(): > + > + # Getting scope definition > + sco = event.get_top_level_scope(ctf.scope.STREAM_EVENT_CONTEXT) > + if sco is None: > + print("ERROR: Cannot get definition scope for {}".format( > + event.get_name())) > + continue > + > + # Getting TID > + tid_field = event.get_field(sco, "_tid") > + tid = tid_field.get_int64() > + > + if ctf.field_error(): > + print("ERROR: Missing TID info for {}".format( > + event.get_name())) > + continue > + > + tmp = (tid, event.get_name()) > + > + if tmp in counts: > + counts[tmp] += 1 > + else: > + counts[tmp] = 1 > + > + # Next event > + ret = ctf_it.next() > + if ret < 0: > + break > + event = ctf_it.read_event() > + > +del ctf_it > + > +# Appending data to table for output > +table = [] > +for item in counts: > + table.append([item[0], item[1], counts[item]]) > +table = sorted(table) > +table.insert(0,["TID", "EVENT", "COUNT"]) > +pprint(table, 2) > diff --git a/bindings/python/examples/python2/eventcountlist.py b/bindings/python/examples/python2/eventcountlist.py > new file mode 100755 > index 0000000..1b42b4e > --- /dev/null > +++ b/bindings/python/examples/python2/eventcountlist.py > @@ -0,0 +1,84 @@ > +#!/usr/bin/env python2 > +# eventcountlist.py > +# > +# Babeltrace event count list example script > +# > +# Copyright 2012 EfficiOS Inc. > +# > +# Author: Danny Serres > +# > +# Permission is hereby granted, free of charge, to any person obtaining a copy > +# of this software and associated documentation files (the "Software"), to deal > +# in the Software without restriction, including without limitation the rights > +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > +# copies of the Software, and to permit persons to whom the Software is > +# furnished to do so, subject to the following conditions: > +# > +# The above copyright notice and this permission notice shall be included in > +# all copies or substantial portions of the Software. > + > +# The script prints a count and rate of events. > +# It also outputs a bar graph of count per event, using the cairoplot module. > + > +import sys > +from babeltrace import * > +from output_format_modules import cairoplot > +from output_format_modules.pprint_table import pprint_table as pprint > + > +# Check for path arg: > +if len(sys.argv) < 2: > + raise TypeError("Usage: python eventcountlist.py path/to/trace") > + > +ctx = Context() > +ret = ctx.add_trace(sys.argv[1], "ctf") > +if ret is None: > + raise IOError("Error adding trace") > + > +# Events and their assossiated count > +# will be stored as a dict: > +events_count = {} > + > +# Setting iterator: > +bp = IterPos(SEEK_BEGIN) > +ctf_it = ctf.Iterator(ctx,bp) > + > +prev_event = None > +event = ctf_it.read_event() > + > +start_time = event.get_timestamp() > + > +# Reading events: > +while(event is not None): > + if event.get_name() in events_count: > + events_count[event.get_name()] += 1 > + else: > + events_count[event.get_name()] = 1 > + > + ret = ctf_it.next() > + if ret < 0: > + break > + else: > + prev_event = event > + event = ctf_it.read_event() > + > +if event: > + total_time = event.get_timestamp() - start_time > +else: > + total_time = prev_event.get_timestamp() - start_time > + > +del ctf_it > + > +# Printing encountered events with respective count and rate: > +print("Total time: {} ns".format(total_time)) > +table = [["EVENT", "COUNT", "RATE (Hz)"]] > +for item in sorted(events_count.iterkeys()): > + tmp = [item, events_count[item], > + events_count[item]/(total_time/1000000000.0)] > + table.append(tmp) > +pprint(table) > + > +# Exporting data as bar graph > +cairoplot.vertical_bar_plot ( 'eventcountlist.svg', events_count, 50+85*len(events_count), > + 800, border = 20, display_values = True, grid = True, > + rounded_corners = True, > + x_labels = sorted(events_count.keys()) ) > diff --git a/bindings/python/examples/python2/events_per_cpu.py b/bindings/python/examples/python2/events_per_cpu.py > new file mode 100755 > index 0000000..6425b2d > --- /dev/null > +++ b/bindings/python/examples/python2/events_per_cpu.py > @@ -0,0 +1,100 @@ > +#!/usr/bin/env python2 > +# events_per_cpu.py > +# > +# Babeltrace events per cpu example script > +# > +# Copyright 2012 EfficiOS Inc. > +# > +# Author: Danny Serres > +# > +# Permission is hereby granted, free of charge, to any person obtaining a copy > +# of this software and associated documentation files (the "Software"), to deal > +# in the Software without restriction, including without limitation the rights > +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > +# copies of the Software, and to permit persons to whom the Software is > +# furnished to do so, subject to the following conditions: > +# > +# The above copyright notice and this permission notice shall be included in > +# all copies or substantial portions of the Software. > + > +# The script opens a trace and prints out CPU statistics > +# for the given trace (event count per CPU, total active > +# time and % of time processing events). > +# It also outputs a .txt file showing each time interval > +# (since the beginning of the trace) in which each CPU > +# was active and the corresponding event. > + > +import sys, multiprocessing > +from output_format_modules.pprint_table import pprint_table as pprint > +from babeltrace import * > + > +if len(sys.argv) < 2: > + raise TypeError("Usage: python events_per_cpu.py path/to/trace") > + > +# Adding trace > +ctx = Context() > +ret = ctx.add_trace(sys.argv[1], "ctf") > +if ret is None: > + raise IOError("Error adding trace") > + > +cpu_usage = [] > +nbEvents = 0 > +i = 0 > +while i < multiprocessing.cpu_count(): > + cpu_usage.append([]) > + i += 1 > + > +# Setting iterator > +bp = IterPos(SEEK_BEGIN) > +ctf_it = ctf.Iterator(ctx, bp) > + > +# Reading events > +event = ctf_it.read_event() > +start_time = event.get_timestamp() > + > +while(event is not None): > + > + event_name = event.get_name() > + ts = event.get_timestamp() > + > + # Getting cpu_id > + scope = event.get_top_level_scope(ctf.scope.STREAM_PACKET_CONTEXT) > + field = event.get_field(scope, "cpu_id") > + cpu_id = field.get_uint64() > + if ctf.field_error(): > + print("ERROR: Missing cpu_id info for {}".format(event.get_name())) > + else: > + cpu_usage[cpu_id].append( (int(ts), event_name) ) > + nbEvents += 1 > + > + # Next Event > + ret = ctf_it.next() > + if ret < 0: > + break > + event = ctf_it.read_event() > + > + > +# Outputting > +table = [] > +output = open("events_per_cpu.txt", "wt") > +output.write("(timestamp, event)\n") > + > +for cpu in range(len(cpu_usage)): > + # Setting table > + event_str = str(100.0 * len(cpu_usage[cpu]) / nbEvents) + '000' > + # % is printed with 2 decimals > + table.append([cpu, len(cpu_usage[cpu]), event_str[0:event_str.find('.') + 3] + ' %']) > + > + # Writing to file > + output.write("\n\n\n----------------------\n") > + output.write("CPU {}\n\n".format(cpu)) > + for event in cpu_usage[cpu]: > + output.write(str(event) + '\n') > + > +# Printing table > +table.insert(0, ["CPU ID", "EVENT COUNT", "TRACE EVENT %"]) > +pprint(table) > +print("Total event count: {}".format(nbEvents)) > +print("Total trace time: {} ns".format(ts - start_time)) > + > +output.close() > diff --git a/bindings/python/examples/python2/histogram.py b/bindings/python/examples/python2/histogram.py > new file mode 100755 > index 0000000..09618cb > --- /dev/null > +++ b/bindings/python/examples/python2/histogram.py > @@ -0,0 +1,140 @@ > +#!/usr/bin/env python2 > +# histogram.py > +# > +# Babeltrace histogram example script > +# > +# Copyright 2012 EfficiOS Inc. > +# > +# Author: Danny Serres > +# > +# Permission is hereby granted, free of charge, to any person obtaining a copy > +# of this software and associated documentation files (the "Software"), to deal > +# in the Software without restriction, including without limitation the rights > +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > +# copies of the Software, and to permit persons to whom the Software is > +# furnished to do so, subject to the following conditions: > +# > +# The above copyright notice and this permission notice shall be included in > +# all copies or substantial portions of the Software. > + > +# The script checks the number of events in the trace > +# and outputs a table and a .svg histogram for the specified > +# range (microseconds) or the total trace if no range specified. > +# The graph is generated using the cairoplot module. > + > +import sys > +from babeltrace import * > +from output_format_modules import cairoplot > +from output_format_modules.pprint_table import pprint_table as pprint > + > +# ------------------------------------------------ > +# Output settings > + > +# number of intervals: > +nbDiv = 25 # Should not be over 150 > + # for usable graph output > + > +# table output stream (file-like object): > +out = sys.stdout > +# ------------------------------------------------- > + > +if len(sys.argv) < 2 or len(sys.argv) > 4: > + raise TypeError("Usage: python histogram.py [ start_time [end_time] ] path/to/trace") > + > +ctx = Context() > +ret = ctx.add_trace(sys.argv[len(sys.argv)-1], "ctf") > +if ret is None: > + raise IOError("Error adding trace") > + > +# Check when to start/stop graphing > +sinceBegin = True > +beginTime = 0.0 > +if len(sys.argv) > 2: > + sinceBegin = False > + beginTime = float(sys.argv[1]) > +untilEnd = True > +if len(sys.argv) == 4: > + untilEnd = False > + > +# Setting iterator > +bp = IterPos(SEEK_BEGIN) > +ctf_it = ctf.Iterator(ctx, bp) > + > +# Reading events > +event = ctf_it.read_event() > +start_time = event.get_timestamp() > +time = 0 > +count = {} > + > +while(event is not None): > + # Microsec. > + time = (event.get_timestamp() - start_time)/1000.0 > + > + # Check if in range > + if not sinceBegin: > + if time < beginTime: > + # Next Event > + ret = ctf_it.next() > + if ret < 0: > + break > + event = ctf_it.read_event() > + continue > + if not untilEnd: > + if time > float(sys.argv[2]): > + break > + > + # Counting events per timestamp: > + if time in count: > + count[time] += 1 > + else: > + count[time] = 1 > + > + # Next Event > + ret = ctf_it.next() > + if ret < 0: > + break > + event = ctf_it.read_event() > + > +del ctf_it > + > +# Setting data for output > +interval = (time - beginTime)/nbDiv > +div_begin_time = beginTime > +div_end_time = beginTime + interval > +data = {} > + > +# Prefix for string sorting, considering > +# there should not be over 150 intervals. > +# This would work up to 9999 intervals. > +# If needed, add zeros. > +prefix = 0.0001 > + > +while div_end_time <= time: > + key = str(prefix) + '[' + str(div_begin_time) + ';' + str(div_end_time) + '[' > + for tmp in count: > + if tmp >= div_begin_time and tmp < div_end_time: > + if key in data: > + data[key] += count[tmp] > + else: > + data[key] = count[tmp] > + if not key in data: > + data[key] = 0 > + div_begin_time = div_end_time > + div_end_time += interval > + # Prefix increment > + prefix += 0.001 > + > +table = [] > +x_labels = [] > +for key in sorted(data): > + table.append([key[key.find('['):], data[key]]) > + x_labels.append(key[key.find('['):]) > + > +# Table output > +table.insert(0, ["INTERVAL (us)", "COUNT"]) > +pprint(table, 1, out) > + > +# Graph output > +cairoplot.vertical_bar_plot ( 'histogram.svg', data, 50 + 150*nbDiv, 50*nbDiv, > + border = 20, display_values = True, grid = True, > + x_labels = x_labels, rounded_corners = True ) > diff --git a/bindings/python/examples/python2/output_format_modules/cairoplot.py b/bindings/python/examples/python2/output_format_modules/cairoplot.py > new file mode 100644 > index 0000000..a27113f > --- /dev/null > +++ b/bindings/python/examples/python2/output_format_modules/cairoplot.py > @@ -0,0 +1,2336 @@ > +?#!/usr/bin/env python > +# -*- coding: utf-8 -*- > + > +# CairoPlot.py > +# > +# Copyright (c) 2008 Rodrigo Moreira Ara?jo > +# > +# Author: Rodrigo Moreiro Araujo > +# > +# This program is free software; you can redistribute it and/or > +# modify it under the terms of the GNU Lesser 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 Lesser 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 > + > +#Contributor: Jo?o S. O. Bueno > + > +#TODO: review BarPlot Code > +#TODO: x_label colision problem on Horizontal Bar Plot > +#TODO: y_label's eat too much space on HBP > + > + > +__version__ = 1.2 > + > +import cairo > +import math > +import random > +from series import Series, Group, Data > + > +HORZ = 0 > +VERT = 1 > +NORM = 2 > + > +COLORS = {"red" : (1.0,0.0,0.0,1.0), "lime" : (0.0,1.0,0.0,1.0), "blue" : (0.0,0.0,1.0,1.0), > + "maroon" : (0.5,0.0,0.0,1.0), "green" : (0.0,0.5,0.0,1.0), "navy" : (0.0,0.0,0.5,1.0), > + "yellow" : (1.0,1.0,0.0,1.0), "magenta" : (1.0,0.0,1.0,1.0), "cyan" : (0.0,1.0,1.0,1.0), > + "orange" : (1.0,0.5,0.0,1.0), "white" : (1.0,1.0,1.0,1.0), "black" : (0.0,0.0,0.0,1.0), > + "gray" : (0.5,0.5,0.5,1.0), "light_gray" : (0.9,0.9,0.9,1.0), > + "transparent" : (0.0,0.0,0.0,0.0)} > + > +THEMES = {"black_red" : [(0.0,0.0,0.0,1.0), (1.0,0.0,0.0,1.0)], > + "red_green_blue" : [(1.0,0.0,0.0,1.0), (0.0,1.0,0.0,1.0), (0.0,0.0,1.0,1.0)], > + "red_orange_yellow" : [(1.0,0.2,0.0,1.0), (1.0,0.7,0.0,1.0), (1.0,1.0,0.0,1.0)], > + "yellow_orange_red" : [(1.0,1.0,0.0,1.0), (1.0,0.7,0.0,1.0), (1.0,0.2,0.0,1.0)], > + "rainbow" : [(1.0,0.0,0.0,1.0), (1.0,0.5,0.0,1.0), (1.0,1.0,0.0,1.0), (0.0,1.0,0.0,1.0), (0.0,0.0,1.0,1.0), (0.3, 0.0, 0.5,1.0), (0.5, 0.0, 1.0, 1.0)]} > + > +def colors_from_theme( theme, series_length, mode = 'solid' ): > + colors = [] > + if theme not in THEMES.keys() : > + raise Exception, "Theme not defined" > + color_steps = THEMES[theme] > + n_colors = len(color_steps) > + if series_length <= n_colors: > + colors = [color + tuple([mode]) for color in color_steps[0:n_colors]] > + else: > + iterations = [(series_length - n_colors)/(n_colors - 1) for i in color_steps[:-1]] > + over_iterations = (series_length - n_colors) % (n_colors - 1) > + for i in range(n_colors - 1): > + if over_iterations <= 0: > + break > + iterations[i] += 1 > + over_iterations -= 1 > + for index,color in enumerate(color_steps[:-1]): > + colors.append(color + tuple([mode])) > + if iterations[index] == 0: > + continue > + next_color = color_steps[index+1] > + color_step = ((next_color[0] - color[0])/(iterations[index] + 1), > + (next_color[1] - color[1])/(iterations[index] + 1), > + (next_color[2] - color[2])/(iterations[index] + 1), > + (next_color[3] - color[3])/(iterations[index] + 1)) > + for i in range( iterations[index] ): > + colors.append((color[0] + color_step[0]*(i+1), > + color[1] + color_step[1]*(i+1), > + color[2] + color_step[2]*(i+1), > + color[3] + color_step[3]*(i+1), > + mode)) > + colors.append(color_steps[-1] + tuple([mode])) > + return colors > + > + > +def other_direction(direction): > + "explicit is better than implicit" > + if direction == HORZ: > + return VERT > + else: > + return HORZ > + > +#Class definition > + > +class Plot(object): > + def __init__(self, > + surface=None, > + data=None, > + width=640, > + height=480, > + background=None, > + border = 0, > + x_labels = None, > + y_labels = None, > + series_colors = None): > + random.seed(2) > + self.create_surface(surface, width, height) > + self.dimensions = {} > + self.dimensions[HORZ] = width > + self.dimensions[VERT] = height > + self.context = cairo.Context(self.surface) > + self.labels={} > + self.labels[HORZ] = x_labels > + self.labels[VERT] = y_labels > + self.load_series(data, x_labels, y_labels, series_colors) > + self.font_size = 10 > + self.set_background (background) > + self.border = border > + self.borders = {} > + self.line_color = (0.5, 0.5, 0.5) > + self.line_width = 0.5 > + self.label_color = (0.0, 0.0, 0.0) > + self.grid_color = (0.8, 0.8, 0.8) > + > + def create_surface(self, surface, width=None, height=None): > + self.filename = None > + if isinstance(surface, cairo.Surface): > + self.surface = surface > + return > + if not type(surface) in (str, unicode): > + raise TypeError("Surface should be either a Cairo surface or a filename, not %s" % surface) > + sufix = surface.rsplit(".")[-1].lower() > + self.filename = surface > + if sufix == "png": > + self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) > + elif sufix == "ps": > + self.surface = cairo.PSSurface(surface, width, height) > + elif sufix == "pdf": > + self.surface = cairo.PSSurface(surface, width, height) > + else: > + if sufix != "svg": > + self.filename += ".svg" > + self.surface = cairo.SVGSurface(self.filename, width, height) > + > + def commit(self): > + try: > + self.context.show_page() > + if self.filename and self.filename.endswith(".png"): > + self.surface.write_to_png(self.filename) > + else: > + self.surface.finish() > + except cairo.Error: > + pass > + > + def load_series (self, data, x_labels=None, y_labels=None, series_colors=None): > + self.series_labels = [] > + self.series = None > + > + #The pretty way > + #if not isinstance(data, Series): > + # # Not an instance of Series > + # self.series = Series(data) > + #else: > + # self.series = data > + # > + #self.series_labels = self.series.get_names() > + > + #TODO: Remove on next version > + # The ugly way, keeping retrocompatibility... > + if callable(data) or type(data) is list and callable(data[0]): # Lambda or List of lambdas > + self.series = data > + self.series_labels = None > + elif isinstance(data, Series): # Instance of Series > + self.series = data > + self.series_labels = data.get_names() > + else: # Anything else > + self.series = Series(data) > + self.series_labels = self.series.get_names() > + > + #TODO: allow user passed series_widths > + self.series_widths = [1.0 for group in self.series] > + > + #TODO: Remove on next version > + self.process_colors( series_colors ) > + > + def process_colors( self, series_colors, length = None, mode = 'solid' ): > + #series_colors might be None, a theme, a string of colors names or a list of color tuples > + if length is None : > + length = len( self.series.to_list() ) > + > + #no colors passed > + if not series_colors: > + #Randomize colors > + self.series_colors = [ [random.random() for i in range(3)] + [1.0, mode] for series in range( length ) ] > + else: > + #Just theme pattern > + if not hasattr( series_colors, "__iter__" ): > + theme = series_colors > + self.series_colors = colors_from_theme( theme.lower(), length ) > + > + #Theme pattern and mode > + elif not hasattr(series_colors, '__delitem__') and not hasattr( series_colors[0], "__iter__" ): > + theme = series_colors[0] > + mode = series_colors[1] > + self.series_colors = colors_from_theme( theme.lower(), length, mode ) > + > + #List > + else: > + self.series_colors = series_colors > + for index, color in enumerate( self.series_colors ): > + #element is a color name > + if not hasattr(color, "__iter__"): > + self.series_colors[index] = COLORS[color.lower()] + tuple([mode]) > + #element is rgb tuple instead of rgba > + elif len( color ) == 3 : > + self.series_colors[index] += (1.0,mode) > + #element has 4 elements, might be rgba tuple or rgb tuple with mode > + elif len( color ) == 4 : > + #last element is mode > + if not hasattr(color[3], "__iter__"): > + self.series_colors[index] += tuple([color[3]]) > + self.series_colors[index][3] = 1.0 > + #last element is alpha > + else: > + self.series_colors[index] += tuple([mode]) > + > + def get_width(self): > + return self.surface.get_width() > + > + def get_height(self): > + return self.surface.get_height() > + > + def set_background(self, background): > + if background is None: > + self.background = (0.0,0.0,0.0,0.0) > + elif type(background) in (cairo.LinearGradient, tuple): > + self.background = background > + elif not hasattr(background,"__iter__"): > + colors = background.split(" ") > + if len(colors) == 1 and colors[0] in COLORS: > + self.background = COLORS[background] > + elif len(colors) > 1: > + self.background = cairo.LinearGradient(self.dimensions[HORZ] / 2, 0, self.dimensions[HORZ] / 2, self.dimensions[VERT]) > + for index,color in enumerate(colors): > + self.background.add_color_stop_rgba(float(index)/(len(colors)-1),*COLORS[color]) > + else: > + raise TypeError ("Background should be either cairo.LinearGradient or a 3/4-tuple, not %s" % type(background)) > + > + def render_background(self): > + if isinstance(self.background, cairo.LinearGradient): > + self.context.set_source(self.background) > + else: > + self.context.set_source_rgba(*self.background) > + self.context.rectangle(0,0, self.dimensions[HORZ], self.dimensions[VERT]) > + self.context.fill() > + > + def render_bounding_box(self): > + self.context.set_source_rgba(*self.line_color) > + self.context.set_line_width(self.line_width) > + self.context.rectangle(self.border, self.border, > + self.dimensions[HORZ] - 2 * self.border, > + self.dimensions[VERT] - 2 * self.border) > + self.context.stroke() > + > + def render(self): > + pass > + > +class ScatterPlot( Plot ): > + def __init__(self, > + surface=None, > + data=None, > + errorx=None, > + errory=None, > + width=640, > + height=480, > + background=None, > + border=0, > + axis = False, > + dash = False, > + discrete = False, > + dots = 0, > + grid = False, > + series_legend = False, > + x_labels = None, > + y_labels = None, > + x_bounds = None, > + y_bounds = None, > + z_bounds = None, > + x_title = None, > + y_title = None, > + series_colors = None, > + circle_colors = None ): > + > + self.bounds = {} > + self.bounds[HORZ] = x_bounds > + self.bounds[VERT] = y_bounds > + self.bounds[NORM] = z_bounds > + self.titles = {} > + self.titles[HORZ] = x_title > + self.titles[VERT] = y_title > + self.max_value = {} > + self.axis = axis > + self.discrete = discrete > + self.dots = dots > + self.grid = grid > + self.series_legend = series_legend > + self.variable_radius = False > + self.x_label_angle = math.pi / 2.5 > + self.circle_colors = circle_colors > + > + Plot.__init__(self, surface, data, width, height, background, border, x_labels, y_labels, series_colors) > + > + self.dash = None > + if dash: > + if hasattr(dash, "keys"): > + self.dash = [dash[key] for key in self.series_labels] > + elif max([hasattr(item,'__delitem__') for item in data]) : > + self.dash = dash > + else: > + self.dash = [dash] > + > + self.load_errors(errorx, errory) > + > + def convert_list_to_tuple(self, data): > + #Data must be converted from lists of coordinates to a single > + # list of tuples > + out_data = zip(*data) > + if len(data) == 3: > + self.variable_radius = True > + return out_data > + > + def load_series(self, data, x_labels = None, y_labels = None, series_colors=None): > + #TODO: In cairoplot 2.0 keep only the Series instances > + > + # Convert Data and Group to Series > + if isinstance(data, Data) or isinstance(data, Group): > + data = Series(data) > + > + # Series > + if isinstance(data, Series): > + for group in data: > + for item in group: > + if len(item) is 3: > + self.variable_radius = True > + > + #Dictionary with lists > + if hasattr(data, "keys") : > + if hasattr( data.values()[0][0], "__delitem__" ) : > + for key in data.keys() : > + data[key] = self.convert_list_to_tuple(data[key]) > + elif len(data.values()[0][0]) == 3: > + self.variable_radius = True > + #List > + elif hasattr(data[0], "__delitem__") : > + #List of lists > + if hasattr(data[0][0], "__delitem__") : > + for index,value in enumerate(data) : > + data[index] = self.convert_list_to_tuple(value) > + #List > + elif type(data[0][0]) != type((0,0)): > + data = self.convert_list_to_tuple(data) > + #Three dimensional data > + elif len(data[0][0]) == 3: > + self.variable_radius = True > + > + #List with three dimensional tuples > + elif len(data[0]) == 3: > + self.variable_radius = True > + Plot.load_series(self, data, x_labels, y_labels, series_colors) > + self.calc_boundaries() > + self.calc_labels() > + > + def load_errors(self, errorx, errory): > + self.errors = None > + if errorx == None and errory == None: > + return > + self.errors = {} > + self.errors[HORZ] = None > + self.errors[VERT] = None > + #asimetric errors > + if errorx and hasattr(errorx[0], "__delitem__"): > + self.errors[HORZ] = errorx > + #simetric errors > + elif errorx: > + self.errors[HORZ] = [errorx] > + #asimetric errors > + if errory and hasattr(errory[0], "__delitem__"): > + self.errors[VERT] = errory > + #simetric errors > + elif errory: > + self.errors[VERT] = [errory] > + > + def calc_labels(self): > + if not self.labels[HORZ]: > + amplitude = self.bounds[HORZ][1] - self.bounds[HORZ][0] > + if amplitude % 10: #if horizontal labels need floating points > + self.labels[HORZ] = ["%.2lf" % (float(self.bounds[HORZ][0] + (amplitude * i / 10.0))) for i in range(11) ] > + else: > + self.labels[HORZ] = ["%d" % (int(self.bounds[HORZ][0] + (amplitude * i / 10.0))) for i in range(11) ] > + if not self.labels[VERT]: > + amplitude = self.bounds[VERT][1] - self.bounds[VERT][0] > + if amplitude % 10: #if vertical labels need floating points > + self.labels[VERT] = ["%.2lf" % (float(self.bounds[VERT][0] + (amplitude * i / 10.0))) for i in range(11) ] > + else: > + self.labels[VERT] = ["%d" % (int(self.bounds[VERT][0] + (amplitude * i / 10.0))) for i in range(11) ] > + > + def calc_extents(self, direction): > + self.context.set_font_size(self.font_size * 0.8) > + self.max_value[direction] = max(self.context.text_extents(item)[2] for item in self.labels[direction]) > + self.borders[other_direction(direction)] = self.max_value[direction] + self.border + 20 > + > + def calc_boundaries(self): > + #HORZ = 0, VERT = 1, NORM = 2 > + min_data_value = [0,0,0] > + max_data_value = [0,0,0] > + > + for group in self.series: > + if type(group[0].content) in (int, float, long): > + group = [Data((index, item.content)) for index,item in enumerate(group)] > + > + for point in group: > + for index, item in enumerate(point.content): > + if item > max_data_value[index]: > + max_data_value[index] = item > + elif item < min_data_value[index]: > + min_data_value[index] = item > + > + if not self.bounds[HORZ]: > + self.bounds[HORZ] = (min_data_value[HORZ], max_data_value[HORZ]) > + if not self.bounds[VERT]: > + self.bounds[VERT] = (min_data_value[VERT], max_data_value[VERT]) > + if not self.bounds[NORM]: > + self.bounds[NORM] = (min_data_value[NORM], max_data_value[NORM]) > + > + def calc_all_extents(self): > + self.calc_extents(HORZ) > + self.calc_extents(VERT) > + > + self.plot_height = self.dimensions[VERT] - 2 * self.borders[VERT] > + self.plot_width = self.dimensions[HORZ] - 2* self.borders[HORZ] > + > + self.plot_top = self.dimensions[VERT] - self.borders[VERT] > + > + def calc_steps(self): > + #Calculates all the x, y, z and color steps > + series_amplitude = [self.bounds[index][1] - self.bounds[index][0] for index in range(3)] > + > + if series_amplitude[HORZ]: > + self.horizontal_step = float (self.plot_width) / series_amplitude[HORZ] > + else: > + self.horizontal_step = 0.00 > + > + if series_amplitude[VERT]: > + self.vertical_step = float (self.plot_height) / series_amplitude[VERT] > + else: > + self.vertical_step = 0.00 > + > + if series_amplitude[NORM]: > + if self.variable_radius: > + self.z_step = float (self.bounds[NORM][1]) / series_amplitude[NORM] > + if self.circle_colors: > + self.circle_color_step = tuple([float(self.circle_colors[1][i]-self.circle_colors[0][i])/series_amplitude[NORM] for i in range(4)]) > + else: > + self.z_step = 0.00 > + self.circle_color_step = ( 0.0, 0.0, 0.0, 0.0 ) > + > + def get_circle_color(self, value): > + return tuple( [self.circle_colors[0][i] + value*self.circle_color_step[i] for i in range(4)] ) > + > + def render(self): > + self.calc_all_extents() > + self.calc_steps() > + self.render_background() > + self.render_bounding_box() > + if self.axis: > + self.render_axis() > + if self.grid: > + self.render_grid() > + self.render_labels() > + self.render_plot() > + if self.errors: > + self.render_errors() > + if self.series_legend and self.series_labels: > + self.render_legend() > + > + def render_axis(self): > + #Draws both the axis lines and their titles > + cr = self.context > + cr.set_source_rgba(*self.line_color) > + cr.move_to(self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT]) > + cr.line_to(self.borders[HORZ], self.borders[VERT]) > + cr.stroke() > + > + cr.move_to(self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT]) > + cr.line_to(self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT]) > + cr.stroke() > + > + cr.set_source_rgba(*self.label_color) > + self.context.set_font_size( 1.2 * self.font_size ) > + if self.titles[HORZ]: > + title_width,title_height = cr.text_extents(self.titles[HORZ])[2:4] > + cr.move_to( self.dimensions[HORZ]/2 - title_width/2, self.borders[VERT] - title_height/2 ) > + cr.show_text( self.titles[HORZ] ) > + > + if self.titles[VERT]: > + title_width,title_height = cr.text_extents(self.titles[VERT])[2:4] > + cr.move_to( self.dimensions[HORZ] - self.borders[HORZ] + title_height/2, self.dimensions[VERT]/2 - title_width/2) > + cr.save() > + cr.rotate( math.pi/2 ) > + cr.show_text( self.titles[VERT] ) > + cr.restore() > + > + def render_grid(self): > + cr = self.context > + horizontal_step = float( self.plot_height ) / ( len( self.labels[VERT] ) - 1 ) > + vertical_step = float( self.plot_width ) / ( len( self.labels[HORZ] ) - 1 ) > + > + x = self.borders[HORZ] + vertical_step > + y = self.plot_top - horizontal_step > + > + for label in self.labels[HORZ][:-1]: > + cr.set_source_rgba(*self.grid_color) > + cr.move_to(x, self.dimensions[VERT] - self.borders[VERT]) > + cr.line_to(x, self.borders[VERT]) > + cr.stroke() > + x += vertical_step > + for label in self.labels[VERT][:-1]: > + cr.set_source_rgba(*self.grid_color) > + cr.move_to(self.borders[HORZ], y) > + cr.line_to(self.dimensions[HORZ] - self.borders[HORZ], y) > + cr.stroke() > + y -= horizontal_step > + > + def render_labels(self): > + self.context.set_font_size(self.font_size * 0.8) > + self.render_horz_labels() > + self.render_vert_labels() > + > + def render_horz_labels(self): > + cr = self.context > + step = float( self.plot_width ) / ( len( self.labels[HORZ] ) - 1 ) > + x = self.borders[HORZ] > + y = self.dimensions[VERT] - self.borders[VERT] + 5 > + > + # store rotation matrix from the initial state > + rotation_matrix = cr.get_matrix() > + rotation_matrix.rotate(self.x_label_angle) > + > + cr.set_source_rgba(*self.label_color) > + > + for item in self.labels[HORZ]: > + width = cr.text_extents(item)[2] > + cr.move_to(x, y) > + cr.save() > + cr.set_matrix(rotation_matrix) > + cr.show_text(item) > + cr.restore() > + x += step > + > + def render_vert_labels(self): > + cr = self.context > + step = ( self.plot_height ) / ( len( self.labels[VERT] ) - 1 ) > + y = self.plot_top > + cr.set_source_rgba(*self.label_color) > + for item in self.labels[VERT]: > + width = cr.text_extents(item)[2] > + cr.move_to(self.borders[HORZ] - width - 5,y) > + cr.show_text(item) > + y -= step > + > + def render_legend(self): > + cr = self.context > + cr.set_font_size(self.font_size) > + cr.set_line_width(self.line_width) > + > + widest_word = max(self.series_labels, key = lambda item: self.context.text_extents(item)[2]) > + tallest_word = max(self.series_labels, key = lambda item: self.context.text_extents(item)[3]) > + max_width = self.context.text_extents(widest_word)[2] > + max_height = self.context.text_extents(tallest_word)[3] * 1.1 > + > + color_box_height = max_height / 2 > + color_box_width = color_box_height * 2 > + > + #Draw a bounding box > + bounding_box_width = max_width + color_box_width + 15 > + bounding_box_height = (len(self.series_labels)+0.5) * max_height > + cr.set_source_rgba(1,1,1) > + cr.rectangle(self.dimensions[HORZ] - self.borders[HORZ] - bounding_box_width, self.borders[VERT], > + bounding_box_width, bounding_box_height) > + cr.fill() > + > + cr.set_source_rgba(*self.line_color) > + cr.set_line_width(self.line_width) > + cr.rectangle(self.dimensions[HORZ] - self.borders[HORZ] - bounding_box_width, self.borders[VERT], > + bounding_box_width, bounding_box_height) > + cr.stroke() > + > + for idx,key in enumerate(self.series_labels): > + #Draw color box > + cr.set_source_rgba(*self.series_colors[idx][:4]) > + cr.rectangle(self.dimensions[HORZ] - self.borders[HORZ] - max_width - color_box_width - 10, > + self.borders[VERT] + color_box_height + (idx*max_height) , > + color_box_width, color_box_height) > + cr.fill() > + > + cr.set_source_rgba(0, 0, 0) > + cr.rectangle(self.dimensions[HORZ] - self.borders[HORZ] - max_width - color_box_width - 10, > + self.borders[VERT] + color_box_height + (idx*max_height), > + color_box_width, color_box_height) > + cr.stroke() > + > + #Draw series labels > + cr.set_source_rgba(0, 0, 0) > + cr.move_to(self.dimensions[HORZ] - self.borders[HORZ] - max_width - 5, self.borders[VERT] + ((idx+1)*max_height)) > + cr.show_text(key) > + > + def render_errors(self): > + cr = self.context > + cr.rectangle(self.borders[HORZ], self.borders[VERT], self.plot_width, self.plot_height) > + cr.clip() > + radius = self.dots > + x0 = self.borders[HORZ] - self.bounds[HORZ][0]*self.horizontal_step > + y0 = self.borders[VERT] - self.bounds[VERT][0]*self.vertical_step > + for index, group in enumerate(self.series): > + cr.set_source_rgba(*self.series_colors[index][:4]) > + for number, data in enumerate(group): > + x = x0 + self.horizontal_step * data.content[0] > + y = self.dimensions[VERT] - y0 - self.vertical_step * data.content[1] > + if self.errors[HORZ]: > + cr.move_to(x, y) > + x1 = x - self.horizontal_step * self.errors[HORZ][0][number] > + cr.line_to(x1, y) > + cr.line_to(x1, y - radius) > + cr.line_to(x1, y + radius) > + cr.stroke() > + if self.errors[HORZ] and len(self.errors[HORZ]) == 2: > + cr.move_to(x, y) > + x1 = x + self.horizontal_step * self.errors[HORZ][1][number] > + cr.line_to(x1, y) > + cr.line_to(x1, y - radius) > + cr.line_to(x1, y + radius) > + cr.stroke() > + if self.errors[VERT]: > + cr.move_to(x, y) > + y1 = y + self.vertical_step * self.errors[VERT][0][number] > + cr.line_to(x, y1) > + cr.line_to(x - radius, y1) > + cr.line_to(x + radius, y1) > + cr.stroke() > + if self.errors[VERT] and len(self.errors[VERT]) == 2: > + cr.move_to(x, y) > + y1 = y - self.vertical_step * self.errors[VERT][1][number] > + cr.line_to(x, y1) > + cr.line_to(x - radius, y1) > + cr.line_to(x + radius, y1) > + cr.stroke() > + > + > + def render_plot(self): > + cr = self.context > + if self.discrete: > + cr.rectangle(self.borders[HORZ], self.borders[VERT], self.plot_width, self.plot_height) > + cr.clip() > + x0 = self.borders[HORZ] - self.bounds[HORZ][0]*self.horizontal_step > + y0 = self.borders[VERT] - self.bounds[VERT][0]*self.vertical_step > + radius = self.dots > + for number, group in enumerate (self.series): > + cr.set_source_rgba(*self.series_colors[number][:4]) > + for data in group : > + if self.variable_radius: > + radius = data.content[2]*self.z_step > + if self.circle_colors: > + cr.set_source_rgba( *self.get_circle_color( data.content[2]) ) > + x = x0 + self.horizontal_step*data.content[0] > + y = y0 + self.vertical_step*data.content[1] > + cr.arc(x, self.dimensions[VERT] - y, radius, 0, 2*math.pi) > + cr.fill() > + else: > + cr.rectangle(self.borders[HORZ], self.borders[VERT], self.plot_width, self.plot_height) > + cr.clip() > + x0 = self.borders[HORZ] - self.bounds[HORZ][0]*self.horizontal_step > + y0 = self.borders[VERT] - self.bounds[VERT][0]*self.vertical_step > + radius = self.dots > + for number, group in enumerate (self.series): > + last_data = None > + cr.set_source_rgba(*self.series_colors[number][:4]) > + for data in group : > + x = x0 + self.horizontal_step*data.content[0] > + y = y0 + self.vertical_step*data.content[1] > + if self.dots: > + if self.variable_radius: > + radius = data.content[2]*self.z_step > + cr.arc(x, self.dimensions[VERT] - y, radius, 0, 2*math.pi) > + cr.fill() > + if last_data : > + old_x = x0 + self.horizontal_step*last_data.content[0] > + old_y = y0 + self.vertical_step*last_data.content[1] > + cr.move_to( old_x, self.dimensions[VERT] - old_y ) > + cr.line_to( x, self.dimensions[VERT] - y) > + cr.set_line_width(self.series_widths[number]) > + > + #?Display line as dash line > + if self.dash and self.dash[number]: > + s = self.series_widths[number] > + cr.set_dash([s*3, s*3], 0) > + > + cr.stroke() > + cr.set_dash([]) > + last_data = data > + > +class DotLinePlot(ScatterPlot): > + def __init__(self, > + surface=None, > + data=None, > + width=640, > + height=480, > + background=None, > + border=0, > + axis = False, > + dash = False, > + dots = 0, > + grid = False, > + series_legend = False, > + x_labels = None, > + y_labels = None, > + x_bounds = None, > + y_bounds = None, > + x_title = None, > + y_title = None, > + series_colors = None): > + > + ScatterPlot.__init__(self, surface, data, None, None, width, height, background, border, > + axis, dash, False, dots, grid, series_legend, x_labels, y_labels, > + x_bounds, y_bounds, None, x_title, y_title, series_colors, None ) > + > + > + def load_series(self, data, x_labels = None, y_labels = None, series_colors=None): > + Plot.load_series(self, data, x_labels, y_labels, series_colors) > + for group in self.series : > + for index,data in enumerate(group): > + group[index].content = (index, data.content) > + > + self.calc_boundaries() > + self.calc_labels() > + > +class FunctionPlot(ScatterPlot): > + def __init__(self, > + surface=None, > + data=None, > + width=640, > + height=480, > + background=None, > + border=0, > + axis = False, > + discrete = False, > + dots = 0, > + grid = False, > + series_legend = False, > + x_labels = None, > + y_labels = None, > + x_bounds = None, > + y_bounds = None, > + x_title = None, > + y_title = None, > + series_colors = None, > + step = 1): > + > + self.function = data > + self.step = step > + self.discrete = discrete > + > + data, x_bounds = self.load_series_from_function( self.function, x_bounds ) > + > + ScatterPlot.__init__(self, surface, data, None, None, width, height, background, border, > + axis, False, discrete, dots, grid, series_legend, x_labels, y_labels, > + x_bounds, y_bounds, None, x_title, y_title, series_colors, None ) > + > + def load_series(self, data, x_labels = None, y_labels = None, series_colors=None): > + Plot.load_series(self, data, x_labels, y_labels, series_colors) > + > + if len(self.series[0][0]) is 1: > + for group_id, group in enumerate(self.series) : > + for index,data in enumerate(group): > + group[index].content = (self.bounds[HORZ][0] + self.step*index, data.content) > + > + self.calc_boundaries() > + self.calc_labels() > + > + def load_series_from_function( self, function, x_bounds ): > + #TODO: Add the possibility for the user to define multiple functions with different discretization parameters > + > + #This function converts a function, a list of functions or a dictionary > + #of functions into its corresponding array of data > + series = Series() > + > + if isinstance(function, Group) or isinstance(function, Data): > + function = Series(function) > + > + # If is instance of Series > + if isinstance(function, Series): > + # Overwrite any bounds passed by the function > + x_bounds = (function.range[0],function.range[-1]) > + > + #if no bounds are provided > + if x_bounds == None: > + x_bounds = (0,10) > + > + > + #TODO: Finish the dict translation > + if hasattr(function, "keys"): #dictionary: > + for key in function.keys(): > + group = Group(name=key) > + #data[ key ] = [] > + i = x_bounds[0] > + while i <= x_bounds[1] : > + group.add_data(function[ key ](i)) > + #data[ key ].append( function[ key ](i) ) > + i += self.step > + series.add_group(group) > + > + elif hasattr(function, "__delitem__"): #list of functions > + for index,f in enumerate( function ) : > + group = Group() > + #data.append( [] ) > + i = x_bounds[0] > + while i <= x_bounds[1] : > + group.add_data(f(i)) > + #data[ index ].append( f(i) ) > + i += self.step > + series.add_group(group) > + > + elif isinstance(function, Series): # instance of Series > + series = function > + > + else: #function > + group = Group() > + i = x_bounds[0] > + while i <= x_bounds[1] : > + group.add_data(function(i)) > + i += self.step > + series.add_group(group) > + > + > + return series, x_bounds > + > + def calc_labels(self): > + if not self.labels[HORZ]: > + self.labels[HORZ] = [] > + i = self.bounds[HORZ][0] > + while i<=self.bounds[HORZ][1]: > + self.labels[HORZ].append(str(i)) > + i += float(self.bounds[HORZ][1] - self.bounds[HORZ][0])/10 > + ScatterPlot.calc_labels(self) > + > + def render_plot(self): > + if not self.discrete: > + ScatterPlot.render_plot(self) > + else: > + last = None > + cr = self.context > + for number, group in enumerate (self.series): > + cr.set_source_rgba(*self.series_colors[number][:4]) > + x0 = self.borders[HORZ] - self.bounds[HORZ][0]*self.horizontal_step > + y0 = self.borders[VERT] - self.bounds[VERT][0]*self.vertical_step > + for data in group: > + x = x0 + self.horizontal_step * data.content[0] > + y = y0 + self.vertical_step * data.content[1] > + cr.move_to(x, self.dimensions[VERT] - y) > + cr.line_to(x, self.plot_top) > + cr.set_line_width(self.series_widths[number]) > + cr.stroke() > + if self.dots: > + cr.new_path() > + cr.arc(x, self.dimensions[VERT] - y, 3, 0, 2.1 * math.pi) > + cr.close_path() > + cr.fill() > + > +class BarPlot(Plot): > + def __init__(self, > + surface = None, > + data = None, > + width = 640, > + height = 480, > + background = "white light_gray", > + border = 0, > + display_values = False, > + grid = False, > + rounded_corners = False, > + stack = False, > + three_dimension = False, > + x_labels = None, > + y_labels = None, > + x_bounds = None, > + y_bounds = None, > + series_colors = None, > + main_dir = None): > + > + self.bounds = {} > + self.bounds[HORZ] = x_bounds > + self.bounds[VERT] = y_bounds > + self.display_values = display_values > + self.grid = grid > + self.rounded_corners = rounded_corners > + self.stack = stack > + self.three_dimension = three_dimension > + self.x_label_angle = math.pi / 2.5 > + self.main_dir = main_dir > + self.max_value = {} > + self.plot_dimensions = {} > + self.steps = {} > + self.value_label_color = (0.5,0.5,0.5,1.0) > + > + Plot.__init__(self, surface, data, width, height, background, border, x_labels, y_labels, series_colors) > + > + def load_series(self, data, x_labels = None, y_labels = None, series_colors = None): > + Plot.load_series(self, data, x_labels, y_labels, series_colors) > + self.calc_boundaries() > + > + def process_colors(self, series_colors): > + #Data for a BarPlot might be a List or a List of Lists. > + #On the first case, colors must be generated for all bars, > + #On the second, colors must be generated for each of the inner lists. > + > + #TODO: Didn't get it... > + #if hasattr(self.data[0], '__getitem__'): > + # length = max(len(series) for series in self.data) > + #else: > + # length = len( self.data ) > + > + length = max(len(group) for group in self.series) > + > + Plot.process_colors( self, series_colors, length, 'linear') > + > + def calc_boundaries(self): > + if not self.bounds[self.main_dir]: > + if self.stack: > + max_data_value = max(sum(group.to_list()) for group in self.series) > + else: > + max_data_value = max(max(group.to_list()) for group in self.series) > + self.bounds[self.main_dir] = (0, max_data_value) > + if not self.bounds[other_direction(self.main_dir)]: > + self.bounds[other_direction(self.main_dir)] = (0, len(self.series)) > + > + def calc_extents(self, direction): > + self.max_value[direction] = 0 > + if self.labels[direction]: > + widest_word = max(self.labels[direction], key = lambda item: self.context.text_extents(item)[2]) > + self.max_value[direction] = self.context.text_extents(widest_word)[3 - direction] > + self.borders[other_direction(direction)] = (2-direction)*self.max_value[direction] + self.border + direction*(5) > + else: > + self.borders[other_direction(direction)] = self.border > + > + def calc_horz_extents(self): > + self.calc_extents(HORZ) > + > + def calc_vert_extents(self): > + self.calc_extents(VERT) > + > + def calc_all_extents(self): > + self.calc_horz_extents() > + self.calc_vert_extents() > + other_dir = other_direction(self.main_dir) > + self.value_label = 0 > + if self.display_values: > + if self.stack: > + self.value_label = self.context.text_extents(str(max(sum(group.to_list()) for group in self.series)))[2 + self.main_dir] > + else: > + self.value_label = self.context.text_extents(str(max(max(group.to_list()) for group in self.series)))[2 + self.main_dir] > + if self.labels[self.main_dir]: > + self.plot_dimensions[self.main_dir] = self.dimensions[self.main_dir] - 2*self.borders[self.main_dir] - self.value_label > + else: > + self.plot_dimensions[self.main_dir] = self.dimensions[self.main_dir] - self.borders[self.main_dir] - 1.2*self.border - self.value_label > + self.plot_dimensions[other_dir] = self.dimensions[other_dir] - self.borders[other_dir] - self.border > + self.plot_top = self.dimensions[VERT] - self.borders[VERT] > + > + def calc_steps(self): > + other_dir = other_direction(self.main_dir) > + self.series_amplitude = self.bounds[self.main_dir][1] - self.bounds[self.main_dir][0] > + if self.series_amplitude: > + self.steps[self.main_dir] = float(self.plot_dimensions[self.main_dir])/self.series_amplitude > + else: > + self.steps[self.main_dir] = 0.00 > + series_length = len(self.series) > + self.steps[other_dir] = float(self.plot_dimensions[other_dir])/(series_length + 0.1*(series_length + 1)) > + self.space = 0.1*self.steps[other_dir] > + > + def render(self): > + self.calc_all_extents() > + self.calc_steps() > + self.render_background() > + self.render_bounding_box() > + if self.grid: > + self.render_grid() > + if self.three_dimension: > + self.render_ground() > + if self.display_values: > + self.render_values() > + self.render_labels() > + self.render_plot() > + if self.series_labels: > + self.render_legend() > + > + def draw_3d_rectangle_front(self, x0, y0, x1, y1, shift): > + self.context.rectangle(x0-shift, y0+shift, x1-x0, y1-y0) > + > + def draw_3d_rectangle_side(self, x0, y0, x1, y1, shift): > + self.context.move_to(x1-shift,y0+shift) > + self.context.line_to(x1, y0) > + self.context.line_to(x1, y1) > + self.context.line_to(x1-shift, y1+shift) > + self.context.line_to(x1-shift, y0+shift) > + self.context.close_path() > + > + def draw_3d_rectangle_top(self, x0, y0, x1, y1, shift): > + self.context.move_to(x0-shift,y0+shift) > + self.context.line_to(x0, y0) > + self.context.line_to(x1, y0) > + self.context.line_to(x1-shift, y0+shift) > + self.context.line_to(x0-shift, y0+shift) > + self.context.close_path() > + > + def draw_round_rectangle(self, x0, y0, x1, y1): > + self.context.arc(x0+5, y0+5, 5, -math.pi, -math.pi/2) > + self.context.line_to(x1-5, y0) > + self.context.arc(x1-5, y0+5, 5, -math.pi/2, 0) > + self.context.line_to(x1, y1-5) > + self.context.arc(x1-5, y1-5, 5, 0, math.pi/2) > + self.context.line_to(x0+5, y1) > + self.context.arc(x0+5, y1-5, 5, math.pi/2, math.pi) > + self.context.line_to(x0, y0+5) > + self.context.close_path() > + > + def render_ground(self): > + self.draw_3d_rectangle_front(self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], > + self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) > + self.context.fill() > + > + self.draw_3d_rectangle_side (self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], > + self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) > + self.context.fill() > + > + self.draw_3d_rectangle_top (self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], > + self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) > + self.context.fill() > + > + def render_labels(self): > + self.context.set_font_size(self.font_size * 0.8) > + if self.labels[HORZ]: > + self.render_horz_labels() > + if self.labels[VERT]: > + self.render_vert_labels() > + > + def render_legend(self): > + cr = self.context > + cr.set_font_size(self.font_size) > + cr.set_line_width(self.line_width) > + > + widest_word = max(self.series_labels, key = lambda item: self.context.text_extents(item)[2]) > + tallest_word = max(self.series_labels, key = lambda item: self.context.text_extents(item)[3]) > + max_width = self.context.text_extents(widest_word)[2] > + max_height = self.context.text_extents(tallest_word)[3] * 1.1 + 5 > + > + color_box_height = max_height / 2 > + color_box_width = color_box_height * 2 > + > + #Draw a bounding box > + bounding_box_width = max_width + color_box_width + 15 > + bounding_box_height = (len(self.series_labels)+0.5) * max_height > + cr.set_source_rgba(1,1,1) > + cr.rectangle(self.dimensions[HORZ] - self.border - bounding_box_width, self.border, > + bounding_box_width, bounding_box_height) > + cr.fill() > + > + cr.set_source_rgba(*self.line_color) > + cr.set_line_width(self.line_width) > + cr.rectangle(self.dimensions[HORZ] - self.border - bounding_box_width, self.border, > + bounding_box_width, bounding_box_height) > + cr.stroke() > + > + for idx,key in enumerate(self.series_labels): > + #Draw color box > + cr.set_source_rgba(*self.series_colors[idx][:4]) > + cr.rectangle(self.dimensions[HORZ] - self.border - max_width - color_box_width - 10, > + self.border + color_box_height + (idx*max_height) , > + color_box_width, color_box_height) > + cr.fill() > + > + cr.set_source_rgba(0, 0, 0) > + cr.rectangle(self.dimensions[HORZ] - self.border - max_width - color_box_width - 10, > + self.border + color_box_height + (idx*max_height), > + color_box_width, color_box_height) > + cr.stroke() > + > + #Draw series labels > + cr.set_source_rgba(0, 0, 0) > + cr.move_to(self.dimensions[HORZ] - self.border - max_width - 5, self.border + ((idx+1)*max_height)) > + cr.show_text(key) > + > + > +class HorizontalBarPlot(BarPlot): > + def __init__(self, > + surface = None, > + data = None, > + width = 640, > + height = 480, > + background = "white light_gray", > + border = 0, > + display_values = False, > + grid = False, > + rounded_corners = False, > + stack = False, > + three_dimension = False, > + series_labels = None, > + x_labels = None, > + y_labels = None, > + x_bounds = None, > + y_bounds = None, > + series_colors = None): > + > + BarPlot.__init__(self, surface, data, width, height, background, border, > + display_values, grid, rounded_corners, stack, three_dimension, > + x_labels, y_labels, x_bounds, y_bounds, series_colors, HORZ) > + self.series_labels = series_labels > + > + def calc_vert_extents(self): > + self.calc_extents(VERT) > + if self.labels[HORZ] and not self.labels[VERT]: > + self.borders[HORZ] += 10 > + > + def draw_rectangle_bottom(self, x0, y0, x1, y1): > + self.context.arc(x0+5, y1-5, 5, math.pi/2, math.pi) > + self.context.line_to(x0, y0+5) > + self.context.arc(x0+5, y0+5, 5, -math.pi, -math.pi/2) > + self.context.line_to(x1, y0) > + self.context.line_to(x1, y1) > + self.context.line_to(x0+5, y1) > + self.context.close_path() > + > + def draw_rectangle_top(self, x0, y0, x1, y1): > + self.context.arc(x1-5, y0+5, 5, -math.pi/2, 0) > + self.context.line_to(x1, y1-5) > + self.context.arc(x1-5, y1-5, 5, 0, math.pi/2) > + self.context.line_to(x0, y1) > + self.context.line_to(x0, y0) > + self.context.line_to(x1, y0) > + self.context.close_path() > + > + def draw_rectangle(self, index, length, x0, y0, x1, y1): > + if length == 1: > + BarPlot.draw_rectangle(self, x0, y0, x1, y1) > + elif index == 0: > + self.draw_rectangle_bottom(x0, y0, x1, y1) > + elif index == length-1: > + self.draw_rectangle_top(x0, y0, x1, y1) > + else: > + self.context.rectangle(x0, y0, x1-x0, y1-y0) > + > + #TODO: Review BarPlot.render_grid code > + def render_grid(self): > + self.context.set_source_rgba(0.8, 0.8, 0.8) > + if self.labels[HORZ]: > + self.context.set_font_size(self.font_size * 0.8) > + step = (self.dimensions[HORZ] - 2*self.borders[HORZ] - self.value_label)/(len(self.labels[HORZ])-1) > + x = self.borders[HORZ] > + next_x = 0 > + for item in self.labels[HORZ]: > + width = self.context.text_extents(item)[2] > + if x - width/2 > next_x and x - width/2 > self.border: > + self.context.move_to(x, self.border) > + self.context.line_to(x, self.dimensions[VERT] - self.borders[VERT]) > + self.context.stroke() > + next_x = x + width/2 > + x += step > + else: > + lines = 11 > + horizontal_step = float(self.plot_dimensions[HORZ])/(lines-1) > + x = self.borders[HORZ] > + for y in xrange(0, lines): > + self.context.move_to(x, self.border) > + self.context.line_to(x, self.dimensions[VERT] - self.borders[VERT]) > + self.context.stroke() > + x += horizontal_step > + > + def render_horz_labels(self): > + step = (self.dimensions[HORZ] - 2*self.borders[HORZ])/(len(self.labels[HORZ])-1) > + x = self.borders[HORZ] > + next_x = 0 > + > + for item in self.labels[HORZ]: > + self.context.set_source_rgba(*self.label_color) > + width = self.context.text_extents(item)[2] > + if x - width/2 > next_x and x - width/2 > self.border: > + self.context.move_to(x - width/2, self.dimensions[VERT] - self.borders[VERT] + self.max_value[HORZ] + 3) > + self.context.show_text(item) > + next_x = x + width/2 > + x += step > + > + def render_vert_labels(self): > + series_length = len(self.labels[VERT]) > + step = (self.plot_dimensions[VERT] - (series_length + 1)*self.space)/(len(self.labels[VERT])) > + y = self.border + step/2 + self.space > + > + for item in self.labels[VERT]: > + self.context.set_source_rgba(*self.label_color) > + width, height = self.context.text_extents(item)[2:4] > + self.context.move_to(self.borders[HORZ] - width - 5, y + height/2) > + self.context.show_text(item) > + y += step + self.space > + self.labels[VERT].reverse() > + > + def render_values(self): > + self.context.set_source_rgba(*self.value_label_color) > + self.context.set_font_size(self.font_size * 0.8) > + if self.stack: > + for i,group in enumerate(self.series): > + value = sum(group.to_list()) > + height = self.context.text_extents(str(value))[3] > + x = self.borders[HORZ] + value*self.steps[HORZ] + 2 > + y = self.borders[VERT] + (i+0.5)*self.steps[VERT] + (i+1)*self.space + height/2 > + self.context.move_to(x, y) > + self.context.show_text(str(value)) > + else: > + for i,group in enumerate(self.series): > + inner_step = self.steps[VERT]/len(group) > + y0 = self.border + i*self.steps[VERT] + (i+1)*self.space > + for number,data in enumerate(group): > + height = self.context.text_extents(str(data.content))[3] > + self.context.move_to(self.borders[HORZ] + data.content*self.steps[HORZ] + 2, y0 + 0.5*inner_step + height/2, ) > + self.context.show_text(str(data.content)) > + y0 += inner_step > + > + def render_plot(self): > + if self.stack: > + for i,group in enumerate(self.series): > + x0 = self.borders[HORZ] > + y0 = self.borders[VERT] + i*self.steps[VERT] + (i+1)*self.space > + for number,data in enumerate(group): > + if self.series_colors[number][4] in ('radial','linear') : > + linear = cairo.LinearGradient( data.content*self.steps[HORZ]/2, y0, data.content*self.steps[HORZ]/2, y0 + self.steps[VERT] ) > + color = self.series_colors[number] > + linear.add_color_stop_rgba(0.0, 3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) > + linear.add_color_stop_rgba(1.0, *color[:4]) > + self.context.set_source(linear) > + elif self.series_colors[number][4] == 'solid': > + self.context.set_source_rgba(*self.series_colors[number][:4]) > + if self.rounded_corners: > + self.draw_rectangle(number, len(group), x0, y0, x0+data.content*self.steps[HORZ], y0+self.steps[VERT]) > + self.context.fill() > + else: > + self.context.rectangle(x0, y0, data.content*self.steps[HORZ], self.steps[VERT]) > + self.context.fill() > + x0 += data.content*self.steps[HORZ] > + else: > + for i,group in enumerate(self.series): > + inner_step = self.steps[VERT]/len(group) > + x0 = self.borders[HORZ] > + y0 = self.border + i*self.steps[VERT] + (i+1)*self.space > + for number,data in enumerate(group): > + linear = cairo.LinearGradient(data.content*self.steps[HORZ]/2, y0, data.content*self.steps[HORZ]/2, y0 + inner_step) > + color = self.series_colors[number] > + linear.add_color_stop_rgba(0.0, 3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) > + linear.add_color_stop_rgba(1.0, *color[:4]) > + self.context.set_source(linear) > + if self.rounded_corners and data.content != 0: > + BarPlot.draw_round_rectangle(self,x0, y0, x0 + data.content*self.steps[HORZ], y0 + inner_step) > + self.context.fill() > + else: > + self.context.rectangle(x0, y0, data.content*self.steps[HORZ], inner_step) > + self.context.fill() > + y0 += inner_step > + > +class VerticalBarPlot(BarPlot): > + def __init__(self, > + surface = None, > + data = None, > + width = 640, > + height = 480, > + background = "white light_gray", > + border = 0, > + display_values = False, > + grid = False, > + rounded_corners = False, > + stack = False, > + three_dimension = False, > + series_labels = None, > + x_labels = None, > + y_labels = None, > + x_bounds = None, > + y_bounds = None, > + series_colors = None): > + > + BarPlot.__init__(self, surface, data, width, height, background, border, > + display_values, grid, rounded_corners, stack, three_dimension, > + x_labels, y_labels, x_bounds, y_bounds, series_colors, VERT) > + self.series_labels = series_labels > + > + def calc_vert_extents(self): > + self.calc_extents(VERT) > + if self.labels[VERT] and not self.labels[HORZ]: > + self.borders[VERT] += 10 > + > + def draw_rectangle_bottom(self, x0, y0, x1, y1): > + self.context.move_to(x1,y1) > + self.context.arc(x1-5, y1-5, 5, 0, math.pi/2) > + self.context.line_to(x0+5, y1) > + self.context.arc(x0+5, y1-5, 5, math.pi/2, math.pi) > + self.context.line_to(x0, y0) > + self.context.line_to(x1, y0) > + self.context.line_to(x1, y1) > + self.context.close_path() > + > + def draw_rectangle_top(self, x0, y0, x1, y1): > + self.context.arc(x0+5, y0+5, 5, -math.pi, -math.pi/2) > + self.context.line_to(x1-5, y0) > + self.context.arc(x1-5, y0+5, 5, -math.pi/2, 0) > + self.context.line_to(x1, y1) > + self.context.line_to(x0, y1) > + self.context.line_to(x0, y0) > + self.context.close_path() > + > + def draw_rectangle(self, index, length, x0, y0, x1, y1): > + if length == 1: > + BarPlot.draw_rectangle(self, x0, y0, x1, y1) > + elif index == 0: > + self.draw_rectangle_bottom(x0, y0, x1, y1) > + elif index == length-1: > + self.draw_rectangle_top(x0, y0, x1, y1) > + else: > + self.context.rectangle(x0, y0, x1-x0, y1-y0) > + > + def render_grid(self): > + self.context.set_source_rgba(0.8, 0.8, 0.8) > + if self.labels[VERT]: > + lines = len(self.labels[VERT]) > + vertical_step = float(self.plot_dimensions[self.main_dir])/(lines-1) > + y = self.borders[VERT] + self.value_label > + else: > + lines = 11 > + vertical_step = float(self.plot_dimensions[self.main_dir])/(lines-1) > + y = 1.2*self.border + self.value_label > + for x in xrange(0, lines): > + self.context.move_to(self.borders[HORZ], y) > + self.context.line_to(self.dimensions[HORZ] - self.border, y) > + self.context.stroke() > + y += vertical_step > + > + def render_ground(self): > + self.draw_3d_rectangle_front(self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], > + self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) > + self.context.fill() > + > + self.draw_3d_rectangle_side (self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], > + self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) > + self.context.fill() > + > + self.draw_3d_rectangle_top (self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT], > + self.dimensions[HORZ] - self.borders[HORZ], self.dimensions[VERT] - self.borders[VERT] + 5, 10) > + self.context.fill() > + > + def render_horz_labels(self): > + series_length = len(self.labels[HORZ]) > + step = float (self.plot_dimensions[HORZ] - (series_length + 1)*self.space)/len(self.labels[HORZ]) > + x = self.borders[HORZ] + step/2 + self.space > + next_x = 0 > + > + for item in self.labels[HORZ]: > + self.context.set_source_rgba(*self.label_color) > + width = self.context.text_extents(item)[2] > + if x - width/2 > next_x and x - width/2 > self.borders[HORZ]: > + self.context.move_to(x - width/2, self.dimensions[VERT] - self.borders[VERT] + self.max_value[HORZ] + 3) > + self.context.show_text(item) > + next_x = x + width/2 > + x += step + self.space > + > + def render_vert_labels(self): > + self.context.set_source_rgba(*self.label_color) > + y = self.borders[VERT] + self.value_label > + step = (self.dimensions[VERT] - 2*self.borders[VERT] - self.value_label)/(len(self.labels[VERT]) - 1) > + self.labels[VERT].reverse() > + for item in self.labels[VERT]: > + width, height = self.context.text_extents(item)[2:4] > + self.context.move_to(self.borders[HORZ] - width - 5, y + height/2) > + self.context.show_text(item) > + y += step > + self.labels[VERT].reverse() > + > + def render_values(self): > + self.context.set_source_rgba(*self.value_label_color) > + self.context.set_font_size(self.font_size * 0.8) > + if self.stack: > + for i,group in enumerate(self.series): > + value = sum(group.to_list()) > + width = self.context.text_extents(str(value))[2] > + x = self.borders[HORZ] + (i+0.5)*self.steps[HORZ] + (i+1)*self.space - width/2 > + y = value*self.steps[VERT] + 2 > + self.context.move_to(x, self.plot_top-y) > + self.context.show_text(str(value)) > + else: > + for i,group in enumerate(self.series): > + inner_step = self.steps[HORZ]/len(group) > + x0 = self.borders[HORZ] + i*self.steps[HORZ] + (i+1)*self.space > + for number,data in enumerate(group): > + width = self.context.text_extents(str(data.content))[2] > + self.context.move_to(x0 + 0.5*inner_step - width/2, self.plot_top - data.content*self.steps[VERT] - 2) > + self.context.show_text(str(data.content)) > + x0 += inner_step > + > + def render_plot(self): > + if self.stack: > + for i,group in enumerate(self.series): > + x0 = self.borders[HORZ] + i*self.steps[HORZ] + (i+1)*self.space > + y0 = 0 > + for number,data in enumerate(group): > + if self.series_colors[number][4] in ('linear','radial'): > + linear = cairo.LinearGradient( x0, data.content*self.steps[VERT]/2, x0 + self.steps[HORZ], data.content*self.steps[VERT]/2 ) > + color = self.series_colors[number] > + linear.add_color_stop_rgba(0.0, 3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) > + linear.add_color_stop_rgba(1.0, *color[:4]) > + self.context.set_source(linear) > + elif self.series_colors[number][4] == 'solid': > + self.context.set_source_rgba(*self.series_colors[number][:4]) > + if self.rounded_corners: > + self.draw_rectangle(number, len(group), x0, self.plot_top - y0 - data.content*self.steps[VERT], x0 + self.steps[HORZ], self.plot_top - y0) > + self.context.fill() > + else: > + self.context.rectangle(x0, self.plot_top - y0 - data.content*self.steps[VERT], self.steps[HORZ], data.content*self.steps[VERT]) > + self.context.fill() > + y0 += data.content*self.steps[VERT] > + else: > + for i,group in enumerate(self.series): > + inner_step = self.steps[HORZ]/len(group) > + y0 = self.borders[VERT] > + x0 = self.borders[HORZ] + i*self.steps[HORZ] + (i+1)*self.space > + for number,data in enumerate(group): > + if self.series_colors[number][4] == 'linear': > + linear = cairo.LinearGradient( x0, data.content*self.steps[VERT]/2, x0 + inner_step, data.content*self.steps[VERT]/2 ) > + color = self.series_colors[number] > + linear.add_color_stop_rgba(0.0, 3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) > + linear.add_color_stop_rgba(1.0, *color[:4]) > + self.context.set_source(linear) > + elif self.series_colors[number][4] == 'solid': > + self.context.set_source_rgba(*self.series_colors[number][:4]) > + if self.rounded_corners and data.content != 0: > + BarPlot.draw_round_rectangle(self, x0, self.plot_top - data.content*self.steps[VERT], x0+inner_step, self.plot_top) > + self.context.fill() > + elif self.three_dimension: > + self.draw_3d_rectangle_front(x0, self.plot_top - data.content*self.steps[VERT], x0+inner_step, self.plot_top, 5) > + self.context.fill() > + self.draw_3d_rectangle_side(x0, self.plot_top - data.content*self.steps[VERT], x0+inner_step, self.plot_top, 5) > + self.context.fill() > + self.draw_3d_rectangle_top(x0, self.plot_top - data.content*self.steps[VERT], x0+inner_step, self.plot_top, 5) > + self.context.fill() > + else: > + self.context.rectangle(x0, self.plot_top - data.content*self.steps[VERT], inner_step, data.content*self.steps[VERT]) > + self.context.fill() > + > + x0 += inner_step > + > +class StreamChart(VerticalBarPlot): > + def __init__(self, > + surface = None, > + data = None, > + width = 640, > + height = 480, > + background = "white light_gray", > + border = 0, > + grid = False, > + series_legend = None, > + x_labels = None, > + x_bounds = None, > + y_bounds = None, > + series_colors = None): > + > + VerticalBarPlot.__init__(self, surface, data, width, height, background, border, > + False, grid, False, True, False, > + None, x_labels, None, x_bounds, y_bounds, series_colors) > + > + def calc_steps(self): > + other_dir = other_direction(self.main_dir) > + self.series_amplitude = self.bounds[self.main_dir][1] - self.bounds[self.main_dir][0] > + if self.series_amplitude: > + self.steps[self.main_dir] = float(self.plot_dimensions[self.main_dir])/self.series_amplitude > + else: > + self.steps[self.main_dir] = 0.00 > + series_length = len(self.data) > + self.steps[other_dir] = float(self.plot_dimensions[other_dir])/series_length > + > + def render_legend(self): > + pass > + > + def ground(self, index): > + sum_values = sum(self.data[index]) > + return -0.5*sum_values > + > + def calc_angles(self): > + middle = self.plot_top - self.plot_dimensions[VERT]/2.0 > + self.angles = [tuple([0.0 for x in range(len(self.data)+1)])] > + for x_index in range(1, len(self.data)-1): > + t = [] > + x0 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ] > + x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ] > + y0 = middle - self.ground(x_index-1)*self.steps[VERT] > + y2 = middle - self.ground(x_index+1)*self.steps[VERT] > + t.append(math.atan(float(y0-y2)/(x0-x2))) > + for data_index in range(len(self.data[x_index])): > + x0 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ] > + x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ] > + y0 = middle - self.ground(x_index-1)*self.steps[VERT] - self.data[x_index-1][data_index]*self.steps[VERT] > + y2 = middle - self.ground(x_index+1)*self.steps[VERT] - self.data[x_index+1][data_index]*self.steps[VERT] > + > + for i in range(0,data_index): > + y0 -= self.data[x_index-1][i]*self.steps[VERT] > + y2 -= self.data[x_index+1][i]*self.steps[VERT] > + > + if data_index == len(self.data[0])-1 and False: > + self.context.set_source_rgba(0.0,0.0,0.0,0.3) > + self.context.move_to(x0,y0) > + self.context.line_to(x2,y2) > + self.context.stroke() > + self.context.arc(x0,y0,2,0,2*math.pi) > + self.context.fill() > + t.append(math.atan(float(y0-y2)/(x0-x2))) > + self.angles.append(tuple(t)) > + self.angles.append(tuple([0.0 for x in range(len(self.data)+1)])) > + > + def render_plot(self): > + self.calc_angles() > + middle = self.plot_top - self.plot_dimensions[VERT]/2.0 > + p = 0.4*self.steps[HORZ] > + for data_index in range(len(self.data[0])-1,-1,-1): > + self.context.set_source_rgba(*self.series_colors[data_index][:4]) > + > + #draw the upper line > + for x_index in range(len(self.data)-1) : > + x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ] > + y1 = middle - self.ground(x_index)*self.steps[VERT] - self.data[x_index][data_index]*self.steps[VERT] > + x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ] > + y2 = middle - self.ground(x_index + 1)*self.steps[VERT] - self.data[x_index + 1][data_index]*self.steps[VERT] > + > + for i in range(0,data_index): > + y1 -= self.data[x_index][i]*self.steps[VERT] > + y2 -= self.data[x_index+1][i]*self.steps[VERT] > + > + if x_index == 0: > + self.context.move_to(x1,y1) > + > + ang1 = self.angles[x_index][data_index+1] > + ang2 = self.angles[x_index+1][data_index+1] + math.pi > + self.context.curve_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1), > + x2+p*math.cos(ang2),y2+p*math.sin(ang2), > + x2,y2) > + > + for x_index in range(len(self.data)-1,0,-1) : > + x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ] > + y1 = middle - self.ground(x_index)*self.steps[VERT] > + x2 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ] > + y2 = middle - self.ground(x_index - 1)*self.steps[VERT] > + > + for i in range(0,data_index): > + y1 -= self.data[x_index][i]*self.steps[VERT] > + y2 -= self.data[x_index-1][i]*self.steps[VERT] > + > + if x_index == len(self.data)-1: > + self.context.line_to(x1,y1+2) > + > + #revert angles by pi degrees to take the turn back > + ang1 = self.angles[x_index][data_index] + math.pi > + ang2 = self.angles[x_index-1][data_index] > + self.context.curve_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1), > + x2+p*math.cos(ang2),y2+p*math.sin(ang2), > + x2,y2+2) > + > + self.context.close_path() > + self.context.fill() > + > + if False: > + self.context.move_to(self.borders[HORZ] + 0.5*self.steps[HORZ], middle) > + for x_index in range(len(self.data)-1) : > + x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ] > + y1 = middle - self.ground(x_index)*self.steps[VERT] - self.data[x_index][data_index]*self.steps[VERT] > + x2 = self.borders[HORZ] + (0.5 + x_index + 1)*self.steps[HORZ] > + y2 = middle - self.ground(x_index + 1)*self.steps[VERT] - self.data[x_index + 1][data_index]*self.steps[VERT] > + > + for i in range(0,data_index): > + y1 -= self.data[x_index][i]*self.steps[VERT] > + y2 -= self.data[x_index+1][i]*self.steps[VERT] > + > + ang1 = self.angles[x_index][data_index+1] > + ang2 = self.angles[x_index+1][data_index+1] + math.pi > + self.context.set_source_rgba(1.0,0.0,0.0) > + self.context.arc(x1+p*math.cos(ang1),y1+p*math.sin(ang1),2,0,2*math.pi) > + self.context.fill() > + self.context.set_source_rgba(0.0,0.0,0.0) > + self.context.arc(x2+p*math.cos(ang2),y2+p*math.sin(ang2),2,0,2*math.pi) > + self.context.fill() > + '''self.context.set_source_rgba(0.0,0.0,0.0,0.3) > + self.context.arc(x2,y2,2,0,2*math.pi) > + self.context.fill()''' > + self.context.move_to(x1,y1) > + self.context.line_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1)) > + self.context.stroke() > + self.context.move_to(x2,y2) > + self.context.line_to(x2+p*math.cos(ang2),y2+p*math.sin(ang2)) > + self.context.stroke() > + if False: > + for x_index in range(len(self.data)-1,0,-1) : > + x1 = self.borders[HORZ] + (0.5 + x_index)*self.steps[HORZ] > + y1 = middle - self.ground(x_index)*self.steps[VERT] > + x2 = self.borders[HORZ] + (0.5 + x_index - 1)*self.steps[HORZ] > + y2 = middle - self.ground(x_index - 1)*self.steps[VERT] > + > + for i in range(0,data_index): > + y1 -= self.data[x_index][i]*self.steps[VERT] > + y2 -= self.data[x_index-1][i]*self.steps[VERT] > + > + #revert angles by pi degrees to take the turn back > + ang1 = self.angles[x_index][data_index] + math.pi > + ang2 = self.angles[x_index-1][data_index] > + self.context.set_source_rgba(0.0,1.0,0.0) > + self.context.arc(x1+p*math.cos(ang1),y1+p*math.sin(ang1),2,0,2*math.pi) > + self.context.fill() > + self.context.set_source_rgba(0.0,0.0,1.0) > + self.context.arc(x2+p*math.cos(ang2),y2+p*math.sin(ang2),2,0,2*math.pi) > + self.context.fill() > + '''self.context.set_source_rgba(0.0,0.0,0.0,0.3) > + self.context.arc(x2,y2,2,0,2*math.pi) > + self.context.fill()''' > + self.context.move_to(x1,y1) > + self.context.line_to(x1+p*math.cos(ang1),y1+p*math.sin(ang1)) > + self.context.stroke() > + self.context.move_to(x2,y2) > + self.context.line_to(x2+p*math.cos(ang2),y2+p*math.sin(ang2)) > + self.context.stroke() > + #break > + > + #self.context.arc(self.dimensions[HORZ]/2, self.dimensions[VERT]/2,50,0,3*math.pi/2) > + #self.context.fill() > + > + > +class PiePlot(Plot): > + #TODO: Check the old cairoplot, graphs aren't matching > + def __init__ (self, > + surface = None, > + data = None, > + width = 640, > + height = 480, > + background = "white light_gray", > + gradient = False, > + shadow = False, > + colors = None): > + > + Plot.__init__( self, surface, data, width, height, background, series_colors = colors ) > + self.center = (self.dimensions[HORZ]/2, self.dimensions[VERT]/2) > + self.total = sum( self.series.to_list() ) > + self.radius = min(self.dimensions[HORZ]/3,self.dimensions[VERT]/3) > + self.gradient = gradient > + self.shadow = shadow > + > + def sort_function(x,y): > + return x.content - y.content > + > + def load_series(self, data, x_labels=None, y_labels=None, series_colors=None): > + Plot.load_series(self, data, x_labels, y_labels, series_colors) > + # Already done inside series > + #self.data = sorted(self.data) > + > + def draw_piece(self, angle, next_angle): > + self.context.move_to(self.center[0],self.center[1]) > + self.context.line_to(self.center[0] + self.radius*math.cos(angle), self.center[1] + self.radius*math.sin(angle)) > + self.context.arc(self.center[0], self.center[1], self.radius, angle, next_angle) > + self.context.line_to(self.center[0], self.center[1]) > + self.context.close_path() > + > + def render(self): > + self.render_background() > + self.render_bounding_box() > + if self.shadow: > + self.render_shadow() > + self.render_plot() > + self.render_series_labels() > + > + def render_shadow(self): > + horizontal_shift = 3 > + vertical_shift = 3 > + self.context.set_source_rgba(0, 0, 0, 0.5) > + self.context.arc(self.center[0] + horizontal_shift, self.center[1] + vertical_shift, self.radius, 0, 2*math.pi) > + self.context.fill() > + > + def render_series_labels(self): > + angle = 0 > + next_angle = 0 > + x0,y0 = self.center > + cr = self.context > + for number,key in enumerate(self.series_labels): > + # self.data[number] should be just a number > + data = sum(self.series[number].to_list()) > + > + next_angle = angle + 2.0*math.pi*data/self.total > + cr.set_source_rgba(*self.series_colors[number][:4]) > + w = cr.text_extents(key)[2] > + if (angle + next_angle)/2 < math.pi/2 or (angle + next_angle)/2 > 3*math.pi/2: > + cr.move_to(x0 + (self.radius+10)*math.cos((angle+next_angle)/2), y0 + (self.radius+10)*math.sin((angle+next_angle)/2) ) > + else: > + cr.move_to(x0 + (self.radius+10)*math.cos((angle+next_angle)/2) - w, y0 + (self.radius+10)*math.sin((angle+next_angle)/2) ) > + cr.show_text(key) > + angle = next_angle > + > + def render_plot(self): > + angle = 0 > + next_angle = 0 > + x0,y0 = self.center > + cr = self.context > + for number,group in enumerate(self.series): > + # Group should be just a number > + data = sum(group.to_list()) > + next_angle = angle + 2.0*math.pi*data/self.total > + if self.gradient or self.series_colors[number][4] in ('linear','radial'): > + gradient_color = cairo.RadialGradient(self.center[0], self.center[1], 0, self.center[0], self.center[1], self.radius) > + gradient_color.add_color_stop_rgba(0.3, *self.series_colors[number][:4]) > + gradient_color.add_color_stop_rgba(1, self.series_colors[number][0]*0.7, > + self.series_colors[number][1]*0.7, > + self.series_colors[number][2]*0.7, > + self.series_colors[number][3]) > + cr.set_source(gradient_color) > + else: > + cr.set_source_rgba(*self.series_colors[number][:4]) > + > + self.draw_piece(angle, next_angle) > + cr.fill() > + > + cr.set_source_rgba(1.0, 1.0, 1.0) > + self.draw_piece(angle, next_angle) > + cr.stroke() > + > + angle = next_angle > + > +class DonutPlot(PiePlot): > + def __init__ (self, > + surface = None, > + data = None, > + width = 640, > + height = 480, > + background = "white light_gray", > + gradient = False, > + shadow = False, > + colors = None, > + inner_radius=-1): > + > + Plot.__init__( self, surface, data, width, height, background, series_colors = colors ) > + > + self.center = ( self.dimensions[HORZ]/2, self.dimensions[VERT]/2 ) > + self.total = sum( self.series.to_list() ) > + self.radius = min( self.dimensions[HORZ]/3,self.dimensions[VERT]/3 ) > + self.inner_radius = inner_radius*self.radius > + > + if inner_radius == -1: > + self.inner_radius = self.radius/3 > + > + self.gradient = gradient > + self.shadow = shadow > + > + def draw_piece(self, angle, next_angle): > + self.context.move_to(self.center[0] + (self.inner_radius)*math.cos(angle), self.center[1] + (self.inner_radius)*math.sin(angle)) > + self.context.line_to(self.center[0] + self.radius*math.cos(angle), self.center[1] + self.radius*math.sin(angle)) > + self.context.arc(self.center[0], self.center[1], self.radius, angle, next_angle) > + self.context.line_to(self.center[0] + (self.inner_radius)*math.cos(next_angle), self.center[1] + (self.inner_radius)*math.sin(next_angle)) > + self.context.arc_negative(self.center[0], self.center[1], self.inner_radius, next_angle, angle) > + self.context.close_path() > + > + def render_shadow(self): > + horizontal_shift = 3 > + vertical_shift = 3 > + self.context.set_source_rgba(0, 0, 0, 0.5) > + self.context.arc(self.center[0] + horizontal_shift, self.center[1] + vertical_shift, self.inner_radius, 0, 2*math.pi) > + self.context.arc_negative(self.center[0] + horizontal_shift, self.center[1] + vertical_shift, self.radius, 0, -2*math.pi) > + self.context.fill() > + > +class GanttChart (Plot) : > + def __init__(self, > + surface = None, > + data = None, > + width = 640, > + height = 480, > + x_labels = None, > + y_labels = None, > + colors = None): > + self.bounds = {} > + self.max_value = {} > + Plot.__init__(self, surface, data, width, height, x_labels = x_labels, y_labels = y_labels, series_colors = colors) > + > + def load_series(self, data, x_labels=None, y_labels=None, series_colors=None): > + Plot.load_series(self, data, x_labels, y_labels, series_colors) > + self.calc_boundaries() > + > + def calc_boundaries(self): > + self.bounds[HORZ] = (0,len(self.series)) > + end_pos = max(self.series.to_list()) > + > + #for group in self.series: > + # if hasattr(item, "__delitem__"): > + # for sub_item in item: > + # end_pos = max(sub_item) > + # else: > + # end_pos = max(item) > + self.bounds[VERT] = (0,end_pos) > + > + def calc_extents(self, direction): > + self.max_value[direction] = 0 > + if self.labels[direction]: > + self.max_value[direction] = max(self.context.text_extents(item)[2] for item in self.labels[direction]) > + else: > + self.max_value[direction] = self.context.text_extents( str(self.bounds[direction][1] + 1) )[2] > + > + def calc_horz_extents(self): > + self.calc_extents(HORZ) > + self.borders[HORZ] = 100 + self.max_value[HORZ] > + > + def calc_vert_extents(self): > + self.calc_extents(VERT) > + self.borders[VERT] = self.dimensions[VERT]/(self.bounds[HORZ][1] + 1) > + > + def calc_steps(self): > + self.horizontal_step = (self.dimensions[HORZ] - self.borders[HORZ])/(len(self.labels[VERT])) > + self.vertical_step = self.borders[VERT] > + > + def render(self): > + self.calc_horz_extents() > + self.calc_vert_extents() > + self.calc_steps() > + self.render_background() > + > + self.render_labels() > + self.render_grid() > + self.render_plot() > + > + def render_background(self): > + cr = self.context > + cr.set_source_rgba(255,255,255) > + cr.rectangle(0,0,self.dimensions[HORZ], self.dimensions[VERT]) > + cr.fill() > + for number,group in enumerate(self.series): > + linear = cairo.LinearGradient(self.dimensions[HORZ]/2, self.borders[VERT] + number*self.vertical_step, > + self.dimensions[HORZ]/2, self.borders[VERT] + (number+1)*self.vertical_step) > + linear.add_color_stop_rgba(0,1.0,1.0,1.0,1.0) > + linear.add_color_stop_rgba(1.0,0.9,0.9,0.9,1.0) > + cr.set_source(linear) > + cr.rectangle(0,self.borders[VERT] + number*self.vertical_step,self.dimensions[HORZ],self.vertical_step) > + cr.fill() > + > + def render_grid(self): > + cr = self.context > + cr.set_source_rgba(0.7, 0.7, 0.7) > + cr.set_dash((1,0,0,0,0,0,1)) > + cr.set_line_width(0.5) > + for number,label in enumerate(self.labels[VERT]): > + h = cr.text_extents(label)[3] > + cr.move_to(self.borders[HORZ] + number*self.horizontal_step, self.vertical_step/2 + h) > + cr.line_to(self.borders[HORZ] + number*self.horizontal_step, self.dimensions[VERT]) > + cr.stroke() > + > + def render_labels(self): > + self.context.set_font_size(0.02 * self.dimensions[HORZ]) > + > + self.render_horz_labels() > + self.render_vert_labels() > + > + def render_horz_labels(self): > + cr = self.context > + labels = self.labels[HORZ] > + if not labels: > + labels = [str(i) for i in range(1, self.bounds[HORZ][1] + 1) ] > + for number,label in enumerate(labels): > + if label != None: > + cr.set_source_rgba(0.5, 0.5, 0.5) > + w,h = cr.text_extents(label)[2], cr.text_extents(label)[3] > + cr.move_to(40,self.borders[VERT] + number*self.vertical_step + self.vertical_step/2 + h/2) > + cr.show_text(label) > + > + def render_vert_labels(self): > + cr = self.context > + labels = self.labels[VERT] > + if not labels: > + labels = [str(i) for i in range(1, self.bounds[VERT][1] + 1) ] > + for number,label in enumerate(labels): > + w,h = cr.text_extents(label)[2], cr.text_extents(label)[3] > + cr.move_to(self.borders[HORZ] + number*self.horizontal_step - w/2, self.vertical_step/2) > + cr.show_text(label) > + > + def render_rectangle(self, x0, y0, x1, y1, color): > + self.draw_shadow(x0, y0, x1, y1) > + self.draw_rectangle(x0, y0, x1, y1, color) > + > + def draw_rectangular_shadow(self, gradient, x0, y0, w, h): > + self.context.set_source(gradient) > + self.context.rectangle(x0,y0,w,h) > + self.context.fill() > + > + def draw_circular_shadow(self, x, y, radius, ang_start, ang_end, mult, shadow): > + gradient = cairo.RadialGradient(x, y, 0, x, y, 2*radius) > + gradient.add_color_stop_rgba(0, 0, 0, 0, shadow) > + gradient.add_color_stop_rgba(1, 0, 0, 0, 0) > + self.context.set_source(gradient) > + self.context.move_to(x,y) > + self.context.line_to(x + mult[0]*radius,y + mult[1]*radius) > + self.context.arc(x, y, 8, ang_start, ang_end) > + self.context.line_to(x,y) > + self.context.close_path() > + self.context.fill() > + > + def draw_rectangle(self, x0, y0, x1, y1, color): > + cr = self.context > + middle = (x0+x1)/2 > + linear = cairo.LinearGradient(middle,y0,middle,y1) > + linear.add_color_stop_rgba(0,3.5*color[0]/5.0, 3.5*color[1]/5.0, 3.5*color[2]/5.0,1.0) > + linear.add_color_stop_rgba(1,*color[:4]) > + cr.set_source(linear) > + > + cr.arc(x0+5, y0+5, 5, 0, 2*math.pi) > + cr.arc(x1-5, y0+5, 5, 0, 2*math.pi) > + cr.arc(x0+5, y1-5, 5, 0, 2*math.pi) > + cr.arc(x1-5, y1-5, 5, 0, 2*math.pi) > + cr.rectangle(x0+5,y0,x1-x0-10,y1-y0) > + cr.rectangle(x0,y0+5,x1-x0,y1-y0-10) > + cr.fill() > + > + def draw_shadow(self, x0, y0, x1, y1): > + shadow = 0.4 > + h_mid = (x0+x1)/2 > + v_mid = (y0+y1)/2 > + h_linear_1 = cairo.LinearGradient(h_mid,y0-4,h_mid,y0+4) > + h_linear_2 = cairo.LinearGradient(h_mid,y1-4,h_mid,y1+4) > + v_linear_1 = cairo.LinearGradient(x0-4,v_mid,x0+4,v_mid) > + v_linear_2 = cairo.LinearGradient(x1-4,v_mid,x1+4,v_mid) > + > + h_linear_1.add_color_stop_rgba( 0, 0, 0, 0, 0) > + h_linear_1.add_color_stop_rgba( 1, 0, 0, 0, shadow) > + h_linear_2.add_color_stop_rgba( 0, 0, 0, 0, shadow) > + h_linear_2.add_color_stop_rgba( 1, 0, 0, 0, 0) > + v_linear_1.add_color_stop_rgba( 0, 0, 0, 0, 0) > + v_linear_1.add_color_stop_rgba( 1, 0, 0, 0, shadow) > + v_linear_2.add_color_stop_rgba( 0, 0, 0, 0, shadow) > + v_linear_2.add_color_stop_rgba( 1, 0, 0, 0, 0) > + > + self.draw_rectangular_shadow(h_linear_1,x0+4,y0-4,x1-x0-8,8) > + self.draw_rectangular_shadow(h_linear_2,x0+4,y1-4,x1-x0-8,8) > + self.draw_rectangular_shadow(v_linear_1,x0-4,y0+4,8,y1-y0-8) > + self.draw_rectangular_shadow(v_linear_2,x1-4,y0+4,8,y1-y0-8) > + > + self.draw_circular_shadow(x0+4, y0+4, 4, math.pi, 3*math.pi/2, (-1,0), shadow) > + self.draw_circular_shadow(x1-4, y0+4, 4, 3*math.pi/2, 2*math.pi, (0,-1), shadow) > + self.draw_circular_shadow(x0+4, y1-4, 4, math.pi/2, math.pi, (0,1), shadow) > + self.draw_circular_shadow(x1-4, y1-4, 4, 0, math.pi/2, (1,0), shadow) > + > + def render_plot(self): > + for index,group in enumerate(self.series): > + for data in group: > + self.render_rectangle(self.borders[HORZ] + data.content[0]*self.horizontal_step, > + self.borders[VERT] + index*self.vertical_step + self.vertical_step/4.0, > + self.borders[HORZ] + data.content[1]*self.horizontal_step, > + self.borders[VERT] + index*self.vertical_step + 3.0*self.vertical_step/4.0, > + self.series_colors[index]) > + > +# Function definition > + > +def scatter_plot(name, > + data = None, > + errorx = None, > + errory = None, > + width = 640, > + height = 480, > + background = "white light_gray", > + border = 0, > + axis = False, > + dash = False, > + discrete = False, > + dots = False, > + grid = False, > + series_legend = False, > + x_labels = None, > + y_labels = None, > + x_bounds = None, > + y_bounds = None, > + z_bounds = None, > + x_title = None, > + y_title = None, > + series_colors = None, > + circle_colors = None): > + > + ''' > + - Function to plot scatter data. > + > + - Parameters > + > + data - The values to be ploted might be passed in a two basic: > + list of points: [(0,0), (0,1), (0,2)] or [(0,0,1), (0,1,4), (0,2,1)] > + lists of coordinates: [ [0,0,0] , [0,1,2] ] or [ [0,0,0] , [0,1,2] , [1,4,1] ] > + Notice that these kinds of that can be grouped in order to form more complex data > + using lists of lists or dictionaries; > + series_colors - Define color values for each of the series > + circle_colors - Define a lower and an upper bound for the circle colors for variable radius > + (3 dimensions) series > + ''' > + > + plot = ScatterPlot( name, data, errorx, errory, width, height, background, border, > + axis, dash, discrete, dots, grid, series_legend, x_labels, y_labels, > + x_bounds, y_bounds, z_bounds, x_title, y_title, series_colors, circle_colors ) > + plot.render() > + plot.commit() > + > +def dot_line_plot(name, > + data, > + width, > + height, > + background = "white light_gray", > + border = 0, > + axis = False, > + dash = False, > + dots = False, > + grid = False, > + series_legend = False, > + x_labels = None, > + y_labels = None, > + x_bounds = None, > + y_bounds = None, > + x_title = None, > + y_title = None, > + series_colors = None): > + ''' > + - Function to plot graphics using dots and lines. > + > + dot_line_plot (name, data, width, height, background = "white light_gray", border = 0, axis = False, grid = False, x_labels = None, y_labels = None, x_bounds = None, y_bounds = None) > + > + - Parameters > + > + name - Name of the desired output file, no need to input the .svg as it will be added at runtim; > + data - The list, list of lists or dictionary holding the data to be plotted; > + width, height - Dimensions of the output image; > + background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. > + If left None, a gray to white gradient will be generated; > + border - Distance in pixels of a square border into which the graphics will be drawn; > + axis - Whether or not the axis are to be drawn; > + dash - Boolean or a list or a dictionary of booleans indicating whether or not the associated series should be drawn in dashed mode; > + dots - Whether or not dots should be drawn on each point; > + grid - Whether or not the gris is to be drawn; > + series_legend - Whether or not the legend is to be drawn; > + x_labels, y_labels - lists of strings containing the horizontal and vertical labels for the axis; > + x_bounds, y_bounds - tuples containing the lower and upper value bounds for the data to be plotted; > + x_title - Whether or not to plot a title over the x axis. > + y_title - Whether or not to plot a title over the y axis. > + > + - Examples of use > + > + data = [0, 1, 3, 8, 9, 0, 10, 10, 2, 1] > + CairoPlot.dot_line_plot('teste', data, 400, 300) > + > + data = { "john" : [10, 10, 10, 10, 30], "mary" : [0, 0, 3, 5, 15], "philip" : [13, 32, 11, 25, 2] } > + x_labels = ["jan/2008", "feb/2008", "mar/2008", "apr/2008", "may/2008" ] > + CairoPlot.dot_line_plot( 'test', data, 400, 300, axis = True, grid = True, > + series_legend = True, x_labels = x_labels ) > + ''' > + plot = DotLinePlot( name, data, width, height, background, border, > + axis, dash, dots, grid, series_legend, x_labels, y_labels, > + x_bounds, y_bounds, x_title, y_title, series_colors ) > + plot.render() > + plot.commit() > + > +def function_plot(name, > + data, > + width, > + height, > + background = "white light_gray", > + border = 0, > + axis = True, > + dots = False, > + discrete = False, > + grid = False, > + series_legend = False, > + x_labels = None, > + y_labels = None, > + x_bounds = None, > + y_bounds = None, > + x_title = None, > + y_title = None, > + series_colors = None, > + step = 1): > + > + ''' > + - Function to plot functions. > + > + function_plot(name, data, width, height, background = "white light_gray", border = 0, axis = True, grid = False, dots = False, x_labels = None, y_labels = None, x_bounds = None, y_bounds = None, step = 1, discrete = False) > + > + - Parameters > + > + name - Name of the desired output file, no need to input the .svg as it will be added at runtim; > + data - The list, list of lists or dictionary holding the data to be plotted; > + width, height - Dimensions of the output image; > + background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. > + If left None, a gray to white gradient will be generated; > + border - Distance in pixels of a square border into which the graphics will be drawn; > + axis - Whether or not the axis are to be drawn; > + grid - Whether or not the gris is to be drawn; > + dots - Whether or not dots should be shown at each point; > + x_labels, y_labels - lists of strings containing the horizontal and vertical labels for the axis; > + x_bounds, y_bounds - tuples containing the lower and upper value bounds for the data to be plotted; > + step - the horizontal distance from one point to the other. The smaller, the smoother the curve will be; > + discrete - whether or not the function should be plotted in discrete format. > + > + - Example of use > + > + data = lambda x : x**2 > + CairoPlot.function_plot('function4', data, 400, 300, grid = True, x_bounds=(-10,10), step = 0.1) > + ''' > + > + plot = FunctionPlot( name, data, width, height, background, border, > + axis, discrete, dots, grid, series_legend, x_labels, y_labels, > + x_bounds, y_bounds, x_title, y_title, series_colors, step ) > + plot.render() > + plot.commit() > + > +def pie_plot( name, data, width, height, background = "white light_gray", gradient = False, shadow = False, colors = None ): > + > + ''' > + - Function to plot pie graphics. > + > + pie_plot(name, data, width, height, background = "white light_gray", gradient = False, colors = None) > + > + - Parameters > + > + name - Name of the desired output file, no need to input the .svg as it will be added at runtim; > + data - The list, list of lists or dictionary holding the data to be plotted; > + width, height - Dimensions of the output image; > + background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. > + If left None, a gray to white gradient will be generated; > + gradient - Whether or not the pie color will be painted with a gradient; > + shadow - Whether or not there will be a shadow behind the pie; > + colors - List of slices colors. > + > + - Example of use > + > + teste_data = {"john" : 123, "mary" : 489, "philip" : 890 , "suzy" : 235} > + CairoPlot.pie_plot("pie_teste", teste_data, 500, 500) > + ''' > + > + plot = PiePlot( name, data, width, height, background, gradient, shadow, colors ) > + plot.render() > + plot.commit() > + > +def donut_plot(name, data, width, height, background = "white light_gray", gradient = False, shadow = False, colors = None, inner_radius = -1): > + > + ''' > + - Function to plot donut graphics. > + > + donut_plot(name, data, width, height, background = "white light_gray", gradient = False, inner_radius = -1) > + > + - Parameters > + > + name - Name of the desired output file, no need to input the .svg as it will be added at runtim; > + data - The list, list of lists or dictionary holding the data to be plotted; > + width, height - Dimensions of the output image; > + background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. > + If left None, a gray to white gradient will be generated; > + shadow - Whether or not there will be a shadow behind the donut; > + gradient - Whether or not the donut color will be painted with a gradient; > + colors - List of slices colors; > + inner_radius - The radius of the donut's inner circle. > + > + - Example of use > + > + teste_data = {"john" : 123, "mary" : 489, "philip" : 890 , "suzy" : 235} > + CairoPlot.donut_plot("donut_teste", teste_data, 500, 500) > + ''' > + > + plot = DonutPlot(name, data, width, height, background, gradient, shadow, colors, inner_radius) > + plot.render() > + plot.commit() > + > +def gantt_chart(name, pieces, width, height, x_labels, y_labels, colors): > + > + ''' > + - Function to generate Gantt Charts. > + > + gantt_chart(name, pieces, width, height, x_labels, y_labels, colors): > + > + - Parameters > + > + name - Name of the desired output file, no need to input the .svg as it will be added at runtim; > + pieces - A list defining the spaces to be drawn. The user must pass, for each line, the index of its start and the index of its end. If a line must have two or more spaces, they must be passed inside a list; > + width, height - Dimensions of the output image; > + x_labels - A list of names for each of the vertical lines; > + y_labels - A list of names for each of the horizontal spaces; > + colors - List containing the colors expected for each of the horizontal spaces > + > + - Example of use > + > + pieces = [ (0.5,5.5) , [(0,4),(6,8)] , (5.5,7) , (7,8)] > + x_labels = [ 'teste01', 'teste02', 'teste03', 'teste04'] > + y_labels = [ '0001', '0002', '0003', '0004', '0005', '0006', '0007', '0008', '0009', '0010' ] > + colors = [ (1.0, 0.0, 0.0), (1.0, 0.7, 0.0), (1.0, 1.0, 0.0), (0.0, 1.0, 0.0) ] > + CairoPlot.gantt_chart('gantt_teste', pieces, 600, 300, x_labels, y_labels, colors) > + ''' > + > + plot = GanttChart(name, pieces, width, height, x_labels, y_labels, colors) > + plot.render() > + plot.commit() > + > +def vertical_bar_plot(name, > + data, > + width, > + height, > + background = "white light_gray", > + border = 0, > + display_values = False, > + grid = False, > + rounded_corners = False, > + stack = False, > + three_dimension = False, > + series_labels = None, > + x_labels = None, > + y_labels = None, > + x_bounds = None, > + y_bounds = None, > + colors = None): > + #TODO: Fix docstring for vertical_bar_plot > + ''' > + - Function to generate vertical Bar Plot Charts. > + > + bar_plot(name, data, width, height, background, border, grid, rounded_corners, three_dimension, > + x_labels, y_labels, x_bounds, y_bounds, colors): > + > + - Parameters > + > + name - Name of the desired output file, no need to input the .svg as it will be added at runtime; > + data - The list, list of lists or dictionary holding the data to be plotted; > + width, height - Dimensions of the output image; > + background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. > + If left None, a gray to white gradient will be generated; > + border - Distance in pixels of a square border into which the graphics will be drawn; > + grid - Whether or not the gris is to be drawn; > + rounded_corners - Whether or not the bars should have rounded corners; > + three_dimension - Whether or not the bars should be drawn in pseudo 3D; > + x_labels, y_labels - lists of strings containing the horizontal and vertical labels for the axis; > + x_bounds, y_bounds - tuples containing the lower and upper value bounds for the data to be plotted; > + colors - List containing the colors expected for each of the bars. > + > + - Example of use > + > + data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] > + CairoPlot.vertical_bar_plot ('bar2', data, 400, 300, border = 20, grid = True, rounded_corners = False) > + ''' > + > + plot = VerticalBarPlot(name, data, width, height, background, border, > + display_values, grid, rounded_corners, stack, three_dimension, > + series_labels, x_labels, y_labels, x_bounds, y_bounds, colors) > + plot.render() > + plot.commit() > + > +def horizontal_bar_plot(name, > + data, > + width, > + height, > + background = "white light_gray", > + border = 0, > + display_values = False, > + grid = False, > + rounded_corners = False, > + stack = False, > + three_dimension = False, > + series_labels = None, > + x_labels = None, > + y_labels = None, > + x_bounds = None, > + y_bounds = None, > + colors = None): > + > + #TODO: Fix docstring for horizontal_bar_plot > + ''' > + - Function to generate Horizontal Bar Plot Charts. > + > + bar_plot(name, data, width, height, background, border, grid, rounded_corners, three_dimension, > + x_labels, y_labels, x_bounds, y_bounds, colors): > + > + - Parameters > + > + name - Name of the desired output file, no need to input the .svg as it will be added at runtime; > + data - The list, list of lists or dictionary holding the data to be plotted; > + width, height - Dimensions of the output image; > + background - A 3 element tuple representing the rgb color expected for the background or a new cairo linear gradient. > + If left None, a gray to white gradient will be generated; > + border - Distance in pixels of a square border into which the graphics will be drawn; > + grid - Whether or not the gris is to be drawn; > + rounded_corners - Whether or not the bars should have rounded corners; > + three_dimension - Whether or not the bars should be drawn in pseudo 3D; > + x_labels, y_labels - lists of strings containing the horizontal and vertical labels for the axis; > + x_bounds, y_bounds - tuples containing the lower and upper value bounds for the data to be plotted; > + colors - List containing the colors expected for each of the bars. > + > + - Example of use > + > + data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] > + CairoPlot.bar_plot ('bar2', data, 400, 300, border = 20, grid = True, rounded_corners = False) > + ''' > + > + plot = HorizontalBarPlot(name, data, width, height, background, border, > + display_values, grid, rounded_corners, stack, three_dimension, > + series_labels, x_labels, y_labels, x_bounds, y_bounds, colors) > + plot.render() > + plot.commit() > + > +def stream_chart(name, > + data, > + width, > + height, > + background = "white light_gray", > + border = 0, > + grid = False, > + series_legend = None, > + x_labels = None, > + x_bounds = None, > + y_bounds = None, > + colors = None): > + > + #TODO: Fix docstring for horizontal_bar_plot > + plot = StreamChart(name, data, width, height, background, border, > + grid, series_legend, x_labels, x_bounds, y_bounds, colors) > + plot.render() > + plot.commit() > + > + > +if __name__ == "__main__": > + import tests > + import seriestests > diff --git a/bindings/python/examples/python2/output_format_modules/pprint_table.py b/bindings/python/examples/python2/output_format_modules/pprint_table.py > new file mode 100644 > index 0000000..3a63d62 > --- /dev/null > +++ b/bindings/python/examples/python2/output_format_modules/pprint_table.py > @@ -0,0 +1,37 @@ > +# pprint_table.py > +# > +# This module is used to pretty-print a table > +# Adapted from > +# http://ginstrom.com/scribbles/2007/09/04/pretty-printing-a-table-in-python/ > + > +import sys > + > +def get_max_width(table, index): > + """Get the maximum width of the given column index""" > + > + return max([len(str(row[index])) for row in table]) > + > + > +def pprint_table(table, nbLeft=1, out=sys.stdout): > + """ > + Prints out a table of data, padded for alignment > + @param table: The table to print. A list of lists. > + Each row must have the same number of columns. > + @param nbLeft: The number of columns aligned left > + @param out: Output stream (file-like object) > + """ > + > + col_paddings = [] > + > + for i in range(len(table[0])): > + col_paddings.append(get_max_width(table, i)) > + > + for row in table: > + # left cols > + for i in range(nbLeft): > + print >> out, str(row[i]).ljust(col_paddings[i] + 1), > + # rest of the cols > + for i in range(nbLeft, len(row)): > + col = str(row[i]).rjust(col_paddings[i] + 2) > + print >> out, col, > + print >> out > diff --git a/bindings/python/examples/python2/output_format_modules/series.py b/bindings/python/examples/python2/output_format_modules/series.py > new file mode 100644 > index 0000000..8e8b236 > --- /dev/null > +++ b/bindings/python/examples/python2/output_format_modules/series.py > @@ -0,0 +1,1140 @@ > +#!/usr/bin/env python > +# -*- coding: utf-8 -*- > + > +# Serie.py > +# > +# Copyright (c) 2008 Magnun Leno da Silva > +# > +# Author: Magnun Leno da Silva > +# > +# This program is free software; you can redistribute it and/or > +# modify it under the terms of the GNU Lesser 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 Lesser 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 > + > +# Contributor: Rodrigo Moreiro Araujo > + > +#import cairoplot > +import doctest > + > +NUMTYPES = (int, float, long) > +LISTTYPES = (list, tuple) > +STRTYPES = (str, unicode) > +FILLING_TYPES = ['linear', 'solid', 'gradient'] > +DEFAULT_COLOR_FILLING = 'solid' > +#TODO: Define default color list > +DEFAULT_COLOR_LIST = None > + > +class Data(object): > + ''' > + Class that models the main data structure. > + It can hold: > + - a number type (int, float or long) > + - a tuple, witch represents a point and can have 2 or 3 items (x,y,z) > + - if a list is passed it will be converted to a tuple. > + > + obs: In case a tuple is passed it will convert to tuple > + ''' > + def __init__(self, data=None, name=None, parent=None): > + ''' > + Starts main atributes from the Data class > + @name - Name for each point; > + @content - The real data, can be an int, float, long or tuple, which > + represents a point (x,y) or (x,y,z); > + @parent - A pointer that give the data access to it's parent. > + > + Usage: > + >>> d = Data(name='empty'); print d > + empty: () > + >>> d = Data((1,1),'point a'); print d > + point a: (1, 1) > + >>> d = Data((1,2,3),'point b'); print d > + point b: (1, 2, 3) > + >>> d = Data([2,3],'point c'); print d > + point c: (2, 3) > + >>> d = Data(12, 'simple value'); print d > + simple value: 12 > + ''' > + # Initial values > + self.__content = None > + self.__name = None > + > + # Setting passed values > + self.parent = parent > + self.name = name > + self.content = data > + > + # Name property > + @apply > + def name(): > + doc = ''' > + Name is a read/write property that controls the input of name. > + - If passed an invalid value it cleans the name with None > + > + Usage: > + >>> d = Data(13); d.name = 'name_test'; print d > + name_test: 13 > + >>> d.name = 11; print d > + 13 > + >>> d.name = 'other_name'; print d > + other_name: 13 > + >>> d.name = None; print d > + 13 > + >>> d.name = 'last_name'; print d > + last_name: 13 > + >>> d.name = ''; print d > + 13 > + ''' > + def fget(self): > + ''' > + returns the name as a string > + ''' > + return self.__name > + > + def fset(self, name): > + ''' > + Sets the name of the Data > + ''' > + if type(name) in STRTYPES and len(name) > 0: > + self.__name = name > + else: > + self.__name = None > + > + > + > + return property(**locals()) > + > + # Content property > + @apply > + def content(): > + doc = ''' > + Content is a read/write property that validate the data passed > + and return it. > + > + Usage: > + >>> d = Data(); d.content = 13; d.content > + 13 > + >>> d = Data(); d.content = (1,2); d.content > + (1, 2) > + >>> d = Data(); d.content = (1,2,3); d.content > + (1, 2, 3) > + >>> d = Data(); d.content = [1,2,3]; d.content > + (1, 2, 3) > + >>> d = Data(); d.content = [1.5,.2,3.3]; d.content > + (1.5, 0.20000000000000001, 3.2999999999999998) > + ''' > + def fget(self): > + ''' > + Return the content of Data > + ''' > + return self.__content > + > + def fset(self, data): > + ''' > + Ensures that data is a valid tuple/list or a number (int, float > + or long) > + ''' > + # Type: None > + if data is None: > + self.__content = None > + return > + > + # Type: Int or Float > + elif type(data) in NUMTYPES: > + self.__content = data > + > + # Type: List or Tuple > + elif type(data) in LISTTYPES: > + # Ensures the correct size > + if len(data) not in (2, 3): > + raise TypeError, "Data (as list/tuple) must have 2 or 3 items" > + return > + > + # Ensures that all items in list/tuple is a number > + isnum = lambda x : type(x) not in NUMTYPES > + > + if max(map(isnum, data)): > + # An item in data isn't an int or a float > + raise TypeError, "All content of data must be a number (int or float)" > + > + # Convert the tuple to list > + if type(data) is list: > + data = tuple(data) > + > + # Append a copy and sets the type > + self.__content = data[:] > + > + # Unknown type! > + else: > + self.__content = None > + raise TypeError, "Data must be an int, float or a tuple with two or three items" > + return > + > + return property(**locals()) > + > + > + def clear(self): > + ''' > + Clear the all Data (content, name and parent) > + ''' > + self.content = None > + self.name = None > + self.parent = None > + > + def copy(self): > + ''' > + Returns a copy of the Data structure > + ''' > + # The copy > + new_data = Data() > + if self.content is not None: > + # If content is a point > + if type(self.content) is tuple: > + new_data.__content = self.content[:] > + > + # If content is a number > + else: > + new_data.__content = self.content > + > + # If it has a name > + if self.name is not None: > + new_data.__name = self.name > + > + return new_data > + > + def __str__(self): > + ''' > + Return a string representation of the Data structure > + ''' > + if self.name is None: > + if self.content is None: > + return '' > + return str(self.content) > + else: > + if self.content is None: > + return self.name+": ()" > + return self.name+": "+str(self.content) > + > + def __len__(self): > + ''' > + Return the length of the Data. > + - If it's a number return 1; > + - If it's a list return it's length; > + - If its None return 0. > + ''' > + if self.content is None: > + return 0 > + elif type(self.content) in NUMTYPES: > + return 1 > + return len(self.content) > + > + > + > + > +class Group(object): > + ''' > + Class that models a group of data. Every value (int, float, long, tuple > + or list) passed is converted to a list of Data. > + It can receive: > + - A single number (int, float, long); > + - A list of numbers; > + - A tuple of numbers; > + - An instance of Data; > + - A list of Data; > + > + Obs: If a tuple with 2 or 3 items is passed it is converted to a point. > + If a tuple with only 1 item is passed it's converted to a number; > + If a tuple with more than 2 items is passed it's converted to a > + list of numbers > + ''' > + def __init__(self, group=None, name=None, parent=None): > + ''' > + Starts main atributes in Group instance. > + @data_list - a list of data which forms the group; > + @range - a range that represent the x axis of possible functions; > + @name - name of the data group; > + @parent - the Serie parent of this group. > + > + Usage: > + >>> g = Group(13, 'simple number'); print g > + simple number ['13'] > + >>> g = Group((1,2), 'simple point'); print g > + simple point ['(1, 2)'] > + >>> g = Group([1,2,3,4], 'list of numbers'); print g > + list of numbers ['1', '2', '3', '4'] > + >>> g = Group((1,2,3,4),'int in tuple'); print g > + int in tuple ['1', '2', '3', '4'] > + >>> g = Group([(1,2),(2,3),(3,4)], 'list of points'); print g > + list of points ['(1, 2)', '(2, 3)', '(3, 4)'] > + >>> g = Group([[1,2,3],[1,2,3]], '2D coordinate lists'); print g > + 2D coordinated lists ['(1, 1)', '(2, 2)', '(3, 3)'] > + >>> g = Group([[1,2],[1,2],[1,2]], '3D coordinate lists'); print g > + 3D coordinated lists ['(1, 1, 1)', '(2, 2, 2)'] > + ''' > + # Initial values > + self.__data_list = [] > + self.__range = [] > + self.__name = None > + > + > + self.parent = parent > + self.name = name > + self.data_list = group > + > + # Name property > + @apply > + def name(): > + doc = ''' > + Name is a read/write property that controls the input of name. > + - If passed an invalid value it cleans the name with None > + > + Usage: > + >>> g = Group(13); g.name = 'name_test'; print g > + name_test ['13'] > + >>> g.name = 11; print g > + ['13'] > + >>> g.name = 'other_name'; print g > + other_name ['13'] > + >>> g.name = None; print g > + ['13'] > + >>> g.name = 'last_name'; print g > + last_name ['13'] > + >>> g.name = ''; print g > + ['13'] > + ''' > + def fget(self): > + ''' > + Returns the name as a string > + ''' > + return self.__name > + > + def fset(self, name): > + ''' > + Sets the name of the Group > + ''' > + if type(name) in STRTYPES and len(name) > 0: > + self.__name = name > + else: > + self.__name = None > + > + return property(**locals()) > + > + # data_list property > + @apply > + def data_list(): > + doc = ''' > + The data_list is a read/write property that can be a list of > + numbers, a list of points or a list of 2 or 3 coordinate lists. This > + property uses mainly the self.add_data method. > + > + Usage: > + >>> g = Group(); g.data_list = 13; print g > + ['13'] > + >>> g.data_list = (1,2); print g > + ['(1, 2)'] > + >>> g.data_list = Data((1,2),'point a'); print g > + ['point a: (1, 2)'] > + >>> g.data_list = [1,2,3]; print g > + ['1', '2', '3'] > + >>> g.data_list = (1,2,3,4); print g > + ['1', '2', '3', '4'] > + >>> g.data_list = [(1,2),(2,3),(3,4)]; print g > + ['(1, 2)', '(2, 3)', '(3, 4)'] > + >>> g.data_list = [[1,2],[1,2]]; print g > + ['(1, 1)', '(2, 2)'] > + >>> g.data_list = [[1,2],[1,2],[1,2]]; print g > + ['(1, 1, 1)', '(2, 2, 2)'] > + >>> g.range = (10); g.data_list = lambda x:x**2; print g > + ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 4.0)', '(3.0, 9.0)', '(4.0, 16.0)', '(5.0, 25.0)', '(6.0, 36.0)', '(7.0, 49.0)', '(8.0, 64.0)', '(9.0, 81.0)'] > + ''' > + def fget(self): > + ''' > + Returns the value of data_list > + ''' > + return self.__data_list > + > + def fset(self, group): > + ''' > + Ensures that group is valid. > + ''' > + # None > + if group is None: > + self.__data_list = [] > + > + # Int/float/long or Instance of Data > + elif type(group) in NUMTYPES or isinstance(group, Data): > + # Clean data_list > + self.__data_list = [] > + self.add_data(group) > + > + # One point > + elif type(group) is tuple and len(group) in (2,3): > + self.__data_list = [] > + self.add_data(group) > + > + # list of items > + elif type(group) in LISTTYPES and type(group[0]) is not list: > + # Clean data_list > + self.__data_list = [] > + for item in group: > + # try to append and catch an exception > + self.add_data(item) > + > + # function lambda > + elif callable(group): > + # Explicit is better than implicit > + function = group > + # Has range > + if len(self.range) is not 0: > + # Clean data_list > + self.__data_list = [] > + # Generate values for the lambda function > + for x in self.range: > + #self.add_data((x,round(group(x),2))) > + self.add_data((x,function(x))) > + > + # Only have range in parent > + elif self.parent is not None and len(self.parent.range) is not 0: > + # Copy parent range > + self.__range = self.parent.range[:] > + # Clean data_list > + self.__data_list = [] > + # Generate values for the lambda function > + for x in self.range: > + #self.add_data((x,round(group(x),2))) > + self.add_data((x,function(x))) > + > + # Don't have range anywhere > + else: > + # x_data don't exist > + raise Exception, "Data argument is valid but to use function type please set x_range first" > + > + # Coordinate Lists > + elif type(group) in LISTTYPES and type(group[0]) is list: > + # Clean data_list > + self.__data_list = [] > + data = [] > + if len(group) == 3: > + data = zip(group[0], group[1], group[2]) > + elif len(group) == 2: > + data = zip(group[0], group[1]) > + else: > + raise TypeError, "Only one list of coordinates was received." > + > + for item in data: > + self.add_data(item) > + > + else: > + raise TypeError, "Group type not supported" > + > + return property(**locals()) > + > + @apply > + def range(): > + doc = ''' > + The range is a read/write property that generates a range of values > + for the x axis of the functions. When passed a tuple it almost works > + like the built-in range funtion: > + - 1 item, represent the end of the range started from 0; > + - 2 items, represents the start and the end, respectively; > + - 3 items, the last one represents the step; > + > + When passed a list the range function understands as a valid range. > + > + Usage: > + >>> g = Group(); g.range = 10; print g.range > + [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] > + >>> g = Group(); g.range = (5); print g.range > + [0.0, 1.0, 2.0, 3.0, 4.0] > + >>> g = Group(); g.range = (1,7); print g.range > + [1.0, 2.0, 3.0, 4.0, 5.0, 6.0] > + >>> g = Group(); g.range = (0,10,2); print g.range > + [0.0, 2.0, 4.0, 6.0, 8.0] > + >>> > + >>> g = Group(); g.range = [0]; print g.range > + [0.0] > + >>> g = Group(); g.range = [0,10,20]; print g.range > + [0.0, 10.0, 20.0] > + ''' > + def fget(self): > + ''' > + Returns the range > + ''' > + return self.__range > + > + def fset(self, x_range): > + ''' > + Controls the input of a valid type and generate the range > + ''' > + # if passed a simple number convert to tuple > + if type(x_range) in NUMTYPES: > + x_range = (x_range,) > + > + # A list, just convert to float > + if type(x_range) is list and len(x_range) > 0: > + # Convert all to float > + x_range = map(float, x_range) > + # Prevents repeated values and convert back to list > + self.__range = list(set(x_range[:])) > + # Sort the list to ascending order > + self.__range.sort() > + > + # A tuple, must check the lengths and generate the values > + elif type(x_range) is tuple and len(x_range) in (1,2,3): > + # Convert all to float > + x_range = map(float, x_range) > + > + # Inital values > + start = 0.0 > + step = 1.0 > + end = 0.0 > + > + # Only the end and it can't be less or iqual to 0 > + if len(x_range) is 1 and x_range > 0: > + end = x_range[0] > + > + # The start and the end but the start must be less then the end > + elif len(x_range) is 2 and x_range[0] < x_range[1]: > + start = x_range[0] > + end = x_range[1] > + > + # All 3, but the start must be less then the end > + elif x_range[0] <= x_range[1]: > + start = x_range[0] > + end = x_range[1] > + step = x_range[2] > + > + # Starts the range > + self.__range = [] > + # Generate the range > + # Can't use the range function because it doesn't support float values > + while start < end: > + self.__range.append(start) > + start += step > + > + # Incorrect type > + else: > + raise Exception, "x_range must be a list with one or more items or a tuple with 2 or 3 items" > + > + return property(**locals()) > + > + def add_data(self, data, name=None): > + ''' > + Append a new data to the data_list. > + - If data is an instance of Data, append it > + - If it's an int, float, tuple or list create an instance of Data and append it > + > + Usage: > + >>> g = Group() > + >>> g.add_data(12); print g > + ['12'] > + >>> g.add_data(7,'other'); print g > + ['12', 'other: 7'] > + >>> > + >>> g = Group() > + >>> g.add_data((1,1),'a'); print g > + ['a: (1, 1)'] > + >>> g.add_data((2,2),'b'); print g > + ['a: (1, 1)', 'b: (2, 2)'] > + >>> > + >>> g.add_data(Data((1,2),'c')); print g > + ['a: (1, 1)', 'b: (2, 2)', 'c: (1, 2)'] > + ''' > + if not isinstance(data, Data): > + # Try to convert > + data = Data(data,name,self) > + > + if data.content is not None: > + self.__data_list.append(data.copy()) > + self.__data_list[-1].parent = self > + > + > + def to_list(self): > + ''' > + Returns the group as a list of numbers (int, float or long) or a > + list of tuples (points 2D or 3D). > + > + Usage: > + >>> g = Group([1,2,3,4],'g1'); g.to_list() > + [1, 2, 3, 4] > + >>> g = Group([(1,2),(2,3),(3,4)],'g2'); g.to_list() > + [(1, 2), (2, 3), (3, 4)] > + >>> g = Group([(1,2,3),(3,4,5)],'g2'); g.to_list() > + [(1, 2, 3), (3, 4, 5)] > + ''' > + return [data.content for data in self] > + > + def copy(self): > + ''' > + Returns a copy of this group > + ''' > + new_group = Group() > + new_group.__name = self.__name > + if self.__range is not None: > + new_group.__range = self.__range[:] > + for data in self: > + new_group.add_data(data.copy()) > + return new_group > + > + def get_names(self): > + ''' > + Return a list with the names of all data in this group > + ''' > + names = [] > + for data in self: > + if data.name is None: > + names.append('Data '+str(data.index()+1)) > + else: > + names.append(data.name) > + return names > + > + > + def __str__ (self): > + ''' > + Returns a string representing the Group > + ''' > + ret = "" > + if self.name is not None: > + ret += self.name + " " > + if len(self) > 0: > + list_str = [str(item) for item in self] > + ret += str(list_str) > + else: > + ret += "[]" > + return ret > + > + def __getitem__(self, key): > + ''' > + Makes a Group iterable, based in the data_list property > + ''' > + return self.data_list[key] > + > + def __len__(self): > + ''' > + Returns the length of the Group, based in the data_list property > + ''' > + return len(self.data_list) > + > + > +class Colors(object): > + ''' > + Class that models the colors its labels (names) and its properties, RGB > + and filling type. > + > + It can receive: > + - A list where each item is a list with 3 or 4 items. The > + first 3 items represent the RGB values and the last argument > + defines the filling type. The list will be converted to a dict > + and each color will receve a name based in its position in the > + list. > + - A dictionary where each key will be the color name and its item > + can be a list with 3 or 4 items. The first 3 items represent > + the RGB colors and the last argument defines the filling type. > + ''' > + def __init__(self, color_list=None): > + ''' > + Start the color_list property > + @ color_list - the list or dict contaning the colors properties. > + ''' > + self.__color_list = None > + > + self.color_list = color_list > + > + @apply > + def color_list(): > + doc = ''' > + >>> c = Colors([[1,1,1],[2,2,2,'linear'],[3,3,3,'gradient']]) > + >>> print c.color_list > + {'Color 2': [2, 2, 2, 'linear'], 'Color 3': [3, 3, 3, 'gradient'], 'Color 1': [1, 1, 1, 'solid']} > + >>> c.color_list = [[1,1,1],(2,2,2,'solid'),(3,3,3,'linear')] > + >>> print c.color_list > + {'Color 2': [2, 2, 2, 'solid'], 'Color 3': [3, 3, 3, 'linear'], 'Color 1': [1, 1, 1, 'solid']} > + >>> c.color_list = {'a':[1,1,1],'b':(2,2,2,'solid'),'c':(3,3,3,'linear'), 'd':(4,4,4)} > + >>> print c.color_list > + {'a': [1, 1, 1, 'solid'], 'c': [3, 3, 3, 'linear'], 'b': [2, 2, 2, 'solid'], 'd': [4, 4, 4, 'solid']} > + ''' > + def fget(self): > + ''' > + Return the color list > + ''' > + return self.__color_list > + > + def fset(self, color_list): > + ''' > + Format the color list to a dictionary > + ''' > + if color_list is None: > + self.__color_list = None > + return > + > + if type(color_list) in LISTTYPES and type(color_list[0]) in LISTTYPES: > + old_color_list = color_list[:] > + color_list = {} > + for index, color in enumerate(old_color_list): > + if len(color) is 3 and max(map(type, color)) in NUMTYPES: > + color_list['Color '+str(index+1)] = list(color)+[DEFAULT_COLOR_FILLING] > + elif len(color) is 4 and max(map(type, color[:-1])) in NUMTYPES and color[-1] in FILLING_TYPES: > + color_list['Color '+str(index+1)] = list(color) > + else: > + raise TypeError, "Unsuported color format" > + elif type(color_list) is not dict: > + raise TypeError, "Unsuported color format" > + > + for name, color in color_list.items(): > + if len(color) is 3: > + if max(map(type, color)) in NUMTYPES: > + color_list[name] = list(color)+[DEFAULT_COLOR_FILLING] > + else: > + raise TypeError, "Unsuported color format" > + elif len(color) is 4: > + if max(map(type, color[:-1])) in NUMTYPES and color[-1] in FILLING_TYPES: > + color_list[name] = list(color) > + else: > + raise TypeError, "Unsuported color format" > + self.__color_list = color_list.copy() > + > + return property(**locals()) > + > + > +class Series(object): > + ''' > + Class that models a Series (group of groups). Every value (int, float, > + long, tuple or list) passed is converted to a list of Group or Data. > + It can receive: > + - a single number or point, will be converted to a Group of one Data; > + - a list of numbers, will be converted to a group of numbers; > + - a list of tuples, will converted to a single Group of points; > + - a list of lists of numbers, each 'sublist' will be converted to a > + group of numbers; > + - a list of lists of tuples, each 'sublist' will be converted to a > + group of points; > + - a list of lists of lists, the content of the 'sublist' will be > + processed as coordinated lists and the result will be converted to > + a group of points; > + - a Dictionary where each item can be the same of the list: number, > + point, list of numbers, list of points or list of lists (coordinated > + lists); > + - an instance of Data; > + - an instance of group. > + ''' > + def __init__(self, series=None, name=None, property=[], colors=None): > + ''' > + Starts main atributes in Group instance. > + @series - a list, dict of data of which the series is composed; > + @name - name of the series; > + @property - a list/dict of properties to be used in the plots of > + this Series > + > + Usage: > + >>> print Series([1,2,3,4]) > + ["Group 1 ['1', '2', '3', '4']"] > + >>> print Series([[1,2,3],[4,5,6]]) > + ["Group 1 ['1', '2', '3']", "Group 2 ['4', '5', '6']"] > + >>> print Series((1,2)) > + ["Group 1 ['(1, 2)']"] > + >>> print Series([(1,2),(2,3)]) > + ["Group 1 ['(1, 2)', '(2, 3)']"] > + >>> print Series([[(1,2),(2,3)],[(4,5),(5,6)]]) > + ["Group 1 ['(1, 2)', '(2, 3)']", "Group 2 ['(4, 5)', '(5, 6)']"] > + >>> print Series([[[1,2,3],[1,2,3],[1,2,3]]]) > + ["Group 1 ['(1, 1, 1)', '(2, 2, 2)', '(3, 3, 3)']"] > + >>> print Series({'g1':[1,2,3], 'g2':[4,5,6]}) > + ["g1 ['1', '2', '3']", "g2 ['4', '5', '6']"] > + >>> print Series({'g1':[(1,2),(2,3)], 'g2':[(4,5),(5,6)]}) > + ["g1 ['(1, 2)', '(2, 3)']", "g2 ['(4, 5)', '(5, 6)']"] > + >>> print Series({'g1':[[1,2],[1,2]], 'g2':[[4,5],[4,5]]}) > + ["g1 ['(1, 1)', '(2, 2)']", "g2 ['(4, 4)', '(5, 5)']"] > + >>> print Series(Data(1,'d1')) > + ["Group 1 ['d1: 1']"] > + >>> print Series(Group([(1,2),(2,3)],'g1')) > + ["g1 ['(1, 2)', '(2, 3)']"] > + ''' > + # Intial values > + self.__group_list = [] > + self.__name = None > + self.__range = None > + > + # TODO: Implement colors with filling > + self.__colors = None > + > + self.name = name > + self.group_list = series > + self.colors = colors > + > + # Name property > + @apply > + def name(): > + doc = ''' > + Name is a read/write property that controls the input of name. > + - If passed an invalid value it cleans the name with None > + > + Usage: > + >>> s = Series(13); s.name = 'name_test'; print s > + name_test ["Group 1 ['13']"] > + >>> s.name = 11; print s > + ["Group 1 ['13']"] > + >>> s.name = 'other_name'; print s > + other_name ["Group 1 ['13']"] > + >>> s.name = None; print s > + ["Group 1 ['13']"] > + >>> s.name = 'last_name'; print s > + last_name ["Group 1 ['13']"] > + >>> s.name = ''; print s > + ["Group 1 ['13']"] > + ''' > + def fget(self): > + ''' > + Returns the name as a string > + ''' > + return self.__name > + > + def fset(self, name): > + ''' > + Sets the name of the Group > + ''' > + if type(name) in STRTYPES and len(name) > 0: > + self.__name = name > + else: > + self.__name = None > + > + return property(**locals()) > + > + > + > + # Colors property > + @apply > + def colors(): > + doc = ''' > + >>> s = Series() > + >>> s.colors = [[1,1,1],[2,2,2,'linear'],[3,3,3,'gradient']] > + >>> print s.colors > + {'Color 2': [2, 2, 2, 'linear'], 'Color 3': [3, 3, 3, 'gradient'], 'Color 1': [1, 1, 1, 'solid']} > + >>> s.colors = [[1,1,1],(2,2,2,'solid'),(3,3,3,'linear')] > + >>> print s.colors > + {'Color 2': [2, 2, 2, 'solid'], 'Color 3': [3, 3, 3, 'linear'], 'Color 1': [1, 1, 1, 'solid']} > + >>> s.colors = {'a':[1,1,1],'b':(2,2,2,'solid'),'c':(3,3,3,'linear'), 'd':(4,4,4)} > + >>> print s.colors > + {'a': [1, 1, 1, 'solid'], 'c': [3, 3, 3, 'linear'], 'b': [2, 2, 2, 'solid'], 'd': [4, 4, 4, 'solid']} > + ''' > + def fget(self): > + ''' > + Return the color list > + ''' > + return self.__colors.color_list > + > + def fset(self, colors): > + ''' > + Format the color list to a dictionary > + ''' > + self.__colors = Colors(colors) > + > + return property(**locals()) > + > + @apply > + def range(): > + doc = ''' > + The range is a read/write property that generates a range of values > + for the x axis of the functions. When passed a tuple it almost works > + like the built-in range funtion: > + - 1 item, represent the end of the range started from 0; > + - 2 items, represents the start and the end, respectively; > + - 3 items, the last one represents the step; > + > + When passed a list the range function understands as a valid range. > + > + Usage: > + >>> s = Series(); s.range = 10; print s.range > + [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0] > + >>> s = Series(); s.range = (5); print s.range > + [0.0, 1.0, 2.0, 3.0, 4.0, 5.0] > + >>> s = Series(); s.range = (1,7); print s.range > + [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] > + >>> s = Series(); s.range = (0,10,2); print s.range > + [0.0, 2.0, 4.0, 6.0, 8.0, 10.0] > + >>> > + >>> s = Series(); s.range = [0]; print s.range > + [0.0] > + >>> s = Series(); s.range = [0,10,20]; print s.range > + [0.0, 10.0, 20.0] > + ''' > + def fget(self): > + ''' > + Returns the range > + ''' > + return self.__range > + > + def fset(self, x_range): > + ''' > + Controls the input of a valid type and generate the range > + ''' > + # if passed a simple number convert to tuple > + if type(x_range) in NUMTYPES: > + x_range = (x_range,) > + > + # A list, just convert to float > + if type(x_range) is list and len(x_range) > 0: > + # Convert all to float > + x_range = map(float, x_range) > + # Prevents repeated values and convert back to list > + self.__range = list(set(x_range[:])) > + # Sort the list to ascending order > + self.__range.sort() > + > + # A tuple, must check the lengths and generate the values > + elif type(x_range) is tuple and len(x_range) in (1,2,3): > + # Convert all to float > + x_range = map(float, x_range) > + > + # Inital values > + start = 0.0 > + step = 1.0 > + end = 0.0 > + > + # Only the end and it can't be less or iqual to 0 > + if len(x_range) is 1 and x_range > 0: > + end = x_range[0] > + > + # The start and the end but the start must be lesser then the end > + elif len(x_range) is 2 and x_range[0] < x_range[1]: > + start = x_range[0] > + end = x_range[1] > + > + # All 3, but the start must be lesser then the end > + elif x_range[0] < x_range[1]: > + start = x_range[0] > + end = x_range[1] > + step = x_range[2] > + > + # Starts the range > + self.__range = [] > + # Generate the range > + # Cnat use the range function becouse it don't suport float values > + while start <= end: > + self.__range.append(start) > + start += step > + > + # Incorrect type > + else: > + raise Exception, "x_range must be a list with one or more item or a tuple with 2 or 3 items" > + > + return property(**locals()) > + > + @apply > + def group_list(): > + doc = ''' > + The group_list is a read/write property used to pre-process the list > + of Groups. > + It can be: > + - a single number, point or lambda, will be converted to a single > + Group of one Data; > + - a list of numbers, will be converted to a group of numbers; > + - a list of tuples, will converted to a single Group of points; > + - a list of lists of numbers, each 'sublist' will be converted to > + a group of numbers; > + - a list of lists of tuples, each 'sublist' will be converted to a > + group of points; > + - a list of lists of lists, the content of the 'sublist' will be > + processed as coordinated lists and the result will be converted > + to a group of points; > + - a list of lambdas, each lambda represents a Group; > + - a Dictionary where each item can be the same of the list: number, > + point, list of numbers, list of points, list of lists > + (coordinated lists) or lambdas > + - an instance of Data; > + - an instance of group. > + > + Usage: > + >>> s = Series() > + >>> s.group_list = [1,2,3,4]; print s > + ["Group 1 ['1', '2', '3', '4']"] > + >>> s.group_list = [[1,2,3],[4,5,6]]; print s > + ["Group 1 ['1', '2', '3']", "Group 2 ['4', '5', '6']"] > + >>> s.group_list = (1,2); print s > + ["Group 1 ['(1, 2)']"] > + >>> s.group_list = [(1,2),(2,3)]; print s > + ["Group 1 ['(1, 2)', '(2, 3)']"] > + >>> s.group_list = [[(1,2),(2,3)],[(4,5),(5,6)]]; print s > + ["Group 1 ['(1, 2)', '(2, 3)']", "Group 2 ['(4, 5)', '(5, 6)']"] > + >>> s.group_list = [[[1,2,3],[1,2,3],[1,2,3]]]; print s > + ["Group 1 ['(1, 1, 1)', '(2, 2, 2)', '(3, 3, 3)']"] > + >>> s.group_list = [(0.5,5.5) , [(0,4),(6,8)] , (5.5,7) , (7,9)]; print s > + ["Group 1 ['(0.5, 5.5)']", "Group 2 ['(0, 4)', '(6, 8)']", "Group 3 ['(5.5, 7)']", "Group 4 ['(7, 9)']"] > + >>> s.group_list = {'g1':[1,2,3], 'g2':[4,5,6]}; print s > + ["g1 ['1', '2', '3']", "g2 ['4', '5', '6']"] > + >>> s.group_list = {'g1':[(1,2),(2,3)], 'g2':[(4,5),(5,6)]}; print s > + ["g1 ['(1, 2)', '(2, 3)']", "g2 ['(4, 5)', '(5, 6)']"] > + >>> s.group_list = {'g1':[[1,2],[1,2]], 'g2':[[4,5],[4,5]]}; print s > + ["g1 ['(1, 1)', '(2, 2)']", "g2 ['(4, 4)', '(5, 5)']"] > + >>> s.range = 10 > + >>> s.group_list = lambda x:x*2 > + >>> s.group_list = [lambda x:x*2, lambda x:x**2, lambda x:x**3]; print s > + ["Group 1 ['(0.0, 0.0)', '(1.0, 2.0)', '(2.0, 4.0)', '(3.0, 6.0)', '(4.0, 8.0)', '(5.0, 10.0)', '(6.0, 12.0)', '(7.0, 14.0)', '(8.0, 16.0)', '(9.0, 18.0)', '(10.0, 20.0)']", "Group 2 ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 4.0)', '(3.0, 9.0)', '(4.0, 16.0)', '(5.0, 25.0)', '(6.0, 36.0)', '(7.0, 49.0)', '(8.0, 64.0)', '(9.0, 81.0)', '(10.0, 100.0)']", "Group 3 ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 8.0)', '(3.0, 27.0)', '(4.0, 64.0)', '(5.0, 125.0)', '(6.0, 216.0)', '(7.0, 343.0)', '(8.0, 512.0)', '(9.0, 729.0)', '(10.0, 1000.0)']"] > + >>> s.group_list = {'linear':lambda x:x*2, 'square':lambda x:x**2, 'cubic':lambda x:x**3}; print s > + ["cubic ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 8.0)', '(3.0, 27.0)', '(4.0, 64.0)', '(5.0, 125.0)', '(6.0, 216.0)', '(7.0, 343.0)', '(8.0, 512.0)', '(9.0, 729.0)', '(10.0, 1000.0)']", "linear ['(0.0, 0.0)', '(1.0, 2.0)', '(2.0, 4.0)', '(3.0, 6.0)', '(4.0, 8.0)', '(5.0, 10.0)', '(6.0, 12.0)', '(7.0, 14.0)', '(8.0, 16.0)', '(9.0, 18.0)', '(10.0, 20.0)']", "square ['(0.0, 0.0)', '(1.0, 1.0)', '(2.0, 4.0)', '(3.0, 9.0)', '(4.0, 16.0)', '(5.0, 25.0)', '(6.0, 36.0)', '(7.0, 49.0)', '(8.0, 64.0)', '(9.0, 81.0)', '(10.0, 100.0)']"] > + >>> s.group_list = Data(1,'d1'); print s > + ["Group 1 ['d1: 1']"] > + >>> s.group_list = Group([(1,2),(2,3)],'g1'); print s > + ["g1 ['(1, 2)', '(2, 3)']"] > + ''' > + def fget(self): > + ''' > + Return the group list. > + ''' > + return self.__group_list > + > + def fset(self, series): > + ''' > + Controls the input of a valid group list. > + ''' > + #TODO: Add support to the following strem of data: [ (0.5,5.5) , [(0,4),(6,8)] , (5.5,7) , (7,9)] > + > + # Type: None > + if series is None: > + self.__group_list = [] > + > + # List or Tuple > + elif type(series) in LISTTYPES: > + self.__group_list = [] > + > + is_function = lambda x: callable(x) > + # Groups > + if list in map(type, series) or max(map(is_function, series)): > + for group in series: > + self.add_group(group) > + > + # single group > + else: > + self.add_group(series) > + > + #old code > + ## List of numbers > + #if type(series[0]) in NUMTYPES or type(series[0]) is tuple: > + # print series > + # self.add_group(series) > + # > + ## List of anything else > + #else: > + # for group in series: > + # self.add_group(group) > + > + # Dict representing series of groups > + elif type(series) is dict: > + self.__group_list = [] > + names = series.keys() > + names.sort() > + for name in names: > + self.add_group(Group(series[name],name,self)) > + > + # A single lambda > + elif callable(series): > + self.__group_list = [] > + self.add_group(series) > + > + # Int/float, instance of Group or Data > + elif type(series) in NUMTYPES or isinstance(series, Group) or isinstance(series, Data): > + self.__group_list = [] > + self.add_group(series) > + > + # Default > + else: > + raise TypeError, "Serie type not supported" > + > + return property(**locals()) > + > + def add_group(self, group, name=None): > + ''' > + Append a new group in group_list > + ''' > + if not isinstance(group, Group): > + #Try to convert > + group = Group(group, name, self) > + > + if len(group.data_list) is not 0: > + # Auto naming groups > + if group.name is None: > + group.name = "Group "+str(len(self.__group_list)+1) > + > + self.__group_list.append(group) > + self.__group_list[-1].parent = self > + > + def copy(self): > + ''' > + Returns a copy of the Series > + ''' > + new_series = Series() > + new_series.__name = self.__name > + if self.__range is not None: > + new_series.__range = self.__range[:] > + #Add color property in the copy method > + #self.__colors = None > + > + for group in self: > + new_series.add_group(group.copy()) > + > + return new_series > + > + def get_names(self): > + ''' > + Returns a list of the names of all groups in the Serie > + ''' > + names = [] > + for group in self: > + if group.name is None: > + names.append('Group '+str(group.index()+1)) > + else: > + names.append(group.name) > + > + return names > + > + def to_list(self): > + ''' > + Returns a list with the content of all groups and data > + ''' > + big_list = [] > + for group in self: > + for data in group: > + if type(data.content) in NUMTYPES: > + big_list.append(data.content) > + else: > + big_list = big_list + list(data.content) > + return big_list > + > + def __getitem__(self, key): > + ''' > + Makes the Series iterable, based in the group_list property > + ''' > + return self.__group_list[key] > + > + def __str__(self): > + ''' > + Returns a string that represents the Series > + ''' > + ret = "" > + if self.name is not None: > + ret += self.name + " " > + if len(self) > 0: > + list_str = [str(item) for item in self] > + ret += str(list_str) > + else: > + ret += "[]" > + return ret > + > + def __len__(self): > + ''' > + Returns the length of the Series, based in the group_lsit property > + ''' > + return len(self.group_list) > + > + > +if __name__ == '__main__': > + doctest.testmod() > diff --git a/bindings/python/examples/python2/softirqtimes.py b/bindings/python/examples/python2/softirqtimes.py > new file mode 100755 > index 0000000..59905c1 > --- /dev/null > +++ b/bindings/python/examples/python2/softirqtimes.py > @@ -0,0 +1,154 @@ > +#!/usr/bin/env python2 > +# softirqtimes.py > +# > +# Babeltrace time of softirqs example script > +# > +# Copyright 2012 EfficiOS Inc. > +# > +# Author: Danny Serres > +# > +# Permission is hereby granted, free of charge, to any person obtaining a copy > +# of this software and associated documentation files (the "Software"), to deal > +# in the Software without restriction, including without limitation the rights > +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > +# copies of the Software, and to permit persons to whom the Software is > +# furnished to do so, subject to the following conditions: > +# > +# The above copyright notice and this permission notice shall be included in > +# all copies or substantial portions of the Software. > + > +# The script checks the number of events in the trace > +# and outputs a table and a .svg histogram for the specified > +# range (microseconds) or the total trace if no range specified. > +# The graph is generated using the cairoplot module. > + > +# The script checks the trace for the amount of time > +# spent from each softirq_raise to softirq_exit. > +# It prints out the min, max (with timestamp), > +# average times, the standard deviation and the total count. > +# Using the cairoplot module, a .svg graph is also outputted > +# showing the taken time in function of the time since the > +# beginning of the trace. > + > +import sys, math > +from output_format_modules import cairoplot > +from babeltrace import * > + > +if len(sys.argv) < 2: > + raise TypeError("Usage: python softirqtimes.py path/to/trace") > + > +ctx = Context() > +ret = ctx.add_trace(sys.argv[1], "ctf") > +if ret is None: > + raise IOError("Error adding trace") > + > +time_taken = [] > +graph_data = [] > +max_time = (0.0, 0.0) # (val, ts) > + > +# tmp template: {(cpu_id, vec):TS raise} > +tmp = {} > +largest_val = 0 > + > +# Setting iterator > +bp = IterPos(SEEK_BEGIN) > +ctf_it = ctf.Iterator(ctx, bp) > + > +# Reading events > +event = ctf_it.read_event() > +start_time = event.get_timestamp() > +while(event is not None): > + > + event_name = event.get_name() > + error = True > + appendNext = False > + > + if event_name == 'softirq_raise' or event_name == 'softirq_exit': > + # Recover cpu_id and vec values to make a key to tmp > + error = False > + scope = event.get_top_level_scope(ctf.scope.STREAM_PACKET_CONTEXT) > + field = event.get_field(scope, "cpu_id") > + cpu_id = field.get_uint64() > + if ctf.field_error(): > + print("ERROR: Missing cpu_id info for {}".format( > + event.get_name())) > + error = True > + > + scope = event.get_top_level_scope(ctf.scope.EVENT_FIELDS) > + field = event.get_field(scope, "_vec") > + vec = field.get_uint64() > + if ctf.field_error(): > + print("ERROR: Missing vec info for {}".format( > + event.get_name())) > + error = True > + key = (cpu_id, vec) > + > + if event_name == 'softirq_raise' and not error: > + # Add timestamp to tmp > + if key in tmp: > + # If key already exists > + i = 0 > + while True: > + # Add index > + key = (cpu_id, vec, i) > + if key in tmp: > + i += 1 > + continue > + if i > largest_val: > + largest_val = i > + break > + > + tmp[key] = event.get_timestamp() > + > + if event_name == 'softirq_exit' and not error: > + # Saving data for output > + # Key check > + if not (key in tmp): > + i = 0 > + while i <= largest_val: > + key = (key[0], key[1], i) > + if key in tmp: > + break > + i += 1 > + > + raise_timestamp = tmp[key] > + time_data = event.get_timestamp() - tmp.pop(key) > + if time_data > max_time[0]: > + # max_time = (val, ts) > + max_time = (time_data, raise_timestamp) > + time_taken.append(time_data) > + graph_data.append((raise_timestamp - start_time, time_data)) > + > + # Next Event > + ret = ctf_it.next() > + if ret < 0: > + break > + event = ctf_it.read_event() > + > + > +del ctf_it > + > +# Standard dev. calc. > +try: > + mean = sum(time_taken)/float(len(time_taken)) > +except ZeroDivisionError: > + raise TypeError("empty data") > +deviations_squared = [] > +for x in time_taken: > + deviations_squared.append(math.pow((x - mean), 2)) > +try: > + stddev = math.sqrt(sum(deviations_squared) / (len(deviations_squared) - 1)) > +except ZeroDivisionError: > + stddev = '-' > + > +# Terminal output > +print("AVG TIME: {} ns".format(mean)) > +print("MIN TIME: {} ns".format(min(time_taken))) > +print("MAX TIME: {} ns, TS: {}".format(max_time[0], max_time[1])) > +print("STD DEV: {}".format(stddev)) > +print("TOTAL COUNT: {}".format(len(time_taken))) > + > +# Graph output > +cairoplot.scatter_plot ( 'softirqtimes.svg', data = graph_data, > + width = 5000, height = 4000, border = 20, axis = True, > + grid = True, series_colors = ["red"] ) > diff --git a/bindings/python/examples/python2/syscalls_by_pid.py b/bindings/python/examples/python2/syscalls_by_pid.py > new file mode 100755 > index 0000000..cf1d581 > --- /dev/null > +++ b/bindings/python/examples/python2/syscalls_by_pid.py > @@ -0,0 +1,85 @@ > +#!/usr/bin/env python2 > +# syscall_by_pid.py > +# > +# Babeltrace syscall by pid example script > +# > +# Copyright 2012 EfficiOS Inc. > +# > +# Author: Danny Serres > +# > +# Permission is hereby granted, free of charge, to any person obtaining a copy > +# of this software and associated documentation files (the "Software"), to deal > +# in the Software without restriction, including without limitation the rights > +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > +# copies of the Software, and to permit persons to whom the Software is > +# furnished to do so, subject to the following conditions: > +# > +# The above copyright notice and this permission notice shall be included in > +# all copies or substantial portions of the Software. > + > +# The script checks the number of events in the trace > +# and outputs a table and a .svg histogram for the specified > +# range (microseconds) or the total trace if no range specified. > +# The graph is generated using the cairoplot module. > + > +# The script checks all syscall in the trace and prints a list > +# showing the number of systemcalls executed by each PID > +# ordered from greatest to least number of syscalls. > +# The trace needs PID context (lttng add-context -k -t pid) > + > +import sys > +from babeltrace import * > +from output_format_modules.pprint_table import pprint_table as pprint > + > +if len(sys.argv) < 2 : > + raise TypeError("Usage: python syscalls_by_pid.py path/to/trace") > + > +ctx = Context() > +ret = ctx.add_trace(sys.argv[1], "ctf") > +if ret is None: > + raise IOError("Error adding trace") > + > +data = {} > + > +# Setting iterator > +bp = IterPos(SEEK_BEGIN) > +ctf_it = ctf.Iterator(ctx, bp) > + > +# Reading events > +event = ctf_it.read_event() > +while event is not None: > + if event.get_name().find("sys") >= 0: > + # Getting scope definition > + sco = event.get_top_level_scope(ctf.scope.STREAM_EVENT_CONTEXT) > + if sco is None: > + print("ERROR: Cannot get definition scope for {}".format( > + event.get_name())) > + else: > + # Getting PID > + pid_field = event.get_field(sco, "_pid") > + pid = pid_field.get_int64() > + > + if ctf.field_error(): > + print("ERROR: Missing PID info for sched_switch".format( > + event.get_name())) > + elif pid in data: > + data[pid] += 1 > + else: > + data[pid] = 1 > + # Next event > + ret = ctf_it.next() > + if ret < 0: > + break > + event = ctf_it.read_event() > + > +del ctf_it > + > +# Setting table for output > +table = [] > +for item in data: > + table.append([data[item], item]) # [count, pid] > +table.sort(reverse = True) # [big count first, pid] > +for i in range(len(table)): > + table[i].reverse() # [pid, big count first] > +table.insert(0, ["PID", "SYSCALL COUNT"]) > +pprint(table) > diff --git a/bindings/python/examples/sched_switch.py b/bindings/python/examples/sched_switch.py > old mode 100644 > new mode 100755 > index 7ae834b..d5ed25b > --- a/bindings/python/examples/sched_switch.py > +++ b/bindings/python/examples/sched_switch.py > @@ -1,18 +1,19 @@ > +#!/usr/bin/env python3 > # sched_switch.py > -# > +# > # Babeltrace example script with sched_switch events > -# > +# > # Copyright 2012 EfficiOS Inc. > -# > +# > # Author: Danny Serres > -# > +# > # Permission is hereby granted, free of charge, to any person obtaining a copy > # of this software and associated documentation files (the "Software"), to deal > # in the Software without restriction, including without limitation the rights > # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > # copies of the Software, and to permit persons to whom the Software is > # furnished to do so, subject to the following conditions: > -# > +# > # The above copyright notice and this permission notice shall be included in > # all copies or substantial portions of the Software. > > diff --git a/bindings/python/examples/softirqtimes.py b/bindings/python/examples/softirqtimes.py > deleted file mode 100644 > index 903bf3e..0000000 > --- a/bindings/python/examples/softirqtimes.py > +++ /dev/null > @@ -1,153 +0,0 @@ > -# softirqtimes.py > -# > -# Babeltrace time of softirqs example script > -# > -# Copyright 2012 EfficiOS Inc. > -# > -# Author: Danny Serres > -# > -# Permission is hereby granted, free of charge, to any person obtaining a copy > -# of this software and associated documentation files (the "Software"), to deal > -# in the Software without restriction, including without limitation the rights > -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > -# copies of the Software, and to permit persons to whom the Software is > -# furnished to do so, subject to the following conditions: > -# > -# The above copyright notice and this permission notice shall be included in > -# all copies or substantial portions of the Software. > - > -# The script checks the number of events in the trace > -# and outputs a table and a .svg histogram for the specified > -# range (microseconds) or the total trace if no range specified. > -# The graph is generated using the cairoplot module. > - > -# The script checks the trace for the amount of time > -# spent from each softirq_raise to softirq_exit. > -# It prints out the min, max (with timestamp), > -# average times, the standard deviation and the total count. > -# Using the cairoplot module, a .svg graph is also outputted > -# showing the taken time in function of the time since the > -# beginning of the trace. > - > -import sys, math > -from output_format_modules import cairoplot > -from babeltrace import * > - > -if len(sys.argv) < 2: > - raise TypeError("Usage: python softirqtimes.py path/to/trace") > - > -ctx = Context() > -ret = ctx.add_trace(sys.argv[1], "ctf") > -if ret is None: > - raise IOError("Error adding trace") > - > -time_taken = [] > -graph_data = [] > -max_time = (0.0, 0.0) # (val, ts) > - > -# tmp template: {(cpu_id, vec):TS raise} > -tmp = {} > -largest_val = 0 > - > -# Setting iterator > -bp = IterPos(SEEK_BEGIN) > -ctf_it = ctf.Iterator(ctx, bp) > - > -# Reading events > -event = ctf_it.read_event() > -start_time = event.get_timestamp() > -while(event is not None): > - > - event_name = event.get_name() > - error = True > - appendNext = False > - > - if event_name == 'softirq_raise' or event_name == 'softirq_exit': > - # Recover cpu_id and vec values to make a key to tmp > - error = False > - scope = event.get_top_level_scope(ctf.scope.STREAM_PACKET_CONTEXT) > - field = event.get_field(scope, "cpu_id") > - cpu_id = field.get_uint64() > - if ctf.field_error(): > - print("ERROR: Missing cpu_id info for {}".format( > - event.get_name())) > - error = True > - > - scope = event.get_top_level_scope(ctf.scope.EVENT_FIELDS) > - field = event.get_field(scope, "_vec") > - vec = field.get_uint64() > - if ctf.field_error(): > - print("ERROR: Missing vec info for {}".format( > - event.get_name())) > - error = True > - key = (cpu_id, vec) > - > - if event_name == 'softirq_raise' and not error: > - # Add timestamp to tmp > - if key in tmp: > - # If key already exists > - i = 0 > - while True: > - # Add index > - key = (cpu_id, vec, i) > - if key in tmp: > - i += 1 > - continue > - if i > largest_val: > - largest_val = i > - break > - > - tmp[key] = event.get_timestamp() > - > - if event_name == 'softirq_exit' and not error: > - # Saving data for output > - # Key check > - if not (key in tmp): > - i = 0 > - while i <= largest_val: > - key = (key[0], key[1], i) > - if key in tmp: > - break > - i += 1 > - > - raise_timestamp = tmp[key] > - time_data = event.get_timestamp() - tmp.pop(key) > - if time_data > max_time[0]: > - # max_time = (val, ts) > - max_time = (time_data, raise_timestamp) > - time_taken.append(time_data) > - graph_data.append((raise_timestamp - start_time, time_data)) > - > - # Next Event > - ret = ctf_it.next() > - if ret < 0: > - break > - event = ctf_it.read_event() > - > - > -del ctf_it > - > -# Standard dev. calc. > -try: > - mean = sum(time_taken)/float(len(time_taken)) > -except ZeroDivisionError: > - raise TypeError("empty data") > -deviations_squared = [] > -for x in time_taken: > - deviations_squared.append(math.pow((x - mean), 2)) > -try: > - stddev = math.sqrt(sum(deviations_squared) / (len(deviations_squared) - 1)) > -except ZeroDivisionError: > - stddev = '-' > - > -# Terminal output > -print("AVG TIME: {} ns".format(mean)) > -print("MIN TIME: {} ns".format(min(time_taken))) > -print("MAX TIME: {} ns, TS: {}".format(max_time[0], max_time[1])) > -print("STD DEV: {}".format(stddev)) > -print("TOTAL COUNT: {}".format(len(time_taken))) > - > -# Graph output > -cairoplot.scatter_plot ( 'softirqtimes.svg', data = graph_data, > - width = 5000, height = 4000, border = 20, axis = True, > - grid = True, series_colors = ["red"] ) > diff --git a/bindings/python/examples/syscalls_by_pid.py b/bindings/python/examples/syscalls_by_pid.py > deleted file mode 100644 > index 3ae342e..0000000 > --- a/bindings/python/examples/syscalls_by_pid.py > +++ /dev/null > @@ -1,84 +0,0 @@ > -# syscall_by_pid.py > -# > -# Babeltrace syscall by pid example script > -# > -# Copyright 2012 EfficiOS Inc. > -# > -# Author: Danny Serres > -# > -# Permission is hereby granted, free of charge, to any person obtaining a copy > -# of this software and associated documentation files (the "Software"), to deal > -# in the Software without restriction, including without limitation the rights > -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > -# copies of the Software, and to permit persons to whom the Software is > -# furnished to do so, subject to the following conditions: > -# > -# The above copyright notice and this permission notice shall be included in > -# all copies or substantial portions of the Software. > - > -# The script checks the number of events in the trace > -# and outputs a table and a .svg histogram for the specified > -# range (microseconds) or the total trace if no range specified. > -# The graph is generated using the cairoplot module. > - > -# The script checks all syscall in the trace and prints a list > -# showing the number of systemcalls executed by each PID > -# ordered from greatest to least number of syscalls. > -# The trace needs PID context (lttng add-context -k -t pid) > - > -import sys > -from babeltrace import * > -from output_format_modules.pprint_table import pprint_table as pprint > - > -if len(sys.argv) < 2 : > - raise TypeError("Usage: python syscalls_by_pid.py path/to/trace") > - > -ctx = Context() > -ret = ctx.add_trace(sys.argv[1], "ctf") > -if ret is None: > - raise IOError("Error adding trace") > - > -data = {} > - > -# Setting iterator > -bp = IterPos(SEEK_BEGIN) > -ctf_it = ctf.Iterator(ctx, bp) > - > -# Reading events > -event = ctf_it.read_event() > -while event is not None: > - if event.get_name().find("sys") >= 0: > - # Getting scope definition > - sco = event.get_top_level_scope(ctf.scope.STREAM_EVENT_CONTEXT) > - if sco is None: > - print("ERROR: Cannot get definition scope for {}".format( > - event.get_name())) > - else: > - # Getting PID > - pid_field = event.get_field(sco, "_pid") > - pid = pid_field.get_int64() > - > - if ctf.field_error(): > - print("ERROR: Missing PID info for sched_switch".format( > - event.get_name())) > - elif pid in data: > - data[pid] += 1 > - else: > - data[pid] = 1 > - # Next event > - ret = ctf_it.next() > - if ret < 0: > - break > - event = ctf_it.read_event() > - > -del ctf_it > - > -# Setting table for output > -table = [] > -for item in data: > - table.append([data[item], item]) # [count, pid] > -table.sort(reverse = True) # [big count first, pid] > -for i in range(len(table)): > - table[i].reverse() # [pid, big count first] > -table.insert(0, ["PID", "SYSCALL COUNT"]) > -pprint(table) > diff --git a/tests/tests-python.py b/tests/tests-python.py > old mode 100644 > new mode 100755 > index 0bd71c2..8695f61 > --- a/tests/tests-python.py > +++ b/tests/tests-python.py > @@ -1,3 +1,4 @@ > +#!/usr/bin/env python3 > import unittest > import sys > from babeltrace import * > -- > 1.8.1.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com From francis.giraldeau at gmail.com Thu Jan 31 14:31:16 2013 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Thu, 31 Jan 2013 14:31:16 -0500 Subject: [lttng-dev] [RELEASE] Workload-kit 0.1.10 Message-ID: Workload-kit is a set of utilities to generate various kind of workloads on a system, aimed at generating traces that presents recognizable features. The generated trace set could be used as a basis to validate trace analysis algorithms. Workload-kit makes it easy to generate the trace set on any architecture in a reproducible way. Changelog: 2013-01-31 Workload-kit 0.1.10 * Fix temp directory cleanup * Modified do_hog function to be closer to the behaviour of the counter function * Add trace scripts to existing executables * Add missing heartbeat script * Add precision about zombie state * Utility to show reparenting a process to init * Synchronisation test cases The traceset has been generated with the following configuration: * LTTng master * Linux 3.7 * Includes lttng-modules addons Sources: http://secretaire.dorsal.polymtl.ca/~fgiraldeau/workload-kit/ Traceset: http://secretaire.dorsal.polymtl.ca/~fgiraldeau/traceset/ Git repo: https://github.com/giraldeau/workload-kit -------------- next part -------------- An HTML attachment was scrubbed... URL: