All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-help] real time task disapears... memory problem ?
@ 2007-06-06 11:59 DESVAGES Arnaud
  2007-06-06 12:25 ` Jan Kiszka
  0 siblings, 1 reply; 33+ messages in thread
From: DESVAGES Arnaud @ 2007-06-06 11:59 UTC (permalink / raw)
  To: xenomai

[-- Attachment #1: Type: text/plain, Size: 1545 bytes --]

Hello,

 

I'm currently working on feedback scheduling. I have a set of tasks : an MPC
controller, a feedback scheduler, and some disturbance tasks.

 

To do feedback scheduling, I need to measure the execution time quite
accurately, and xenomai can not measure the execution time spend in the
secondary mode. So I'm trying to stay in the primary mode. I had some calloc
and free in one function that made me leave primary mode (for the MPC task).

 

I tried to replace this by a rt_heap, and doing rt_heap_alloc in place of
calloc, and I also tried to have static allocation.

 

 

In both cases, my MPC task disappears when executing it! (nothing in
/proc/xenomai/stat after the first try to execute it, but present during
initialisation. and the other tasks are still here).

 

I'm working on it for a few days now, and I can't find out what is wrong. I
have tested to increase the maximum locked-in-memory size (in
/etc/security/limits.conf). If I debug it with ddd, all is ok, array are
well allocated...

 

The strangest thing is that if I put a printf (this make a switch to
secondary mode) saying that heap allocation was successful, everything works
fine. So there is a function call that kills my task if I am in primary
mode, and executes well if I am in secondary mode?

 

 

Do you have any idea on where may be the mistake? Do you need some more
information?

 

 

My config: Linux 2.6.17-x320 preempt

 

 

Thanks in advance,

 

 

Arnaud DESVAGES

 


[-- Attachment #2: Type: text/html, Size: 5776 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-help] real time task disapears... memory problem ?
  2007-06-06 11:59 DESVAGES Arnaud
@ 2007-06-06 12:25 ` Jan Kiszka
  0 siblings, 0 replies; 33+ messages in thread
From: Jan Kiszka @ 2007-06-06 12:25 UTC (permalink / raw)
  To: DESVAGES Arnaud; +Cc: xenomai

[-- Attachment #1: Type: text/plain, Size: 2117 bytes --]

DESVAGES Arnaud wrote:
> Hello,
> 
>  
> 
> I'm currently working on feedback scheduling. I have a set of tasks : an MPC
> controller, a feedback scheduler, and some disturbance tasks.
> 
>  
> 
> To do feedback scheduling, I need to measure the execution time quite
> accurately, and xenomai can not measure the execution time spend in the
> secondary mode.

What kind of statistics would you precisely need? And where would you
need it, means where is your scheduler located, what API does it use?

> So I'm trying to stay in the primary mode. I had some calloc
> and free in one function that made me leave primary mode (for the MPC task).
> 
>  
> 
> I tried to replace this by a rt_heap, and doing rt_heap_alloc in place of
> calloc, and I also tried to have static allocation.
> 
>  
> 
>  
> 
> In both cases, my MPC task disappears when executing it! (nothing in
> /proc/xenomai/stat after the first try to execute it, but present during
> initialisation. and the other tasks are still here).
> 
>  
> 
> I'm working on it for a few days now, and I can't find out what is wrong. I
> have tested to increase the maximum locked-in-memory size (in
> /etc/security/limits.conf). If I debug it with ddd, all is ok, array are
> well allocated...
> 
>  
> 
> The strangest thing is that if I put a printf (this make a switch to
> secondary mode) saying that heap allocation was successful, everything works
> fine. So there is a function call that kills my task if I am in primary
> mode, and executes well if I am in secondary mode?
> 
>  
> 
>  
> 
> Do you have any idea on where may be the mistake? Do you need some more
> information?
> 

Primarily code. We need your code that demonstrates the weird behaviour.
If you patched Xenomai in any way, that patch would be required as well
of course.

BTW, did you already try to attach gdb to your disappearing process?
Maybe it can catch what makes it terminate.

>  
> 
>  
> 
> My config: Linux 2.6.17-x320 preempt
> 

.config, Xenomai version, and I-pipe version can be helpful too.

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-help] real time task disapears... memory problem ?
@ 2007-06-07 16:23 desvages
  2007-06-07 17:44 ` Jan Kiszka
  0 siblings, 1 reply; 33+ messages in thread
From: desvages @ 2007-06-07 16:23 UTC (permalink / raw)
  To: jan.kiszka; +Cc: xenomai

[-- Attachment #1: Type: text/plain, Size: 1502 bytes --]

> What kind of statistics would you precisely need? And where would you
> need it, means where is your scheduler located, what API does it use?

I need execution time (and not response time). A patch for this has been
create by a former student (now Doctor David Robert) working before me.
You can find it enclosed with this mail. Anyway the problem doesn't come
from this patch, it appears also with vanilla xenomai.

> Primarily code. We need your code that demonstrates the weird behaviour.
> If you patched Xenomai in any way, that patch would be required as well
> of course.

I have reduced the size of the code to the thing that is not working. You
can find it enclosed.
The main program creates a task that calls the gsl_qp function (a
quadratic solver).
The problem appends during the call of ql0001_. If I remove this call, it
works. I if keep it, the task disapears without any error (I only see that
in /proc/xenomai/stat ).

> BTW, did you already try to attach gdb to your disappearing process?
> Maybe it can catch what makes it terminate.
I have tried without success, but I don really know how to use it in that
way...

My config: (I have install the last availlable xenomai since last mail)
- Linux kernel : 2.6.20.3
- xenomai : 2.3.1
- Adeos : 1.7-03
- Laptop compact Evo N600c Pentium 3M 1.2Ghz

> .config, Xenomai version, and I-pipe version can be helpful too.
.config is enclosed (DentiX231)


> Jan

Thanks for your help

Arnaud DESVAGES

[-- Attachment #2: DentiX231 --]
[-- Type: application/octet-stream, Size: 49463 bytes --]

#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20.3-x231
# Thu Jun  7 11:58:12 2007
#
CONFIG_X86_32=y
CONFIG_GENERIC_TIME=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_SEMAPHORE_SLEEPERS=y
CONFIG_X86=y
CONFIG_MMU=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_DMI=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"

#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32

#
# General setup
#
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_IPC_NS is not set
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_UTS_NS is not set
CONFIG_AUDIT=y
CONFIG_AUDITSYSCALL=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_EXTRA_PASS=y
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set

#
# Loadable module support
#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_KMOD=y

#
# Block layer
#
CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
CONFIG_LSF=y

#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=m
CONFIG_IOSCHED_DEADLINE=m
CONFIG_IOSCHED_CFQ=m
# CONFIG_DEFAULT_AS is not set
# CONFIG_DEFAULT_DEADLINE is not set
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"

#
# Real-time sub-system
#
CONFIG_XENOMAI=y
CONFIG_XENO_OPT_NUCLEUS=m
CONFIG_XENO_OPT_PERVASIVE=y
CONFIG_XENO_OPT_ISHIELD=y
CONFIG_XENO_OPT_RPIDISABLE=y
CONFIG_XENO_OPT_SECURITY_ACCESS=y
CONFIG_XENO_OPT_PIPELINE_HEAD=y
CONFIG_XENO_OPT_PIPE=y
CONFIG_XENO_OPT_PIPE_NRDEV=32
CONFIG_XENO_OPT_REGISTRY=y
CONFIG_XENO_OPT_REGISTRY_NRSLOTS=512
CONFIG_XENO_OPT_SYS_HEAPSZ=128
CONFIG_XENO_OPT_STATS=y
CONFIG_XENO_OPT_DEBUG=y
# CONFIG_XENO_OPT_DEBUG_NUCLEUS is not set
# CONFIG_XENO_OPT_DEBUG_QUEUES is not set
CONFIG_XENO_OPT_WATCHDOG=y

#
# Timing
#
# CONFIG_XENO_OPT_TIMING_PERIODIC is not set
CONFIG_XENO_OPT_TIMING_PERIOD=0
CONFIG_XENO_OPT_TIMING_TIMERLAT=0
CONFIG_XENO_OPT_TIMING_SCHEDLAT=0

#
# Scalability
#
# CONFIG_XENO_OPT_SCALABLE_SCHED is not set
CONFIG_XENO_OPT_TIMER_LIST=y
# CONFIG_XENO_OPT_TIMER_HEAP is not set
# CONFIG_XENO_OPT_TIMER_WHEEL is not set

#
# Shared interrupts
#
CONFIG_XENO_OPT_SHIRQ_LEVEL=y
CONFIG_XENO_OPT_SHIRQ_EDGE=y

#
# Machine
#
CONFIG_XENO_HW_FPU=y

#
# NMI watchdog
#
# CONFIG_XENO_HW_NMI_DEBUG_LATENCY is not set

#
# SMI workaround
#
# CONFIG_XENO_HW_SMI_DETECT_DISABLE is not set
CONFIG_XENO_HW_SMI_DETECT=y
CONFIG_XENO_HW_SMI_WORKAROUND=y
CONFIG_XENO_HW_SMI_ALL=y

#
# Interfaces
#
CONFIG_XENO_SKIN_NATIVE=m
CONFIG_XENO_OPT_NATIVE_PIPE=y
CONFIG_XENO_OPT_NATIVE_PIPE_BUFSZ=4096
CONFIG_XENO_OPT_NATIVE_REGISTRY=y
CONFIG_XENO_OPT_NATIVE_SEM=y
CONFIG_XENO_OPT_NATIVE_EVENT=y
CONFIG_XENO_OPT_NATIVE_MUTEX=y
CONFIG_XENO_OPT_NATIVE_COND=y
CONFIG_XENO_OPT_NATIVE_QUEUE=y
CONFIG_XENO_OPT_NATIVE_HEAP=y
CONFIG_XENO_OPT_NATIVE_ALARM=y
CONFIG_XENO_OPT_NATIVE_MPS=y
CONFIG_XENO_OPT_NATIVE_INTR=y
CONFIG_XENO_SKIN_POSIX=m
CONFIG_XENO_OPT_POSIX_SHM=y
CONFIG_XENO_OPT_POSIX_INTR=y
CONFIG_XENO_OPT_DEBUG_POSIX=y
# CONFIG_XENO_SKIN_PSOS is not set
# CONFIG_XENO_SKIN_UITRON is not set
# CONFIG_XENO_SKIN_VRTX is not set
# CONFIG_XENO_SKIN_VXWORKS is not set
# CONFIG_XENO_SKIN_RTAI is not set
CONFIG_XENO_SKIN_RTDM=m
CONFIG_XENO_OPT_RTDM_FILDES=128
CONFIG_XENO_OPT_DEBUG_RTDM=y

#
# Drivers
#

#
# Serial drivers
#
CONFIG_XENO_DRIVERS_16550A=m

#
# Testing drivers
#
CONFIG_XENO_DRIVERS_TIMERBENCH=m
CONFIG_XENO_DRIVERS_IRQBENCH=m
CONFIG_XENO_DRIVERS_SWITCHTEST=m

#
# CAN drivers
#
# CONFIG_XENO_DRIVERS_CAN is not set

#
# Processor type and features
#
# CONFIG_SMP is not set
CONFIG_X86_PC=y
# CONFIG_X86_ELAN is not set
# CONFIG_X86_VOYAGER is not set
# CONFIG_X86_NUMAQ is not set
# CONFIG_X86_SUMMIT is not set
# CONFIG_X86_BIGSMP is not set
# CONFIG_X86_VISWS is not set
# CONFIG_X86_GENERICARCH is not set
# CONFIG_X86_ES7000 is not set
# CONFIG_PARAVIRT is not set
# CONFIG_M386 is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
# CONFIG_M686 is not set
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
CONFIG_MPENTIUMM=y
# CONFIG_MCORE2 is not set
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MCRUSOE is not set
# CONFIG_MEFFICEON is not set
# CONFIG_MWINCHIPC6 is not set
# CONFIG_MWINCHIP2 is not set
# CONFIG_MWINCHIP3D is not set
# CONFIG_MGEODEGX1 is not set
# CONFIG_MGEODE_LX is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
CONFIG_X86_GENERIC=y
CONFIG_X86_CMPXCHG=y
CONFIG_X86_XADD=y
CONFIG_X86_L1_CACHE_SHIFT=7
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
CONFIG_X86_BSWAP=y
CONFIG_X86_POPAD_OK=y
CONFIG_X86_CMPXCHG64=y
CONFIG_X86_GOOD_APIC=y
CONFIG_X86_INTEL_USERCOPY=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
CONFIG_X86_TSC=y
CONFIG_HPET_TIMER=y
# CONFIG_PREEMPT_NONE is not set
# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
CONFIG_PREEMPT_BKL=y
CONFIG_IPIPE=y
CONFIG_X86_UP_APIC=y
CONFIG_X86_UP_IOAPIC=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
CONFIG_X86_MCE=y
# CONFIG_X86_MCE_NONFATAL is not set
# CONFIG_X86_MCE_P4THERMAL is not set
CONFIG_VM86=y
# CONFIG_TOSHIBA is not set
# CONFIG_I8K is not set
# CONFIG_X86_REBOOTFIXUPS is not set
CONFIG_MICROCODE=m
CONFIG_MICROCODE_OLD_INTERFACE=y
CONFIG_X86_MSR=m
CONFIG_X86_CPUID=m

#
# Firmware Drivers
#
CONFIG_EDD=m
# CONFIG_DELL_RBU is not set
CONFIG_DCDBAS=m
CONFIG_NOHIGHMEM=y
# CONFIG_HIGHMEM4G is not set
# CONFIG_HIGHMEM64G is not set
CONFIG_PAGE_OFFSET=0xC0000000
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_SPARSEMEM_STATIC=y
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_RESOURCES_64BIT is not set
# CONFIG_MATH_EMULATION is not set
CONFIG_MTRR=y
# CONFIG_EFI is not set
CONFIG_SECCOMP=y
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
CONFIG_HZ_1000=y
CONFIG_HZ=1000
# CONFIG_KEXEC is not set
CONFIG_PHYSICAL_START=0x100000
# CONFIG_RELOCATABLE is not set
CONFIG_PHYSICAL_ALIGN=0x100000
CONFIG_COMPAT_VDSO=y

#
# Power management options (ACPI, APM)
#
CONFIG_PM=y
# CONFIG_PM_LEGACY is not set
# CONFIG_PM_DEBUG is not set
# CONFIG_PM_SYSFS_DEPRECATED is not set
# CONFIG_SOFTWARE_SUSPEND is not set

#
# ACPI (Advanced Configuration and Power Interface) Support
#
CONFIG_ACPI=y
# CONFIG_ACPI_SLEEP is not set
CONFIG_ACPI_AC=m
CONFIG_ACPI_BATTERY=m
CONFIG_ACPI_BUTTON=m
# CONFIG_ACPI_VIDEO is not set
# CONFIG_ACPI_HOTKEY is not set
CONFIG_ACPI_FAN=m
# CONFIG_ACPI_DOCK is not set
# CONFIG_ACPI_PROCESSOR is not set
# CONFIG_ACPI_ASUS is not set
# CONFIG_ACPI_IBM is not set
# CONFIG_ACPI_TOSHIBA is not set
CONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
CONFIG_ACPI_EC=y
CONFIG_ACPI_POWER=y
CONFIG_ACPI_SYSTEM=y
CONFIG_X86_PM_TIMER=y
# CONFIG_ACPI_CONTAINER is not set
# CONFIG_ACPI_SBS is not set

#
# APM (Advanced Power Management) BIOS Support
#
# CONFIG_APM is not set

#
# CPU Frequency scaling
#
# CONFIG_CPU_FREQ is not set

#
# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
#
CONFIG_PCI=y
# CONFIG_PCI_GOBIOS is not set
# CONFIG_PCI_GOMMCONFIG is not set
# CONFIG_PCI_GODIRECT is not set
CONFIG_PCI_GOANY=y
CONFIG_PCI_BIOS=y
CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCIEAER=y
# CONFIG_PCI_MSI is not set
CONFIG_HT_IRQ=y
CONFIG_ISA_DMA_API=y
CONFIG_ISA=y
# CONFIG_EISA is not set
# CONFIG_MCA is not set
# CONFIG_SCx200 is not set

#
# PCCARD (PCMCIA/CardBus) support
#
CONFIG_PCCARD=m
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=m
CONFIG_PCMCIA_LOAD_CIS=y
CONFIG_PCMCIA_IOCTL=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_I82365=m
CONFIG_TCIC=m
CONFIG_PCMCIA_PROBE=y
CONFIG_PCCARD_NONSTATIC=m

#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set

#
# Executable file formats
#
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_AOUT=m
CONFIG_BINFMT_MISC=y

#
# Networking
#
CONFIG_NET=y

#
# Networking options
#
# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
# CONFIG_XFRM_SUB_POLICY is not set
CONFIG_NET_KEY=m
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_FIB_HASH=y
# CONFIG_IP_PNP is not set
CONFIG_NET_IPIP=m
CONFIG_NET_IPGRE=m
# CONFIG_ARPD is not set
# CONFIG_SYN_COOKIES is not set
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=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_XFRM_MODE_BEET=y
CONFIG_INET_DIAG=m
CONFIG_INET_TCP_DIAG=m
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
CONFIG_IPV6=m
CONFIG_IPV6_PRIVACY=y
# CONFIG_IPV6_ROUTER_PREF is not set
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_IPCOMP=m
# CONFIG_IPV6_MIP6 is not set
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 is not set
CONFIG_IPV6_SIT=m
CONFIG_IPV6_TUNNEL=m
# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_NETLABEL is not set
CONFIG_NETWORK_SECMARK=y
# CONFIG_NETFILTER is not set

#
# DCCP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_DCCP is not set

#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set

#
# TIPC Configuration (EXPERIMENTAL)
#
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set

#
# QoS and/or fair queueing
#
# CONFIG_NET_SCHED is not set

#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
CONFIG_IEEE80211=m
# CONFIG_IEEE80211_DEBUG is not set
# CONFIG_IEEE80211_CRYPT_WEP is not set
# CONFIG_IEEE80211_CRYPT_CCMP is not set
# CONFIG_IEEE80211_CRYPT_TKIP is not set
# CONFIG_IEEE80211_SOFTMAC is not set
CONFIG_WIRELESS_EXT=y

#
# Device Drivers
#

#
# Generic Driver Options
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
# CONFIG_SYS_HYPERVISOR is not set

#
# Connector - unified userspace <-> kernelspace linker
#
# CONFIG_CONNECTOR is not set

#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set

#
# Parallel port support
#
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 is not set
CONFIG_PARPORT_1284=y
CONFIG_PARPORT_NOT_PC=y

#
# Plug and Play support
#
CONFIG_PNP=y
# CONFIG_PNP_DEBUG is not set

#
# Protocols
#
CONFIG_ISAPNP=y
# CONFIG_PNPBIOS is not set
CONFIG_PNPACPI=y

#
# Block devices
#
CONFIG_BLK_DEV_FD=m
# CONFIG_BLK_DEV_XD is not set
CONFIG_PARIDE=m
CONFIG_PARIDE_PARPORT=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 is not set
# CONFIG_PARIDE_BPCK is not set
# CONFIG_PARIDE_BPCK6 is not set
# CONFIG_PARIDE_COMM is not set
# CONFIG_PARIDE_DSTR is not set
# CONFIG_PARIDE_FIT2 is not set
# CONFIG_PARIDE_FIT3 is not set
# CONFIG_PARIDE_EPAT is not set
# CONFIG_PARIDE_EPIA is not set
# CONFIG_PARIDE_FRIQ is not set
# CONFIG_PARIDE_FRPW is not set
# CONFIG_PARIDE_KBIC is not set
# CONFIG_PARIDE_KTTI is not set
# CONFIG_PARIDE_ON20 is not set
# CONFIG_PARIDE_ON26 is not set
CONFIG_BLK_CPQ_DA=m
CONFIG_BLK_CPQ_CISS_DA=m
CONFIG_CISS_SCSI_TAPE=y
CONFIG_BLK_DEV_DAC960=y
CONFIG_BLK_DEV_UMEM=y
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_CRYPTOLOOP=m
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_SX8=m
# CONFIG_BLK_DEV_UB is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=16384
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
CONFIG_ATA_OVER_ETH=m

#
# Misc devices
#
# CONFIG_IBM_ASM is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set

#
# ATA/ATAPI/MFM/RLL support
#
CONFIG_IDE=y
CONFIG_BLK_DEV_IDE=y

#
# Please see Documentation/ide.txt for help/info on IDE drives
#
# CONFIG_BLK_DEV_IDE_SATA is not set
# CONFIG_BLK_DEV_HD_IDE is not set
CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_IDEDISK_MULTI_MODE is not set
CONFIG_BLK_DEV_IDECS=m
CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDETAPE is not set
CONFIG_BLK_DEV_IDEFLOPPY=y
CONFIG_BLK_DEV_IDESCSI=m
# CONFIG_IDE_TASK_IOCTL is not set

#
# IDE chipset support/bugfixes
#
# CONFIG_IDE_GENERIC is not set
CONFIG_BLK_DEV_CMD640=y
CONFIG_BLK_DEV_CMD640_ENHANCED=y
CONFIG_BLK_DEV_IDEPNP=y
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_IDEPCI_SHARE_IRQ=y
# CONFIG_BLK_DEV_OFFBOARD is not set
CONFIG_BLK_DEV_GENERIC=m
# CONFIG_BLK_DEV_OPTI621 is not set
CONFIG_BLK_DEV_RZ1000=m
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_IDEDMA_ONLYDISK is not set
# CONFIG_BLK_DEV_AEC62XX is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD74XX is not set
# CONFIG_BLK_DEV_ATIIXP is not set
# CONFIG_BLK_DEV_CMD64X is not set
# CONFIG_BLK_DEV_TRIFLEX is not set
# CONFIG_BLK_DEV_CY82C693 is not set
# CONFIG_BLK_DEV_CS5520 is not set
# CONFIG_BLK_DEV_CS5530 is not set
# CONFIG_BLK_DEV_CS5535 is not set
# CONFIG_BLK_DEV_HPT34X is not set
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_JMICRON is not set
# CONFIG_BLK_DEV_SC1200 is not set
CONFIG_BLK_DEV_PIIX=m
# CONFIG_BLK_DEV_IT821X is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIIMAGE is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_IDE_ARM is not set
# CONFIG_IDE_CHIPSETS is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_IVB is not set
CONFIG_IDEDMA_AUTO=y
# CONFIG_BLK_DEV_HD is not set

#
# SCSI device support
#
CONFIG_RAID_ATTRS=m
CONFIG_SCSI=m
# CONFIG_SCSI_TGT is not set
CONFIG_SCSI_NETLINK=y
CONFIG_SCSI_PROC_FS=y

#
# 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 is not set

#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_CONSTANTS is not set
CONFIG_SCSI_LOGGING=y
# CONFIG_SCSI_SCAN_ASYNC is not set

#
# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=m
CONFIG_SCSI_FC_ATTRS=m
CONFIG_SCSI_ISCSI_ATTRS=m
CONFIG_SCSI_SAS_ATTRS=m
CONFIG_SCSI_SAS_LIBSAS=m
# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set

#
# SCSI low-level drivers
#
# CONFIG_ISCSI_TCP is not set
CONFIG_BLK_DEV_3W_XXXX_RAID=m
CONFIG_SCSI_3W_9XXX=m
# CONFIG_SCSI_7000FASST is not set
CONFIG_SCSI_ACARD=m
CONFIG_SCSI_AHA152X=m
CONFIG_SCSI_AHA1542=m
CONFIG_SCSI_AACRAID=m
CONFIG_SCSI_AIC7XXX=m
CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
CONFIG_AIC7XXX_RESET_DELAY_MS=15000
# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
CONFIG_AIC7XXX_DEBUG_MASK=0
# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
CONFIG_SCSI_AIC7XXX_OLD=m
CONFIG_SCSI_AIC79XX=m
CONFIG_AIC79XX_CMDS_PER_DEVICE=4
CONFIG_AIC79XX_RESET_DELAY_MS=15000
# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
# CONFIG_AIC79XX_DEBUG_ENABLE is not set
CONFIG_AIC79XX_DEBUG_MASK=0
# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
CONFIG_SCSI_AIC94XX=m
# CONFIG_AIC94XX_DEBUG is not set
CONFIG_SCSI_DPT_I2O=m
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_ARCMSR is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_DTC3280 is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_GENERIC_NCR5380 is not set
# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_PPA is not set
# CONFIG_SCSI_IMM is not set
# CONFIG_SCSI_NCR53C406A is not set
# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_PAS16 is not set
# CONFIG_SCSI_PSI240I is not set
# CONFIG_SCSI_QLOGIC_FAS is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_QLA_FC is not set
# CONFIG_SCSI_QLA_ISCSI is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_SEAGATE is not set
# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_U14_34F is not set
# CONFIG_SCSI_ULTRASTOR is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set

#
# PCMCIA SCSI adapter support
#
CONFIG_PCMCIA_AHA152X=m
CONFIG_PCMCIA_FDOMAIN=m
CONFIG_PCMCIA_NINJA_SCSI=m
CONFIG_PCMCIA_QLOGIC=m
CONFIG_PCMCIA_SYM53C500=m

#
# Serial ATA (prod) and Parallel ATA (experimental) drivers
#
CONFIG_ATA=m
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_AHCI=m
# CONFIG_SATA_SVW is not set
CONFIG_ATA_PIIX=m
# CONFIG_SATA_MV is not set
# CONFIG_SATA_NV is not set
# CONFIG_PDC_ADMA is not set
# CONFIG_SATA_QSTOR is not set
# CONFIG_SATA_PROMISE is not set
# CONFIG_SATA_SX4 is not set
# CONFIG_SATA_SIL is not set
# CONFIG_SATA_SIL24 is not set
# CONFIG_SATA_SIS is not set
# CONFIG_SATA_ULI is not set
# CONFIG_SATA_VIA is not set
# CONFIG_SATA_VITESSE is not set
CONFIG_SATA_INTEL_COMBINED=y
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD64X is not set
# CONFIG_PATA_CS5520 is not set
# CONFIG_PATA_CS5530 is not set
# CONFIG_PATA_CS5535 is not set
# CONFIG_PATA_CYPRESS is not set
# CONFIG_PATA_EFAR is not set
# CONFIG_ATA_GENERIC is not set
# CONFIG_PATA_HPT366 is not set
# CONFIG_PATA_HPT37X is not set
# CONFIG_PATA_HPT3X2N is not set
# CONFIG_PATA_HPT3X3 is not set
# CONFIG_PATA_ISAPNP is not set
# CONFIG_PATA_IT821X is not set
# CONFIG_PATA_JMICRON is not set
# CONFIG_PATA_LEGACY is not set
# CONFIG_PATA_TRIFLEX is not set
# CONFIG_PATA_MARVELL is not set
CONFIG_PATA_MPIIX=m
CONFIG_PATA_OLDPIIX=m
# CONFIG_PATA_NETCELL is not set
# CONFIG_PATA_NS87410 is not set
# CONFIG_PATA_OPTI is not set
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PCMCIA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_QDI is not set
# CONFIG_PATA_RADISYS is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
# CONFIG_PATA_PDC2027X is not set
# CONFIG_PATA_SIL680 is not set
# CONFIG_PATA_SIS is not set
# CONFIG_PATA_VIA is not set
# CONFIG_PATA_WINBOND is not set
# CONFIG_PATA_WINBOND_VLB is not set

#
# Old CD-ROM drivers (not SCSI, not IDE)
#
# CONFIG_CD_NO_IDESCSI is not set

#
# Multi-device support (RAID and LVM)
#
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 is not set
CONFIG_MD_MULTIPATH=m
CONFIG_MD_FAULTY=m
CONFIG_BLK_DEV_DM=m
# CONFIG_DM_DEBUG is not set
CONFIG_DM_CRYPT=m
CONFIG_DM_SNAPSHOT=m
CONFIG_DM_MIRROR=m
CONFIG_DM_ZERO=m
CONFIG_DM_MULTIPATH=m
CONFIG_DM_MULTIPATH_EMC=m

#
# Fusion MPT device support
#
# CONFIG_FUSION is not set
# CONFIG_FUSION_SPI is not set
# CONFIG_FUSION_FC is not set
# CONFIG_FUSION_SAS is not set

#
# IEEE 1394 (FireWire) support
#
# CONFIG_IEEE1394 is not set

#
# I2O device support
#
# CONFIG_I2O is not set

#
# Macintosh device drivers
#
# CONFIG_MAC_EMUMOUSEBTN is not set

#
# Network device support
#
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
CONFIG_NET_SB1000=m

#
# ARCnet devices
#
# CONFIG_ARCNET is not set

#
# PHY device support
#
# CONFIG_PHYLIB is not set

#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
CONFIG_MII=m
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set

#
# Tulip family network device support
#
CONFIG_NET_TULIP=y
CONFIG_DE2104X=m
CONFIG_TULIP=m
# CONFIG_TULIP_MWI is not set
CONFIG_TULIP_MMIO=y
# CONFIG_TULIP_NAPI is not set
CONFIG_DE4X5=m
CONFIG_WINBOND_840=m
CONFIG_DM9102=m
# CONFIG_ULI526X is not set
CONFIG_PCMCIA_XIRCOM=m
# CONFIG_PCMCIA_XIRTULIP is not set
# CONFIG_AT1700 is not set
# CONFIG_DEPCA is not set
# CONFIG_HP100 is not set
# CONFIG_NET_ISA is not set
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_AC3200 is not set
# CONFIG_APRICOT is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
# CONFIG_CS89x0 is not set
# CONFIG_DGRS is not set
# CONFIG_EEPRO100 is not set
CONFIG_E100=m
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
# CONFIG_8139CP is not set
# CONFIG_8139TOO is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_NET_POCKET is not set

#
# Ethernet (1000 Mbit)
#
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SKY2 is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
# CONFIG_QLA3XXX is not set

#
# Ethernet (10000 Mbit)
#
# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set

#
# Token Ring devices
#
# CONFIG_TR is not set

#
# Wireless LAN (non-hamradio)
#
CONFIG_NET_RADIO=y
# CONFIG_NET_WIRELESS_RTNETLINK is not set

#
# Obsolete Wireless cards support (pre-802.11)
#
# CONFIG_STRIP is not set
# CONFIG_ARLAN is not set
# CONFIG_WAVELAN is not set
# CONFIG_PCMCIA_WAVELAN is not set
# CONFIG_PCMCIA_NETWAVE is not set

#
# Wireless 802.11 Frequency Hopping cards support
#
# CONFIG_PCMCIA_RAYCS is not set

#
# Wireless 802.11b ISA/PCI cards support
#
# CONFIG_IPW2100 is not set
CONFIG_IPW2200=m
# CONFIG_IPW2200_MONITOR is not set
# CONFIG_IPW2200_QOS is not set
# CONFIG_IPW2200_DEBUG is not set
# CONFIG_AIRO is not set
# CONFIG_HERMES is not set
# CONFIG_ATMEL is not set

#
# Wireless 802.11b Pcmcia/Cardbus cards support
#
# CONFIG_AIRO_CS is not set
# CONFIG_PCMCIA_WL3501 is not set

#
# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
#
CONFIG_PRISM54=m
CONFIG_USB_ZD1201=m
# CONFIG_HOSTAP is not set
CONFIG_NET_WIRELESS=y

#
# PCMCIA network device support
#
# CONFIG_NET_PCMCIA is not set

#
# Wan interfaces
#
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
CONFIG_PLIP=m
CONFIG_PPP=m
CONFIG_PPP_MULTILINK=y
CONFIG_PPP_FILTER=y
CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
CONFIG_PPP_DEFLATE=m
# CONFIG_PPP_BSDCOMP is not set
# CONFIG_PPP_MPPE is not set
CONFIG_PPPOE=m
CONFIG_SLIP=m
CONFIG_SLIP_COMPRESSED=y
CONFIG_SLHC=m
CONFIG_SLIP_SMART=y
# CONFIG_SLIP_MODE_SLIP6 is not set
CONFIG_NET_FC=y
# CONFIG_SHAPER is not set
CONFIG_NETCONSOLE=m
CONFIG_NETPOLL=y
# CONFIG_NETPOLL_RX is not set
# CONFIG_NETPOLL_TRAP is not set
CONFIG_NET_POLL_CONTROLLER=y

#
# ISDN subsystem
#
# CONFIG_ISDN is not set

#
# Telephony Support
#
# CONFIG_PHONE is not set

#
# Input device support
#
CONFIG_INPUT=y
CONFIG_INPUT_FF_MEMLESS=y

#
# 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 is not set
# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set

#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
# CONFIG_MOUSE_SERIAL is not set
# CONFIG_MOUSE_INPORT is not set
# CONFIG_MOUSE_LOGIBM is not set
# CONFIG_MOUSE_PC110PAD is not set
# CONFIG_MOUSE_VSXXXAA is not set
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_DB9=m
CONFIG_JOYSTICK_GAMECON=m
CONFIG_JOYSTICK_TURBOGRAFX=m
CONFIG_JOYSTICK_JOYDUMP=m
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_GUNZE=m
CONFIG_TOUCHSCREEN_ELO=m
CONFIG_TOUCHSCREEN_MTOUCH=m
CONFIG_TOUCHSCREEN_MK712=m
# CONFIG_TOUCHSCREEN_PENMOUNT is not set
# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
# CONFIG_TOUCHSCREEN_UCB1400 is not set
CONFIG_INPUT_MISC=y
CONFIG_INPUT_PCSPKR=m
# CONFIG_INPUT_WISTRON_BTNS is not set
CONFIG_INPUT_UINPUT=m

#
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_SERIO_I8042=y
CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PARKBD is not set
# CONFIG_SERIO_PCIPS2 is not set
CONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not set
CONFIG_GAMEPORT=y
# CONFIG_GAMEPORT_NS558 is not set
# CONFIG_GAMEPORT_L4 is not set
# CONFIG_GAMEPORT_EMU10K1 is not set
# CONFIG_GAMEPORT_FM801 is not set

#
# Character devices
#
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_COMPUTONE is not set
CONFIG_ROCKETPORT=m
# CONFIG_CYCLADES is not set
# CONFIG_DIGIEPCA is not set
# CONFIG_ESPSERIAL is not set
# CONFIG_MOXA_INTELLIO is not set
# CONFIG_MOXA_SMARTIO is not set
# CONFIG_MOXA_SMARTIO_NEW is not set
# CONFIG_ISI is not set
CONFIG_SYNCLINK=m
CONFIG_SYNCLINKMP=m
# CONFIG_SYNCLINK_GT is not set
CONFIG_N_HDLC=m
# CONFIG_RISCOM8 is not set
# CONFIG_SPECIALIX is not set
# CONFIG_SX is not set
# CONFIG_RIO is not set
CONFIG_STALDRV=y
# CONFIG_STALLION is not set
# CONFIG_ISTALLION is not set

#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=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_FOURPORT is not set
# CONFIG_SERIAL_8250_ACCENT is not set
# CONFIG_SERIAL_8250_BOCA is not set
# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
# CONFIG_SERIAL_8250_HUB6 is not set
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_DETECT_IRQ=y
CONFIG_SERIAL_8250_RSA=y

#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_PRINTER=m
CONFIG_LP_CONSOLE=y
# CONFIG_PPDEV is not set
# CONFIG_TIPAR is not set

#
# IPMI
#
# CONFIG_IPMI_HANDLER is not set

#
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_INTEL=y
CONFIG_HW_RANDOM_AMD=y
CONFIG_HW_RANDOM_GEODE=y
CONFIG_HW_RANDOM_VIA=y
CONFIG_NVRAM=m
CONFIG_RTC=m
CONFIG_GEN_RTC=m
# CONFIG_GEN_RTC_X is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_SONYPI is not set
CONFIG_AGP=m
# CONFIG_AGP_ALI is not set
CONFIG_AGP_ATI=m
# CONFIG_AGP_AMD is not set
# CONFIG_AGP_AMD64 is not set
CONFIG_AGP_INTEL=m
# CONFIG_AGP_NVIDIA is not set
# CONFIG_AGP_SIS is not set
# CONFIG_AGP_SWORKS is not set
# CONFIG_AGP_VIA is not set
# CONFIG_AGP_EFFICEON is not set
CONFIG_DRM=m
# CONFIG_DRM_TDFX is not set
# CONFIG_DRM_R128 is not set
CONFIG_DRM_RADEON=m
# CONFIG_DRM_I810 is not set
# CONFIG_DRM_I830 is not set
# CONFIG_DRM_I915 is not set
# CONFIG_DRM_MGA is not set
# CONFIG_DRM_SIS is not set
# CONFIG_DRM_VIA is not set
# CONFIG_DRM_SAVAGE is not set

#
# PCMCIA character devices
#
CONFIG_SYNCLINK_CS=m
# CONFIG_CARDMAN_4000 is not set
# CONFIG_CARDMAN_4040 is not set
CONFIG_MWAVE=m
# CONFIG_PC8736x_GPIO is not set
# CONFIG_NSC_GPIO is not set
# CONFIG_CS5535_GPIO is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_HPET is not set
CONFIG_HANGCHECK_TIMER=m

#
# TPM devices
#
# CONFIG_TCG_TPM is not set
# CONFIG_TELCLOCK is not set

#
# I2C support
#
CONFIG_I2C=m
CONFIG_I2C_CHARDEV=m

#
# I2C Algorithms
#
CONFIG_I2C_ALGOBIT=m
CONFIG_I2C_ALGOPCF=m
CONFIG_I2C_ALGOPCA=m

#
# I2C Hardware Bus support
#
# CONFIG_I2C_ALI1535 is not set
# CONFIG_I2C_ALI1563 is not set
# CONFIG_I2C_ALI15X3 is not set
# CONFIG_I2C_AMD756 is not set
# CONFIG_I2C_AMD8111 is not set
# CONFIG_I2C_ELEKTOR is not set
CONFIG_I2C_I801=m
CONFIG_I2C_I810=m
CONFIG_I2C_PIIX4=m
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PARPORT is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
# CONFIG_I2C_SAVAGE4 is not set
# CONFIG_SCx200_ACB is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
# CONFIG_I2C_STUB is not set
# CONFIG_I2C_VIA is not set
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_VOODOO3 is not set
# CONFIG_I2C_PCA_ISA is not set

#
# Miscellaneous I2C Chip support
#
# CONFIG_SENSORS_DS1337 is not set
# CONFIG_SENSORS_DS1374 is not set
CONFIG_SENSORS_EEPROM=m
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set

#
# SPI support
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set

#
# Dallas's 1-wire bus
#
# CONFIG_W1 is not set

#
# Hardware Monitoring support
#
# CONFIG_HWMON is not set
# CONFIG_HWMON_VID is not set

#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set

#
# Digital Video Broadcasting Devices
#
# CONFIG_DVB is not set
# CONFIG_USB_DABUSB is not set

#
# Graphics support
#
CONFIG_FIRMWARE_EDID=y
CONFIG_FB=y
CONFIG_FB_DDC=m
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not set
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y
CONFIG_FB_CIRRUS=m
# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_ARC is not set
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
CONFIG_FB_VGA16=m
CONFIG_FB_VESA=y
# CONFIG_FB_HGA is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_I810 is not set
# CONFIG_FB_INTEL is not set
# CONFIG_FB_MATROX is not set
CONFIG_FB_RADEON=m
CONFIG_FB_RADEON_I2C=y
# CONFIG_FB_RADEON_DEBUG is not set
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_ATY is not set
# CONFIG_FB_SAVAGE is not set
# CONFIG_FB_SIS is not set
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
# CONFIG_FB_CYBLA is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_GEODE is not set
# CONFIG_FB_VIRTUAL is not set

#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
# CONFIG_VGACON_SOFT_SCROLLBACK is not set
CONFIG_VIDEO_SELECT=y
CONFIG_MDA_CONSOLE=m
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y

#
# Logo configuration
#
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_LOGO_LINUX_CLUT224=y
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set

#
# Sound
#
CONFIG_SOUND=m

#
# Advanced Linux Sound Architecture
#
CONFIG_SND=m
CONFIG_SND_TIMER=m
CONFIG_SND_PCM=m
CONFIG_SND_RAWMIDI=m
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=y
CONFIG_SND_RTCTIMER=m
CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
# CONFIG_SND_DYNAMIC_MINORS is not set
CONFIG_SND_SUPPORT_OLD_API=y
CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set

#
# Generic devices
#
CONFIG_SND_MPU401_UART=m
CONFIG_SND_AC97_CODEC=m
CONFIG_SND_DUMMY=m
CONFIG_SND_VIRMIDI=m
CONFIG_SND_MTPAV=m
# CONFIG_SND_MTS64 is not set
# CONFIG_SND_SERIAL_U16550 is not set
CONFIG_SND_MPU401=m

#
# ISA devices
#
# CONFIG_SND_ADLIB is not set
# CONFIG_SND_AD1816A is not set
# CONFIG_SND_AD1848 is not set
# CONFIG_SND_ALS100 is not set
# CONFIG_SND_AZT2320 is not set
# CONFIG_SND_CMI8330 is not set
# CONFIG_SND_CS4231 is not set
# CONFIG_SND_CS4232 is not set
# CONFIG_SND_CS4236 is not set
# CONFIG_SND_DT019X is not set
# CONFIG_SND_ES968 is not set
# CONFIG_SND_ES1688 is not set
# CONFIG_SND_ES18XX is not set
# CONFIG_SND_GUSCLASSIC is not set
# CONFIG_SND_GUSEXTREME is not set
# CONFIG_SND_GUSMAX is not set
# CONFIG_SND_INTERWAVE is not set
# CONFIG_SND_INTERWAVE_STB is not set
# CONFIG_SND_OPL3SA2 is not set
# CONFIG_SND_OPTI92X_AD1848 is not set
# CONFIG_SND_OPTI92X_CS4231 is not set
# CONFIG_SND_OPTI93X is not set
# CONFIG_SND_MIRO is not set
# CONFIG_SND_SB8 is not set
# CONFIG_SND_SB16 is not set
# CONFIG_SND_SBAWE is not set
# CONFIG_SND_SGALAXY is not set
# CONFIG_SND_SSCAPE is not set
# CONFIG_SND_WAVEFRONT is not set

#
# PCI devices
#
# CONFIG_SND_AD1889 is not set
# CONFIG_SND_ALS300 is not set
# CONFIG_SND_ALS4000 is not set
# CONFIG_SND_ALI5451 is not set
# CONFIG_SND_ATIIXP is not set
# CONFIG_SND_ATIIXP_MODEM is not set
# CONFIG_SND_AU8810 is not set
# CONFIG_SND_AU8820 is not set
# CONFIG_SND_AU8830 is not set
# CONFIG_SND_AZT3328 is not set
# CONFIG_SND_BT87X is not set
# CONFIG_SND_CA0106 is not set
# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_CS4281 is not set
# CONFIG_SND_CS46XX is not set
# CONFIG_SND_CS5535AUDIO is not set
# CONFIG_SND_DARLA20 is not set
# CONFIG_SND_GINA20 is not set
# CONFIG_SND_LAYLA20 is not set
# CONFIG_SND_DARLA24 is not set
# CONFIG_SND_GINA24 is not set
# CONFIG_SND_LAYLA24 is not set
# CONFIG_SND_MONA is not set
# CONFIG_SND_MIA is not set
# CONFIG_SND_ECHO3G is not set
# CONFIG_SND_INDIGO is not set
# CONFIG_SND_INDIGOIO is not set
# CONFIG_SND_INDIGODJ is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_EMU10K1X is not set
# CONFIG_SND_ENS1370 is not set
# CONFIG_SND_ENS1371 is not set
# CONFIG_SND_ES1938 is not set
# CONFIG_SND_ES1968 is not set
# CONFIG_SND_FM801 is not set
# CONFIG_SND_HDA_INTEL is not set
# CONFIG_SND_HDSP is not set
# CONFIG_SND_HDSPM is not set
# CONFIG_SND_ICE1712 is not set
# CONFIG_SND_ICE1724 is not set
# CONFIG_SND_INTEL8X0 is not set
# CONFIG_SND_INTEL8X0M is not set
# CONFIG_SND_KORG1212 is not set
CONFIG_SND_MAESTRO3=m
# CONFIG_SND_MIXART is not set
# CONFIG_SND_NM256 is not set
# CONFIG_SND_PCXHR is not set
# CONFIG_SND_RIPTIDE is not set
# CONFIG_SND_RME32 is not set
# CONFIG_SND_RME96 is not set
# CONFIG_SND_RME9652 is not set
# CONFIG_SND_SONICVIBES is not set
# CONFIG_SND_TRIDENT is not set
# CONFIG_SND_VIA82XX is not set
# CONFIG_SND_VIA82XX_MODEM is not set
# CONFIG_SND_VX222 is not set
# CONFIG_SND_YMFPCI is not set
# CONFIG_SND_AC97_POWER_SAVE is not set

#
# USB devices
#
# CONFIG_SND_USB_AUDIO is not set
# CONFIG_SND_USB_USX2Y is not set

#
# PCMCIA devices
#
# CONFIG_SND_VXPOCKET is not set
# CONFIG_SND_PDAUDIOCF is not set

#
# Open Sound System
#
# CONFIG_SOUND_PRIME is not set
CONFIG_AC97_BUS=m

#
# HID Devices
#
CONFIG_HID=y

#
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set

#
# Miscellaneous USB options
#
CONFIG_USB_DEVICEFS=y
# CONFIG_USB_BANDWIDTH is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_SUSPEND is not set
# CONFIG_USB_OTG is not set

#
# USB Host Controller Drivers
#
CONFIG_USB_EHCI_HCD=m
CONFIG_USB_EHCI_SPLIT_ISO=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=m
# CONFIG_USB_OHCI_BIG_ENDIAN is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_UHCI_HCD=m
CONFIG_USB_SL811_HCD=m
CONFIG_USB_SL811_CS=m

#
# USB Device Class drivers
#
CONFIG_USB_ACM=m
CONFIG_USB_PRINTER=m

#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#

#
# may also be needed; see USB_STORAGE Help for more information
#
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
CONFIG_USB_STORAGE_DATAFAB=y
CONFIG_USB_STORAGE_FREECOM=y
CONFIG_USB_STORAGE_ISD200=y
CONFIG_USB_STORAGE_DPCM=y
CONFIG_USB_STORAGE_USBAT=y
CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
CONFIG_USB_STORAGE_JUMPSHOT=y
# CONFIG_USB_STORAGE_ALAUDA is not set
# CONFIG_USB_STORAGE_KARMA is not set
# CONFIG_USB_LIBUSUAL is not set

#
# USB Input Devices
#
CONFIG_USB_HID=y
# CONFIG_USB_HIDINPUT_POWERBOOK is not set
CONFIG_HID_FF=y
CONFIG_HID_PID=y
CONFIG_LOGITECH_FF=y
CONFIG_THRUSTMASTER_FF=y
# CONFIG_ZEROPLUS_FF is not set
CONFIG_USB_HIDDEV=y
CONFIG_USB_AIPTEK=m
CONFIG_USB_WACOM=m
# CONFIG_USB_ACECAD is not set
CONFIG_USB_KBTAB=m
CONFIG_USB_POWERMATE=m
# CONFIG_USB_TOUCHSCREEN is not set
# CONFIG_USB_YEALINK is not set
CONFIG_USB_XPAD=m
CONFIG_USB_ATI_REMOTE=m
# CONFIG_USB_ATI_REMOTE2 is not set
# CONFIG_USB_KEYSPAN_REMOTE is not set
# CONFIG_USB_APPLETOUCH is not set

#
# USB Imaging devices
#
CONFIG_USB_MDC800=m
CONFIG_USB_MICROTEK=m

#
# USB Network Adapters
#
CONFIG_USB_CATC=m
CONFIG_USB_KAWETH=m
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
CONFIG_USB_USBNET_MII=m
CONFIG_USB_USBNET=m
CONFIG_USB_NET_AX8817X=m
CONFIG_USB_NET_CDCETHER=m
# CONFIG_USB_NET_GL620A is not set
CONFIG_USB_NET_NET1080=m
# CONFIG_USB_NET_PLUSB is not set
# CONFIG_USB_NET_MCS7830 is not set
# CONFIG_USB_NET_RNDIS_HOST is not set
# CONFIG_USB_NET_CDC_SUBSET is not set
CONFIG_USB_NET_ZAURUS=m
CONFIG_USB_MON=y

#
# USB port drivers
#
CONFIG_USB_USS720=m

#
# USB Serial Converter support
#
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_GENERIC=y
# CONFIG_USB_SERIAL_AIRCABLE is not set
CONFIG_USB_SERIAL_AIRPRIME=m
# CONFIG_USB_SERIAL_ARK3116 is not set
CONFIG_USB_SERIAL_BELKIN=m
CONFIG_USB_SERIAL_WHITEHEAT=m
CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
CONFIG_USB_SERIAL_CP2101=m
CONFIG_USB_SERIAL_CYPRESS_M8=m
CONFIG_USB_SERIAL_EMPEG=m
CONFIG_USB_SERIAL_FTDI_SIO=m
# CONFIG_USB_SERIAL_FUNSOFT is not set
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_GARMIN=m
CONFIG_USB_SERIAL_IPW=m
CONFIG_USB_SERIAL_KEYSPAN_PDA=m
CONFIG_USB_SERIAL_KEYSPAN=m
CONFIG_USB_SERIAL_KEYSPAN_MPR=y
CONFIG_USB_SERIAL_KEYSPAN_USA28=y
CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
CONFIG_USB_SERIAL_KEYSPAN_USA19=y
CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
CONFIG_USB_SERIAL_KLSI=m
CONFIG_USB_SERIAL_KOBIL_SCT=m
CONFIG_USB_SERIAL_MCT_U232=m
# CONFIG_USB_SERIAL_MOS7720 is not set
# CONFIG_USB_SERIAL_MOS7840 is not set
# CONFIG_USB_SERIAL_NAVMAN is not set
CONFIG_USB_SERIAL_PL2303=m
CONFIG_USB_SERIAL_HP4X=m
CONFIG_USB_SERIAL_SAFE=m
CONFIG_USB_SERIAL_SAFE_PADDED=y
# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
CONFIG_USB_SERIAL_TI=m
CONFIG_USB_SERIAL_CYBERJACK=m
CONFIG_USB_SERIAL_XIRCOM=m
CONFIG_USB_SERIAL_OPTION=m
CONFIG_USB_SERIAL_OMNINET=m
# CONFIG_USB_SERIAL_DEBUG is not set
CONFIG_USB_EZUSB=y

#
# USB Miscellaneous drivers
#
CONFIG_USB_EMI62=m
# CONFIG_USB_EMI26 is not set
# CONFIG_USB_ADUTUX is not set
CONFIG_USB_AUERSWALD=m
CONFIG_USB_RIO500=m
CONFIG_USB_LEGOTOWER=m
CONFIG_USB_LCD=m
CONFIG_USB_LED=m
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_PHIDGET is not set
CONFIG_USB_IDMOUSE=m
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
CONFIG_USB_SISUSBVGA=m
# CONFIG_USB_SISUSBVGA_CON is not set
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
CONFIG_USB_TEST=m

#
# USB DSL modem support
#

#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set

#
# MMC/SD Card support
#
# CONFIG_MMC is not set

#
# LED devices
#
# CONFIG_NEW_LEDS is not set

#
# LED drivers
#

#
# LED Triggers
#

#
# InfiniBand support
#
# CONFIG_INFINIBAND is not set

#
# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
#
# CONFIG_EDAC is not set

#
# Real Time Clock
#
CONFIG_RTC_LIB=m
CONFIG_RTC_CLASS=m

#
# RTC interfaces
#
CONFIG_RTC_INTF_SYSFS=m
CONFIG_RTC_INTF_PROC=m
CONFIG_RTC_INTF_DEV=m
# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set

#
# RTC drivers
#
# CONFIG_RTC_DRV_X1205 is not set
# CONFIG_RTC_DRV_DS1307 is not set
# CONFIG_RTC_DRV_DS1553 is not set
# CONFIG_RTC_DRV_ISL1208 is not set
# CONFIG_RTC_DRV_DS1672 is not set
# CONFIG_RTC_DRV_DS1742 is not set
# CONFIG_RTC_DRV_PCF8563 is not set
# CONFIG_RTC_DRV_PCF8583 is not set
# CONFIG_RTC_DRV_RS5C372 is not set
# CONFIG_RTC_DRV_M48T86 is not set
# CONFIG_RTC_DRV_TEST is not set
# CONFIG_RTC_DRV_V3020 is not set

#
# DMA Engine support
#
CONFIG_DMA_ENGINE=y

#
# DMA Clients
#
CONFIG_NET_DMA=y

#
# DMA Devices
#
CONFIG_INTEL_IOATDMA=m

#
# Virtualization
#
# CONFIG_KVM is not set

#
# File systems
#
CONFIG_EXT2_FS=y
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_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
# CONFIG_EXT4DEV_FS is not set
CONFIG_JBD=m
# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
# CONFIG_FUSE_FS is not set

#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=y
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
CONFIG_ZISOFS_FS=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="ascii"
CONFIG_NTFS_FS=m
# CONFIG_NTFS_DEBUG is not set
# CONFIG_NTFS_RW is not set

#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
# CONFIG_CONFIGFS_FS is not set

#
# Miscellaneous filesystems
#
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_ECRYPT_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set

#
# Network File Systems
#
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
CONFIG_NFS_DIRECTIO=y
CONFIG_NFSD=m
CONFIG_NFSD_V3=y
# CONFIG_NFSD_V3_ACL is not set
CONFIG_NFSD_V4=y
CONFIG_NFSD_TCP=y
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=m
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_RPCSEC_GSS_KRB5=m
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
# CONFIG_9P_FS is not set

#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
# CONFIG_ACORN_PARTITION is not set
# CONFIG_OSF_PARTITION is not set
# CONFIG_AMIGA_PARTITION is not set
# CONFIG_ATARI_PARTITION is not set
# CONFIG_MAC_PARTITION is not set
CONFIG_MSDOS_PARTITION=y
CONFIG_BSD_DISKLABEL=y
CONFIG_MINIX_SUBPARTITION=y
CONFIG_SOLARIS_X86_PARTITION=y
CONFIG_UNIXWARE_DISKLABEL=y
# CONFIG_LDM_PARTITION is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set

#
# Native Language Support
#
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
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=y
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_UTF8=m

#
# Distributed Lock Manager
#
# CONFIG_DLM is not set

#
# Instrumentation Support
#
# CONFIG_PROFILING is not set
# CONFIG_KPROBES is not set

#
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_ENABLE_MUST_CHECK is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
# CONFIG_IPIPE_DEBUG is not set
CONFIG_IPIPE_TRACE_ENABLE_VALUE=0
# CONFIG_DEBUG_KERNEL is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_EARLY_PRINTK=y
CONFIG_X86_FIND_SMP_CONFIG=y
CONFIG_X86_MPPARSE=y
CONFIG_DOUBLEFAULT=y

#
# Security options
#
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
# CONFIG_SECURITY_NETWORK_XFRM is not set
CONFIG_SECURITY_CAPABILITIES=y
# CONFIG_SECURITY_ROOTPLUG is not set
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
CONFIG_SECURITY_SELINUX_DISABLE=y
CONFIG_SECURITY_SELINUX_DEVELOP=y
CONFIG_SECURITY_SELINUX_AVC_STATS=y
CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set

#
# Cryptographic options
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_BLKCIPHER=m
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_TGR192=m
# CONFIG_CRYPTO_GF128MUL is not set
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_CBC=m
# CONFIG_CRYPTO_LRW is not set
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_TWOFISH_COMMON=m
# CONFIG_CRYPTO_TWOFISH_586 is not set
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
CONFIG_CRYPTO_AES_586=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set

#
# Hardware crypto devices
#
CONFIG_CRYPTO_DEV_PADLOCK=m
CONFIG_CRYPTO_DEV_PADLOCK_AES=m
CONFIG_CRYPTO_DEV_PADLOCK_SHA=m
CONFIG_CRYPTO_DEV_GEODE=m

#
# Library routines
#
CONFIG_BITREVERSE=y
CONFIG_CRC_CCITT=m
CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_AUDIT_GENERIC=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
CONFIG_PLIST=y
CONFIG_IOMAP_COPY=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_X86_BIOS_REBOOT=y
CONFIG_KTIME_SCALAR=y

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: xenomai-exectime-2.3.1.patch --]
[-- Type: text/x-patch; name="xenomai-exectime-2.3.1.patch", Size: 9572 bytes --]

diff -urN xenomai-2.3.1/include/native/syscall.h xenomai-exectime-2.3.1/include/native/syscall.h
--- xenomai-2.3.1/include/native/syscall.h	2006-12-26 19:38:57.000000000 +0100
+++ xenomai-exectime-2.3.1/include/native/syscall.h	2007-04-02 16:58:13.389399000 +0200
@@ -119,7 +119,7 @@
 #define __native_timer_tsc2ns       93
 #define __native_queue_write        94
 #define __native_queue_read         95
-
+#define __native_task_get_exectime  96
 struct rt_arg_bulk {
 
     u_long a1;
diff -urN xenomai-2.3.1/include/native/task.h xenomai-exectime-2.3.1/include/native/task.h
--- xenomai-2.3.1/include/native/task.h	2006-12-26 19:38:57.000000000 +0100
+++ xenomai-exectime-2.3.1/include/native/task.h	2007-04-02 16:58:13.393395000 +0200
@@ -292,6 +292,8 @@
 int rt_task_slice(RT_TASK *task,
 		  RTIME quantum);
 
+int rt_task_get_exectime (RT_TASK *task, RTIME *exectime);
+
 ssize_t rt_task_send(RT_TASK *task,
 		     RT_TASK_MCB *mcb_s,
 		     RT_TASK_MCB *mcb_r,
diff -urN xenomai-2.3.1/include/nucleus/pod.h xenomai-exectime-2.3.1/include/nucleus/pod.h
--- xenomai-2.3.1/include/nucleus/pod.h	2007-03-18 17:02:02.000000000 +0100
+++ xenomai-exectime-2.3.1/include/nucleus/pod.h	2007-04-02 16:58:13.399389000 +0200
@@ -486,6 +486,8 @@
 
 xnticks_t xnpod_get_time(void);
 
+xnticks_t xnpod_get_exectime (xnthread_t *thread);
+
 static inline xntime_t xnpod_get_cpu_time(void)
 {
 	return xnarch_get_cpu_time();
diff -urN xenomai-2.3.1/include/nucleus/thread.h xenomai-exectime-2.3.1/include/nucleus/thread.h
--- xenomai-2.3.1/include/nucleus/thread.h	2007-03-15 15:10:30.000000000 +0100
+++ xenomai-exectime-2.3.1/include/nucleus/thread.h	2007-04-02 16:58:13.404387000 +0200
@@ -228,6 +228,9 @@
 
     void *cookie;		/* Cookie to pass to the entry routine */
 
+    xnticks_t lastswitch;	/* timestamp of the last switch to execute the thread */ 
+    xnticks_t exectime;	/* execution time since the start of the thread */ 
+
     XNARCH_DECL_DISPLAY_CONTEXT();
 
 } xnthread_t;
diff -urN xenomai-2.3.1/ksrc/nucleus/pod.c xenomai-exectime-2.3.1/ksrc/nucleus/pod.c
--- xenomai-2.3.1/ksrc/nucleus/pod.c	2007-03-19 12:14:13.000000000 +0100
+++ xenomai-exectime-2.3.1/ksrc/nucleus/pod.c	2007-04-02 16:58:13.431357000 +0200
@@ -2453,6 +2453,10 @@
 	xnstat_runtime_switch(sched, &threadin->stat.account);
 	xnstat_counter_inc(&threadin->stat.csw);
 
+	/* David */
+	threadout->exectime += xnarch_get_cpu_tsc() - threadout->lastswitch;
+ 	threadin->lastswitch=xnarch_get_cpu_tsc();
+ 	
 	xnarch_switch_to(xnthread_archtcb(threadout),
 			 xnthread_archtcb(threadin));
 
@@ -2537,7 +2541,7 @@
 void xnpod_schedule_runnable(xnthread_t *thread, int flags)
 {
 	xnsched_t *sched = thread->sched;
-	xnthread_t *runthread = sched->runthread, *threadin;
+	xnthread_t *runthread = sched->runthread, *threadout, *threadin;
 
 	xnltt_log_event(xeno_ev_fastsched);
 	xnarch_trace_pid(xnthread_user_task(thread) ?
@@ -2625,6 +2629,11 @@
 	xnstat_runtime_switch(sched, &threadin->stat.account);
 	xnstat_counter_inc(&threadin->stat.csw);
 
+	/* David */
+	threadout = runthread;	
+	threadout->exectime += xnarch_get_cpu_tsc() - threadout->lastswitch;
+ 	threadin->lastswitch=xnarch_get_cpu_tsc();
+
 	xnarch_switch_to(xnthread_archtcb(runthread),
 			 xnthread_archtcb(threadin));
 
@@ -2710,6 +2719,34 @@
 	return xntimer_get_jiffies() + nkpod->wallclock_offset;
 }
 
+
+
+/*!
+ * \fn xnticks_t xnpod_get_exectime (xnthread_t *thread);
+ * \brief Get the thread execution time.
+ *
+ * This service gets the CPU time consumed by the task in the Xenomai domain. 
+ * The result is expressed in CPU clock ticks.
+ * 
+ * @return The execution time expressed in CPU clock ticks.
+ *
+ * Environments:
+ *
+ * This service can be called from: (to be checked)
+ * - Kernel module initialization/cleanup code
+ * - Kernel-based task
+ * - User-space task
+ * 
+ * Rescheduling: never
+ */
+
+xnticks_t xnpod_get_exectime (xnthread_t *thread)
+
+{
+	return thread->exectime;
+}
+
+
 /*! 
  * \fn int xnpod_add_hook(int type,void (*routine)(xnthread_t *))
  * \brief Install a nucleus hook.
@@ -3581,6 +3618,7 @@
 EXPORT_SYMBOL(xnpod_delete_thread);
 EXPORT_SYMBOL(xnpod_fatal_helper);
 EXPORT_SYMBOL(xnpod_get_time);
+EXPORT_SYMBOL(xnpod_get_exectime);
 EXPORT_SYMBOL(xnpod_init);
 EXPORT_SYMBOL(xnpod_init_thread);
 EXPORT_SYMBOL(xnpod_migrate_thread);
diff -urN xenomai-2.3.1/ksrc/nucleus/thread.c xenomai-exectime-2.3.1/ksrc/nucleus/thread.c
--- xenomai-2.3.1/ksrc/nucleus/thread.c	2007-02-02 02:17:32.000000000 +0100
+++ xenomai-exectime-2.3.1/ksrc/nucleus/thread.c	2007-04-02 16:58:13.436352000 +0200
@@ -97,6 +97,8 @@
 	thread->cookie = 0;
 	thread->stime = 0;
 
+ 	thread->lastswitch = 0;
+ 	thread->exectime = 0;
 	if (name)
 		xnobject_copy_name(thread->name, name);
 	else
diff -urN xenomai-2.3.1/ksrc/skins/native/syscall.c xenomai-exectime-2.3.1/ksrc/skins/native/syscall.c
--- xenomai-2.3.1/ksrc/skins/native/syscall.c	2006-12-31 16:18:30.000000000 +0100
+++ xenomai-exectime-2.3.1/ksrc/skins/native/syscall.c	2007-04-02 16:58:13.469319000 +0200
@@ -512,6 +512,52 @@
 	return err;
 }
 
+
+/*
+ * int __rt_task_get_exectime(RT_TASK_PLACEHOLDER *ph,
+ *                       RTIME *exectime)
+ */
+
+
+static int __rt_task_get_exectime (struct task_struct *curr, struct pt_regs *regs)
+
+{
+    RT_TASK_PLACEHOLDER ph;
+    RTIME exectime;
+    RT_TASK *task;
+    int err;
+
+    if (!__xn_access_ok(curr,VERIFY_WRITE,__xn_reg_arg2(regs),sizeof(exectime)))
+		return -EFAULT;
+
+    if (__xn_reg_arg1(regs))
+	{
+	if (!__xn_access_ok(curr,VERIFY_READ,__xn_reg_arg1(regs),sizeof(ph)))
+	    return -EFAULT;
+
+	__xn_copy_from_user(curr,&ph,(void __user *)__xn_reg_arg1(regs),sizeof(ph));
+
+	task = (RT_TASK *)xnregistry_fetch(ph.opaque);
+	}
+    else
+		task = __rt_task_current(curr);
+
+    if (!task)
+		return -ESRCH;
+
+    err = rt_task_get_exectime(task,&exectime);
+
+    if (!err)
+		__xn_copy_to_user(curr,(void __user *)__xn_reg_arg2(regs),&exectime,
+		sizeof(exectime));
+
+    return err;
+}
+
+
+
+
+
 /*
  * int __rt_task_notify(RT_TASK_PLACEHOLDER *ph,
  *                      rt_sigset_t signals)
@@ -3694,6 +3740,7 @@
 	    {&__rt_task_sleep_until, __xn_exec_primary},
 	[__native_task_unblock] = {&__rt_task_unblock, __xn_exec_any},
 	[__native_task_inquire] = {&__rt_task_inquire, __xn_exec_any},
+ 	[__native_task_get_exectime ] = { &__rt_task_get_exectime, __xn_exec_any },
 	[__native_task_notify] = {&__rt_task_notify, __xn_exec_any},
 	[__native_task_set_mode] = {&__rt_task_set_mode, __xn_exec_primary},
 	[__native_task_self] = {&__rt_task_self, __xn_exec_any},
diff -urN xenomai-2.3.1/ksrc/skins/native/task.c xenomai-exectime-2.3.1/ksrc/skins/native/task.c
--- xenomai-2.3.1/ksrc/skins/native/task.c	2007-02-28 18:25:52.000000000 +0100
+++ xenomai-exectime-2.3.1/ksrc/skins/native/task.c	2007-04-02 16:58:13.481308000 +0200
@@ -1590,6 +1590,67 @@
 	return err;
 }
 
+
+/**
+ * @fn int rt_task_get_exectime (RT_TASK *task, RTIME *exectime)
+ * @brief Return execution time of the task.
+ *
+ * Get the CPU time consumed by the task in the Xenomai domain. The result 
+ * is expressed in CPU clock ticks.
+ *
+ * @param task The descriptor address of the affected task. If @a task
+ * is NULL, the current task is considered.
+ *
+ * @param exectime The CPU time consumed expressed in CPU clock ticks.
+ *
+ * @return 0 is returned upon success. Otherwise:
+ *
+ * - -EINVAL is returned if @a task is not a task descriptor, 
+ *
+ * - -EPERM is returned if @a task is NULL but not called from a task
+ * context.
+ *
+ * Environments:
+ *
+ * This service can be called from:
+ * - Kernel module initialization/cleanup code (to be checked)
+ * - Kernel-based task
+ * - User-space task (see note)
+ *
+ * Rescheduling: never.
+ * 
+ * @note : When the task is executing in the Linux domain, the internal 
+ * counter is not increased as the task is not scheduled by Xenomai. So 
+ * CPU time consumed on Linux domain is not measured.
+ *
+ */
+
+int rt_task_get_exectime (RT_TASK *task, RTIME *exectime)
+
+{
+	int err=0;
+
+    if (!task)
+	{
+		if (!xnpod_primary_p())
+	    	return -EPERM;
+		task = xeno_current_task();
+	}
+
+    task = xeno_h2obj_validate(task,XENO_TASK_MAGIC,RT_TASK);
+
+    if (!task)
+	{
+		err = xeno_handle_error(task,XENO_TASK_MAGIC,RT_TASK);
+		return err;
+	}
+
+	*exectime = xnpod_get_exectime(&task->thread_base);
+	
+	return err;
+}
+
+
 #ifdef CONFIG_XENO_OPT_NATIVE_MPS
 
 /**
@@ -2378,6 +2439,7 @@
 EXPORT_SYMBOL(rt_task_set_mode);
 EXPORT_SYMBOL(rt_task_self);
 EXPORT_SYMBOL(rt_task_slice);
+EXPORT_SYMBOL(rt_task_get_exectime);
 #ifdef CONFIG_XENO_OPT_NATIVE_MPS
 EXPORT_SYMBOL(rt_task_send);
 EXPORT_SYMBOL(rt_task_receive);
diff -urN xenomai-2.3.1/src/skins/native/task.c xenomai-exectime-2.3.1/src/skins/native/task.c
--- xenomai-2.3.1/src/skins/native/task.c	2007-03-20 09:16:41.000000000 +0100
+++ xenomai-exectime-2.3.1/src/skins/native/task.c	2007-04-02 16:58:13.488301000 +0200
@@ -256,6 +256,15 @@
 				 info);
 }
 
+int rt_task_get_exectime (RT_TASK *task,
+			 RTIME *exectime)
+ {
+ 	return XENOMAI_SKINCALL2(__native_muxid,
+ 				__native_task_get_exectime,
+ 				task,
+ 				exectime);	
+ }
+ 
 int rt_task_notify(RT_TASK *task, rt_sigset_t signals)
 {
 	return XENOMAI_SKINCALL2(__native_muxid,

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: qld.c --]
[-- Type: text/x-csrc; name="qld.c", Size: 43656 bytes --]


/* Set error number */
#define SETERRNO(nr) {errno = nr; return -1;}
//#define SETERRNO(nr) {return -1;}
/* Error number definitions */
#define ECONVERGE (sys_nerr+0) /* Iterative algoritm failed to converge */

#include <math.h>
#include <gsl/gsl_matrix.h> 
//#include "Exec/prr.h"
//#include <unistd.h> //appel a sysconf 
//#include <native/heap.h>
//#include "test_essai_qld.h"

#define HORIZON 27//25//25
#define Npas    2 //10 //nombre de pas entre deux points apres l'horizon normal
#define HORIZ2  0//15//10 // NOMBRE de points de l'horizon ou le pas augmente
#define Nin     4//
#define Nout    2//
#define Nst     9//
#define Noptim  (Nout+(HORIZON+1)*Nst+HORIZON*Nin) //taille du vecteur d'optimisation
#define Nconstr (Nout+(HORIZON+1)*Nst+2*HORIZON*Nin+Nout) //taille du vecteur de contraintes (eq+ineq)




int gsl_qp()//(gsl_matrix *x,const gsl_matrix *C,const gsl_matrix *d,int me, const gsl_matrix *A,const gsl_matrix *b,const gsl_matrix *xl, const gsl_matrix *xu)
{


  /* Variables for call to qld */ 
  int mnn = Nconstr +2*Noptim;//A->size1+2*C->size1;	/* Constant set to m+2*n */

 
  double* qp_Cd;		// Objective function [nxn]
  double* qp_dd;		// Constant vector of the objective function [n]  
  double* qp_Ad;		// Data constraints [mxn]  
  double* qp_bd;		// Constant data of linear constraints [m]  
  double *qp_xud,*qp_xld;  // Constraints  
  double* qp_xd;    // Output  
  double* qp_u;		// Lagrange multipliers [m+n+n] (output vector)  
  double* qp_war;		// Workspace [3*n*n/2 + 10*n + 2*n]
  int* qp_iwar;		   // Integer workspace [n]


  int iout = 0;		/* Not used (code comented out in qld.c) */
  int ifail = 0;	/* Termination reason 0 == OK (output value) */
  int iprint = 0;	/* Print control 0 == off */
  //  double* war;		// Workspace [3*n*n/2 + 10*n + 2*n]
  int lwar = 3*Noptim*Noptim/2 + 10*Noptim + 2*Nconstr + 1;  //3*C->size1*C->size1/2 + 10*C->size1 + 2*A->size1 +1;	/* Workspace size */
  //  int* iwar;		   // Integer workspace [n]
  int liwar = Noptim; //C->size1;	/* Integer workspace size */
  double eps1 = 1.11e-16;	/* Machine presision */

  int i,j,k;

  
#define HEAP_SIZE (16*1024*1024)  
#define HEAP_MODE 0		// Local heap. 
 
  RT_HEAP heap_desc;  
  void *block;  
   int err;  
  
  int varNoptim = Noptim;
  int varNconstr = Nconstr;
  int me= Nconstr /2;


  
    err = rt_heap_create(&heap_desc,"gsl_qp_Heap",HEAP_SIZE,HEAP_MODE); 

  
    err = rt_heap_alloc(&heap_desc,Noptim*Noptim*sizeof(double),TM_NONBLOCK,(void*)&qp_Cd);  
    err |= rt_heap_alloc(&heap_desc,Noptim*sizeof(double),TM_NONBLOCK,(void*)&qp_dd);  
    err |= rt_heap_alloc(&heap_desc,Noptim*Nconstr*sizeof(double),TM_NONBLOCK,(void*)&qp_Ad);  
    err |= rt_heap_alloc(&heap_desc,Nconstr*sizeof(double),TM_NONBLOCK,(void*)&qp_bd);  
    err |= rt_heap_alloc(&heap_desc,Noptim*sizeof(double),TM_NONBLOCK,(void*)&qp_xld);  
    err |= rt_heap_alloc(&heap_desc,Noptim*sizeof(double),TM_NONBLOCK,(void*)&qp_xud);  
    err |= rt_heap_alloc(&heap_desc,Noptim*sizeof(double),TM_NONBLOCK,(void*)&qp_xd); 
    err |= rt_heap_alloc(&heap_desc,mnn*sizeof(double),TM_NONBLOCK,(void*)&qp_u);  
    err |= rt_heap_alloc(&heap_desc,lwar*sizeof(double),TM_NONBLOCK,(void*)&qp_war);  
    err |= rt_heap_alloc(&heap_desc,liwar*sizeof(double),TM_NONBLOCK,(void*)&qp_iwar);  

  //remise a zero des variables (u, war, iwar) qui ne sont pas initialisées automatiquement derriere
  for (i=0;i<(Nconstr+2*Noptim);i++)
    qp_u[i] = 0;
  for (i=0;i<(3*Noptim*Noptim/2 + 10*Noptim + 2*(Nout+(HORIZON+1)*Nst+2*HORIZON*Nin+Nout) +1);i++)
    qp_war[i] = 0;
  for (i=0;i<(Noptim);i++)
    qp_iwar[i] = 0;


  
  qp_iwar[0]=1;

  // Copy data in C, d and A, b to Cd, dd and Ad, bd (Fortran 77 standard) 
  for(k=0,j=0;j<Noptim;j++)
    for(i=0;i<Noptim;i++,k++)
      qp_Cd[k] = k;//gsl_matrix_get(C,i,j);
  for(i=0;i<Noptim;i++)
    qp_dd[i] = i;//gsl_matrix_get(d,i,0); 
  for(k=0,j=0;j<Noptim;j++)
    for(i=0;i<Nconstr;i++,k++)
      qp_Ad[k] = k;//-1.0 * gsl_matrix_get(A,i,j); 
  for(i=0;i<Nconstr;i++)
    qp_bd[i] = i;//gsl_matrix_get(b,i,0); 
  // Copy data in x, xu and xl to xd, xud and xld
  for(i=0;i<Noptim;i++)
    {   qp_xd[i]  = i;//gsl_matrix_get(x,i,0); 
      qp_xud[i] = i;//gsl_matrix_get(xu,i,0); 
      qp_xld[i] = i;//gsl_matrix_get(xl,i,0);
    };

  // Call interface function in qld.c
  ql0001_(&varNconstr, &me, &varNconstr, &varNoptim, &varNoptim, &mnn, qp_Cd, qp_dd, qp_Ad, qp_bd, qp_xld, qp_xud, qp_xd, qp_u, &iout, &ifail, &iprint, qp_war, &lwar, qp_iwar, &liwar, &eps1);

  //rt_task_set_mode(T_WARNSW , 0,  NULL);
  

  
  // Free the block: rt_heap_free(&heap_desc,block);
  rt_heap_free(&heap_desc,qp_iwar); 
  rt_heap_free(&heap_desc,qp_war); 
  rt_heap_free(&heap_desc,qp_u); 
  rt_heap_free(&heap_desc,qp_xd); 
  rt_heap_free(&heap_desc,qp_xud); 
  rt_heap_free(&heap_desc,qp_xld); 
  rt_heap_free(&heap_desc,qp_Ad); 
  rt_heap_free(&heap_desc,qp_bd); 
  rt_heap_free(&heap_desc,qp_dd); 
  rt_heap_free(&heap_desc,qp_Cd); 

  //printf("Heap Freed Succed\n");

  rt_heap_delete(&heap_desc); 
  //printf("Heap Delete Succeed\n");
  
  //rt_task_set_mode(0, T_WARNSW , NULL);
  //rt_task_set_mode(0, T_PRIMARY , NULL);

  /* If failure return -1 */
  if(ifail != 0)
    SETERRNO(ECONVERGE);

  return 0;
}


#ifndef F2C_INCLUDE
#define F2C_INCLUDE

typedef int integer;
typedef char *address;
typedef short int shortint;
typedef float real;
typedef double doublereal;
typedef struct { real r, i; } complex;
typedef struct { doublereal r, i; } doublecomplex;
typedef long int logical;
typedef short int shortlogical;

#define TRUE_ (1)
#define FALSE_ (0)

/* Extern is for use with -E */
#ifndef Extern
#define Extern extern
#endif

/* I/O stuff */

#ifdef f2c_i2
/* for -i2 */
typedef short flag;
typedef short ftnlen;
typedef short ftnint;
#else
typedef long flag;
typedef long ftnlen;
typedef long ftnint;
#endif

/*external read, write*/
typedef struct
{	flag cierr;
	ftnint ciunit;
	flag ciend;
	char *cifmt;
	ftnint cirec;
} cilist;

/*internal read, write*/
typedef struct
{	flag icierr;
	char *iciunit;
	flag iciend;
	char *icifmt;
	ftnint icirlen;
	ftnint icirnum;
} icilist;

/*open*/
typedef struct
{	flag oerr;
	ftnint ounit;
	char *ofnm;
	ftnlen ofnmlen;
	char *osta;
	char *oacc;
	char *ofm;
	ftnint orl;
	char *oblnk;
} olist;

/*close*/
typedef struct
{	flag cerr;
	ftnint cunit;
	char *csta;
} cllist;

/*rewind, backspace, endfile*/
typedef struct
{	flag aerr;
	ftnint aunit;
} alist;

/* inquire */
typedef struct
{	flag inerr;
	ftnint inunit;
	char *infile;
	ftnlen infilen;
	ftnint	*inex;	/*parameters in standard's order*/
	ftnint	*inopen;
	ftnint	*innum;
	ftnint	*innamed;
	char	*inname;
	ftnlen	innamlen;
	char	*inacc;
	ftnlen	inacclen;
	char	*inseq;
	ftnlen	inseqlen;
	char 	*indir;
	ftnlen	indirlen;
	char	*infmt;
	ftnlen	infmtlen;
	char	*inform;
	ftnint	informlen;
	char	*inunf;
	ftnlen	inunflen;
	ftnint	*inrecl;
	ftnint	*innrec;
	char	*inblank;
	ftnlen	inblanklen;
} inlist;

#define VOID void

union Multitype {	/* for multiple entry points */
	shortint h;
	integer i;
	real r;
	doublereal d;
	complex c;
	doublecomplex z;
	};

typedef union Multitype Multitype;

typedef long Long;

struct Vardesc {	/* for Namelist */
	char *name;
	char *addr;
	Long *dims;
	int  type;
	};
typedef struct Vardesc Vardesc;

struct Namelist {
	char *name;
	Vardesc **vars;
	int nvars;
	};
typedef struct Namelist Namelist;

#define abs(x) ((x) >= 0 ? (x) : -(x))
#define dabs(x) (doublereal)abs(x)
#define min(a,b) ((a) <= (b) ? (a) : (b))
#define max(a,b) ((a) >= (b) ? (a) : (b))
#define dmin(a,b) (doublereal)min(a,b)
#define dmax(a,b) (doublereal)max(a,b)

/* procedure parameter types for -A and -C++ */

#define F2C_proc_par_types 1
#ifdef __cplusplus
typedef int /* Unknown procedure type */ (*U_fp)(...);
typedef shortint (*J_fp)(...);
typedef integer (*I_fp)(...);
typedef real (*R_fp)(...);
typedef doublereal (*D_fp)(...), (*E_fp)(...);
typedef /* Complex */ VOID (*C_fp)(...);
typedef /* Double Complex */ VOID (*Z_fp)(...);
typedef logical (*L_fp)(...);
typedef shortlogical (*K_fp)(...);
typedef /* Character */ VOID (*H_fp)(...);
typedef /* Subroutine */ int (*S_fp)(...);
#else
typedef int /* Unknown procedure type */ (*U_fp)();
typedef shortint (*J_fp)();
typedef integer (*I_fp)();
typedef real (*R_fp)();
typedef doublereal (*D_fp)(), (*E_fp)();
typedef /* Complex */ VOID (*C_fp)();
typedef /* Double Complex */ VOID (*Z_fp)();
typedef logical (*L_fp)();
typedef shortlogical (*K_fp)();
typedef /* Character */ VOID (*H_fp)();
typedef /* Subroutine */ int (*S_fp)();
#endif
/* E_fp is for real functions when -R is not specified */
typedef VOID C_f;	/* complex function */
typedef VOID H_f;	/* character function */
typedef VOID Z_f;	/* double complex function */
typedef doublereal E_f;	/* real function with -R not specified */

/* undef any lower-case symbols that your C compiler predefines, e.g.: */

#ifndef Skip_f2c_Undefs
#undef cray
#undef gcos
#undef mc68010
#undef mc68020
#undef mips
#undef pdp11
#undef sgi
#undef sparc
#undef sun
#undef sun2
#undef sun3
#undef sun4
#undef u370
#undef u3b
#undef u3b2
#undef u3b5
#undef unix
#undef vax
#endif
#endif



/* Common Block Declarations */

struct {
    doublereal eps;
} cmache_;

#define cmache_1 cmache_

/* Table of constant values */

/*static integer c__1 = 1; */

/* umd */
/*
ql0002_ is declared here to provide ANSI C compliance.
(Thanks got to Martin Wauchope for providing this correction)
*/
/* umd */
/*
When the fortran code was f2c converted, the use of fortran COMMON
blocks was no longer available. Thus an additional variable, eps1,
was added to the parameter list to account for this.
*/
/* umd */
/* 
Two alternative definitions are provided in order to give ANSI
compliance.
*/
int ql0002_(integer *n,integer *m,integer *meq,integer *mmax,
            integer *mn,integer *mnn,integer *nmax,
            logical *lql,
            doublereal *a,doublereal *b,doublereal *grad,
            doublereal *g,doublereal *xl,doublereal *xu,doublereal *x,
            integer *nact,integer *iact,integer *maxit,
            doublereal *vsmall,
            integer *info,
            doublereal *diag, doublereal *w,
            integer *lw)
{
    /* System generated locals */
    integer a_dim1, a_offset, g_dim1, g_offset, i__1, i__2, i__3, i__4;
    doublereal d__1, d__2, d__3, d__4;

    /* Builtin functions */
    /* umd */
    /* double sqrt();    */

    /* Local variables */
    static doublereal onha, xmag, suma, sumb, sumc, temp, step, zero;
    static integer iwwn;
    static doublereal sumx, sumy;
    static integer i, j, k;
    static doublereal fdiff;
    static integer iflag, jflag, kflag, lflag;
    static doublereal diagr;
    static integer ifinc, kfinc, jfinc, mflag, nflag;
    static doublereal vfact, tempa;
    static integer iterc, itref;
    static doublereal cvmax, ratio, xmagr;
    static integer kdrop;
    static logical lower;
    static integer knext, k1;
    static doublereal ga, gb;
    static integer ia, id;
    static doublereal fdiffa;
    static integer ii, il, kk, jl, ip, ir, nm, is, iu, iw, ju, ix, iz, nu, iy;

    static doublereal parinc, parnew;
    static integer ira, irb, iwa;
    static doublereal one;
    static integer iwd, iza;
    static doublereal res;
    static integer ipp, iwr, iws;
    static doublereal sum;
    static integer iww, iwx, iwy;
    static doublereal two;
    static integer iwz;



    /* Parameter adjustments */
    --w;
    --iact;
    --x;
    --xu;
    --xl;
    g_dim1 = *nmax;
    g_offset = g_dim1 + 1;
    g -= g_offset;
    --grad;
    --b;
    a_dim1 = *mmax;
    a_offset = a_dim1 + 1;
    a -= a_offset;

    /* Function Body */
    iwz = *nmax;
    iwr = iwz + *nmax * *nmax;
    iww = iwr + *nmax * (*nmax + 3) / 2;
    iwd = iww + *nmax;
    iwx = iwd + *nmax;
    iwa = iwx + *nmax;

/*     SET SOME CONSTANTS. */

    zero = 0.;
    one = 1.;
    two = 2.;
    onha = 1.5;
    vfact = 1.;

/*     SET SOME PARAMETERS. */
/*     NUMBER LESS THAN VSMALL ARE ASSUMED TO BE NEGLIGIBLE. */
/*     THE MULTIPLE OF I THAT IS ADDED TO G IS AT MOST DIAGR TIMES */
/*       THE LEAST MULTIPLE OF I THAT GIVES POSITIVE DEFINITENESS. */
/*     X IS RE-INITIALISED IF ITS MAGNITUDE IS REDUCED BY THE */
/*       FACTOR XMAGR. */
/*     A CHECK IS MADE FOR AN INCREASE IN F EVERY IFINC ITERATIONS, */
/*       AFTER KFINC ITERATIONS ARE COMPLETED. */

    diagr = two;
    xmagr = .01;
    ifinc = 3;
    kfinc = max(10,*n);

/*     FIND THE RECIPROCALS OF THE LENGTHS OF THE CONSTRAINT NORMALS. */
/*     RETURN IF A CONSTRAINT IS INFEASIBLE DUE TO A ZERO NORMAL. */

    *nact = 0;
    if (*m <= 0) {
	goto L45;
    }
    i__1 = *m;
    for (k = 1; k <= i__1; ++k) {
	sum = zero;
	i__2 = *n;
	for (i = 1; i <= i__2; ++i) {
/* L10: */
/* Computing 2nd power */
	    d__1 = a[k + i * a_dim1];
	    sum += d__1 * d__1;
	}
	if (sum > zero) {
	    goto L20;
	}
	if (b[k] == zero) {
	    goto L30;
	}
	*info = -k;
	if (k <= *meq) {
	    goto L730;
	}
	if (b[k] <= 0.) {
	    goto L30;
	} else {
	    goto L730;
	}
L20:
	sum = one / sqrt(sum);
L30:
	ia = iwa + k;
/* L40: */
	w[ia] = sum;
    }
L45:
    i__1 = *n;
    for (k = 1; k <= i__1; ++k) {
	ia = iwa + *m + k;
/* L50: */
	w[ia] = one;
    }

/*     IF NECESSARY INCREASE THE DIAGONAL ELEMENTS OF G. */

    if (! (*lql)) {
	goto L165;
    }
    *diag = zero;
    i__1 = *n;
    for (i = 1; i <= i__1; ++i) {
	id = iwd + i;
	w[id] = g[i + i * g_dim1];
/* Computing MAX */
	d__1 = *diag, d__2 = *vsmall - w[id];
	*diag = max(d__1,d__2);
	if (i == *n) {
	    goto L60;
	}
	ii = i + 1;
	i__2 = *n;
	for (j = ii; j <= i__2; ++j) {
/* Computing MIN */
	    d__1 = w[id], d__2 = g[j + j * g_dim1];
	    ga = -min(d__1,d__2);
	    gb = (d__1 = w[id] - g[j + j * g_dim1], abs(d__1)) + (d__2 = g[i 
		    + j * g_dim1], abs(d__2));
	    if (gb > zero) {
/* Computing 2nd power */
		d__1 = g[i + j * g_dim1];
		ga += d__1 * d__1 / gb;
	    }
/* L55: */
	    *diag = max(*diag,ga);
	}
L60:
	;
    }
    if (*diag <= zero) {
	goto L90;
    }
L70:
    *diag = diagr * *diag;
    i__1 = *n;
    for (i = 1; i <= i__1; ++i) {
	id = iwd + i;
/* L80: */
	g[i + i * g_dim1] = *diag + w[id];
    }

/*     FORM THE CHOLESKY FACTORISATION OF G. THE TRANSPOSE */
/*     OF THE FACTOR WILL BE PLACED IN THE R-PARTITION OF W. */

L90:
    ir = iwr;
    i__1 = *n;
    for (j = 1; j <= i__1; ++j) {
	ira = iwr;
	irb = ir + 1;
	i__2 = j;
	for (i = 1; i <= i__2; ++i) {
	    temp = g[i + j * g_dim1];
	    if (i == 1) {
		goto L110;
	    }
	    i__3 = ir;
	    for (k = irb; k <= i__3; ++k) {
		++ira;
/* L100: */
		temp -= w[k] * w[ira];
	    }
L110:
	    ++ir;
	    ++ira;
	    if (i < j) {
		w[ir] = temp / w[ira];
	    }
/* L120: */
	}
	if (temp < *vsmall) {
	    goto L140;
	}
/* L130: */
	w[ir] = sqrt(temp);
    }
    goto L170;

/*     INCREASE FURTHER THE DIAGONAL ELEMENT OF G. */

L140:
    w[j] = one;
    sumx = one;
    k = j;
L150:
    sum = zero;
    ira = ir - 1;
    i__1 = j;
    for (i = k; i <= i__1; ++i) {
	sum -= w[ira] * w[i];
/* L160: */
	ira += i;
    }
    ir -= k;
    --k;
    w[k] = sum / w[ir];
/* Computing 2nd power */
    d__1 = w[k];
    sumx += d__1 * d__1;
    if (k >= 2) {
	goto L150;
    }
    *diag = *diag + *vsmall - temp / sumx;
    goto L70;

/*     STORE THE CHOLESKY FACTORISATION IN THE R-PARTITION */
/*     OF W. */

L165:
    ir = iwr;
    i__1 = *n;
    for (i = 1; i <= i__1; ++i) {
	i__2 = i;
	for (j = 1; j <= i__2; ++j) {
	    ++ir;
/* L166: */
	    w[ir] = g[j + i * g_dim1];
	}
    }

/*     SET Z THE INVERSE OF THE MATRIX IN R. */

L170:
    nm = *n - 1;
    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	iz = iwz + i;
	if (i == 1) {
	    goto L190;
	}
	i__1 = i;
	for (j = 2; j <= i__1; ++j) {
	    w[iz] = zero;
/* L180: */
	    iz += *n;
	}
L190:
	ir = iwr + (i + i * i) / 2;
	w[iz] = one / w[ir];
	if (i == *n) {
	    goto L220;
	}
	iza = iz;
	i__1 = nm;
	for (j = i; j <= i__1; ++j) {
	    ir += i;
	    sum = zero;
	    i__3 = iz;
	    i__4 = *n;
	    for (k = iza; i__4 < 0 ? k >= i__3 : k <= i__3; k += i__4) {
		sum += w[k] * w[ir];
/* L200: */
		++ir;
	    }
	    iz += *n;
/* L210: */
	    w[iz] = -sum / w[ir];
	}
L220:
	;
    }

/*     SET THE INITIAL VALUES OF SOME VARIABLES. */
/*     ITERC COUNTS THE NUMBER OF ITERATIONS. */
/*     ITREF IS SET TO ONE WHEN ITERATIVE REFINEMENT IS REQUIRED. */
/*     JFINC INDICATES WHEN TO TEST FOR AN INCREASE IN F. */

    iterc = 1;
    itref = 0;
    jfinc = -kfinc;

/*     SET X TO ZERO AND SET THE CORRESPONDING RESIDUALS OF THE */
/*     KUHN-TUCKER CONDITIONS. */

L230:
    iflag = 1;
    iws = iww - *n;
    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	x[i] = zero;
	iw = iww + i;
	w[iw] = grad[i];
	if (i > *nact) {
	    goto L240;
	}
	w[i] = zero;
	is = iws + i;
	k = iact[i];
	if (k <= *m) {
	    goto L235;
	}
	if (k > *mn) {
	    goto L234;
	}
	k1 = k - *m;
	w[is] = xl[k1];
	goto L240;
L234:
	k1 = k - *mn;
	w[is] = -xu[k1];
	goto L240;
L235:
	w[is] = b[k];
L240:
	;
    }
    xmag = zero;
    vfact = 1.;
    if (*nact <= 0) {
	goto L340;
    } else {
	goto L280;
    }

/*     SET THE RESIDUALS OF THE KUHN-TUCKER CONDITIONS FOR GENERAL X. */

L250:
    iflag = 2;
    iws = iww - *n;
    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	iw = iww + i;
	w[iw] = grad[i];
	if (*lql) {
	    goto L259;
	}
	id = iwd + i;
	w[id] = zero;
	i__1 = *n;
	for (j = i; j <= i__1; ++j) {
/* L251: */
	    w[id] += g[i + j * g_dim1] * x[j];
	}
	i__1 = i;
	for (j = 1; j <= i__1; ++j) {
	    id = iwd + j;
/* L252: */
	    w[iw] += g[j + i * g_dim1] * w[id];
	}
	goto L260;
L259:
	i__1 = *n;
	for (j = 1; j <= i__1; ++j) {
/* L261: */
	    w[iw] += g[i + j * g_dim1] * x[j];
	}
L260:
	;
    }
    if (*nact == 0) {
	goto L340;
    }
    i__2 = *nact;
    for (k = 1; k <= i__2; ++k) {
	kk = iact[k];
	is = iws + k;
	if (kk > *m) {
	    goto L265;
	}
	w[is] = b[kk];
	i__1 = *n;
	for (i = 1; i <= i__1; ++i) {
	    iw = iww + i;
	    w[iw] -= w[k] * a[kk + i * a_dim1];
/* L264: */
	    w[is] -= x[i] * a[kk + i * a_dim1];
	}
	goto L270;
L265:
	if (kk > *mn) {
	    goto L266;
	}
	k1 = kk - *m;
	iw = iww + k1;
	w[iw] -= w[k];
	w[is] = xl[k1] - x[k1];
	goto L270;
L266:
	k1 = kk - *mn;
	iw = iww + k1;
	w[iw] += w[k];
	w[is] = -xu[k1] + x[k1];
L270:
	;
    }

/*     PRE-MULTIPLY THE VECTOR IN THE S-PARTITION OF W BY THE */
/*     INVERS OF R TRANSPOSE. */

L280:
    ir = iwr;
    ip = iww + 1;
    ipp = iww + *n;
    il = iws + 1;
    iu = iws + *nact;
    i__2 = iu;
    for (i = il; i <= i__2; ++i) {
	sum = zero;
	if (i == il) {
	    goto L300;
	}
	ju = i - 1;
	i__1 = ju;
	for (j = il; j <= i__1; ++j) {
	    ++ir;
/* L290: */
	    sum += w[ir] * w[j];
	}
L300:
	++ir;
/* L310: */
	w[i] = (w[i] - sum) / w[ir];
    }

/*     SHIFT X TO SATISFY THE ACTIVE CONSTRAINTS AND MAKE THE */
/*     CORRESPONDING CHANGE TO THE GRADIENT RESIDUALS. */

    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	iz = iwz + i;
	sum = zero;
	i__1 = iu;
	for (j = il; j <= i__1; ++j) {
	    sum += w[j] * w[iz];
/* L320: */
	    iz += *n;
	}
	x[i] += sum;
	if (*lql) {
	    goto L329;
	}
	id = iwd + i;
	w[id] = zero;
	i__1 = *n;
	for (j = i; j <= i__1; ++j) {
/* L321: */
	    w[id] += g[i + j * g_dim1] * sum;
	}
	iw = iww + i;
	i__1 = i;
	for (j = 1; j <= i__1; ++j) {
	    id = iwd + j;
/* L322: */
	    w[iw] += g[j + i * g_dim1] * w[id];
	}
	goto L330;
L329:
	i__1 = *n;
	for (j = 1; j <= i__1; ++j) {
	    iw = iww + j;
/* L331: */
	    w[iw] += sum * g[i + j * g_dim1];
	}
L330:
	;
    }

/*     FORM THE SCALAR PRODUCT OF THE CURRENT GRADIENT RESIDUALS */
/*     WITH EACH COLUMN OF Z. */

L340:
    kflag = 1;
    goto L930;
L350:
    if (*nact == *n) {
	goto L380;
    }

/*     SHIFT X SO THAT IT SATISFIES THE REMAINING KUHN-TUCKER */
/*     CONDITIONS. */

    il = iws + *nact + 1;
    iza = iwz + *nact * *n;
    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	sum = zero;
	iz = iza + i;
	i__1 = iww;
	for (j = il; j <= i__1; ++j) {
	    sum += w[iz] * w[j];
/* L360: */
	    iz += *n;
	}
/* L370: */
	x[i] -= sum;
    }
    *info = 0;
    if (*nact == 0) {
	goto L410;
    }

/*     UPDATE THE LAGRANGE MULTIPLIERS. */

L380:
    lflag = 3;
    goto L740;
L390:
    i__2 = *nact;
    for (k = 1; k <= i__2; ++k) {
	iw = iww + k;
/* L400: */
	w[k] += w[iw];
    }

/*     REVISE THE VALUES OF XMAG. */
/*     BRANCH IF ITERATIVE REFINEMENT IS REQUIRED. */

L410:
    jflag = 1;
    goto L910;
L420:
    if (iflag == itref) {
	goto L250;
    }

/*     DELETE A CONSTRAINT IF A LAGRANGE MULTIPLIER OF AN */
/*     INEQUALITY CONSTRAINT IS NEGATIVE. */

    kdrop = 0;
    goto L440;
L430:
    ++kdrop;
    if (w[kdrop] >= zero) {
	goto L440;
    }
    if (iact[kdrop] <= *meq) {
	goto L440;
    }
    nu = *nact;
    mflag = 1;
    goto L800;
L440:
    if (kdrop < *nact) {
	goto L430;
    }

/*     SEEK THE GREATEAST NORMALISED CONSTRAINT VIOLATION, DISREGARDING */

/*     ANY THAT MAY BE DUE TO COMPUTER ROUNDING ERRORS. */

L450:
    cvmax = zero;
    if (*m <= 0) {
	goto L481;
    }
    i__2 = *m;
    for (k = 1; k <= i__2; ++k) {
	ia = iwa + k;
	if (w[ia] <= zero) {
	    goto L480;
	}
	sum = -b[k];
	i__1 = *n;
	for (i = 1; i <= i__1; ++i) {
/* L460: */
	    sum += x[i] * a[k + i * a_dim1];
	}
	sumx = -sum * w[ia];
	if (k <= *meq) {
	    sumx = abs(sumx);
	}
	if (sumx <= cvmax) {
	    goto L480;
	}
	temp = (d__1 = b[k], abs(d__1));
	i__1 = *n;
	for (i = 1; i <= i__1; ++i) {
/* L470: */
	    temp += (d__1 = x[i] * a[k + i * a_dim1], abs(d__1));
	}
	tempa = temp + abs(sum);
	if (tempa <= temp) {
	    goto L480;
	}
	temp += onha * abs(sum);
	if (temp <= tempa) {
	    goto L480;
	}
	cvmax = sumx;
	res = sum;
	knext = k;
L480:
	;
    }
L481:
    i__2 = *n;
    for (k = 1; k <= i__2; ++k) {
	lower = TRUE_;
	ia = iwa + *m + k;
	if (w[ia] <= zero) {
	    goto L485;
	}
	sum = xl[k] - x[k];
	if (sum < 0.) {
	    goto L482;
	} else if (sum == 0) {
	    goto L485;
	} else {
	    goto L483;
	}
L482:
	sum = x[k] - xu[k];
	lower = FALSE_;
L483:
	if (sum <= cvmax) {
	    goto L485;
	}
	cvmax = sum;
	res = -sum;
	knext = k + *m;
	if (lower) {
	    goto L485;
	}
	knext = k + *mn;
L485:
	;
    }

/*     TEST FOR CONVERGENCE */

    *info = 0;
    if (cvmax <= *vsmall) {
	goto L700;
    }

/*     RETURN IF, DUE TO ROUNDING ERRORS, THE ACTUAL CHANGE IN */
/*     X MAY NOT INCREASE THE OBJECTIVE FUNCTION */

    ++jfinc;
    if (jfinc == 0) {
	goto L510;
    }
    if (jfinc != ifinc) {
	goto L530;
    }
    fdiff = zero;
    fdiffa = zero;
    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	sum = two * grad[i];
	sumx = abs(sum);
	if (*lql) {
	    goto L489;
	}
	id = iwd + i;
	w[id] = zero;
	i__1 = *n;
	for (j = i; j <= i__1; ++j) {
	    ix = iwx + j;
/* L486: */
	    w[id] += g[i + j * g_dim1] * (w[ix] + x[j]);
	}
	i__1 = i;
	for (j = 1; j <= i__1; ++j) {
	    id = iwd + j;
	    temp = g[j + i * g_dim1] * w[id];
	    sum += temp;
/* L487: */
	    sumx += abs(temp);
	}
	goto L495;
L489:
	i__1 = *n;
	for (j = 1; j <= i__1; ++j) {
	    ix = iwx + j;
	    temp = g[i + j * g_dim1] * (w[ix] + x[j]);
	    sum += temp;
/* L490: */
	    sumx += abs(temp);
	}
L495:
	ix = iwx + i;
	fdiff += sum * (x[i] - w[ix]);
/* L500: */
	fdiffa += sumx * (d__1 = x[i] - w[ix], abs(d__1));
    }
    *info = 2;
    sum = fdiffa + fdiff;
    if (sum <= fdiffa) {
	goto L700;
    }
    temp = fdiffa + onha * fdiff;
    if (temp <= sum) {
	goto L700;
    }
    jfinc = 0;
    *info = 0;
L510:
    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	ix = iwx + i;
/* L520: */
	w[ix] = x[i];
    }

/*     FORM THE SCALAR PRODUCT OF THE NEW CONSTRAINT NORMAL WITH EACH */
/*     COLUMN OF Z. PARNEW WILL BECOME THE LAGRANGE MULTIPLIER OF */
/*     THE NEW CONSTRAINT. */

L530:
    ++iterc;
    if (iterc <= *maxit) {
	goto L531;
    }
    *info = 1;
    goto L710;
L531:
    iws = iwr + (*nact + *nact * *nact) / 2;
    if (knext > *m) {
	goto L541;
    }
    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	iw = iww + i;
/* L540: */
	w[iw] = a[knext + i * a_dim1];
    }
    goto L549;
L541:
    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	iw = iww + i;
/* L542: */
	w[iw] = zero;
    }
    k1 = knext - *m;
    if (k1 > *n) {
	goto L545;
    }
    iw = iww + k1;
    w[iw] = one;
    iz = iwz + k1;
    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	is = iws + i;
	w[is] = w[iz];
/* L543: */
	iz += *n;
    }
    goto L550;
L545:
    k1 = knext - *mn;
    iw = iww + k1;
    w[iw] = -one;
    iz = iwz + k1;
    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	is = iws + i;
	w[is] = -w[iz];
/* L546: */
	iz += *n;
    }
    goto L550;
L549:
    kflag = 2;
    goto L930;
L550:
    parnew = zero;

/*     APPLY GIVENS ROTATIONS TO MAKE THE LAST (N-NACT-2) SCALAR */
/*     PRODUCTS EQUAL TO ZERO. */

    if (*nact == *n) {
	goto L570;
    }
    nu = *n;
    nflag = 1;
    goto L860;

/*     BRANCH IF THERE IS NO NEED TO DELETE A CONSTRAINT. */

L560:
    is = iws + *nact;
    if (*nact == 0) {
	goto L640;
    }
    suma = zero;
    sumb = zero;
    sumc = zero;
    iz = iwz + *nact * *n;
    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	++iz;
	iw = iww + i;
	suma += w[iw] * w[iz];
	sumb += (d__1 = w[iw] * w[iz], abs(d__1));
/* L563: */
/* Computing 2nd power */
	d__1 = w[iz];
	sumc += d__1 * d__1;
    }
    temp = sumb + abs(suma) * .1;
    tempa = sumb + abs(suma) * .2;
    if (temp <= sumb) {
	goto L570;
    }
    if (tempa <= temp) {
	goto L570;
    }
    if (sumb > *vsmall) {
	goto L5;
    }
    goto L570;
L5:
    sumc = sqrt(sumc);
    ia = iwa + knext;
    if (knext <= *m) {
	sumc /= w[ia];
    }
    temp = sumc + abs(suma) * .1;
    tempa = sumc + abs(suma) * .2;
    if (temp <= sumc) {
	goto L567;
    }
    if (tempa <= temp) {
	goto L567;
    }
    goto L640;

/*     CALCULATE THE MULTIPLIERS FOR THE NEW CONSTRAINT NORMAL */
/*     EXPRESSED IN TERMS OF THE ACTIVE CONSTRAINT NORMALS. */
/*     THEN WORK OUT WHICH CONTRAINT TO DROP. */

L567:
    lflag = 4;
    goto L740;
L570:
    lflag = 1;
    goto L740;

/*     COMPLETE THE TEST FOR LINEARLY DEPENDENT CONSTRAINTS. */

L571:
    if (knext > *m) {
	goto L574;
    }
    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	suma = a[knext + i * a_dim1];
	sumb = abs(suma);
	if (*nact == 0) {
	    goto L581;
	}
	i__1 = *nact;
	for (k = 1; k <= i__1; ++k) {
	    kk = iact[k];
	    if (kk <= *m) {
		goto L568;
	    }
	    kk -= *m;
	    temp = zero;
	    if (kk == i) {
		temp = w[iww + kk];
	    }
	    kk -= *n;
	    if (kk == i) {
		temp = -w[iww + kk];
	    }
	    goto L569;
L568:
	    iw = iww + k;
	    temp = w[iw] * a[kk + i * a_dim1];
L569:
	    suma -= temp;
/* L572: */
	    sumb += abs(temp);
	}
L581:
	if (suma <= *vsmall) {
	    goto L573;
	}
	temp = sumb + abs(suma) * .1;
	tempa = sumb + abs(suma) * .2;
	if (temp <= sumb) {
	    goto L573;
	}
	if (tempa <= temp) {
	    goto L573;
	}
	goto L630;
L573:
	;
    }
    lflag = 1;
    goto L775;
L574:
    k1 = knext - *m;
    if (k1 > *n) {
	k1 -= *n;
    }
    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	suma = zero;
	if (i != k1) {
	    goto L575;
	}
	suma = one;
	if (knext > *mn) {
	    suma = -one;
	}
L575:
	sumb = abs(suma);
	if (*nact == 0) {
	    goto L582;
	}
	i__1 = *nact;
	for (k = 1; k <= i__1; ++k) {
	    kk = iact[k];
	    if (kk <= *m) {
		goto L579;
	    }
	    kk -= *m;
	    temp = zero;
	    if (kk == i) {
		temp = w[iww + kk];
	    }
	    kk -= *n;
	    if (kk == i) {
		temp = -w[iww + kk];
	    }
	    goto L576;
L579:
	    iw = iww + k;
	    temp = w[iw] * a[kk + i * a_dim1];
L576:
	    suma -= temp;
/* L577: */
	    sumb += abs(temp);
	}
L582:
	temp = sumb + abs(suma) * .1;
	tempa = sumb + abs(suma) * .2;
	if (temp <= sumb) {
	    goto L578;
	}
	if (tempa <= temp) {
	    goto L578;
	}
	goto L630;
L578:
	;
    }
    lflag = 1;
    goto L775;

/*     BRANCH IF THE CONTRAINTS ARE INCONSISTENT. */

L580:

    *info = -knext;
    if (kdrop == 0) {
	goto L700;
    }
    parinc = ratio;
    parnew = parinc;

/*     REVISE THE LAGRANGE MULTIPLIERS OF THE ACTIVE CONSTRAINTS. */

L590:
    if (*nact == 0) {
	goto L601;
    }
    i__2 = *nact;
    for (k = 1; k <= i__2; ++k) {
	iw = iww + k;
	w[k] -= parinc * w[iw];
	if (iact[k] > *meq) {
/* Computing MAX */
	    d__1 = zero, d__2 = w[k];
	    w[k] = max(d__1,d__2);
	}
/* L600: */
    }
L601:
    if (kdrop == 0) {
	goto L680;
    }

/*     DELETE THE CONSTRAINT TO BE DROPPED. */
/*     SHIFT THE VECTOR OF SCALAR PRODUCTS. */
/*     THEN, IF APPROPRIATE, MAKE ONE MORE SCALAR PRODUCT ZERO. */

    nu = *nact + 1;
    mflag = 2;
    goto L800;
L610:
    iws = iws - *nact - 1;
    nu = min(*n,nu);
    i__2 = nu;
    for (i = 1; i <= i__2; ++i) {
	is = iws + i;
	j = is + *nact;
/* L620: */
	w[is] = w[j + 1];
    }
    nflag = 2;
    goto L860;

/*     CALCULATE THE STEP TO THE VIOLATED CONSTRAINT. */

L630:
    is = iws + *nact;
L640:
    sumy = w[is + 1];
    step = -res / sumy;
    parinc = step / sumy;
    if (*nact == 0) {
	goto L660;
    }

/*     CALCULATE THE CHANGES TO THE LAGRANGE MULTIPLIERS, AND REDUCE */
/*     THE STEP ALONG THE NEW SEARCH DIRECTION IF NECESSARY. */

    lflag = 2;
    goto L740;
L650:
    if (kdrop == 0) {
	goto L660;
    }
    temp = one - ratio / parinc;
    if (temp <= zero) {
	kdrop = 0;
    }
    if (kdrop == 0) {
	goto L660;
    }
    step = ratio * sumy;
    parinc = ratio;
    res = temp * res;

/*     UPDATE X AND THE LAGRANGE MULTIPIERS. */
/*     DROP A CONSTRAINT IF THE FULL STEP IS NOT TAKEN. */

L660:
    iwy = iwz + *nact * *n;
    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	iy = iwy + i;
/* L670: */
	x[i] += step * w[iy];
    }
    parnew += parinc;
    if (*nact >= 1) {
	goto L590;
    }

/*     ADD THE NEW CONSTRAINT TO THE ACTIVE SET. */

L680:
    ++(*nact);
    w[*nact] = parnew;
    iact[*nact] = knext;
    ia = iwa + knext;
    if (knext > *mn) {
	ia -= *n;
    }
    w[ia] = -w[ia];

/*     ESTIMATE THE MAGNITUDE OF X. THEN BEGIN A NEW ITERATION, */
/*     RE-INITILISING X IF THIS MAGNITUDE IS SMALL. */

    jflag = 2;
    goto L910;
L690:
    if (sum < xmagr * xmag) {
	goto L230;
    }
    if (itref <= 0) {
	goto L450;
    } else {
	goto L250;
    }

/*     INITIATE ITERATIVE REFINEMENT IF IT HAS NOT YET BEEN USED, */
/*     OR RETURN AFTER RESTORING THE DIAGONAL ELEMENTS OF G. */

L700:
    if (iterc == 0) {
	goto L710;
    }
    ++itref;
    jfinc = -1;
    if (itref == 1) {
	goto L250;
    }
L710:
    if (! (*lql)) {
	return 0;
    }
    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	id = iwd + i;
/* L720: */
	g[i + i * g_dim1] = w[id];
    }
L730:
    return 0;


/*     THE REMAINIG INSTRUCTIONS ARE USED AS SUBROUTINES. */


/* ******************************************************************** */



/*     CALCULATE THE LAGRANGE MULTIPLIERS BY PRE-MULTIPLYING THE */
/*     VECTOR IN THE S-PARTITION OF W BY THE INVERSE OF R. */

L740:
    ir = iwr + (*nact + *nact * *nact) / 2;
    i = *nact;
    sum = zero;
    goto L770;
L750:
    ira = ir - 1;
    sum = zero;
    if (*nact == 0) {
	goto L761;
    }
    i__2 = *nact;
    for (j = i; j <= i__2; ++j) {
	iw = iww + j;
	sum += w[ira] * w[iw];
/* L760: */
	ira += j;
    }
L761:
    ir -= i;
    --i;
L770:
    iw = iww + i;
    is = iws + i;
    w[iw] = (w[is] - sum) / w[ir];
    if (i > 1) {
	goto L750;
    }
    if (lflag == 3) {
	goto L390;
    }
    if (lflag == 4) {
	goto L571;
    }

/*     CALCULATE THE NEXT CONSTRAINT TO DROP. */

L775:
    ip = iww + 1;
    ipp = iww + *nact;
    kdrop = 0;
    if (*nact == 0) {
	goto L791;
    }
    i__2 = *nact;
    for (k = 1; k <= i__2; ++k) {
	if (iact[k] <= *meq) {
	    goto L790;
	}
	iw = iww + k;
	if (res * w[iw] >= zero) {
	    goto L790;
	}
	temp = w[k] / w[iw];
	if (kdrop == 0) {
	    goto L780;
	}
	if (abs(temp) >= abs(ratio)) {
	    goto L790;
	}
L780:
	kdrop = k;
	ratio = temp;
L790:
	;
    }
L791:
    switch ((int)lflag) {
	case 1:  goto L580;
	case 2:  goto L650;
    }


/* ******************************************************************** */



/*     DROP THE CONSTRAINT IN POSITION KDROP IN THE ACTIVE SET. */

L800:
    ia = iwa + iact[kdrop];
    if (iact[kdrop] > *mn) {
	ia -= *n;
    }
    w[ia] = -w[ia];
    if (kdrop == *nact) {
	goto L850;
    }

/*     SET SOME INDICES AND CALCULATE THE ELEMENTS OF THE NEXT */
/*     GIVENS ROTATION. */

    iz = iwz + kdrop * *n;
    ir = iwr + (kdrop + kdrop * kdrop) / 2;
L810:
    ira = ir;
    ir = ir + kdrop + 1;
/* Computing MAX */
    d__3 = (d__1 = w[ir - 1], abs(d__1)), d__4 = (d__2 = w[ir], abs(d__2));
    temp = max(d__3,d__4);
/* Computing 2nd power */
    d__1 = w[ir - 1] / temp;
/* Computing 2nd power */
    d__2 = w[ir] / temp;
    sum = temp * sqrt(d__1 * d__1 + d__2 * d__2);
    ga = w[ir - 1] / sum;
    gb = w[ir] / sum;

/*     EXCHANGE THE COLUMNS OF R. */

    i__2 = kdrop;
    for (i = 1; i <= i__2; ++i) {
	++ira;
	j = ira - kdrop;
	temp = w[ira];
	w[ira] = w[j];
/* L820: */
	w[j] = temp;
    }
    w[ir] = zero;

/*     APPLY THE ROTATION TO THE ROWS OF R. */

    w[j] = sum;
    ++kdrop;
    i__2 = nu;
    for (i = kdrop; i <= i__2; ++i) {
	temp = ga * w[ira] + gb * w[ira + 1];
	w[ira + 1] = ga * w[ira + 1] - gb * w[ira];
	w[ira] = temp;
/* L830: */
	ira += i;
    }

/*     APPLY THE ROTATION TO THE COLUMNS OF Z. */

    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	++iz;
	j = iz - *n;
	temp = ga * w[j] + gb * w[iz];
	w[iz] = ga * w[iz] - gb * w[j];
/* L840: */
	w[j] = temp;
    }

/*     REVISE IACT AND THE LAGRANGE MULTIPLIERS. */

    iact[kdrop - 1] = iact[kdrop];
    w[kdrop - 1] = w[kdrop];
    if (kdrop < *nact) {
	goto L810;
    }
L850:
    --(*nact);
    switch ((int)mflag) {
	case 1:  goto L250;
	case 2:  goto L610;
    }


/* ******************************************************************** */



/*     APPLY GIVENS ROTATION TO REDUCE SOME OF THE SCALAR */
/*     PRODUCTS IN THE S-PARTITION OF W TO ZERO. */

L860:
    iz = iwz + nu * *n;
L870:
    iz -= *n;
L880:
    is = iws + nu;
    --nu;
    if (nu == *nact) {
	goto L900;
    }
    if (w[is] == zero) {
	goto L870;
    }
/* Computing MAX */
    d__3 = (d__1 = w[is - 1], abs(d__1)), d__4 = (d__2 = w[is], abs(d__2));
    temp = max(d__3,d__4);
/* Computing 2nd power */
    d__1 = w[is - 1] / temp;
/* Computing 2nd power */
    d__2 = w[is] / temp;
    sum = temp * sqrt(d__1 * d__1 + d__2 * d__2);
    ga = w[is - 1] / sum;
    gb = w[is] / sum;
    w[is - 1] = sum;
    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	k = iz + *n;
	temp = ga * w[iz] + gb * w[k];
	w[k] = ga * w[k] - gb * w[iz];
	w[iz] = temp;
/* L890: */
	--iz;
    }
    goto L880;
L900:
    switch ((int)nflag) {
	case 1:  goto L560;
	case 2:  goto L630;
    }


/* ******************************************************************** */



/*     CALCULATE THE MAGNITUDE OF X AN REVISE XMAG. */

L910:
    sum = zero;
    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	sum += (d__1 = x[i], abs(d__1)) * vfact * ((d__2 = grad[i], abs(d__2))
		 + (d__3 = g[i + i * g_dim1] * x[i], abs(d__3)));
	if (*lql) {
	    goto L920;
	}
	if (sum < 1e-30) {
	    goto L920;
	}
	vfact *= 1e-10;
	sum *= 1e-10;
	xmag *= 1e-10;
L920:
	;
    }
/* L925: */
    xmag = max(xmag,sum);
    switch ((int)jflag) {
	case 1:  goto L420;
	case 2:  goto L690;
    }


/* ******************************************************************** */



/*     PRE-MULTIPLY THE VECTOR IN THE W-PARTITION OF W BY Z TRANSPOSE. */

L930:
    jl = iww + 1;
    iz = iwz;
    i__2 = *n;
    for (i = 1; i <= i__2; ++i) {
	is = iws + i;
	w[is] = zero;
	iwwn = iww + *n;
	i__1 = iwwn;
	for (j = jl; j <= i__1; ++j) {
	    ++iz;
/* L940: */
	    w[is] += w[iz] * w[j];
	}
    }
    switch ((int)kflag) {
	case 1:  goto L350;
	case 2:  goto L550;
    }
    return 0;
} /* ql0002_ */
#ifdef __STDC__
int ql0001_(int *m,int *me,int *mmax,int *n,int *nmax,int *mnn,
            double *c,double *d,double *a,double *b,double *xl,
            double *xu,double *x,double *u,int *iout,int *ifail,
            int *iprint,double *war,int *lwar,int *iwar,int *liwar,
            double *eps1)
#else
/* Subroutine */ 
int ql0001_(m, me, mmax, n, nmax, mnn, c, d, a, b, xl, xu, x,
	 u, iout, ifail, iprint, war, lwar, iwar, liwar, eps1)
integer *m, *me, *mmax, *n, *nmax, *mnn;
doublereal *c, *d, *a, *b, *xl, *xu, *x, *u;
integer *iout, *ifail, *iprint;
doublereal *war;
integer *lwar, *iwar, *liwar;
doublereal *eps1;
#endif
{
    /* Format strings */
/*     static char fmt_1000[] = "(/8x,\002***QL: MATRIX G WAS ENLARGED\002,i3\ */
/* ,\002-TIMES BY UNITMATRIX\002)"; */
/*     static char fmt_1100[] = "(/8x,\002***QL: CONSTRAINT \002,i5,\002 NOT CO\ */
/* NSISTENT TO \002,/,(10x,10i5))"; */
/*     static char fmt_1200[] = "(/8x,\002***QL: LWAR TOO SMALL\002)"; */
/*     static char fmt_1210[] = "(/8x,\002***QL: LIWAR TOO SMALL\002)"; */
/*     static char fmt_1220[] = "(/8x,\002***QL: MNN TOO SMALL\002)"; */
/*     static char fmt_1300[] = "(/8x,\002***QL: TOO MANY ITERATIONS (MORE THA\ */
/* N\002,i6,\002)\002)"; */
/*     static char fmt_1400[] = "(/8x,\002***QL: ACCURACY INSUFFICIENT TO ATTAI\ */
/* N CONVERGENCE\002)"; */

    /* System generated locals */
    integer c_dim1, c_offset, a_dim1, a_offset, i__1;

    /* Builtin functions */
/*    integer s_wsfe(), do_fio(), e_wsfe(); */

    /* Local variables */
    static doublereal diag;
    /* extern int ql0002_(); */
    static integer nact, info;
    static doublereal zero;
    static integer i, j, idiag, maxit;
    static doublereal qpeps;
    static integer in, mn, lw;
    static doublereal ten;
    static logical lql;
    static integer inw1, inw2;

    /* Fortran I/O blocks */
    /*     static cilist io___16 = { 0, 0, 0, fmt_1000, 0 }; */
    /*     static cilist io___18 = { 0, 0, 0, fmt_1100, 0 }; */
    /*     static cilist io___19 = { 0, 0, 0, fmt_1200, 0 }; */
    /*     static cilist io___20 = { 0, 0, 0, fmt_1210, 0 }; */
    /*     static cilist io___21 = { 0, 0, 0, fmt_1220, 0 }; */
    /*     static cilist io___22 = { 0, 0, 0, fmt_1300, 0 }; */
    /*     static cilist io___23 = { 0, 0, 0, fmt_1400, 0 }; */





/*     INTRINSIC FUNCTIONS:  DSQRT */

    /* Parameter adjustments */
    --iwar;
    --war;
    --u;
    --x;
    --xu;
    --xl;
    --b;
    a_dim1 = *mmax;
    a_offset = a_dim1 + 1;
    a -= a_offset;
    --d;
    c_dim1 = *nmax;
    c_offset = c_dim1 + 1;
    c -= c_offset;

    /* Function Body */
    cmache_1.eps = *eps1;

/*     CONSTANT DATA */

/* ################################################################# */

    if (fabs(c[*nmax + *nmax * c_dim1]) == 0.e0) {
	c[*nmax + *nmax * c_dim1] = cmache_1.eps;
    }

/* umd */
/*  This prevents a subsequent more major modification of the Hessian */
/*  matrix in the important case when a minmax problem (yielding a */
/*  singular Hessian matrix) is being solved. */
/*                                 ----UMCP, April 1991, Jian L. Zhou */
/* ################################################################# */

    lql = FALSE_;
    if (iwar[1] == 1) {
	lql = TRUE_;
    }
    zero = 0.;
    ten = 10.;
    maxit = (*m + *n) * 40;
    qpeps = cmache_1.eps;
    inw1 = 1;
    inw2 = inw1 + *mmax;

/*     PREPARE PROBLEM DATA FOR EXECUTION */

    if (*m <= 0) {
	goto L20;
    }
    in = inw1;
    i__1 = *m;
    for (j = 1; j <= i__1; ++j) {
	war[in] = -b[j];
/* L10: */
	++in;
    }
L20:
    lw = *nmax * 3 * *nmax / 2 + *nmax * 10 + *m;
    if (inw2 + lw > *lwar) {
	goto L80;
    }
    if (*liwar < *n) {
	goto L81;
    }
    if (*mnn < *m + *n + *n) {
	goto L82;
    }
    mn = *m + *n;

/*     CALL OF QL0002 */

    ql0002_(n, m, me, mmax, &mn, mnn, nmax, &lql, &a[a_offset], &war[inw1], &
	    d[1], &c[c_offset], &xl[1], &xu[1], &x[1], &nact, &iwar[1], &
	    maxit, &qpeps, &info, &diag, &war[inw2], &lw);

/*     TEST OF MATRIX CORRECTIONS */

    *ifail = 0;
    if (info == 1) {
	goto L40;
    }
    if (info == 2) {
	goto L90;
    }
    idiag = 0;
    if (diag > zero && diag < 1e3) {
	idiag = (integer) diag;
    }
/*
    if (*iprint > 0 && idiag > 0) {
	io___16.ciunit = *iout;
	s_wsfe(&io___16);
	do_fio(&c__1, (char *)&idiag, (ftnlen)sizeof(integer));
	e_wsfe();
    }
*/
    if (info < 0) {
	goto L70;
    }

/*     REORDER MULTIPLIER */

    i__1 = *mnn;
    for (j = 1; j <= i__1; ++j) {
/* L50: */
	u[j] = zero;
    }
    in = inw2 - 1;
    if (nact == 0) {
	goto L30;
    }
    i__1 = nact;
    for (i = 1; i <= i__1; ++i) {
	j = iwar[i];
	u[j] = war[in + i];
/* L60: */
    }
L30:
    return 0;

/*     ERROR MESSAGES */

L70:
    *ifail = -info + 10;
/*
    if (*iprint > 0 && nact > 0) {
	io___18.ciunit = *iout;
	s_wsfe(&io___18);
	i__1 = -info;
	do_fio(&c__1, (char *)&i__1, (ftnlen)sizeof(integer));
	i__2 = nact;
	for (i = 1; i <= i__2; ++i) {
	    do_fio(&c__1, (char *)&iwar[i], (ftnlen)sizeof(integer));
	}
	e_wsfe();
    }
*/
    return 0;
L80:
    *ifail = 5;
/*
    if (*iprint > 0) {
	io___19.ciunit = *iout;
	s_wsfe(&io___19);
	e_wsfe();
    }
*/
    return 0;
L81:
    *ifail = 5;
/*
    if (*iprint > 0) {
	io___20.ciunit = *iout;
	s_wsfe(&io___20);
	e_wsfe();
    }
*/
    return 0;
L82:
    *ifail = 5;
/*
    if (*iprint > 0) {
	io___21.ciunit = *iout;
	s_wsfe(&io___21);
	e_wsfe();
    }
*/
    return 0;
L40:
    *ifail = 1;
/*
    if (*iprint > 0) {
	io___22.ciunit = *iout;
	s_wsfe(&io___22);
	do_fio(&c__1, (char *)&maxit, (ftnlen)sizeof(integer));
	e_wsfe();
    }
*/
    return 0;
L90:
    *ifail = 2;
/*
    if (*iprint > 0) {
	io___23.ciunit = *iout;
	s_wsfe(&io___23);
	e_wsfe();
    }
*/
    return 0;

/*     FORMAT-INSTRUCTIONS */

} /* ql0001_ */


/* umd
Two alternative definitions are provided in order to give ANSI
compliance.
(Thanks got to Martin Wauchope for providing this correction)
*/
 //#ifdef __STDC__

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: orcalarm.c --]
[-- Type: text/x-csrc; name="orcalarm.c", Size: 3834 bytes --]

//#include "orcnative.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/io.h>
#include <sys/mman.h>
#include <native/types.h>
#include <native/task.h>
#include <native/queue.h>
#include <native/intr.h>
#include <native/timer.h>
#include <native/sem.h>
#include <native/alarm.h>
#include <native/heap.h>
#include <native/queue.h>
#include <native/syscall.h>
#define STACK_SIZE 8192
#define MIN_PRIO 1
#define MAX_PRIO 99


#include "qld.c"

typedef void * (*FUNCPTR) (void *);
typedef void * (*SOSO) (void *); /**< Special type to be used for casting in pthread_create() */
//                     --s-ms-us-ns
RTIME task_period_ns =  10000000000llu;
#define NSEC_PER_SEC     1000000000
#define NBCLKS 3
#define BASECLK 0.001 //seconds !!!

#define OK 0
#define ERROR -1
#define STATUS int

#define FALSE 0
#define TRUE 1
#define POLICY 1

static int ji = 0;
//static int togparport = 0;
static RTIME startime, now;// inittime, nexttime;
static long long hjitter, jinc, max, moy, drift, jitter;
struct timespec clock_resolution;

RT_SEM mainSem;
RT_SEM handSem;
RT_ALARM BaseClk;
int status, err2, end = 0;
//pthread_t * tid;
char *dummy;
RT_TASK thr_clockit;


///Function that returns the cpu time in nanoseconds
inline long long GetCpuTime(void)
{
  return (long long)rt_timer_ticks2ns(rt_timer_read());
}

// Trap Ctrl C Interruption
void clean_exit(int dummy)
{
    printf("Ctrl C Interrupt\n");
/*     printf("rt_sem_v(mainSem); \n"); */
/*     rt_sem_v(&mainSem); */
    end = 1;
    err2 = rt_task_join(&thr_clockit);
    if (err2 != 0)printf("rt_task_join() error %d \n", err2);

    printf("deleting rt devices \n");
    rt_alarm_delete(&BaseClk);
    if((err2 = rt_task_delete(&thr_clockit)) != 0)
      printf("rt_task_delete err2or %d \n", err2);
    //rt_sem_delete(&mainSem);
    return ;
}

int orcTimerSigMask(void)
{
    sigset_t set;
    sigfillset(&set);
    if ((err2 = pthread_sigmask(SIG_BLOCK, &set, NULL)) != OK)
    {
        printf("pthread_sigmask Failed %d \n", err2);
        return ERROR;
    }
    sigemptyset(&set);
    sigaddset(&set, SIGINT);
    sigaddset(&set, SIGTERM);
    if ((err2 = pthread_sigmask(SIG_UNBLOCK, &set, NULL)) != OK)
    {
        printf("pthread_sigmask Failed %d \n", err2);
        return ERROR;
    }

    return OK;
}

void setTimer(void)
{
    /***starting timer ***/
    err2 = rt_alarm_create(&BaseClk, "BaseClock");
    if (err2 != 0)printf("rt_alarm_create() error %d \n", err2);
    err2 = rt_alarm_start(&BaseClk,
			 rt_timer_ns2ticks(task_period_ns),
			 //                         1000,
                         rt_timer_ns2ticks(task_period_ns));
    if (err2 != 0)printf("rt_alarm_start() error %d \n", err2);

    else printf("alarm started with period %llu ns \n", task_period_ns);
    printf("period in ticks %ld \n", (long)rt_timer_ns2ticks(task_period_ns));
    return ;

}

//void *clock_it(void *cookie)
FUNCPTR clock_it()
{
  //int ret;
    while (!end)
    {
       rt_alarm_wait(&BaseClk);
       printf("rt_alarm_wait \n");
       gsl_qp();
    } 
    return OK;
}

int main(void)
{

    orcTimerSigMask();

    mlockall(MCL_CURRENT | MCL_FUTURE);

    signal(SIGTERM, clean_exit);
    signal(SIGINT, clean_exit);

    setTimer();
    err2 = rt_task_spawn(&thr_clockit,
                        "MyAlarmServer",
                        0,
                        MAX_PRIO,
                        T_FPU|T_JOINABLE,
                        (void *) clock_it,
                        NULL);

    if (err2 != 0) printf("rt_task_spawn error %d \n", err2);


    pause();
    fflush(NULL);

    return 0;
}



[-- Attachment #6: Makefile --]
[-- Type: application/octet-stream, Size: 1007 bytes --]


# To use this makefile with xeno-config not located in PATH, type :
# make XENO_CONFIG=/path/to/xeno-config
XENO_CONFIG=xeno-config
prefix := $(shell $(XENO_CONFIG) --prefix)


ifeq ($(prefix),)
$(error Please add <xenomai-install-path>/bin to your PATH variable or type: \
make XENO_CONFIG=<xenomai-install-path>/bin/xeno-config)
endif

BIN      =  .
INCLUDE  = -I. -I$(HOME)/include 
LIBDIRS_USR  = -L$(HOME)/lib/$(ARCH) 
LIB_STATIC = -L/usr/lib/nptl 
LIBS_USR  = -lm -lrt -lpthread  
DEBUG    = -g -DDEBUG
#DEBUG    = -O2
CFLAGS   = $(DEBUG) -D_GNU_SOURCE -D_REENTRANT -Wall -Wstrict-prototypes -O2 
CFLAGS_RT:= $(shell $(XENO_CONFIG) --posix-cflags) -g
LDFLAGS_RT:= $(shell $(XENO_CONFIG) --posix-ldflags)
XENO_CFLAGS = $(shell  $(XENO_CONFIG) --xeno-cflags)
XENO_LDFLAGS = $(shell $(XENO_CONFIG) --xeno-ldflags) -lnative



all:  orcalarm

orcalarm: orcalarm.c #orcnative.h
	$(CC) $(XENO_CFLAGS) $(DEBUG) $(XENO_LDFLAGS) -o orcalarm orcalarm.c -lnative $(LIBS_USR) 


clean: 
	rm -rf  orcalarm *.o *~

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-help] real time task disapears... memory problem ?
  2007-06-07 16:23 [Xenomai-help] real time task disapears... memory problem ? desvages
@ 2007-06-07 17:44 ` Jan Kiszka
  2007-06-08 10:49   ` [Xenomai-help] measuring tasks execution time Daniel Simon
       [not found]   ` <1753.194.254.210.7.1181246882.squirrel@domain.hid>
  0 siblings, 2 replies; 33+ messages in thread
From: Jan Kiszka @ 2007-06-07 17:44 UTC (permalink / raw)
  To: desvages; +Cc: xenomai

[-- Attachment #1: Type: text/plain, Size: 2789 bytes --]

desvages@domain.hid wrote:
>> What kind of statistics would you precisely need? And where would you
>> need it, means where is your scheduler located, what API does it use?
> 
> I need execution time (and not response time). A patch for this has been
> create by a former student (now Doctor David Robert) working before me.

Hmm, the patch looks like it consequently reimplements existing runtime
statistics instead of reusing them as a foundation...

Anyway, I think we could discuss some API extension of Xenomai (for
native, probably via rt_task_inquire). Likely we would keep this report
optional, ie. make it return -1 or so if CONFIG_XENO_OPT_STATS is off.
Tracking stats is not as costly as other instrumentations, but it's also
not free. If you are interested, let us know. It won't be a one-liner,
but it doesn't look like it has to be as invasive as your approach.

> You can find it enclosed with this mail. Anyway the problem doesn't come
> from this patch, it appears also with vanilla xenomai.

OK.

> 
>> Primarily code. We need your code that demonstrates the weird behaviour.
>> If you patched Xenomai in any way, that patch would be required as well
>> of course.
> 
> I have reduced the size of the code to the thing that is not working. You
> can find it enclosed.
> The main program creates a task that calls the gsl_qp function (a
> quadratic solver).
> The problem appends during the call of ql0001_. If I remove this call, it
> works. I if keep it, the task disapears without any error (I only see that
> in /proc/xenomai/stat ).

This sounds like some fault is triggered and your program simply
terminates on report of the same ("Hey, if I add that printf, my program
stops. What's wrong with printf?" -- You can't imagine how often I
already heard this. ;) ).

> 
>> BTW, did you already try to attach gdb to your disappearing process?
>> Maybe it can catch what makes it terminate.
> I have tried without success, but I don really know how to use it in that
> way...

You should compile it with "-g", start it with "gdb <your program>" (or
the graphical front-end "ddd"), simply let it "run" and wait what gdb
reports. It should really say /something/.

I can't help anyway, some files are missing, at least gsl/gsl_matrix.h.
If I shall have a look, I really need a smaller test-case, only
including Xenomai interaction.

> 
> My config: (I have install the last availlable xenomai since last mail)
> - Linux kernel : 2.6.20.3
> - xenomai : 2.3.1
> - Adeos : 1.7-03
> - Laptop compact Evo N600c Pentium 3M 1.2Ghz
> 
>> .config, Xenomai version, and I-pipe version can be helpful too.
> .config is enclosed (DentiX231)
> 
> 
>> Jan
> 
> Thanks for your help
> 
> Arnaud DESVAGES
> 

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [Xenomai-help]  measuring tasks execution time
  2007-06-07 17:44 ` Jan Kiszka
@ 2007-06-08 10:49   ` Daniel Simon
  2007-06-08 11:20     ` [Xenomai-core] " Jan Kiszka
       [not found]   ` <1753.194.254.210.7.1181246882.squirrel@domain.hid>
  1 sibling, 1 reply; 33+ messages in thread
From: Daniel Simon @ 2007-06-08 10:49 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai

On Thu, 07 Jun 2007 19:44:47 +0200
Jan Kiszka <jan.kiszka@domain.hid> wrote:

Hello, opening a new thead forking from the one opened yesterday by Arnaud
Desvages

> Hmm, the patch looks like it consequently reimplements existing runtime
> statistics instead of reusing them as a foundation...
> 
Yes, might be simpler now. This patch has been done in urgency upon
xenomai 2.1 and was more or less sleeping since one year. It has been weakly
tested, only on Pentium 3 cpus.

> Anyway, I think we could discuss some API extension of Xenomai (for
> native, probably via  ). Likely we would keep this report
> optional, ie. make it return -1 or so if CONFIG_XENO_OPT_STATS is off.
> Tracking stats is not as costly as other instrumentations, but it's also
> not free. If you are interested, let us know. It won't be a one-liner,
> but it doesn't look like it has to be as invasive as your approach.

Our goal is computing the accumulated cost of some selected real-time tasks
to get an image of the  cpu load.

What we need is a record of  the accumulated execution time of the
rt_tasks (not the response time, hence the instants when the task is
preempted or suspended must not be counted).
This record must be accessible at any time, either from the calling
task or by another one.  

Our current patch only does that for tasks running in primary mode (and
moreover the measure seems not correctly updated for the calling
task record).  

Thus we would be very happy to get an improved instrumentation api.
I understand that  xnstat_runtime_update() handles the measure we need? 
Making it available, e.g.  via a rt_task_inquire call, would be great! 

	Daniel
-- 
       Daniel SIMON    Projet NeCS  INRIA Rhone-Alpes
        Inovallee, 655 avenue de l'Europe, Montbonnot
             38 334 Saint Ismier Cedex France
 Daniel.Simon@domain.hid Phone:(33)476615328 Fax:(33)476615252
          http://necs.inrialpes.fr/people/simon/




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] [Xenomai-help] measuring tasks execution time
  2007-06-08 10:49   ` [Xenomai-help] measuring tasks execution time Daniel Simon
@ 2007-06-08 11:20     ` Jan Kiszka
  2007-06-08 13:09       ` Daniel Simon
  2007-06-25 15:51       ` [Xenomai-core] " Daniel Simon
  0 siblings, 2 replies; 33+ messages in thread
From: Jan Kiszka @ 2007-06-08 11:20 UTC (permalink / raw)
  To: Daniel Simon; +Cc: xenomai-core

[-- Attachment #1: Type: text/plain, Size: 2745 bytes --]

Daniel Simon wrote:
> On Thu, 07 Jun 2007 19:44:47 +0200
> Jan Kiszka <jan.kiszka@domain.hid> wrote:
> 
> Hello, opening a new thead forking from the one opened yesterday by Arnaud
> Desvages

I moved the thread to xenomai-core, hope you don't mind.

> 
>> Hmm, the patch looks like it consequently reimplements existing runtime
>> statistics instead of reusing them as a foundation...
>>
> Yes, might be simpler now. This patch has been done in urgency upon
> xenomai 2.1 and was more or less sleeping since one year. It has been weakly

This explains why your changes are right below the xnstat infrastructure
code...

> tested, only on Pentium 3 cpus.
> 
>> Anyway, I think we could discuss some API extension of Xenomai (for
>> native, probably via  ). Likely we would keep this report
>> optional, ie. make it return -1 or so if CONFIG_XENO_OPT_STATS is off.
>> Tracking stats is not as costly as other instrumentations, but it's also
>> not free. If you are interested, let us know. It won't be a one-liner,
>> but it doesn't look like it has to be as invasive as your approach.
> 
> Our goal is computing the accumulated cost of some selected real-time tasks
> to get an image of the  cpu load.
> 
> What we need is a record of  the accumulated execution time of the
> rt_tasks (not the response time, hence the instants when the task is
> preempted or suspended must not be counted).
> This record must be accessible at any time, either from the calling
> task or by another one.  
> 
> Our current patch only does that for tasks running in primary mode (and
> moreover the measure seems not correctly updated for the calling
> task record).  
> 
> Thus we would be very happy to get an improved instrumentation api.
> I understand that  xnstat_runtime_update() handles the measure we need? 

It was designed to collect precise runtime statistics to be displayed in
/proc/xenomai/stat. We would just have to keep a total counter for each
task as dumping /proc resets the statistics ATM.

> Making it available, e.g.  via a rt_task_inquire call, would be great! 

Well, the best (==most comfortable :o) ) way from my POV would be if you
could try rebasing your work on your own first. Questions, even on minor
details, are always welcome, review on patches will be provided. Should
be no problem to get this into Xenomai 2.4.

The rough to-do list would be:

 o add some persistent runtimer counter to xnthread::stat and maintain
   it
 o introduce an xnpod service (inline function) to obtain it (let that
   thing return [0..LONGLONG_MAX] when stats are available, -1
   otherwise)
 o export the runtime via struct rt_task_info, maybe also the task start
   time

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] [Xenomai-help] measuring tasks execution time
  2007-06-08 11:20     ` [Xenomai-core] " Jan Kiszka
@ 2007-06-08 13:09       ` Daniel Simon
  2007-06-08 15:24         ` Jan Kiszka
  2007-06-25 15:51       ` [Xenomai-core] " Daniel Simon
  1 sibling, 1 reply; 33+ messages in thread
From: Daniel Simon @ 2007-06-08 13:09 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai-core

On Fri, 08 Jun 2007 13:20:11 +0200
Jan Kiszka <jan.kiszka@domain.hid> wrote:

> Daniel Simon wrote:
> > On Thu, 07 Jun 2007 19:44:47 +0200
> > Jan Kiszka <jan.kiszka@domain.hid> wrote:
> > 
> > Hello, opening a new thead forking from the one opened yesterday by Arnaud
> > Desvages
> 
> I moved the thread to xenomai-core, hope you don't mind.

OK,  I guess it is the right place
> > 
[...]
> > Our goal is computing the accumulated cost of some selected real-time tasks
> > to get an image of the  cpu load.
> > 
> > What we need is a record of  the accumulated execution time of the
> > rt_tasks (not the response time, hence the instants when the task is
> > preempted or suspended must not be counted).
> > This record must be accessible at any time, either from the calling
> > task or by another one.  
> > 
> > Our current patch only does that for tasks running in primary mode (and
> > moreover the measure seems not correctly updated for the calling
> > task record).  
> > 
> > Thus we would be very happy to get an improved instrumentation api.
> > I understand that  xnstat_runtime_update() handles the measure we need? 
> 
> It was designed to collect precise runtime statistics to be displayed in
> /proc/xenomai/stat. We would just have to keep a total counter for each
> task as dumping /proc resets the statistics ATM.
> 
> > Making it available, e.g.  via a rt_task_inquire call, would be great! 
> 
> Well, the best (==most comfortable :o) ) way from my POV would be if you
> could try rebasing your work on your own first. Questions, even on minor
> details, are always welcome, review on patches will be provided. Should
> be no problem to get this into Xenomai 2.4.
> 
> The rough to-do list would be:
> 
>  o add some persistent runtimer counter to xnthread::stat and maintain
>    it
>  o introduce an xnpod service (inline function) to obtain it (let that
>    thing return [0..LONGLONG_MAX] when stats are available, -1
>    otherwise)
>  o export the runtime via struct rt_task_info, maybe also the task start
>    time
> 
> Jan
> 
I am afraid that it is far beyond my own programming capabilities, and I have no
longer skilled enough students at hand...
Anyway there are some highly skilled (and overloaded) engineers around, i'll try
to hire one of them!
	Daniel


-- 
       Daniel SIMON    Projet NeCS  INRIA Rhone-Alpes
        Inovallee, 655 avenue de l'Europe, Montbonnot
             38 334 Saint Ismier Cedex France
 Daniel.Simon@domain.hid Phone:(33)476615328 Fax:(33)476615252
          http://necs.inrialpes.fr/people/simon/




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-help] real time task disapears... memory problem ?
       [not found]   ` <1753.194.254.210.7.1181246882.squirrel@domain.hid>
@ 2007-06-08 15:19     ` Jan Kiszka
  2007-06-09 16:06       ` desvages
  0 siblings, 1 reply; 33+ messages in thread
From: Jan Kiszka @ 2007-06-08 15:19 UTC (permalink / raw)
  To: desvages; +Cc: xenomai-help

[-- Attachment #1: Type: text/plain, Size: 4270 bytes --]

desvages@domain.hid wrote:
>> desvages@domain.hid wrote:
>>>> What kind of statistics would you precisely need? And where would you
>>>> need it, means where is your scheduler located, what API does it use?
>>> I need execution time (and not response time). A patch for this has been
>>> create by a former student (now Doctor David Robert) working before me.
>> Hmm, the patch looks like it consequently reimplements existing runtime
>> statistics instead of reusing them as a foundation...
>>
>> Anyway, I think we could discuss some API extension of Xenomai (for
>> native, probably via rt_task_inquire). Likely we would keep this report
>> optional, ie. make it return -1 or so if CONFIG_XENO_OPT_STATS is off.
>> Tracking stats is not as costly as other instrumentations, but it's also
>> not free. If you are interested, let us know. It won't be a one-liner,
>> but it doesn't look like it has to be as invasive as your approach.
> 
> It can be interesting to have something like that. My tutor will probably
> explain better than me what could be the best. I let him open a new topic
> on this patch.
> 
>>> You can find it enclosed with this mail. Anyway the problem doesn't come
>>> from this patch, it appears also with vanilla xenomai.
>> OK.
>>
>>>> Primarily code. We need your code that demonstrates the weird
>>>> behaviour.
>>>> If you patched Xenomai in any way, that patch would be required as well
>>>> of course.
>>> I have reduced the size of the code to the thing that is not working.
>>> You
>>> can find it enclosed.
>>> The main program creates a task that calls the gsl_qp function (a
>>> quadratic solver).
>>> The problem appends during the call of ql0001_. If I remove this call,
>>> it
>>> works. I if keep it, the task disapears without any error (I only see
>>> that
>>> in /proc/xenomai/stat ).
>> This sounds like some fault is triggered and your program simply
>> terminates on report of the same ("Hey, if I add that printf, my program
>> stops. What's wrong with printf?" -- You can't imagine how often I
>> already heard this. ;) ).
>>
>>>> BTW, did you already try to attach gdb to your disappearing process?
>>>> Maybe it can catch what makes it terminate.
>>> I have tried without success, but I don really know how to use it in
>>> that
>>> way...
>> You should compile it with "-g", start it with "gdb <your program>" (or
>> the graphical front-end "ddd"), simply let it "run" and wait what gdb
>> reports. It should really say /something/.
> 
> Yes I only know how to use ddd in fact, and the -g flag is used at compile
> time. And with ddd, no bug is found... I don't catch anything. The problem
> only appears when I launch the program  in console mode.
> The thing I didn't really know how to use id the attach command of gdb,
> that I have read on the web it can catch errors on program launched from
> outside gdb. Am I wrong ?
> 
>> I can't help anyway, some files are missing, at least gsl/gsl_matrix.h.
>> If I shall have a look, I really need a smaller test-case, only
>> including Xenomai interaction.
>>
> 
> It's a mistake, I forgot to remove this unuseful include line. I have
> tried to reduce the program at the minimum (some heap data allocation with
> random values, and a call to the optimizer function that cause the
> termination of the task). Normally you can remove this include, and there
> will only stay xenomai calls...
> 
>>> My config: (I have install the last availlable xenomai since last mail)
>>> - Linux kernel : 2.6.20.3
>>> - xenomai : 2.3.1
>>> - Adeos : 1.7-03
>>> - Laptop compact Evo N600c Pentium 3M 1.2Ghz
>>>
>>>> .config, Xenomai version, and I-pipe version can be helpful too.
>>> .config is enclosed (DentiX231)
>>>
>>>
>>>> Jan
>>> Thanks for your help
>>>
>>> Arnaud DESVAGES
>>>
>> Jan
> 
> Hope these new information will help to solve it.
> 

From my kernel console after running your program for a few seconds:

Xenomai: watchdog triggered -- killing runaway thread 'MyAlarmServer'

Previously, "rt_alarm_wait" was printed on the console, thus gsl_qp()
likely entered some infinite loop. You have the watchdog enabled as
well, so you should see the same effect, right?

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] [Xenomai-help] measuring tasks execution time
  2007-06-08 13:09       ` Daniel Simon
@ 2007-06-08 15:24         ` Jan Kiszka
  2007-06-08 16:04           ` Jan Kiszka
  0 siblings, 1 reply; 33+ messages in thread
From: Jan Kiszka @ 2007-06-08 15:24 UTC (permalink / raw)
  To: Daniel Simon; +Cc: xenomai-core

[-- Attachment #1: Type: text/plain, Size: 3051 bytes --]

Daniel Simon wrote:
> On Fri, 08 Jun 2007 13:20:11 +0200
> Jan Kiszka <jan.kiszka@domain.hid> wrote:
> 
>> Daniel Simon wrote:
>>> On Thu, 07 Jun 2007 19:44:47 +0200
>>> Jan Kiszka <jan.kiszka@domain.hid> wrote:
>>>
>>> Hello, opening a new thead forking from the one opened yesterday by Arnaud
>>> Desvages
>> I moved the thread to xenomai-core, hope you don't mind.
> 
> OK,  I guess it is the right place
> [...]
>>> Our goal is computing the accumulated cost of some selected real-time tasks
>>> to get an image of the  cpu load.
>>>
>>> What we need is a record of  the accumulated execution time of the
>>> rt_tasks (not the response time, hence the instants when the task is
>>> preempted or suspended must not be counted).
>>> This record must be accessible at any time, either from the calling
>>> task or by another one.  
>>>
>>> Our current patch only does that for tasks running in primary mode (and
>>> moreover the measure seems not correctly updated for the calling
>>> task record).  
>>>
>>> Thus we would be very happy to get an improved instrumentation api.
>>> I understand that  xnstat_runtime_update() handles the measure we need? 
>> It was designed to collect precise runtime statistics to be displayed in
>> /proc/xenomai/stat. We would just have to keep a total counter for each
>> task as dumping /proc resets the statistics ATM.
>>
>>> Making it available, e.g.  via a rt_task_inquire call, would be great! 
>> Well, the best (==most comfortable :o) ) way from my POV would be if you
>> could try rebasing your work on your own first. Questions, even on minor
>> details, are always welcome, review on patches will be provided. Should
>> be no problem to get this into Xenomai 2.4.
>>
>> The rough to-do list would be:
>>
>>  o add some persistent runtimer counter to xnthread::stat and maintain
>>    it
>>  o introduce an xnpod service (inline function) to obtain it (let that
>>    thing return [0..LONGLONG_MAX] when stats are available, -1
>>    otherwise)
>>  o export the runtime via struct rt_task_info, maybe also the task start
>>    time
>>
>> Jan
>>
> I am afraid that it is far beyond my own programming capabilities, and I have no
> longer skilled enough students at hand...
> Anyway there are some highly skilled (and overloaded) engineers around, i'll try
> to hire one of them!

Any support is welcome, offers still stand!

Damn, meanwhile I started thinking about this more than I wanted. So,
whoever will implement it, a few more remarks/suggestions:

- Considering the existing xnthread:stime and its usage (I didn't found
  a place), I would say just add another xnstat_runtime_t to
  xnthread::stat for life-time statistics and delete stime.

- Note that migrating life-time stats between CPUs requires rebasing the
  thread start time properly.

- And then I think we could also dump the life-time CPU usage based on
  that new data in /proc/xenomai/stat. Would be a nice test besides the
  native API extension... :->

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] [Xenomai-help] measuring tasks execution time
  2007-06-08 15:24         ` Jan Kiszka
@ 2007-06-08 16:04           ` Jan Kiszka
  0 siblings, 0 replies; 33+ messages in thread
From: Jan Kiszka @ 2007-06-08 16:04 UTC (permalink / raw)
  To: Daniel Simon; +Cc: xenomai-core

[-- Attachment #1: Type: text/plain, Size: 211 bytes --]

Jan Kiszka wrote:
> ...
> - Note that migrating life-time stats between CPUs requires rebasing the
>   thread start time properly.

Nonsense. CPU-local clocks are considered offset-free for Xenomai use.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-help] real time task disapears... memory problem ?
  2007-06-08 15:19     ` [Xenomai-help] real time task disapears... memory problem ? Jan Kiszka
@ 2007-06-09 16:06       ` desvages
  2007-06-09 17:10         ` Jan Kiszka
  0 siblings, 1 reply; 33+ messages in thread
From: desvages @ 2007-06-09 16:06 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai-help

>
> From my kernel console after running your program for a few seconds:
>
> Xenomai: watchdog triggered -- killing runaway thread 'MyAlarmServer'
>
> Previously, "rt_alarm_wait" was printed on the console, thus gsl_qp()
> likely entered some infinite loop. You have the watchdog enabled as
> well, so you should see the same effect, right?
>
> Jan

In my console, I only see the "rt_alarm_wait". Is there something to
activate to enable xenomai errors messages ?

As this gsl_qp() function takes about 6/7 secondes to solve my quadratic
problem, the watchdog could effectively be the thing that goes wrong...

To be sure to understand how works the watchdog in xenomai:
- Is it a limit on the execution time (so time effectively used by the task)
- or is it a limit on the response time (the time between the beginning
and the end of the task, even if it is preempted) ?

Because, if it is the first case, maybe that putting the gsl_qp() function
in primary mode increases the execution time measured by xenomai, and this
activate the watchdog ? whereas in secondary mode, time is not counted by
xenomai watchdog ?

I will try to increase the watchdog time to see if this is only a matter
of a task taking to much time.


Thanks a lot for your help !

Arnaud DESVAGES



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-help] real time task disapears... memory problem ?
  2007-06-09 16:06       ` desvages
@ 2007-06-09 17:10         ` Jan Kiszka
  0 siblings, 0 replies; 33+ messages in thread
From: Jan Kiszka @ 2007-06-09 17:10 UTC (permalink / raw)
  To: desvages; +Cc: xenomai-help

[-- Attachment #1: Type: text/plain, Size: 2020 bytes --]

desvages@domain.hid wrote:
>> From my kernel console after running your program for a few seconds:
>>
>> Xenomai: watchdog triggered -- killing runaway thread 'MyAlarmServer'
>>
>> Previously, "rt_alarm_wait" was printed on the console, thus gsl_qp()
>> likely entered some infinite loop. You have the watchdog enabled as
>> well, so you should see the same effect, right?
>>
>> Jan
> 
> In my console, I only see the "rt_alarm_wait". Is there something to
> activate to enable xenomai errors messages ?

Not local console, _kernel console_. Check your systems log files (eg.
/var/log/syslog or .../messages), or run "dmesg" to see the last kernel
messages.

> 
> As this gsl_qp() function takes about 6/7 secondes to solve my quadratic
> problem, the watchdog could effectively be the thing that goes wrong...

Well, don't blame others until you are sure (== you measured) that it is
not your own code. :)

> 
> To be sure to understand how works the watchdog in xenomai:
> - Is it a limit on the execution time (so time effectively used by the task)
> - or is it a limit on the response time (the time between the beginning
> and the end of the task, even if it is preempted) ?

See documentation. Linux must be able to run at least once in _4_ seconds.

> 
> Because, if it is the first case, maybe that putting the gsl_qp() function
> in primary mode increases the execution time measured by xenomai, and this
> activate the watchdog ? whereas in secondary mode, time is not counted by
> xenomai watchdog ?

Yes, secondary mode would be accounted to Linux, thus the watchdog would
be happy (and your Linux subsystem as well because it would be allowed
to breath).

> 
> I will try to increase the watchdog time to see if this is only a matter
> of a task taking to much time.

Wrong approach. First check how long your loop actually takes. If you
have to tweak the watchdog (and there is no bug in the trivial watchdog
code), it's your code that is broken.

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-06-08 11:20     ` [Xenomai-core] " Jan Kiszka
  2007-06-08 13:09       ` Daniel Simon
@ 2007-06-25 15:51       ` Daniel Simon
  2007-06-25 16:55         ` Jan Kiszka
  1 sibling, 1 reply; 33+ messages in thread
From: Daniel Simon @ 2007-06-25 15:51 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai-core

[-- Attachment #1: Type: text/plain, Size: 2114 bytes --]

On Fri, 08 Jun 2007 13:20:11 +0200
Jan Kiszka <jan.kiszka@domain.hid> wrote:

Hello,

> Well, the best (==most comfortable :o) ) way from my POV would be if you
> could try rebasing your work on your own first. Questions, even on minor
> details, are always welcome, review on patches will be provided. Should
> be no problem to get this into Xenomai 2.4.
> 
> The rough to-do list would be:
> 
>  o add some persistent runtimer counter to xnthread::stat and maintain
>    it
>  o introduce an xnpod service (inline function) to obtain it (let that
>    thing return [0..LONGLONG_MAX] when stats are available, -1
>    otherwise)
>  o export the runtime via struct rt_task_info, maybe also the task start
>    time

Coming back on this topic:
please find attached a first draft of a patch following (more or less)  your
suggestions:
-there is an additional field "exectime" in  TASK_INFO, which can be set by
rt_task_inquire and read in the info structure (the computation is slightly
different for self and remote measurement);
-xnthread_get_exectime() and xnthread_get_lastswitch() pass the values of the
current thread's  timing out of xn;
-exectime and lastswitch times are stored in an extended xnstat_runtime_t,
updated by xnstat_runtime_update() (but not exactly like the "total" item)

it has been tested (only on  P3 single core cpu) with the testexec program also
attached : there are 2 periodic tasks, clockit and loop, which measure
either their exectime, or the one of the other task: the measures 
seems reasonable, except when the clockit task measures itself, in that case the
first and second printed values are always absurd for a reason I cannot
understand...)

Only works in primary mode... (also I hope that the tsc is monotonic?)

I have no idea of what may happen on a smp or when on the fly migrating tasks!

	Daniel

-- 
       Daniel SIMON    Projet NeCS  INRIA Rhone-Alpes
        Inovallee, 655 avenue de l'Europe, Montbonnot
             38 334 Saint Ismier Cedex France
 Daniel.Simon@domain.hid Phone:(33)476615328 Fax:(33)476615252
          http://necs.inrialpes.fr/people/simon/



[-- Attachment #2: exec-info-2.3.1.patch --]
[-- Type: text/x-patch, Size: 4341 bytes --]

diff -urN xenomai-2.3.1-orig/include/native/task.h xenomai-2.3.1/include/native/task.h
--- xenomai-2.3.1-orig/include/native/task.h	2006-12-26 19:38:57.000000000 +0100
+++ xenomai-2.3.1/include/native/task.h	2007-06-22 16:08:10.000000000 +0200
@@ -91,6 +91,8 @@
     
     char name[XNOBJECT_NAME_LEN];  /**< Symbolic name assigned at creation. */
 
+    xnticks_t exectime; /**<execution time in tsc ticks since the task started. */
+
 } RT_TASK_INFO;
 
 #define RT_MCB_FSTORE_LIMIT  64
diff -urN xenomai-2.3.1-orig/include/nucleus/stat.h xenomai-2.3.1/include/nucleus/stat.h
--- xenomai-2.3.1-orig/include/nucleus/stat.h	2006-12-26 19:38:59.000000000 +0100
+++ xenomai-2.3.1/include/nucleus/stat.h	2007-06-25 15:48:25.000000000 +0200
@@ -31,6 +31,10 @@
 
 	xnticks_t total; /* Accumulated execution time */
 
+	xnticks_t exectime; /* Overall execution time from taskspawn upto lastswitch*/
+
+	xnticks_t lastswitch; /* Last time the task was made active */
+
 } xnstat_runtime_t;
 
 /* Return current date which can be passed to other xnstat services for
@@ -42,6 +46,10 @@
 do { \
 	(sched)->current_account->total += \
 		start - (sched)->last_account_switch; \
+	(sched)->current_account->exectime += \
+                xnstat_runtime_now() - (sched)->last_account_switch; \
+	(sched)->current_account->lastswitch = \
+                xnstat_runtime_now(); \
 	(sched)->last_account_switch = start; \
 } while (0)
 
diff -urN xenomai-2.3.1-orig/include/nucleus/thread.h xenomai-2.3.1/include/nucleus/thread.h
--- xenomai-2.3.1-orig/include/nucleus/thread.h	2007-03-15 15:10:30.000000000 +0100
+++ xenomai-2.3.1/include/nucleus/thread.h	2007-06-22 16:17:24.000000000 +0200
@@ -228,6 +228,7 @@
 
     void *cookie;		/* Cookie to pass to the entry routine */
 
+
     XNARCH_DECL_DISPLAY_CONTEXT();
 
 } xnthread_t;
@@ -277,7 +278,8 @@
 #define xnthread_user_pid(thread) \
     (xnthread_test_state((thread),XNROOT) || !xnthread_user_task(thread) ? \
     0 : xnarch_user_pid(xnthread_archtcb(thread)))
-
+#define xnthread_get_exectime(thread)      ((thread)->stat.account.exectime)
+#define xnthread_get_lastswitch(thread)    ((thread)->stat.account.lastswitch)
 #ifdef __cplusplus
 extern "C" {
 #endif
diff -urN xenomai-2.3.1-orig/ksrc/nucleus/thread.c xenomai-2.3.1/ksrc/nucleus/thread.c
--- xenomai-2.3.1-orig/ksrc/nucleus/thread.c	2007-02-02 02:17:32.000000000 +0100
+++ xenomai-2.3.1/ksrc/nucleus/thread.c	2007-06-22 16:55:08.000000000 +0200
@@ -89,7 +89,10 @@
 	thread->registry.waitkey = NULL;
 #endif /* CONFIG_XENO_OPT_REGISTRY */
 	memset(&thread->stat, 0, sizeof(thread->stat));
-
+#ifdef CONFIG_XENO_OPT_STATS
+	thread->stat.account.exectime = 0;
+	thread->stat.account.lastswitch = 0;
+#endif
 	/* These will be filled by xnpod_start_thread() */
 	thread->imask = 0;
 	thread->imode = 0;
diff -urN xenomai-2.3.1-orig/ksrc/skins/native/task.c xenomai-2.3.1/ksrc/skins/native/task.c
--- xenomai-2.3.1-orig/ksrc/skins/native/task.c	2007-02-28 18:25:52.000000000 +0100
+++ xenomai-2.3.1/ksrc/skins/native/task.c	2007-06-25 16:20:58.000000000 +0200
@@ -1102,15 +1102,22 @@
 
 int rt_task_inquire(RT_TASK *task, RT_TASK_INFO *info)
 {
-	int err = 0;
-	spl_t s;
-
-	if (!task) {
+  int err = 0;
+  spl_t s;
+	/* xnprintf("1- task value ptr = %p \n", (task)); */
+	if (!task) {		
+	 /*  xnprintf("if(!task) est vrai\n"); */
 		if (!xnpod_primary_p())
 			return -EPERM;
-
 		task = xeno_current_task();
 	}
+/* 	else  */
+/* 	  { */
+/* 	     xnprintf("if(!task) est fx\n"); */
+/* 	  } */
+
+/* 	xnprintf("2- task value ptr = %p\n",(task)); */
+	
 
 	xnlock_get_irqsave(&nklock, s);
 
@@ -1126,7 +1133,12 @@
 	info->cprio = xnthread_current_priority(&task->thread_base);
 	info->status = xnthread_state_flags(&task->thread_base);
 	info->relpoint = xntimer_get_date(&task->thread_base.ptimer);
-
+	if(task == xeno_current_task()){
+	  info->exectime = xnthread_get_exectime(&task->thread_base) + (xnstat_runtime_now() - xnthread_get_lastswitch(&task->thread_base));
+	  xnprintf("self inquire runtime_now %llu lastswitch %llu exectime %llu\n", (xnstat_runtime_now()), xnthread_get_lastswitch(&task->thread_base), (info->exectime));}
+	else {
+	  info->exectime = xnthread_get_exectime(&task->thread_base);
+	  xnprintf("not self %lld \n", (long long)info->exectime);}
       unlock_and_exit:
 
 	xnlock_put_irqrestore(&nklock, s);

[-- Attachment #3: testexec.c --]
[-- Type: text/x-csrc, Size: 16605 bytes --]

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/io.h>
#include <sys/mman.h>
#include <native/types.h>
#include <native/task.h>
#include <native/queue.h>
#include <native/intr.h>
#include <native/timer.h>
#include <native/sem.h>
#include <native/alarm.h>
#include <native/heap.h>
#include <native/queue.h>
#include <native/syscall.h>
#define STACK_SIZE 8192
#define MIN_PRIO 1
#define MAX_PRIO 99
#define PRI_MT_MAX MAX_PRIO - 6
#define PRI_MT_MIN MIN_PRIO

typedef void * (*FUNCPTR) (void *);
typedef void (*SOSO) (void *); /**< Special type to be used for casting in task_create() */
#define ORCMSGQ RT_QUEUE *  /**< Message Queue Type */
#define ORCSEM_ID RT_SEM *  /**< Semaphore Type */
#define ORCFULL  1        /**< State of a Full Binary Semaphore */
#define ORCEMPTY 0        /**< State of a Empty Binary Semaphore */
#define ORCFOREVER TM_INFINITE     /**< State of a ??? Binary Semaphore */
#define SIZE_QUEUE  100       /**< Size of the Message Queue */
#define SIZE_MES_MAX 4056    /**< Maximum size of a message in Message Queue */
#define SIZE_MES_MIN 128     /**< Minimum size of a message in Message Queue */ 
/*-------Tasks----------*/
#define ORCTHR_ID RT_TASK * /**< Xeno RT-Task Type */
#define STACKSIZE int      /**< Stack size Type */
#define SCHED_OTHER             0
#define SCHED_FIFO              1
#define SCHED_RR                2
#define SCHEDPOLICY SCHED_FIFO  /**< Scheduling policy (see schedbits.h, sched.h )*/
#define SMALL_STACK  1000           /**< Small task stack size PTHREAD_STACK_MIN not defined */
#define NORMAL_STACK (5*SMALL_STACK)  /**< Normal task stack size */
#define BIG_STACK    (15*SMALL_STACK) /**< Big task stack size */ 
//                     --s-ms-us-ns
RTIME task_period_ns = 500000000llu;
#define NSEC_PER_SEC 1000000000

#define OK 0
#define ERROR -1
#define STATUS int

#define FALSE 0
#define TRUE 1
#define POLICY 1

static int ji = 0;
//static int togparport = 0;
static RTIME startime, now; // inittime, nexttime;
struct timespec clock_resolution;
static int message_counter = 0;

RT_ALARM BaseClk;
int status, err, end = 0, loops = 10;

char *dummy;

ORCTHR_ID thr_clockit;
ORCTHR_ID thr_loop;
ORCMSGQ Queue;

ORCSEM_ID SynchroSem;

static int cpt_sem = 10000;
char nameSem[10];
int crexec, cr;
long past = 0;
ORCTHR_ID MAIN_RT;
/*-------Message Queues----------*/
/**
 * Function to create a message queue
 *
 * @param
 * @return ORCMSGQ pointer if message queue created, NULL otherwise and errno is set
 * @see ORCMSGQ
 * @see <sys/msg.h>#msgget
 * @see <sys/msg.h>#msgctl
 */
ORCMSGQ orcMsgQCreate()
{
    size_t size;
    ORCMSGQ OrcQueue;
    message_counter = 0;
    size = SIZE_MES_MAX;
    int err;

    OrcQueue = malloc(sizeof(RT_QUEUE));
    if (OrcQueue == 0)
    {
        printf("ERROR  orcMsgQCreate malloc\n");
        return 0;
    }
    memset(OrcQueue, 0, sizeof(RT_QUEUE));
    if ((err = rt_queue_create(OrcQueue, "OrcRTQ", SIZE_MES_MAX*SIZE_QUEUE, SIZE_QUEUE, Q_FIFO | Q_SHARED)) != 0)
    {
      printf("orcMsgQCreate ERROR %d \n", err);
    }
    else printf("orcMsgQCreate OK\n");
    return OrcQueue;
}

/**
 * Function to get the number of messages pending in a message queue
 *
 * @param queue pointer to the message queue 
 * @return long number of messages if no error occurs otherwise ERROR and errno is set
 * @see <sys/msg.h>#msgctl
 */
long orcMsgQNumMsgs(ORCMSGQ queue)
{
    return (long)message_counter;
}

/**
 * Function to send a message on a message queue
 * Sending the message is done according to a priority level such as :
 *
 * @param queue pointer to the message queue
 * @param msg message to be sent
 * @param prio message priority level
 * @return OK if successfull, ERROR otherwise and errno is set
 * @see <sys/msg.h>#msgsnd
 */
int orcMsgQSend(ORCMSGQ OrcQueue, int msg, int prio)
{
    int i;
    void * tmpbuf;
    size_t orcEventSize;
    orcEventSize = (size_t)sizeof(int);
    if ((tmpbuf = rt_queue_alloc(OrcQueue, orcEventSize)) == 0)
    {
        printf("ERROR orcMsgQSend tmpbuf not created \n");
        return ERROR;
    }
    memcpy(tmpbuf, &msg, orcEventSize);
    if ((i = rt_queue_send(OrcQueue, tmpbuf, orcEventSize, Q_NORMAL)) < 0)
    {
        printf("ERROR orcMsgQSend %d \n", i);
        return ERROR;
    }
    message_counter++;
    return OK;
}

/**
 * Function to receive messages on a message queue
 *
 * @param queue pointer to the message queue
 * @param msg pointer to the received message 
 * @return OK if successfull, ERROR otherwise and errno is set
 * @see <sys/msg.h>#msgrcv
 *
 */
int orcMsgQReceive(ORCMSGQ OrcQueue, int *msg)
{
    ssize_t i;
    void *message;

    if ((i = rt_queue_receive(OrcQueue, &message, TM_INFINITE )) < 0)
    {
        printf("ERREUR orcMsgQReceive %d \n", i);
        return ERROR;
    }
    else
    {
      memcpy(msg, message, i);
        rt_queue_free(OrcQueue, message);
        message_counter--;
        return OK;
    }
}

/**
 * Function to close and erase a message queue
 *
 * @param queue pointer to the message queue 
 * @return OK if successfull, ERROR otherwise and errno is set
 * @see <sys/msg.h>#msgctl
 */
int orcMsgQClose(ORCMSGQ OrcQueue)
{
    int i;
    if (OrcQueue == 0)
        return ERROR;
    if ((i = rt_queue_delete(OrcQueue)) != 0)
    {
        printf("ERREUR orcMsgQClose %d \n", i);
        return ERROR;
    }

    else
    {
        free(OrcQueue);
        return OK;
    }
}

/*-------Semaphores----------*/
/**
 * Function to create a semaphore
 *
 * @param initState semaphore initial creation state, eg ORCFULL, ORCEMPTY
 * @return ORCSEM_ID semaphore pointer created if successfull, NULL otherwise 
 * @see ORCFULL
 * @see ORCEMPTY
 * @see <semaphore.h>#sem_init
 */

ORCSEM_ID orcSemCreate(int initState)
{
    ORCSEM_ID newSem;
    int status;

    sprintf(nameSem,"%d",cpt_sem);
    newSem = malloc(sizeof(RT_SEM));
    if (newSem == 0)
    {
        printf("ERROR orcSem init \n");
        return 0;
    }
    memset(newSem, 0, sizeof(RT_SEM));
    if(initState == ORCFULL)
{
        status = rt_sem_create(newSem, nameSem, initState, S_FIFO);
#ifdef DEBUG
        printf("WARNING binary Sem created FULL \n");
#endif 
}
    else
        status = rt_sem_create(newSem, nameSem, initState, S_FIFO|S_PULSE);
    if (status == OK)
    {
#ifdef DEBUG
        printf("orcSemCreate %p\n", newSem);
#endif
        cpt_sem++;
        return newSem;
    }
    else
    {
#ifdef DEBUG
        printf("orcSemCreate ERROR %d\n", status);
#endif
        return NULL;
    }
}

ORCSEM_ID orcSemCreate_count(int initState)
{
    RT_SEM * newSem;
    int status;

    sprintf(nameSem,"%d",cpt_sem);
    newSem = malloc(sizeof(RT_SEM));
    if (newSem == 0)
    {
        printf("ERROR SemCreate_count init \n");
        return 0;
    }
    memset(newSem, 0, sizeof(RT_SEM));

    status = rt_sem_create(newSem, nameSem, initState, S_FIFO);
    if (status == OK)
    {
#ifdef DEBUG
        printf("orcSemCreate_count %p\n", newSem);
#endif
        cpt_sem++;
        return newSem;
    }
    else
    {
#ifdef DEBUG
        printf("orcSemCreate ERROR %d \n", status);
#endif
        return NULL;
    }

}

/**
 * Function to delete a given semaphore
 * 
 * @param sem semaphore to be deleted
 * @return sem_destroy() returned value
 * @see <semaphore.h>#sem_destroy
 */
int orcSemDelete(ORCSEM_ID sem)
{
    if (sem == 0)
        return ERROR;
    if (rt_sem_delete(sem) == 0)
    {
        free(sem);
        return OK;
    }
    printf("Erreur:orcSemDelete\n");
    return ERROR;
}

/**
 * Function to give a semaphore
 *
 * @param sem semaphore id
 * @return sem_post) returned value
 * @see <semaphore.h>#sem_post
 */
int orcSemGive(ORCSEM_ID sem)
{
#ifdef DEBUG
    printf("SemGive %p\n", sem);
#endif
    return (rt_sem_v(sem));
}

/**
 * Function to take a semaphore
 * TODO : no timeout in Posix semaphores
 *
 * @param sem semaphore
 * @param timeout value 
 * @return sem_wait() returned value
 * @see <semaphore.h>#sem_wait
 */
int orcSemTake(ORCSEM_ID sem, int timeout)
{
#ifdef DEBUG
    printf("SemTake %p\n", sem);
#endif
    return (rt_sem_p(sem, timeout));
}

/*-------Tasks----------*/
/**
 * Function for suspending current process
 * TODO : no taskDelay in Posix (sleep uses seconds, delay ?, nanosleep ?)
 *
 * @param delay
 * @return OK
 */
int orcTaskDelay(int delay)
{
    //int dummy = delay; // set to avoid compilation warnings

    return OK;
}

/// Function to set relative linux task priority
int orcScalePriority(int os_priority)
{
    if ((PRI_MT_MIN + os_priority < PRI_MT_MAX) && os_priority > 0)
        return ( PRI_MT_MIN + os_priority );
    printf("ERROR orcScalePriority, priority=%d\n", os_priority);
    return PRI_MT_MAX;
}


/**
 * Function to check if a task is still valid or not
 *
 * @param Id task identifier 
 * @return OK if task is valid, ERROR otherwise
 * @see ORCTHR_ID
 * @see pthread_kill
 */
int orcTaskIdVerify(ORCTHR_ID Id)
{
    if (Id != NULL)
    {
        return OK;
    }
    printf("orcTaskIdVerify ERROR \n");
    return ERROR;
}

/**
 * Function to kill a task (pthread)
 *
 * @param Id task identifier
 * @return ERROR or pthread_cancel returned value
 * @see ORCTHR_ID
 * @see <pthread.h>#pthread_kill
 * @see <pthread.h>#pthread_cancel
 */
int orcTaskDelete(ORCTHR_ID task)
{
    int result;

    if (task == 0)
    {
        printf("ERROR rt_task_delete, task == 0\n");
        return ERROR;
    }
    result = rt_task_delete(task);
    if (result != 0)
    {
        printf("ERROR rt_task_delete  %p error %d\n", task, result);
        return ERROR;
    }
    //    if (result == 0)
    free(task);
    return OK;
}

/**
 * Function to spawn a task
 *
 * @param tid task identifier
 * @param name name descripting the task
 * @param prio task priority level
 * @param stackSize stack size to be allocated for the task
 * @param funcptr routine to be spawn by the task
 * @param arg argument needed for the routine to be spawn
 * @return pthread_create returned value
 * @see ORCTHR_ID
 * @see STACKSIZE
 * @see FUNCPTR
 * @see <pthread.h>#pthread_create
 */
int orcSpawn(ORCTHR_ID *tid, const char *name, int prio, STACKSIZE stackSize, SOSO funcptr, void * arg)
{
    int err;

    //Allocate memory
    if (((*tid) = (RT_TASK*) malloc (sizeof(RT_TASK))) == NULL)
    {
        printf("Error malloc orcspawn\n" );
        return ERROR;
    }
    if ((err = rt_task_spawn(*tid, name, stackSize, prio, T_FPU|T_JOINABLE|T_CPU(0), (SOSO) funcptr, arg)) != 0)
      //if ((err = rt_task_spawn(*tid, name, stackSize, prio, T_FPU, (SOSO) funcptr, arg)) != 0)

    {
        printf("ERROR %d rt_task_init\n", err);
        return ERROR;
    }
    //#ifdef DEBUG
    printf("rt_task create %s prio %d StackSize %d Id %p \n", name, prio, stackSize, tid);
    //#endif
    return OK;
}
int orcSpawn1(ORCTHR_ID *tid, const char *name, int prio, STACKSIZE stackSize, SOSO funcptr, void * arg)
{
    int err;

    //Allocate memory
    if (((*tid) = (RT_TASK*) malloc (sizeof(RT_TASK))) == NULL)
    {
        printf("Error malloc orcspawn\n" );
        return ERROR;
    }
    if ((err = rt_task_spawn(*tid, name, stackSize, prio, T_FPU|T_JOINABLE|T_CPU(1), (SOSO) funcptr, arg)) != 0)
      //if ((err = rt_task_spawn(*tid, name, stackSize, prio, T_FPU, (SOSO) funcptr, arg)) != 0)

    {
        printf("ERROR %d rt_task_init\n", err);
        return ERROR;
    }
    //#ifdef DEBUG
    printf("rt_task create %s prio %d StackSize %d Id %p \n", name, prio, stackSize, tid);
    //#endif
    return OK;
}

/**
 * Function to lock a task
 * This function does nothing : defined for interoperability between OS needs
 * 
 * @param 
 * @return OK
 */
int orcTaskLock()
{
    return OK;
}

/**
 * Function to unlock a task
 * This function does nothing : defined for interoperability between OS needs
 * 
 * @param 
 * @return OK
 */
int orcTaskUnlock()
{
    return OK;
}

int orcTaskSuspend(ORCTHR_ID task)
{
    return rt_task_suspend(task);
}

///Function that returns the cpu time in nanoseconds
inline long long GetCpuTime(void)
{
    return (long long)rt_timer_ticks2ns(rt_timer_read());
}

inline  unsigned long long orcGetExecTime(ORCTHR_ID task)
{
RT_TASK_INFO info;
crexec = rt_task_inquire(task,&info);
  if (crexec != 0){
    printf("rt_task_get_exectime error %d \n", crexec);
    return (unsigned long long)0;}
  else return (unsigned long long)rt_timer_tsc2ns((SRTIME)info.exectime);
}

inline long long orcGetStartTime(ORCTHR_ID task)
{
    return (long long)0;
}

int orcMakeRealTime(void)
{
int prio_main = PRI_MT_MAX + 1;
    mlockall(MCL_CURRENT | MCL_FUTURE);
    if ((cr = rt_task_shadow(MAIN_RT, "MAIN_PRR", prio_main, T_FPU | T_JOINABLE)) != 0)
      {printf("rt_task_shadow error %d \n", cr);}
    else {printf("rt_task_shadow done priority %d \n", prio_main);}
    return cr;
}

int orcTaskJoin(ORCTHR_ID task)
{
cr = rt_task_join(task);
 if (cr != 0){
   printf("rt_task_join error %d on task %p \n", cr, task);
   return cr;}
 else return OK;
}

// Trap Ctrl C Interruption
void clean_exit(int dummy)
{
    printf("Ctrl C Interrupt\n");
    end = 1;
    err = rt_task_join(thr_clockit);
    if (err != 0)printf("rt_task_join() error %d \n", err);
    err = rt_task_join(thr_loop);
    if (err != 0)printf("rt_task_join() error %d \n", err);

    printf("deleting rt devices \n");
    err = rt_alarm_delete(&BaseClk);
    if (err != 0)printf("rt_alarm_delete() error %d \n", err);

    orcMsgQClose(Queue);
    orcSemDelete(SynchroSem);
    return ;
}

int orcTimerSigMask(void)
{
    sigset_t set;
    sigfillset(&set);
    if ((err = pthread_sigmask(SIG_BLOCK, &set, NULL)) != OK)
    {
        printf("pthread_sigmask Failed %d \n", err);
        return ERROR;
    }
    sigemptyset(&set);
    sigaddset(&set, SIGINT);
    sigaddset(&set, SIGTERM);
    if ((err = pthread_sigmask(SIG_UNBLOCK, &set, NULL)) != OK)
    {
        printf("pthread_sigmask Failed %d \n", err);
        return ERROR;
    }

    return OK;
}

void setTimer(void)
{
    /***starting timer ***/
    err = rt_alarm_create(&BaseClk, "BaseClock");
    if (err != 0)printf("rt_alarm_create() error %d \n", err);
    err = rt_alarm_start(&BaseClk,
                         rt_timer_ns2ticks(task_period_ns),
                         rt_timer_ns2ticks(task_period_ns));
    if (err != 0)printf("rt_alarm_start() error %d \n", err);

    else printf("alarm started with period %llu ns \n", task_period_ns);
    printf("period in ticks %ld \n", (long)rt_timer_ns2ticks(task_period_ns));
    return ;

}

void clock_it(void)
{
    int msg = 1;    
    unsigned long long clockexectime, clockdiff;
    static unsigned long long clockpast = 0;
    while (!end)
    {
        err = rt_alarm_wait(&BaseClk);

	//rt_timer_spin((RTIME)rt_timer_ns2ticks(100000000));	
/*       clockexectime = orcGetExecTime(NULL); */
/*       if(msg > 2){ */
/*       clockdiff = clockexectime - clockpast; */
/*       clockpast  = clockexectime; */
/*       printf("clockexectime %llu clockdiff %llu \n", clockexectime, clockdiff );} */
/*       else clockpast  = clockexectime; */

            orcMsgQSend(Queue, msg, 0);
            msg++;
    }
/*     printf("clocktotal %llu clockdiffexec moyen %llu \n", clockexectime, (clockexectime/msg)); */
    return ;
}
void func_loop()
{
    int msg;
    unsigned long long loopexectime, loopdiff;
    static unsigned long long looppast;
    while (!end)
    {
      //printf("WAITING FOR MESSAGE  \n");
      orcMsgQReceive(Queue, &msg);
      printf("RECEIVED MESSAGE  \n");
      rt_timer_spin((RTIME)rt_timer_ns2ticks(100000000));
      loopexectime = orcGetExecTime(NULL);
      if(msg > 2){
	  loopdiff = loopexectime - looppast;
	  looppast  = loopexectime;
      printf("loopexectime  %llu loopdiff %llu \n", loopexectime, loopdiff );}
      else looppast  = loopexectime;
      printf("received msg = %d \n", msg);
	    }
    printf("ENDING msg = %d \n", msg); 
/*     printf("looptotal %llu loopdiffexec moyen %llu \n", loopexectime, (loopexectime/msg)); */
    printf("convert 1000 ticks = %llu ns \n", rt_timer_tsc2ns(1000));
    return;
}
int main(void)
{

    orcTimerSigMask();

    signal(SIGTERM, clean_exit);
    signal(SIGINT, clean_exit);

    orcMakeRealTime();

    setTimer();

    SynchroSem = orcSemCreate(ORCEMPTY);
    Queue = orcMsgQCreate();
    
    orcSpawn(&thr_clockit, "AlarmServer", MAX_PRIO, NORMAL_STACK, (SOSO) clock_it, NULL);
    orcSpawn(&thr_loop, "Loop", MAX_PRIO - 1, NORMAL_STACK, (SOSO) func_loop, NULL);

    pause();
    fflush(NULL);

    return 0;
}




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-06-25 15:51       ` [Xenomai-core] " Daniel Simon
@ 2007-06-25 16:55         ` Jan Kiszka
  2007-06-27  8:57           ` Daniel Simon
  0 siblings, 1 reply; 33+ messages in thread
From: Jan Kiszka @ 2007-06-25 16:55 UTC (permalink / raw)
  To: Daniel Simon; +Cc: xenomai-core

[-- Attachment #1: Type: text/plain, Size: 4611 bytes --]

Daniel Simon wrote:
> On Fri, 08 Jun 2007 13:20:11 +0200
> Jan Kiszka <jan.kiszka@domain.hid> wrote:
> 
> Hello,
> 
>> Well, the best (==most comfortable :o) ) way from my POV would be if you
>> could try rebasing your work on your own first. Questions, even on minor
>> details, are always welcome, review on patches will be provided. Should
>> be no problem to get this into Xenomai 2.4.
>>
>> The rough to-do list would be:
>>
>>  o add some persistent runtimer counter to xnthread::stat and maintain
>>    it
>>  o introduce an xnpod service (inline function) to obtain it (let that
>>    thing return [0..LONGLONG_MAX] when stats are available, -1
>>    otherwise)
>>  o export the runtime via struct rt_task_info, maybe also the task start
>>    time
> 
> Coming back on this topic:
> please find attached a first draft of a patch following (more or less)  your
> suggestions:
> -there is an additional field "exectime" in  TASK_INFO, which can be set by
> rt_task_inquire and read in the info structure (the computation is slightly
> different for self and remote measurement);
> -xnthread_get_exectime() and xnthread_get_lastswitch() pass the values of the
> current thread's  timing out of xn;
> -exectime and lastswitch times are stored in an extended xnstat_runtime_t,
> updated by xnstat_runtime_update() (but not exactly like the "total" item)

That was not my idea, and there is a reason for it, see below.

> 
> it has been tested (only on  P3 single core cpu) with the testexec program also
> attached : there are 2 periodic tasks, clockit and loop, which measure
> either their exectime, or the one of the other task: the measures 
> seems reasonable, except when the clockit task measures itself, in that case the
> first and second printed values are always absurd for a reason I cannot
> understand...)

A few generic wishes related to your patch:

 - Please don't include debug or commented out code in your patches.

 - Please avoid unrelated changes

 - Please use an editor that properly formats your code, e.g. doesn't
   insert spaces where tabs belong according to kernel style

> 
> Only works in primary mode... (also I hope that the tsc is monotonic?)

Don't worry, TSC can be considered monotonic under Xenomai (that's why
you have to switch off frequency scaling e.g.).

> 
> I have no idea of what may happen on a smp or when on the fly migrating tasks!

SMP should not be an issue, given that we rely on more or less
synchronised TSCs anyway.

...
> diff -urN xenomai-2.3.1-orig/include/nucleus/stat.h xenomai-2.3.1/include/nucleus/stat.h
> --- xenomai-2.3.1-orig/include/nucleus/stat.h	2006-12-26 19:38:59.000000000 +0100
> +++ xenomai-2.3.1/include/nucleus/stat.h	2007-06-25 15:48:25.000000000 +0200
> @@ -31,6 +31,10 @@
>  
>  	xnticks_t total; /* Accumulated execution time */
>  
> +	xnticks_t exectime; /* Overall execution time from taskspawn upto lastswitch*/
> +
> +	xnticks_t lastswitch; /* Last time the task was made active */
> +
>  } xnstat_runtime_t;
>  
>  /* Return current date which can be passed to other xnstat services for
> @@ -42,6 +46,10 @@
>  do { \
>  	(sched)->current_account->total += \
>  		start - (sched)->last_account_switch; \
> +	(sched)->current_account->exectime += \
> +                xnstat_runtime_now() - (sched)->last_account_switch; \
> +	(sched)->current_account->lastswitch = \
> +                xnstat_runtime_now(); \

My idea was to keep a persistent version the existing xnstat_runtime_t
instance in xnthread (and later on also xnintr). That one shall not be
reset on readout via /proc.

Instead, you establish quite some new calculations that break
the existing API (the switch date is given via "start" - which was
misnamed so far, I just changed it to "date") and increase the runtime
overhead in the hotpath. Why? All the information you should need is
already there, it just has to be saved from being vaporised when the
user dumps /proc/xenomai/stat.

>  	(sched)->last_account_switch = start; \
>  } while (0)
>  

Let's try it like this: Change Xenomai so that it leaves the existing
xnthread_t::stat.account untouched when it reads /proc. Rather add
something like "xnstat_runtime_t last;" to xnthread_t::stat. On readout
for /proc output, do the stats now like "account-last" and then move
account into last. For your task exectime, you can then read
xnthread_t::stat.account directly, because it will always reflect the
full task history. Would't this work better?

Thanks for working on this!

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-06-25 16:55         ` Jan Kiszka
@ 2007-06-27  8:57           ` Daniel Simon
  2007-06-27 11:56             ` Jan Kiszka
  0 siblings, 1 reply; 33+ messages in thread
From: Daniel Simon @ 2007-06-27  8:57 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai-core

On Mon, 25 Jun 2007 18:55:45 +0200
Jan Kiszka <jan.kiszka@domain.hid> wrote:



> My idea was to keep a persistent version the existing xnstat_runtime_t
> instance in xnthread (and later on also xnintr). That one shall not be
> reset on readout via /proc.
Is it necessary to keep also the reset one?

> Instead, you establish quite some new calculations that break
> the existing API (the switch date is given via "start" - which was
> misnamed so far, I just changed it to "date") 

ok, better fit the behaviour.
I should better work from the last svn version?

>and increase the runtime
> overhead in the hotpath. Why? All the information you should need is
> already there, it just has to be saved from being vaporised when the
> user dumps /proc/xenomai/stat.
> 
> >  	(sched)->last_account_switch = start; \
> >  } while (0)
> >    
> 
> Let's try it like this: Change Xenomai so that it leaves the existing
> xnthread_t::stat.account untouched when it reads /proc. Rather add
> something like "xnstat_runtime_t last;" to xnthread_t::stat. On readout
> for /proc output, 
Where is this done? I've found one place in module::stat_seq_open where total is
reset to 0, is it the only one? 
In fact I don't have a clear picture of the stat
process and what it is assumed to do (and thus did not want to break something!)
>do the stats now like "account-last" and then move
> account into last. For your task exectime, you can then read
> xnthread_t::stat.account directly, because it will always reflect the
> full task history. Would't this work better?

> Thanks for working on this!
I'll try to find enough time by the end of this week to improve this...

	Daniel

-- 
       Daniel SIMON    Projet NeCS  INRIA Rhone-Alpes
        Inovallee, 655 avenue de l'Europe, Montbonnot
             38 334 Saint Ismier Cedex France
 Daniel.Simon@domain.hid Phone:(33)476615328 Fax:(33)476615252
          http://necs.inrialpes.fr/people/simon/




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-06-27  8:57           ` Daniel Simon
@ 2007-06-27 11:56             ` Jan Kiszka
  2007-06-29 14:43               ` Daniel Simon
  0 siblings, 1 reply; 33+ messages in thread
From: Jan Kiszka @ 2007-06-27 11:56 UTC (permalink / raw)
  To: Daniel Simon; +Cc: xenomai-core

[-- Attachment #1: Type: text/plain, Size: 2488 bytes --]

Daniel Simon wrote:
> On Mon, 25 Jun 2007 18:55:45 +0200
> Jan Kiszka <jan.kiszka@domain.hid> wrote:
> 
> 
> 
>> My idea was to keep a persistent version the existing xnstat_runtime_t
>> instance in xnthread (and later on also xnintr). That one shall not be
>> reset on readout via /proc.
> Is it necessary to keep also the reset one?

Yep, at least virtually (as in my proposal): We are dumping CPU share
percentages in /proc, and those need to be calculated over the same
measurement period. Thus we restart the measurement each time the user
reads the stats.

> 
>> Instead, you establish quite some new calculations that break
>> the existing API (the switch date is given via "start" - which was
>> misnamed so far, I just changed it to "date") 
> 
> ok, better fit the behaviour.
> I should better work from the last svn version?

SVN trunk would be best, indeed.

> 
>> and increase the runtime
>> overhead in the hotpath. Why? All the information you should need is
>> already there, it just has to be saved from being vaporised when the
>> user dumps /proc/xenomai/stat.
>>
>>>  	(sched)->last_account_switch = start; \
>>>  } while (0)
>>>    
>> Let's try it like this: Change Xenomai so that it leaves the existing
>> xnthread_t::stat.account untouched when it reads /proc. Rather add
>> something like "xnstat_runtime_t last;" to xnthread_t::stat. On readout
>> for /proc output, 
> Where is this done? I've found one place in module::stat_seq_open where total is
> reset to 0, is it the only one? 

That's one spot, the other is xnpod_migrate_thread()
(xnstat_runtime_reset_stats()) IIRC.

> In fact I don't have a clear picture of the stat
> process and what it is assumed to do (and thus did not want to break something!)

Stat generation happens based on services that are provided by
nucleus/stat.h, stat dumping is concentrated in modules.c, namely
stat_seq_open. Using the cross reference [1] can help if you want to
verify this on your own.

>> do the stats now like "account-last" and then move
>> account into last. For your task exectime, you can then read
>> xnthread_t::stat.account directly, because it will always reflect the
>> full task history. Would't this work better?
> 
>> Thanks for working on this!
> I'll try to find enough time by the end of this week to improve this...
> 
> 	Daniel
> 

Looking forward.

Jan

[1] http://www.rts.uni-hannover.de/xenomai/lxr/source/?v=SVN-trunk


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-06-27 11:56             ` Jan Kiszka
@ 2007-06-29 14:43               ` Daniel Simon
  2007-06-29 15:00                 ` Jan Kiszka
  2007-07-08 10:11                 ` Jan Kiszka
  0 siblings, 2 replies; 33+ messages in thread
From: Daniel Simon @ 2007-06-29 14:43 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai-core

[-- Attachment #1: Type: text/plain, Size: 2545 bytes --]

On Wed, 27 Jun 2007 13:56:04 +0200
Jan Kiszka <jan.kiszka@domain.hid> wrote:

> > On Mon, 25 Jun 2007 18:55:45 +0200
> > Jan Kiszka <jan.kiszka@domain.hid> wrote:

> >> My idea was to keep a persistent version the existing xnstat_runtime_t
> >> instance in xnthread (and later on also xnintr). That one shall not be
> >> reset on readout via /proc.
> > Is it necessary to keep also the reset one?
> 
> Yep, at least virtually (as in my proposal): We are dumping CPU share
> percentages in /proc, and those need to be calculated over the same
> measurement period. Thus we restart the measurement each time the user
> reads the stats.
> 
> >> Let's try it like this: Change Xenomai so that it leaves the existing
> >> xnthread_t::stat.account untouched when it reads /proc. Rather add
> >> something like " last;" to xnthread_t::stat. On readout
> >> for /proc output, 

> That's one spot, the other is xnpod_migrate_thread()
> (xnstat_runtime_reset_stats()) IIRC.

ok, i've found only these two reset points.

the account structure is also partially touched by  xnstat_runtime_finalize()
in pod.c, I don't understand when and why...

> >> account into last. For your task exectime, you can then read
> >> xnthread_t::stat.account directly, because it will always reflect the
> >> full task history. Would't this work better?
> Jan
> 
please find attached a new patch following these ideas:
 (patch against svn trunk Revision: 2672) 

account is now persistent, its "start" field is the last_switch time, and the
new xnstat_runtime_t "lastperiod" handles the past values necessary to compute
the runtime values plot at snapshot time.

from a few trials, it seems that /proc/xenomai/stat still behaves normally (i.e.
like in the original version where the first reading of stat does gives nothing
for the tasks runtime?)

exectime returns likely values when a task is measured by another one, but self
measurement (with the NULL task calling parameter in rt_task_inquire) sometime
provides incoherent values (e.g. returns the period rather than the exectime,
or returns non-monotonic exectime values...). 
I could not manage to fix this bug upto now. 
And unfortunately i'll be away and probably far from any xenomai-capable
machine next week...

Looking forward,
			Daniel

-- 
       Daniel SIMON    Projet NeCS  INRIA Rhone-Alpes
        Inovallee, 655 avenue de l'Europe, Montbonnot
             38 334 Saint Ismier Cedex France
 Daniel.Simon@domain.hid Phone:(33)476615328 Fax:(33)476615252
          http://necs.inrialpes.fr/people/simon/



[-- Attachment #2: 2672-exectime.patch --]
[-- Type: text/x-patch, Size: 5070 bytes --]

diff -urN xenomai-orig/include/native/task.h xenomai/include/native/task.h
--- xenomai-orig/include/native/task.h	2007-06-28 10:19:19.000000000 +0200
+++ xenomai/include/native/task.h	2007-06-29 15:07:08.000000000 +0200
@@ -90,6 +90,8 @@
     
     char name[XNOBJECT_NAME_LEN];  /**< Symbolic name assigned at creation. */
 
+    RTIME exectime; /**<execution time in tsc ticks since the task spawned (primary mode only) */
+
 } RT_TASK_INFO;
 
 #define RT_MCB_FSTORE_LIMIT  64
diff -urN xenomai-orig/include/nucleus/stat.h xenomai/include/nucleus/stat.h
--- xenomai-orig/include/nucleus/stat.h	2007-06-28 10:19:37.000000000 +0200
+++ xenomai/include/nucleus/stat.h	2007-06-28 17:19:58.000000000 +0200
@@ -42,7 +42,7 @@
 do { \
 	(sched)->current_account->total += \
 		date - (sched)->last_account_switch; \
-	(sched)->last_account_switch = date; \
+	(sched)->last_account_switch = (sched)->current_account->start = date; \
 } while (0)
 
 /* Update the current account reference, returning the previous one. */
diff -urN xenomai-orig/include/nucleus/thread.h xenomai/include/nucleus/thread.h
--- xenomai-orig/include/nucleus/thread.h	2007-06-28 10:19:37.000000000 +0200
+++ xenomai/include/nucleus/thread.h	2007-06-28 12:46:11.000000000 +0200
@@ -204,7 +204,8 @@
 	xnstat_counter_t ssw;	/* Primary -> secondary mode switch count */
 	xnstat_counter_t csw;	/* Context switches (includes secondary -> primary switches) */
 	xnstat_counter_t pf;	/* Number of page faults */
-	xnstat_runtime_t account; /* Runtime accounting entity */
+	xnstat_runtime_t account; /* Exectime accounting entity */
+	xnstat_runtime_t lastperiod;  /* Runtime accounting entity */
     } stat;
 
     int errcode;		/* Local errno */
@@ -291,7 +292,8 @@
 #define xnthread_user_pid(thread) \
     (xnthread_test_state((thread),XNROOT) || !xnthread_user_task(thread) ? \
     0 : xnarch_user_pid(xnthread_archtcb(thread)))
-
+#define xnthread_get_exectime(thread)      ((thread)->stat.account.total)
+#define xnthread_get_lastswitch(thread)    ((thread)->stat.account.start)
 /* Class-level operations for threads. */
 static inline int xnthread_get_denormalized_prio(xnthread_t *t)
 {
diff -urN xenomai-orig/ksrc/nucleus/module.c xenomai/ksrc/nucleus/module.c
--- xenomai-orig/ksrc/nucleus/module.c	2007-06-28 10:20:36.000000000 +0200
+++ xenomai/ksrc/nucleus/module.c	2007-06-28 15:07:40.000000000 +0200
@@ -421,16 +421,16 @@
 		stat_info->csw = xnstat_counter_get(&thread->stat.csw);
 		stat_info->pf = xnstat_counter_get(&thread->stat.pf);
 
-		period = sched->last_account_switch - thread->stat.account.start;
+		period = sched->last_account_switch - thread->stat.lastperiod.start;
 		if (!period && thread == sched->runthread) {
 			stat_info->runtime = 1;
 			stat_info->account_period = 1;
 		} else {
-			stat_info->runtime = thread->stat.account.total;
+			stat_info->runtime = thread->stat.account.total - thread->stat.lastperiod.total;
 			stat_info->account_period = period;
 		}
-		thread->stat.account.total = 0;
-		thread->stat.account.start = sched->last_account_switch;
+		thread->stat.lastperiod.total = thread->stat.account.total;
+		thread->stat.lastperiod.start = sched->last_account_switch;
 
 		holder = nextq(&nkpod->threadq, holder);
 
diff -urN xenomai-orig/ksrc/nucleus/pod.c xenomai/ksrc/nucleus/pod.c
--- xenomai-orig/ksrc/nucleus/pod.c	2007-06-28 10:20:36.000000000 +0200
+++ xenomai/ksrc/nucleus/pod.c	2007-06-28 12:10:09.000000000 +0200
@@ -1772,7 +1772,7 @@
 	xnpod_schedule();
 
 	/* Reset execution time stats due to unsync'ed TSCs */
-	xnstat_runtime_reset_stats(&thread->stat.account);
+	xnstat_runtime_reset_stats(&thread->stat.lastperiod);
 
       unlock_and_exit:
 
diff -urN xenomai-orig/ksrc/nucleus/thread.c xenomai/ksrc/nucleus/thread.c
--- xenomai-orig/ksrc/nucleus/thread.c	2007-06-28 10:20:36.000000000 +0200
+++ xenomai/ksrc/nucleus/thread.c	2007-06-28 12:40:51.000000000 +0200
@@ -97,7 +97,12 @@
 	thread->registry.waitkey = NULL;
 #endif /* CONFIG_XENO_OPT_REGISTRY */
 	memset(&thread->stat, 0, sizeof(thread->stat));
-
+#ifdef CONFIG_XENO_OPT_STATS
+	thread->stat.account.total = 0;
+	thread->stat.account.start = 0;
+	thread->stat.lastperiod.total = 0;
+	thread->stat.lastperiod.start = 0;
+#endif
 	/* These will be filled by xnpod_start_thread() */
 	thread->imask = 0;
 	thread->imode = 0;
diff -urN xenomai-orig/ksrc/skins/native/task.c xenomai/ksrc/skins/native/task.c
--- xenomai-orig/ksrc/skins/native/task.c	2007-06-28 10:20:17.000000000 +0200
+++ xenomai/ksrc/skins/native/task.c	2007-06-28 17:20:29.000000000 +0200
@@ -1144,7 +1144,10 @@
 	info->cprio = xnthread_current_priority(&task->thread_base);
 	info->status = xnthread_state_flags(&task->thread_base);
 	info->relpoint = xntimer_get_date(&task->thread_base.ptimer);
-
+	if(task == xeno_current_task())
+	  info->exectime = xnthread_get_exectime(&task->thread_base) + (xnstat_runtime_now() - xnthread_get_lastswitch(&task->thread_base));
+	else 
+	  info->exectime = xnthread_get_exectime(&task->thread_base);
       unlock_and_exit:
 
 	xnlock_put_irqrestore(&nklock, s);

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-06-29 14:43               ` Daniel Simon
@ 2007-06-29 15:00                 ` Jan Kiszka
  2007-06-29 15:29                   ` Daniel Simon
  2007-07-08 10:11                 ` Jan Kiszka
  1 sibling, 1 reply; 33+ messages in thread
From: Jan Kiszka @ 2007-06-29 15:00 UTC (permalink / raw)
  To: Daniel Simon; +Cc: xenomai-core

[-- Attachment #1: Type: text/plain, Size: 3718 bytes --]

Daniel Simon wrote:
> On Wed, 27 Jun 2007 13:56:04 +0200
> Jan Kiszka <jan.kiszka@domain.hid> wrote:
> 
>>> On Mon, 25 Jun 2007 18:55:45 +0200
>>> Jan Kiszka <jan.kiszka@domain.hid> wrote:
> 
>>>> My idea was to keep a persistent version the existing xnstat_runtime_t
>>>> instance in xnthread (and later on also xnintr). That one shall not be
>>>> reset on readout via /proc.
>>> Is it necessary to keep also the reset one?
>> Yep, at least virtually (as in my proposal): We are dumping CPU share
>> percentages in /proc, and those need to be calculated over the same
>> measurement period. Thus we restart the measurement each time the user
>> reads the stats.
>>
>>>> Let's try it like this: Change Xenomai so that it leaves the existing
>>>> xnthread_t::stat.account untouched when it reads /proc. Rather add
>>>> something like " last;" to xnthread_t::stat. On readout
>>>> for /proc output, 
> 
>> That's one spot, the other is xnpod_migrate_thread()
>> (xnstat_runtime_reset_stats()) IIRC.
> 
> ok, i've found only these two reset points.
> 
> the account structure is also partially touched by  xnstat_runtime_finalize()
> in pod.c, I don't understand when and why...

xnstat_runtime_finalize is called when a task passes away, i.e. you
wouldn't be able to retrieve it's stats later on anyway.

> 
>>>> account into last. For your task exectime, you can then read
>>>> xnthread_t::stat.account directly, because it will always reflect the
>>>> full task history. Would't this work better?
>> Jan
>>
> please find attached a new patch following these ideas:
>  (patch against svn trunk Revision: 2672) 
> 
> account is now persistent, its "start" field is the last_switch time, and the
> new xnstat_runtime_t "lastperiod" handles the past values necessary to compute
> the runtime values plot at snapshot time.
> 
> from a few trials, it seems that /proc/xenomai/stat still behaves normally (i.e.
> like in the original version where the first reading of stat does gives nothing
> for the tasks runtime?)

The first dump is always bogus as the task set changed since the
previous measurement date (here: Xenomai start-up time).

> 
> exectime returns likely values when a task is measured by another one, but self
> measurement (with the NULL task calling parameter in rt_task_inquire) sometime
> provides incoherent values (e.g. returns the period rather than the exectime,
> or returns non-monotonic exectime values...). 
> I could not manage to fix this bug upto now. 

I think I already see one, though it doesn't explain all your observed
behaviour to me:

> --- xenomai-orig/ksrc/skins/native/task.c	2007-06-28 10:20:17.000000000 +0200
> +++ xenomai/ksrc/skins/native/task.c	2007-06-28 17:20:29.000000000 +0200
> @@ -1144,7 +1144,10 @@
>  	info->cprio = xnthread_current_priority(&task->thread_base);
>  	info->status = xnthread_state_flags(&task->thread_base);
>  	info->relpoint = xntimer_get_date(&task->thread_base.ptimer);
> -
> +	if(task == xeno_current_task())
> +	  info->exectime = xnthread_get_exectime(&task->thread_base) + (xnstat_runtime_now() - xnthread_get_lastswitch(&task->thread_base));
> +	else 
> +	  info->exectime = xnthread_get_exectime(&task->thread_base);

Exectime is only updated on task switches. So you are not obtaining the true value when requesting your own data. Use the same formula for both cases.

> And unfortunately i'll be away and probably far from any xenomai-capable
> machine next week...
> 

OK. I'll try to look into this in the meantime. But I think it should be no problem to merge a final version even after the approaching 2.4-rc1, the patch is yet fairly confined.

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-06-29 15:00                 ` Jan Kiszka
@ 2007-06-29 15:29                   ` Daniel Simon
  2007-06-29 15:47                     ` Philippe Gerum
  2007-06-29 15:52                     ` Jan Kiszka
  0 siblings, 2 replies; 33+ messages in thread
From: Daniel Simon @ 2007-06-29 15:29 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai-core

On Fri, 29 Jun 2007 17:00:39 +0200
Jan Kiszka <jan.kiszka@domain.hid> wrote:

> Exectime is only updated on task switches. So you are not obtaining the true
> value when requesting your own data. Use the same formula for both cases.

yes, but like that the fraction of time spent in the current execution is not
accounted, which might be sometimes useful (e.g. to integrate the cost of a
feedback scheduler in the total control budget)

another potentially useful feature would be also accounting the execution time
spent in secondary mode... no idea on how to do that. 
BTW, Posix defines an optional CLOCK_THREAD_CPUTIME which is assumed to provide
this measure ?

	Daniel

-- 
       Daniel SIMON    Projet NeCS  INRIA Rhone-Alpes
        Inovallee, 655 avenue de l'Europe, Montbonnot
             38 334 Saint Ismier Cedex France
 Daniel.Simon@domain.hid Phone:(33)476615328 Fax:(33)476615252
          http://necs.inrialpes.fr/people/simon/




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-06-29 15:29                   ` Daniel Simon
@ 2007-06-29 15:47                     ` Philippe Gerum
  2007-06-29 15:56                       ` Gilles Chanteperdrix
  2007-06-29 15:52                     ` Jan Kiszka
  1 sibling, 1 reply; 33+ messages in thread
From: Philippe Gerum @ 2007-06-29 15:47 UTC (permalink / raw)
  To: Daniel Simon; +Cc: Jan Kiszka, xenomai-core

On Fri, 2007-06-29 at 17:29 +0200, Daniel Simon wrote:
> On Fri, 29 Jun 2007 17:00:39 +0200
> Jan Kiszka <jan.kiszka@domain.hid> wrote:
> 
> > Exectime is only updated on task switches. So you are not obtaining the true
> > value when requesting your own data. Use the same formula for both cases.
> 
> yes, but like that the fraction of time spent in the current execution is not
> accounted, which might be sometimes useful (e.g. to integrate the cost of a
> feedback scheduler in the total control budget)
> 
> another potentially useful feature would be also accounting the execution time
> spent in secondary mode... no idea on how to do that. 

Xenomai-wise, secondary mode starts for an emerging thread in
xnshadow_map(), then stops when exiting xnshadow_harden(), then resumes
when exiting xnshadow_relax(). All routines are defined in
nucleus/shadow.c.

> BTW, Posix defines an optional CLOCK_THREAD_CPUTIME which is assumed to provide
> this measure ?
> 
> 	Daniel
> 
-- 
Philippe.




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-06-29 15:29                   ` Daniel Simon
  2007-06-29 15:47                     ` Philippe Gerum
@ 2007-06-29 15:52                     ` Jan Kiszka
  1 sibling, 0 replies; 33+ messages in thread
From: Jan Kiszka @ 2007-06-29 15:52 UTC (permalink / raw)
  To: Daniel Simon; +Cc: xenomai-core

[-- Attachment #1: Type: text/plain, Size: 1040 bytes --]

Daniel Simon wrote:
> On Fri, 29 Jun 2007 17:00:39 +0200
> Jan Kiszka <jan.kiszka@domain.hid> wrote:
> 
>> Exectime is only updated on task switches. So you are not obtaining the true
>> value when requesting your own data. Use the same formula for both cases.
> 
> yes, but like that the fraction of time spent in the current execution is not
> accounted, which might be sometimes useful (e.g. to integrate the cost of a
> feedback scheduler in the total control budget)

Yeah, true, I applied the inverse logic. However, this interface is
inconsistent, one should expects the same algorithm applied on both
local as well as remote task queries. Why do you differentiate?

> 
> another potentially useful feature would be also accounting the execution time
> spent in secondary mode... no idea on how to do that. 
> BTW, Posix defines an optional CLOCK_THREAD_CPUTIME which is assumed to provide
> this measure ?

This should work for shadow threads to retrieve their secondary-mode
runtime. Give it a try.

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-06-29 15:47                     ` Philippe Gerum
@ 2007-06-29 15:56                       ` Gilles Chanteperdrix
  0 siblings, 0 replies; 33+ messages in thread
From: Gilles Chanteperdrix @ 2007-06-29 15:56 UTC (permalink / raw)
  To: rpm; +Cc: Jan Kiszka, xenomai-core

On 6/29/07, Philippe Gerum <rpm@xenomai.org> wrote:
> On Fri, 2007-06-29 at 17:29 +0200, Daniel Simon wrote:
> > On Fri, 29 Jun 2007 17:00:39 +0200
> > Jan Kiszka <jan.kiszka@domain.hid> wrote:
> >
> > > Exectime is only updated on task switches. So you are not obtaining the true
> > > value when requesting your own data. Use the same formula for both cases.
> >
> > yes, but like that the fraction of time spent in the current execution is not
> > accounted, which might be sometimes useful (e.g. to integrate the cost of a
> > feedback scheduler in the total control budget)
> >
> > another potentially useful feature would be also accounting the execution time
> > spent in secondary mode... no idea on how to do that.
>
> Xenomai-wise, secondary mode starts for an emerging thread in
> xnshadow_map(), then stops when exiting xnshadow_harden(), then resumes
> when exiting xnshadow_relax(). All routines are defined in
> nucleus/shadow.c.

Additionnaly when a task is suspended by Linux, the function
do_schedule_event is triggered by Adeos.

-- 
                                               Gilles Chanteperdrix


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-06-29 14:43               ` Daniel Simon
  2007-06-29 15:00                 ` Jan Kiszka
@ 2007-07-08 10:11                 ` Jan Kiszka
  2007-07-09  8:49                   ` Daniel Simon
  2007-07-11 13:59                   ` Daniel Simon
  1 sibling, 2 replies; 33+ messages in thread
From: Jan Kiszka @ 2007-07-08 10:11 UTC (permalink / raw)
  To: Daniel Simon; +Cc: xenomai-core

[-- Attachment #1: Type: text/plain, Size: 623 bytes --]

Daniel Simon wrote:
> please find attached a new patch following these ideas:
>  (patch against svn trunk Revision: 2672) 
> 

Based on this version, I integrated your patch into my patch stack. The
actual rt_task_inquire interface is totally untested, but the rest
appears to cause no regressions here. See

http://www.rts.uni-hannover.de/rtaddon/patches/xenomai

namely the enhance-thread-stats.patch. It may depend on some of the
previous patches in the stack, but only organisationally, not technically.

You are welcome to test, fix, improve, or just use it. Looking forward
to your feedback!

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-07-08 10:11                 ` Jan Kiszka
@ 2007-07-09  8:49                   ` Daniel Simon
  2007-07-11 13:59                   ` Daniel Simon
  1 sibling, 0 replies; 33+ messages in thread
From: Daniel Simon @ 2007-07-09  8:49 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai-core

On Sun, 08 Jul 2007 12:11:56 +0200
Jan Kiszka <jan.kiszka@domain.hid> wrote:

> You are welcome to test, fix, improve, or just use it. Looking forward
> to your feedback!

Thanks, I'll try it this week

	Daniel
-- 
       Daniel SIMON    Projet NeCS  INRIA Rhone-Alpes
        Inovallee, 655 avenue de l'Europe, Montbonnot
             38 334 Saint Ismier Cedex France
 Daniel.Simon@domain.hid Phone:(33)476615328 Fax:(33)476615252
          http://necs.inrialpes.fr/people/simon/




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-07-08 10:11                 ` Jan Kiszka
  2007-07-09  8:49                   ` Daniel Simon
@ 2007-07-11 13:59                   ` Daniel Simon
  2007-07-11 14:30                     ` Jan Kiszka
  1 sibling, 1 reply; 33+ messages in thread
From: Daniel Simon @ 2007-07-11 13:59 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai-core

[-- Attachment #1: Type: text/plain, Size: 897 bytes --]

On Sun, 08 Jul 2007 12:11:56 +0200
Jan Kiszka <jan.kiszka@domain.hid> wrote:

Hello,
> You are welcome to test, fix, improve, or just use it. Looking forward
> to your feedback!

here are attached some corrections against your previous patch (itself against
#2758 files): from my tests I now get likely exectime values from both remote
and self measurement (i.e. we get the accumulated exectime at the instant we
call rt_task_inquire ), and the stats given in /proc still seem to behave
normally...

the full patch against the original 2758 version is also given in attachement

	Looking forward to your feedback...

	Daniel
-- 
       Daniel SIMON    Projet NeCS  INRIA Rhone-Alpes
        Inovallee, 655 avenue de l'Europe, Montbonnot
             38 334 Saint Ismier Cedex France
 Daniel.Simon@domain.hid Phone:(33)476615328 Fax:(33)476615252
          http://necs.inrialpes.fr/people/simon/



[-- Attachment #2: enhance-thread-stats-corrections.patch --]
[-- Type: text/x-patch, Size: 3164 bytes --]

diff -urN xenomai-2758/include/nucleus/stat.h xenomai-2758-V2/include/nucleus/stat.h
--- xenomai-2758/include/nucleus/stat.h	2007-07-11 15:16:14.000000000 +0200
+++ xenomai-2758-V2/include/nucleus/stat.h	2007-07-11 15:09:38.000000000 +0200
@@ -42,7 +42,7 @@
 do { \
 	(sched)->current_account->total += \
 		date - (sched)->last_account_switch; \
-	(sched)->last_account_switch = date; \
+	(sched)->last_account_switch = (sched)->current_account->start = date; \
 	/* All changes must be committed before changing the current_account \
 	   reference in sched (required for xnintr_sync_stat_references) */ \
 	xnarch_memory_barrier(); \
@@ -71,6 +71,9 @@
 #define xnstat_runtime_get_start(account)	((account)->start)
 #define xnstat_runtime_get_total(account)	((account)->total)
 
+/* Obtain last time something has been switched */
+#define xnstat_runtime_get_last_switch(sched)	((sched)->last_account_switch)
+
 /* Reset statistics from inside the accounted entity (e.g. after CPU
    migration). */
 #define xnstat_runtime_reset_stats(stat) \
@@ -113,6 +116,7 @@
 #define xnstat_runtime_finalize(sched, new_account)		do { } while (0)
 #define xnstat_runtime_get_start(account)			({ 0; })
 #define xnstat_runtime_get_total(account)			({ 0; })
+#define xnstat_runtime_get_last_switch(sched)			({ 0; })
 #define xnstat_runtime_reset_stats(account)			do { } while (0)
 
 typedef struct xnstat_counter {
diff -urN xenomai-2758/include/nucleus/thread.h xenomai-2758-V2/include/nucleus/thread.h
--- xenomai-2758/include/nucleus/thread.h	2007-07-11 15:16:14.000000000 +0200
+++ xenomai-2758-V2/include/nucleus/thread.h	2007-07-11 14:28:15.000000000 +0200
@@ -294,7 +294,7 @@
 #define xnthread_affinity(thread)          ((thread)->affinity)
 #define xnthread_affine_p(thread, cpu)     xnarch_cpu_isset(cpu, (thread)->affinity)
 #define xnthread_get_exectime(thread)      xnstat_runtime_get_total(&(thread)->stat.account)
-#define xnthread_get_lastswitch(thread)    xnstat_runtime_get_start(&(thread)->stat.account)
+#define xnthread_get_lastswitch(thread)    xnstat_runtime_get_last_switch((thread)->sched)
 
 /* Class-level operations for threads. */
 static inline int xnthread_get_denormalized_prio(xnthread_t *t)
diff -urN xenomai-2758/ksrc/skins/native/task.c xenomai-2758-V2/ksrc/skins/native/task.c
--- xenomai-2758/ksrc/skins/native/task.c	2007-07-11 15:16:14.000000000 +0200
+++ xenomai-2758-V2/ksrc/skins/native/task.c	2007-07-11 15:22:10.000000000 +0200
@@ -1144,10 +1144,13 @@
 	info->cprio = xnthread_current_priority(&task->thread_base);
 	info->status = xnthread_state_flags(&task->thread_base);
 	info->relpoint = xntimer_get_date(&task->thread_base.ptimer);
+	if(task == xeno_current_task())
 	info->exectime = xnarch_tsc_to_ns(
 		xnthread_get_exectime(&task->thread_base) +
 		xnstat_runtime_now() -
 		xnthread_get_lastswitch(&task->thread_base));
+	else 
+	  info->exectime = xnarch_tsc_to_ns(xnthread_get_exectime(&task->thread_base));
 	info->modeswitches = xnstat_counter_get(&task->thread_base.stat.ssw);
 	info->ctxswitches = xnstat_counter_get(&task->thread_base.stat.csw);
 	info->pagefaults = xnstat_counter_get(&task->thread_base.stat.pf);

[-- Attachment #3: 2758-exectime.patch --]
[-- Type: text/x-patch, Size: 7237 bytes --]

diff -urN xenomai/include/native/task.h xenomai-2758-V2/include/native/task.h
--- xenomai/include/native/task.h	2007-07-09 13:06:54.000000000 +0200
+++ xenomai-2758-V2/include/native/task.h	2007-07-11 09:55:02.000000000 +0200
@@ -90,6 +90,14 @@
     
     char name[XNOBJECT_NAME_LEN];  /**< Symbolic name assigned at creation. */
 
+    RTIME exectime; /**< Execution time in primary mode in nanoseconds. */
+
+    int modeswitches; /**< Number of primary->secondary mode switches. */
+
+    int ctxswitches; /**< Number of context switches. */
+
+    int pagefaults; /**< Number of triggered page faults. */
+
 } RT_TASK_INFO;
 
 #define RT_MCB_FSTORE_LIMIT  64
diff -urN xenomai/include/nucleus/stat.h xenomai-2758-V2/include/nucleus/stat.h
--- xenomai/include/nucleus/stat.h	2007-07-09 13:07:01.000000000 +0200
+++ xenomai-2758-V2/include/nucleus/stat.h	2007-07-11 15:09:38.000000000 +0200
@@ -42,7 +42,7 @@
 do { \
 	(sched)->current_account->total += \
 		date - (sched)->last_account_switch; \
-	(sched)->last_account_switch = date; \
+	(sched)->last_account_switch = (sched)->current_account->start = date; \
 	/* All changes must be committed before changing the current_account \
 	   reference in sched (required for xnintr_sync_stat_references) */ \
 	xnarch_memory_barrier(); \
@@ -67,6 +67,13 @@
 	(sched)->current_account = (new_account); \
 } while (0)
 
+/* Obtain content of xnstat_runtime_t */
+#define xnstat_runtime_get_start(account)	((account)->start)
+#define xnstat_runtime_get_total(account)	((account)->total)
+
+/* Obtain last time something has been switched */
+#define xnstat_runtime_get_last_switch(sched)	((sched)->last_account_switch)
+
 /* Reset statistics from inside the accounted entity (e.g. after CPU
    migration). */
 #define xnstat_runtime_reset_stats(stat) \
@@ -104,9 +111,12 @@
 
 #define xnstat_runtime_now()					({ 0; })
 #define xnstat_runtime_update(sched, date)			do { } while (0)
-#define xnstat_runtime_set_current(sched, new_account)	({ (void)sched; NULL; })
+#define xnstat_runtime_set_current(sched, new_account)		({ (void)sched; NULL; })
 #define xnstat_runtime_get_current(sched)			({ (void)sched; NULL; })
 #define xnstat_runtime_finalize(sched, new_account)		do { } while (0)
+#define xnstat_runtime_get_start(account)			({ 0; })
+#define xnstat_runtime_get_total(account)			({ 0; })
+#define xnstat_runtime_get_last_switch(sched)			({ 0; })
 #define xnstat_runtime_reset_stats(account)			do { } while (0)
 
 typedef struct xnstat_counter {
diff -urN xenomai/include/nucleus/thread.h xenomai-2758-V2/include/nucleus/thread.h
--- xenomai/include/nucleus/thread.h	2007-07-09 13:07:01.000000000 +0200
+++ xenomai-2758-V2/include/nucleus/thread.h	2007-07-11 14:28:15.000000000 +0200
@@ -205,7 +205,8 @@
 	xnstat_counter_t ssw;	/* Primary -> secondary mode switch count */
 	xnstat_counter_t csw;	/* Context switches (includes secondary -> primary switches) */
 	xnstat_counter_t pf;	/* Number of page faults */
-	xnstat_runtime_t account; /* Runtime accounting entity */
+	xnstat_runtime_t account; /* Execution time accounting entity */
+	xnstat_runtime_t lastperiod; /* Interval marker for execution time reports */
     } stat;
 
     int errcode;		/* Local errno */
@@ -235,8 +236,6 @@
 
     char name[XNOBJECT_NAME_LEN]; /* Symbolic name of thread */
 
-    xnticks_t stime;		/* Start time */
-
     void (*entry)(void *cookie); /* Thread entry routine */
 
     void *cookie;		/* Cookie to pass to the entry routine */
@@ -294,6 +293,8 @@
     0 : xnarch_user_pid(xnthread_archtcb(thread)))
 #define xnthread_affinity(thread)          ((thread)->affinity)
 #define xnthread_affine_p(thread, cpu)     xnarch_cpu_isset(cpu, (thread)->affinity)
+#define xnthread_get_exectime(thread)      xnstat_runtime_get_total(&(thread)->stat.account)
+#define xnthread_get_lastswitch(thread)    xnstat_runtime_get_last_switch((thread)->sched)
 
 /* Class-level operations for threads. */
 static inline int xnthread_get_denormalized_prio(xnthread_t *t)
diff -urN xenomai/ksrc/nucleus/module.c xenomai-2758-V2/ksrc/nucleus/module.c
--- xenomai/ksrc/nucleus/module.c	2007-07-09 13:07:18.000000000 +0200
+++ xenomai-2758-V2/ksrc/nucleus/module.c	2007-07-11 09:55:02.000000000 +0200
@@ -421,16 +421,17 @@
 		stat_info->csw = xnstat_counter_get(&thread->stat.csw);
 		stat_info->pf = xnstat_counter_get(&thread->stat.pf);
 
-		period = sched->last_account_switch - thread->stat.account.start;
+		period = sched->last_account_switch - thread->stat.lastperiod.start;
 		if (!period && thread == sched->runthread) {
 			stat_info->runtime = 1;
 			stat_info->account_period = 1;
 		} else {
-			stat_info->runtime = thread->stat.account.total;
+			stat_info->runtime = thread->stat.account.total -
+				thread->stat.lastperiod.total;
 			stat_info->account_period = period;
 		}
-		thread->stat.account.total = 0;
-		thread->stat.account.start = sched->last_account_switch;
+		thread->stat.lastperiod.total = thread->stat.account.total;
+		thread->stat.lastperiod.start = sched->last_account_switch;
 
 		holder = nextq(&nkpod->threadq, holder);
 
diff -urN xenomai/ksrc/nucleus/pod.c xenomai-2758-V2/ksrc/nucleus/pod.c
--- xenomai/ksrc/nucleus/pod.c	2007-07-09 13:07:18.000000000 +0200
+++ xenomai-2758-V2/ksrc/nucleus/pod.c	2007-07-11 09:55:02.000000000 +0200
@@ -832,7 +832,6 @@
 	thread->imode = (mode & XNTHREAD_MODE_BITS);
 	thread->entry = entry;
 	thread->cookie = cookie;
-	thread->stime = xnarch_get_cpu_time();
 
 	if (xnthread_test_state(thread, XNRRB))
 		thread->rrcredit = thread->rrperiod;
@@ -1781,8 +1780,9 @@
 
 	xnpod_schedule();
 
-	/* Reset execution time stats due to unsync'ed TSCs */
-	xnstat_runtime_reset_stats(&thread->stat.account);
+	/* Reset execution time measurement period so that we don't mess up
+	   per-CPU statistics. */
+	xnstat_runtime_reset_stats(&thread->stat.lastperiod);
 
       unlock_and_exit:
 
diff -urN xenomai/ksrc/nucleus/thread.c xenomai-2758-V2/ksrc/nucleus/thread.c
--- xenomai/ksrc/nucleus/thread.c	2007-07-09 13:07:18.000000000 +0200
+++ xenomai-2758-V2/ksrc/nucleus/thread.c	2007-07-11 09:55:02.000000000 +0200
@@ -103,7 +103,6 @@
 	thread->imode = 0;
 	thread->entry = NULL;
 	thread->cookie = 0;
-	thread->stime = 0;
 	thread->ops = ops;
 
 	inith(&thread->glink);
diff -urN xenomai/ksrc/skins/native/task.c xenomai-2758-V2/ksrc/skins/native/task.c
--- xenomai/ksrc/skins/native/task.c	2007-07-09 13:07:13.000000000 +0200
+++ xenomai-2758-V2/ksrc/skins/native/task.c	2007-07-11 15:22:10.000000000 +0200
@@ -1144,6 +1144,16 @@
 	info->cprio = xnthread_current_priority(&task->thread_base);
 	info->status = xnthread_state_flags(&task->thread_base);
 	info->relpoint = xntimer_get_date(&task->thread_base.ptimer);
+	if(task == xeno_current_task())
+	info->exectime = xnarch_tsc_to_ns(
+		xnthread_get_exectime(&task->thread_base) +
+		xnstat_runtime_now() -
+		xnthread_get_lastswitch(&task->thread_base));
+	else 
+	  info->exectime = xnarch_tsc_to_ns(xnthread_get_exectime(&task->thread_base));
+	info->modeswitches = xnstat_counter_get(&task->thread_base.stat.ssw);
+	info->ctxswitches = xnstat_counter_get(&task->thread_base.stat.csw);
+	info->pagefaults = xnstat_counter_get(&task->thread_base.stat.pf);
 
       unlock_and_exit:
 

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-07-11 13:59                   ` Daniel Simon
@ 2007-07-11 14:30                     ` Jan Kiszka
  2007-07-11 15:35                       ` Daniel Simon
  0 siblings, 1 reply; 33+ messages in thread
From: Jan Kiszka @ 2007-07-11 14:30 UTC (permalink / raw)
  To: Daniel Simon; +Cc: xenomai-core

[-- Attachment #1: Type: text/plain, Size: 4930 bytes --]

Daniel Simon wrote:
> On Sun, 08 Jul 2007 12:11:56 +0200
> Jan Kiszka <jan.kiszka@domain.hid> wrote:
> 
> Hello,
>> You are welcome to test, fix, improve, or just use it. Looking forward
>> to your feedback!
> 
> here are attached some corrections against your previous patch (itself against
> #2758 files): from my tests I now get likely exectime values from both remote
> and self measurement (i.e. we get the accumulated exectime at the instant we
> call rt_task_inquire ), and the stats given in /proc still seem to behave
> normally...
> 
> the full patch against the original 2758 version is also given in attachement

To check if I got it the first attachment is an add-on patch, the second
one is the base patch as in my repos + the former add-on patch?

Then let's comment on the add-on:

> diff -urN xenomai-2758/include/nucleus/stat.h xenomai-2758-V2/include/nucleus/stat.h
> --- xenomai-2758/include/nucleus/stat.h	2007-07-11 15:16:14.000000000 +0200
> +++ xenomai-2758-V2/include/nucleus/stat.h	2007-07-11 15:09:38.000000000 +0200
> @@ -42,7 +42,7 @@
>  do { \
>  	(sched)->current_account->total += \
>  		date - (sched)->last_account_switch; \
> -	(sched)->last_account_switch = date; \
> +	(sched)->last_account_switch = (sched)->current_account->start = date; \

That looks bogus on first sight, but I might miss your intention.
current_account points to the overall stats of an accounted entity.
Therefore, start must always contain the start time, not the last switch
time. Please explain your idea.

>  	/* All changes must be committed before changing the current_account \
>  	   reference in sched (required for xnintr_sync_stat_references) */ \
>  	xnarch_memory_barrier(); \
> @@ -71,6 +71,9 @@
>  #define xnstat_runtime_get_start(account)	((account)->start)
>  #define xnstat_runtime_get_total(account)	((account)->total)
>  
> +/* Obtain last time something has been switched */
> +#define xnstat_runtime_get_last_switch(sched)	((sched)->last_account_switch)
> +

OK (though a more precise comment would be good :))

>  /* Reset statistics from inside the accounted entity (e.g. after CPU
>     migration). */
>  #define xnstat_runtime_reset_stats(stat) \
> @@ -113,6 +116,7 @@
>  #define xnstat_runtime_finalize(sched, new_account)		do { } while (0)
>  #define xnstat_runtime_get_start(account)			({ 0; })
>  #define xnstat_runtime_get_total(account)			({ 0; })
> +#define xnstat_runtime_get_last_switch(sched)			({ 0; })
>  #define xnstat_runtime_reset_stats(account)			do { } while (0)
>  
>  typedef struct xnstat_counter {
> diff -urN xenomai-2758/include/nucleus/thread.h xenomai-2758-V2/include/nucleus/thread.h
> --- xenomai-2758/include/nucleus/thread.h	2007-07-11 15:16:14.000000000 +0200
> +++ xenomai-2758-V2/include/nucleus/thread.h	2007-07-11 14:28:15.000000000 +0200
> @@ -294,7 +294,7 @@
>  #define xnthread_affinity(thread)          ((thread)->affinity)
>  #define xnthread_affine_p(thread, cpu)     xnarch_cpu_isset(cpu, (thread)->affinity)
>  #define xnthread_get_exectime(thread)      xnstat_runtime_get_total(&(thread)->stat.account)
> -#define xnthread_get_lastswitch(thread)    xnstat_runtime_get_start(&(thread)->stat.account)
> +#define xnthread_get_lastswitch(thread)    xnstat_runtime_get_last_switch((thread)->sched)

Yeah, that was wrong. Did your first patch hunk relate to an initial
attempt to fix this bug?

>  
>  /* Class-level operations for threads. */
>  static inline int xnthread_get_denormalized_prio(xnthread_t *t)
> diff -urN xenomai-2758/ksrc/skins/native/task.c xenomai-2758-V2/ksrc/skins/native/task.c
> --- xenomai-2758/ksrc/skins/native/task.c	2007-07-11 15:16:14.000000000 +0200
> +++ xenomai-2758-V2/ksrc/skins/native/task.c	2007-07-11 15:22:10.000000000 +0200
> @@ -1144,10 +1144,13 @@
>  	info->cprio = xnthread_current_priority(&task->thread_base);
>  	info->status = xnthread_state_flags(&task->thread_base);
>  	info->relpoint = xntimer_get_date(&task->thread_base.ptimer);
> +	if(task == xeno_current_task())
>  	info->exectime = xnarch_tsc_to_ns(
>  		xnthread_get_exectime(&task->thread_base) +
>  		xnstat_runtime_now() -
>  		xnthread_get_lastswitch(&task->thread_base));
> +	else 
> +	  info->exectime = xnarch_tsc_to_ns(xnthread_get_exectime(&task->thread_base));

OK, second bug taken. But you approach was written without SMP in mind
(while I thought too much about SMP). The correct condition is "task is
running, somewhere?":

if (task->thread_base.sched->runthread == &task->thread_base)
	<exectime up to now>
else
	<currently stored exectime>

Of course, one may still optimise the expression.

>  	info->modeswitches = xnstat_counter_get(&task->thread_base.stat.ssw);
>  	info->ctxswitches = xnstat_counter_get(&task->thread_base.stat.csw);
>  	info->pagefaults = xnstat_counter_get(&task->thread_base.stat.pf);
> 
> 

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-07-11 14:30                     ` Jan Kiszka
@ 2007-07-11 15:35                       ` Daniel Simon
  2007-07-11 15:56                         ` Jan Kiszka
  0 siblings, 1 reply; 33+ messages in thread
From: Daniel Simon @ 2007-07-11 15:35 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai-core

On Wed, 11 Jul 2007 16:30:03 +0200
Jan Kiszka <jan.kiszka@domain.hid> wrote:

> Daniel Simon wrote:
> > On Sun, 08 Jul 2007 12:11:56 +0200
> > Jan Kiszka <jan.kiszka@domain.hid> wrote:
> > 
> > Hello,
> >> You are welcome to test, fix, improve, or just use it. Looking forward
> >> to your feedback!
> > 
> > here are attached some corrections against your previous patch (itself against
> > #2758 files): from my tests I now get likely exectime values from both remote
> > and self measurement (i.e. we get the accumulated exectime at the instant we
> > call rt_task_inquire ), and the stats given in /proc still seem to behave
> > normally...
> > 
> > the full patch against the original 2758 version is also given in attachement
> 
> To check if I got it the first attachment is an add-on patch, the second
> one is the base patch as in my repos + the former add-on patch?
yes
> Then let's comment on the add-on:
> 
> > diff -urN xenomai-2758/include/nucleus/stat.h xenomai-2758-V2/include/nucleus/stat.h
> > --- xenomai-2758/include/nucleus/stat.h	2007-07-11 15:16:14.000000000 +0200
> > +++ xenomai-2758-V2/include/nucleus/stat.h	2007-07-11 15:09:38.000000000 +0200
> > @@ -42,7 +42,7 @@
> >  do { \
> >  	(sched)->current_account->total += \
> >  		date - (sched)->last_account_switch; \
> > -	(sched)->last_account_switch = date; \
> > +	(sched)->last_account_switch = (sched)->current_account->start = date; \
> 
> That looks bogus on first sight, but I might miss your intention.
> current_account points to the overall stats of an accounted entity.
> Therefore, start must always contain the start time, not the last switch
> time. Please explain your idea.

sorry, I forgot to delete this attempt to correct a former bug, it's useless now, line 45 in stat.h remains as 
in your original patch

	(sched)->last_account_switch = date; \

just tested, the exectime measure still works...
> >  	/* All changes must be committed before changing the current_account \
> >  	   reference in sched (required for xnintr_sync_stat_references) */ \
> >  	xnarch_memory_barrier(); \
> > @@ -71,6 +71,9 @@
> >  #define xnstat_runtime_get_start(account)	((account)->start)
> >  #define xnstat_runtime_get_total(account)	((account)->total)
> >  
> > +/* Obtain last time something has been switched */
> > +#define xnstat_runtime_get_last_switch(sched)	((sched)->last_account_switch)
> > +
> 
> OK (though a more precise comment would be good :))
> 
/* Get the last time the calling thread was switched active */ 

may be better, but it could be also an intr. handler, isn't?

> >  /* Reset statistics from inside the accounted entity (e.g. after CPU
> >     migration). */
> >  #define xnstat_runtime_reset_stats(stat) \
> > @@ -113,6 +116,7 @@
> >  #define xnstat_runtime_finalize(sched, new_account)		do { } while (0)
> >  #define xnstat_runtime_get_start(account)			({ 0; })
> >  #define xnstat_runtime_get_total(account)			({ 0; })
> > +#define xnstat_runtime_get_last_switch(sched)			({ 0; })
> >  #define xnstat_runtime_reset_stats(account)			do { } while (0)
> >  
> >  typedef struct xnstat_counter {
> > diff -urN xenomai-2758/include/nucleus/thread.h xenomai-2758-V2/include/nucleus/thread.h
> > --- xenomai-2758/include/nucleus/thread.h	2007-07-11 15:16:14.000000000 +0200
> > +++ xenomai-2758-V2/include/nucleus/thread.h	2007-07-11 14:28:15.000000000 +0200
> > @@ -294,7 +294,7 @@
> >  #define xnthread_affinity(thread)          ((thread)->affinity)
> >  #define xnthread_affine_p(thread, cpu)     xnarch_cpu_isset(cpu, (thread)->affinity)
> >  #define xnthread_get_exectime(thread)      xnstat_runtime_get_total(&(thread)->stat.account)
> > -#define xnthread_get_lastswitch(thread)    xnstat_runtime_get_start(&(thread)->stat.account)
> > +#define xnthread_get_lastswitch(thread)    xnstat_runtime_get_last_switch((thread)->sched)
> 
> Yeah, that was wrong. Did your first patch hunk relate to an initial
> attempt to fix this bug?
> 
yes, it was made to cancel an extra period in the measure
> >  
> >  /* Class-level operations for threads. */
> >  static inline int xnthread_get_denormalized_prio(xnthread_t *t)
> > diff -urN xenomai-2758/ksrc/skins/native/task.c xenomai-2758-V2/ksrc/skins/native/task.c
> > --- xenomai-2758/ksrc/skins/native/task.c	2007-07-11 15:16:14.000000000 +0200
> > +++ xenomai-2758-V2/ksrc/skins/native/task.c	2007-07-11 15:22:10.000000000 +0200
> > @@ -1144,10 +1144,13 @@
> >  	info->cprio = xnthread_current_priority(&task->thread_base);
> >  	info->status = xnthread_state_flags(&task->thread_base);
> >  	info->relpoint = xntimer_get_date(&task->thread_base.ptimer);
> > +	if(task == xeno_current_task())
> >  	info->exectime = xnarch_tsc_to_ns(
> >  		xnthread_get_exectime(&task->thread_base) +
> >  		xnstat_runtime_now() -
> >  		xnthread_get_lastswitch(&task->thread_base));
> > +	else 
> > +	  info->exectime = xnarch_tsc_to_ns(xnthread_get_exectime(&task->thread_base));
> 
> OK, second bug taken. But you approach was written without SMP in mind
> (while I thought too much about SMP). The correct condition is "task is
> running, somewhere?":
> 
> if (task->thread_base.sched->runthread == &task->thread_base)
> 	<exectime up to now>
> else
> 	<currently stored exectime>

Can I leave you handling (and testing) this correction, as I don't have a running Xenomai/SMP machine at hand?

> Of course, one may still optimise the expression.
> 
> >  	info->modeswitches = xnstat_counter_get(&task->thread_base.stat.ssw);
> >  	info->ctxswitches = xnstat_counter_get(&task->thread_base.stat.csw);
> >  	info->pagefaults = xnstat_counter_get(&task->thread_base.stat.pf);
> > 
> > 
> 
> Jan
> 
> 
	Daniel

-- 
       Daniel SIMON    Projet NeCS  INRIA Rhone-Alpes
        Inovallee, 655 avenue de l'Europe, Montbonnot
             38 334 Saint Ismier Cedex France
 Daniel.Simon@domain.hid Phone:(33)476615328 Fax:(33)476615252
          http://necs.inrialpes.fr/people/simon/




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-07-11 15:35                       ` Daniel Simon
@ 2007-07-11 15:56                         ` Jan Kiszka
  2007-07-11 16:55                           ` Daniel Simon
  0 siblings, 1 reply; 33+ messages in thread
From: Jan Kiszka @ 2007-07-11 15:56 UTC (permalink / raw)
  To: Daniel Simon; +Cc: xenomai-core

[-- Attachment #1: Type: text/plain, Size: 6048 bytes --]

Daniel Simon wrote:
> On Wed, 11 Jul 2007 16:30:03 +0200
> Jan Kiszka <jan.kiszka@domain.hid> wrote:
> 
>> Daniel Simon wrote:
>>> On Sun, 08 Jul 2007 12:11:56 +0200
>>> Jan Kiszka <jan.kiszka@domain.hid> wrote:
>>>
>>> Hello,
>>>> You are welcome to test, fix, improve, or just use it. Looking forward
>>>> to your feedback!
>>> here are attached some corrections against your previous patch (itself against
>>> #2758 files): from my tests I now get likely exectime values from both remote
>>> and self measurement (i.e. we get the accumulated exectime at the instant we
>>> call rt_task_inquire ), and the stats given in /proc still seem to behave
>>> normally...
>>>
>>> the full patch against the original 2758 version is also given in attachement
>> To check if I got it the first attachment is an add-on patch, the second
>> one is the base patch as in my repos + the former add-on patch?
> yes
>> Then let's comment on the add-on:
>>
>>> diff -urN xenomai-2758/include/nucleus/stat.h xenomai-2758-V2/include/nucleus/stat.h
>>> --- xenomai-2758/include/nucleus/stat.h	2007-07-11 15:16:14.000000000 +0200
>>> +++ xenomai-2758-V2/include/nucleus/stat.h	2007-07-11 15:09:38.000000000 +0200
>>> @@ -42,7 +42,7 @@
>>>  do { \
>>>  	(sched)->current_account->total += \
>>>  		date - (sched)->last_account_switch; \
>>> -	(sched)->last_account_switch = date; \
>>> +	(sched)->last_account_switch = (sched)->current_account->start = date; \
>> That looks bogus on first sight, but I might miss your intention.
>> current_account points to the overall stats of an accounted entity.
>> Therefore, start must always contain the start time, not the last switch
>> time. Please explain your idea.
> 
> sorry, I forgot to delete this attempt to correct a former bug, it's useless now, line 45 in stat.h remains as 
> in your original patch
> 
> 	(sched)->last_account_switch = date; \
> 
> just tested, the exectime measure still works...
>>>  	/* All changes must be committed before changing the current_account \
>>>  	   reference in sched (required for xnintr_sync_stat_references) */ \
>>>  	xnarch_memory_barrier(); \
>>> @@ -71,6 +71,9 @@
>>>  #define xnstat_runtime_get_start(account)	((account)->start)
>>>  #define xnstat_runtime_get_total(account)	((account)->total)
>>>  
>>> +/* Obtain last time something has been switched */
>>> +#define xnstat_runtime_get_last_switch(sched)	((sched)->last_account_switch)
>>> +
>> OK (though a more precise comment would be good :))
>>
> /* Get the last time the calling thread was switched active */ 
> 
> may be better, but it could be also an intr. handler, isn't?

Yep, we have executable entities here (threads and interrupt handlers)
that have an exectime account. And that account is switched.

"Get last account switch date on given sched", or so.

> 
>>>  /* Reset statistics from inside the accounted entity (e.g. after CPU
>>>     migration). */
>>>  #define xnstat_runtime_reset_stats(stat) \
>>> @@ -113,6 +116,7 @@
>>>  #define xnstat_runtime_finalize(sched, new_account)		do { } while (0)
>>>  #define xnstat_runtime_get_start(account)			({ 0; })
>>>  #define xnstat_runtime_get_total(account)			({ 0; })
>>> +#define xnstat_runtime_get_last_switch(sched)			({ 0; })
>>>  #define xnstat_runtime_reset_stats(account)			do { } while (0)
>>>  
>>>  typedef struct xnstat_counter {
>>> diff -urN xenomai-2758/include/nucleus/thread.h xenomai-2758-V2/include/nucleus/thread.h
>>> --- xenomai-2758/include/nucleus/thread.h	2007-07-11 15:16:14.000000000 +0200
>>> +++ xenomai-2758-V2/include/nucleus/thread.h	2007-07-11 14:28:15.000000000 +0200
>>> @@ -294,7 +294,7 @@
>>>  #define xnthread_affinity(thread)          ((thread)->affinity)
>>>  #define xnthread_affine_p(thread, cpu)     xnarch_cpu_isset(cpu, (thread)->affinity)
>>>  #define xnthread_get_exectime(thread)      xnstat_runtime_get_total(&(thread)->stat.account)
>>> -#define xnthread_get_lastswitch(thread)    xnstat_runtime_get_start(&(thread)->stat.account)
>>> +#define xnthread_get_lastswitch(thread)    xnstat_runtime_get_last_switch((thread)->sched)
>> Yeah, that was wrong. Did your first patch hunk relate to an initial
>> attempt to fix this bug?
>>
> yes, it was made to cancel an extra period in the measure
>>>  
>>>  /* Class-level operations for threads. */
>>>  static inline int xnthread_get_denormalized_prio(xnthread_t *t)
>>> diff -urN xenomai-2758/ksrc/skins/native/task.c xenomai-2758-V2/ksrc/skins/native/task.c
>>> --- xenomai-2758/ksrc/skins/native/task.c	2007-07-11 15:16:14.000000000 +0200
>>> +++ xenomai-2758-V2/ksrc/skins/native/task.c	2007-07-11 15:22:10.000000000 +0200
>>> @@ -1144,10 +1144,13 @@
>>>  	info->cprio = xnthread_current_priority(&task->thread_base);
>>>  	info->status = xnthread_state_flags(&task->thread_base);
>>>  	info->relpoint = xntimer_get_date(&task->thread_base.ptimer);
>>> +	if(task == xeno_current_task())
>>>  	info->exectime = xnarch_tsc_to_ns(
>>>  		xnthread_get_exectime(&task->thread_base) +
>>>  		xnstat_runtime_now() -
>>>  		xnthread_get_lastswitch(&task->thread_base));
>>> +	else 
>>> +	  info->exectime = xnarch_tsc_to_ns(xnthread_get_exectime(&task->thread_base));
>> OK, second bug taken. But you approach was written without SMP in mind
>> (while I thought too much about SMP). The correct condition is "task is
>> running, somewhere?":
>>
>> if (task->thread_base.sched->runthread == &task->thread_base)
>> 	<exectime up to now>
>> else
>> 	<currently stored exectime>
> 
> Can I leave you handling (and testing) this correction, as I don't have a running Xenomai/SMP machine at hand?

Let's find a compromise: I will try to role out -v2 of this patch with
your fixes soon. And you will try to do the in-depth tests of exectime
reporting once you have a Xenomai box again? Hacking is cheap, testing
takes the time... :) Or does the test code you once submitted report
clear results /wrt the correctness of the exectime data?

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-07-11 15:56                         ` Jan Kiszka
@ 2007-07-11 16:55                           ` Daniel Simon
  2007-07-11 21:20                             ` Jan Kiszka
  0 siblings, 1 reply; 33+ messages in thread
From: Daniel Simon @ 2007-07-11 16:55 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai-core

[-- Attachment #1: Type: text/plain, Size: 1390 bytes --]

On Wed, 11 Jul 2007 17:56:09 +0200
Jan Kiszka <jan.kiszka@domain.hid> wrote:

> Let's find a compromise: I will try to role out -v2 of this patch with
> your fixes soon. And you will try to do the in-depth tests of exectime
> reporting once you have a Xenomai box again? Hacking is cheap, testing
> takes the time... :) Or does the test code you once submitted report
> clear results /wrt the correctness of the exectime data?

What I mean is that I can perform tests _only on a Pentium3 UP_, and on this
machine I upto now get consistent results on the basic tests using the last
fixes (and I will do further testing with various applications).

I cannot (and will not be able in a previsible future) perform tests
neither on a SMP nor on not_i386 architectures...

In attachment: 
the full exectime-V2.patch (including all the fixes we discussed
today) against a vanilla 2758 release, which compiled and behaves well on my
basic examples and UP machine. (it also patches with no hunk against
last release 2764), 
and the add-on against your original patch (I don't know what
is the easiest way for you...)

	Daniel

-- 
       Daniel SIMON    Projet NeCS  INRIA Rhone-Alpes
        Inovallee, 655 avenue de l'Europe, Montbonnot
             38 334 Saint Ismier Cedex France
 Daniel.Simon@domain.hid Phone:(33)476615328 Fax:(33)476615252
          http://necs.inrialpes.fr/people/simon/



[-- Attachment #2: 2758-exectime.patch --]
[-- Type: text/x-patch, Size: 7237 bytes --]

diff -urN xenomai/include/native/task.h xenomai-2758-V2/include/native/task.h
--- xenomai/include/native/task.h	2007-07-09 13:06:54.000000000 +0200
+++ xenomai-2758-V2/include/native/task.h	2007-07-11 09:55:02.000000000 +0200
@@ -90,6 +90,14 @@
     
     char name[XNOBJECT_NAME_LEN];  /**< Symbolic name assigned at creation. */
 
+    RTIME exectime; /**< Execution time in primary mode in nanoseconds. */
+
+    int modeswitches; /**< Number of primary->secondary mode switches. */
+
+    int ctxswitches; /**< Number of context switches. */
+
+    int pagefaults; /**< Number of triggered page faults. */
+
 } RT_TASK_INFO;
 
 #define RT_MCB_FSTORE_LIMIT  64
diff -urN xenomai/include/nucleus/stat.h xenomai-2758-V2/include/nucleus/stat.h
--- xenomai/include/nucleus/stat.h	2007-07-09 13:07:01.000000000 +0200
+++ xenomai-2758-V2/include/nucleus/stat.h	2007-07-11 15:09:38.000000000 +0200
@@ -42,7 +42,7 @@
 do { \
 	(sched)->current_account->total += \
 		date - (sched)->last_account_switch; \
-	(sched)->last_account_switch = date; \
+	(sched)->last_account_switch = (sched)->current_account->start = date; \
 	/* All changes must be committed before changing the current_account \
 	   reference in sched (required for xnintr_sync_stat_references) */ \
 	xnarch_memory_barrier(); \
@@ -67,6 +67,13 @@
 	(sched)->current_account = (new_account); \
 } while (0)
 
+/* Obtain content of xnstat_runtime_t */
+#define xnstat_runtime_get_start(account)	((account)->start)
+#define xnstat_runtime_get_total(account)	((account)->total)
+
+/* Obtain last time something has been switched */
+#define xnstat_runtime_get_last_switch(sched)	((sched)->last_account_switch)
+
 /* Reset statistics from inside the accounted entity (e.g. after CPU
    migration). */
 #define xnstat_runtime_reset_stats(stat) \
@@ -104,9 +111,12 @@
 
 #define xnstat_runtime_now()					({ 0; })
 #define xnstat_runtime_update(sched, date)			do { } while (0)
-#define xnstat_runtime_set_current(sched, new_account)	({ (void)sched; NULL; })
+#define xnstat_runtime_set_current(sched, new_account)		({ (void)sched; NULL; })
 #define xnstat_runtime_get_current(sched)			({ (void)sched; NULL; })
 #define xnstat_runtime_finalize(sched, new_account)		do { } while (0)
+#define xnstat_runtime_get_start(account)			({ 0; })
+#define xnstat_runtime_get_total(account)			({ 0; })
+#define xnstat_runtime_get_last_switch(sched)			({ 0; })
 #define xnstat_runtime_reset_stats(account)			do { } while (0)
 
 typedef struct xnstat_counter {
diff -urN xenomai/include/nucleus/thread.h xenomai-2758-V2/include/nucleus/thread.h
--- xenomai/include/nucleus/thread.h	2007-07-09 13:07:01.000000000 +0200
+++ xenomai-2758-V2/include/nucleus/thread.h	2007-07-11 14:28:15.000000000 +0200
@@ -205,7 +205,8 @@
 	xnstat_counter_t ssw;	/* Primary -> secondary mode switch count */
 	xnstat_counter_t csw;	/* Context switches (includes secondary -> primary switches) */
 	xnstat_counter_t pf;	/* Number of page faults */
-	xnstat_runtime_t account; /* Runtime accounting entity */
+	xnstat_runtime_t account; /* Execution time accounting entity */
+	xnstat_runtime_t lastperiod; /* Interval marker for execution time reports */
     } stat;
 
     int errcode;		/* Local errno */
@@ -235,8 +236,6 @@
 
     char name[XNOBJECT_NAME_LEN]; /* Symbolic name of thread */
 
-    xnticks_t stime;		/* Start time */
-
     void (*entry)(void *cookie); /* Thread entry routine */
 
     void *cookie;		/* Cookie to pass to the entry routine */
@@ -294,6 +293,8 @@
     0 : xnarch_user_pid(xnthread_archtcb(thread)))
 #define xnthread_affinity(thread)          ((thread)->affinity)
 #define xnthread_affine_p(thread, cpu)     xnarch_cpu_isset(cpu, (thread)->affinity)
+#define xnthread_get_exectime(thread)      xnstat_runtime_get_total(&(thread)->stat.account)
+#define xnthread_get_lastswitch(thread)    xnstat_runtime_get_last_switch((thread)->sched)
 
 /* Class-level operations for threads. */
 static inline int xnthread_get_denormalized_prio(xnthread_t *t)
diff -urN xenomai/ksrc/nucleus/module.c xenomai-2758-V2/ksrc/nucleus/module.c
--- xenomai/ksrc/nucleus/module.c	2007-07-09 13:07:18.000000000 +0200
+++ xenomai-2758-V2/ksrc/nucleus/module.c	2007-07-11 09:55:02.000000000 +0200
@@ -421,16 +421,17 @@
 		stat_info->csw = xnstat_counter_get(&thread->stat.csw);
 		stat_info->pf = xnstat_counter_get(&thread->stat.pf);
 
-		period = sched->last_account_switch - thread->stat.account.start;
+		period = sched->last_account_switch - thread->stat.lastperiod.start;
 		if (!period && thread == sched->runthread) {
 			stat_info->runtime = 1;
 			stat_info->account_period = 1;
 		} else {
-			stat_info->runtime = thread->stat.account.total;
+			stat_info->runtime = thread->stat.account.total -
+				thread->stat.lastperiod.total;
 			stat_info->account_period = period;
 		}
-		thread->stat.account.total = 0;
-		thread->stat.account.start = sched->last_account_switch;
+		thread->stat.lastperiod.total = thread->stat.account.total;
+		thread->stat.lastperiod.start = sched->last_account_switch;
 
 		holder = nextq(&nkpod->threadq, holder);
 
diff -urN xenomai/ksrc/nucleus/pod.c xenomai-2758-V2/ksrc/nucleus/pod.c
--- xenomai/ksrc/nucleus/pod.c	2007-07-09 13:07:18.000000000 +0200
+++ xenomai-2758-V2/ksrc/nucleus/pod.c	2007-07-11 09:55:02.000000000 +0200
@@ -832,7 +832,6 @@
 	thread->imode = (mode & XNTHREAD_MODE_BITS);
 	thread->entry = entry;
 	thread->cookie = cookie;
-	thread->stime = xnarch_get_cpu_time();
 
 	if (xnthread_test_state(thread, XNRRB))
 		thread->rrcredit = thread->rrperiod;
@@ -1781,8 +1780,9 @@
 
 	xnpod_schedule();
 
-	/* Reset execution time stats due to unsync'ed TSCs */
-	xnstat_runtime_reset_stats(&thread->stat.account);
+	/* Reset execution time measurement period so that we don't mess up
+	   per-CPU statistics. */
+	xnstat_runtime_reset_stats(&thread->stat.lastperiod);
 
       unlock_and_exit:
 
diff -urN xenomai/ksrc/nucleus/thread.c xenomai-2758-V2/ksrc/nucleus/thread.c
--- xenomai/ksrc/nucleus/thread.c	2007-07-09 13:07:18.000000000 +0200
+++ xenomai-2758-V2/ksrc/nucleus/thread.c	2007-07-11 09:55:02.000000000 +0200
@@ -103,7 +103,6 @@
 	thread->imode = 0;
 	thread->entry = NULL;
 	thread->cookie = 0;
-	thread->stime = 0;
 	thread->ops = ops;
 
 	inith(&thread->glink);
diff -urN xenomai/ksrc/skins/native/task.c xenomai-2758-V2/ksrc/skins/native/task.c
--- xenomai/ksrc/skins/native/task.c	2007-07-09 13:07:13.000000000 +0200
+++ xenomai-2758-V2/ksrc/skins/native/task.c	2007-07-11 15:22:10.000000000 +0200
@@ -1144,6 +1144,16 @@
 	info->cprio = xnthread_current_priority(&task->thread_base);
 	info->status = xnthread_state_flags(&task->thread_base);
 	info->relpoint = xntimer_get_date(&task->thread_base.ptimer);
+	if(task == xeno_current_task())
+	info->exectime = xnarch_tsc_to_ns(
+		xnthread_get_exectime(&task->thread_base) +
+		xnstat_runtime_now() -
+		xnthread_get_lastswitch(&task->thread_base));
+	else 
+	  info->exectime = xnarch_tsc_to_ns(xnthread_get_exectime(&task->thread_base));
+	info->modeswitches = xnstat_counter_get(&task->thread_base.stat.ssw);
+	info->ctxswitches = xnstat_counter_get(&task->thread_base.stat.csw);
+	info->pagefaults = xnstat_counter_get(&task->thread_base.stat.pf);
 
       unlock_and_exit:
 

[-- Attachment #3: exectime-add-on.patch --]
[-- Type: text/x-patch, Size: 2824 bytes --]

diff -urN xenomai-2758/include/nucleus/stat.h xenomai-exectime-V2/include/nucleus/stat.h
--- xenomai-2758/include/nucleus/stat.h	2007-07-11 18:47:11.000000000 +0200
+++ xenomai-exectime-V2/include/nucleus/stat.h	2007-07-11 18:22:53.000000000 +0200
@@ -71,6 +71,9 @@
 #define xnstat_runtime_get_start(account)	((account)->start)
 #define xnstat_runtime_get_total(account)	((account)->total)
 
+/*Get last account switch date on considered sched */
+#define xnstat_runtime_get_last_switch(sched)	((sched)->last_account_switch)
+
 /* Reset statistics from inside the accounted entity (e.g. after CPU
    migration). */
 #define xnstat_runtime_reset_stats(stat) \
@@ -113,6 +116,7 @@
 #define xnstat_runtime_finalize(sched, new_account)		do { } while (0)
 #define xnstat_runtime_get_start(account)			({ 0; })
 #define xnstat_runtime_get_total(account)			({ 0; })
+#define xnstat_runtime_get_last_switch(sched)			({ 0; })
 #define xnstat_runtime_reset_stats(account)			do { } while (0)
 
 typedef struct xnstat_counter {
diff -urN xenomai-2758/include/nucleus/thread.h xenomai-exectime-V2/include/nucleus/thread.h
--- xenomai-2758/include/nucleus/thread.h	2007-07-11 18:47:11.000000000 +0200
+++ xenomai-exectime-V2/include/nucleus/thread.h	2007-07-11 14:28:15.000000000 +0200
@@ -294,7 +294,7 @@
 #define xnthread_affinity(thread)          ((thread)->affinity)
 #define xnthread_affine_p(thread, cpu)     xnarch_cpu_isset(cpu, (thread)->affinity)
 #define xnthread_get_exectime(thread)      xnstat_runtime_get_total(&(thread)->stat.account)
-#define xnthread_get_lastswitch(thread)    xnstat_runtime_get_start(&(thread)->stat.account)
+#define xnthread_get_lastswitch(thread)    xnstat_runtime_get_last_switch((thread)->sched)
 
 /* Class-level operations for threads. */
 static inline int xnthread_get_denormalized_prio(xnthread_t *t)
diff -urN xenomai-2758/ksrc/skins/native/task.c xenomai-exectime-V2/ksrc/skins/native/task.c
--- xenomai-2758/ksrc/skins/native/task.c	2007-07-11 18:47:11.000000000 +0200
+++ xenomai-exectime-V2/ksrc/skins/native/task.c	2007-07-11 18:10:12.000000000 +0200
@@ -1144,10 +1144,13 @@
 	info->cprio = xnthread_current_priority(&task->thread_base);
 	info->status = xnthread_state_flags(&task->thread_base);
 	info->relpoint = xntimer_get_date(&task->thread_base.ptimer);
+	if (task->thread_base.sched->runthread == &task->thread_base)
 	info->exectime = xnarch_tsc_to_ns(
 		xnthread_get_exectime(&task->thread_base) +
 		xnstat_runtime_now() -
 		xnthread_get_lastswitch(&task->thread_base));
+	else 
+	  info->exectime = xnarch_tsc_to_ns(xnthread_get_exectime(&task->thread_base));
 	info->modeswitches = xnstat_counter_get(&task->thread_base.stat.ssw);
 	info->ctxswitches = xnstat_counter_get(&task->thread_base.stat.csw);
 	info->pagefaults = xnstat_counter_get(&task->thread_base.stat.pf);

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-07-11 16:55                           ` Daniel Simon
@ 2007-07-11 21:20                             ` Jan Kiszka
  2007-07-12  9:30                               ` Daniel Simon
  0 siblings, 1 reply; 33+ messages in thread
From: Jan Kiszka @ 2007-07-11 21:20 UTC (permalink / raw)
  To: Daniel Simon; +Cc: xenomai-core

[-- Attachment #1: Type: text/plain, Size: 1605 bytes --]

Daniel Simon wrote:
> On Wed, 11 Jul 2007 17:56:09 +0200
> Jan Kiszka <jan.kiszka@domain.hid> wrote:
> 
>> Let's find a compromise: I will try to role out -v2 of this patch with
>> your fixes soon. And you will try to do the in-depth tests of exectime
>> reporting once you have a Xenomai box again? Hacking is cheap, testing
>> takes the time... :) Or does the test code you once submitted report
>> clear results /wrt the correctness of the exectime data?
> 
> What I mean is that I can perform tests _only on a Pentium3 UP_, and on this
> machine I upto now get consistent results on the basic tests using the last
> fixes (and I will do further testing with various applications).

Ah, ok, /me should have read more thoroughly.

> 
> I cannot (and will not be able in a previsible future) perform tests
> neither on a SMP nor on not_i386 architectures...
> 
> In attachment: 
> the full exectime-V2.patch (including all the fixes we discussed
> today) against a vanilla 2758 release, which compiled and behaves well on my
> basic examples and UP machine. (it also patches with no hunk against
> last release 2764), 
> and the add-on against your original patch (I don't know what
> is the easiest way for you...)
> 

I've merge you changes (whitespaces...), reformatted it a bit, and
uploaded the result. See

http://www.rts.uni-hannover.de/rtaddon/patches/xenomai/enhance-thread-stats-v2.patch

Hope I didn't messed anything up, it was just compile-tested in a hurry.
If the patch happens to work fine, I would start advertising it for
merge into trunk.

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-07-11 21:20                             ` Jan Kiszka
@ 2007-07-12  9:30                               ` Daniel Simon
  2007-07-12 11:02                                 ` Jan Kiszka
  0 siblings, 1 reply; 33+ messages in thread
From: Daniel Simon @ 2007-07-12  9:30 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai-core

[-- Attachment #1: Type: text/plain, Size: 1134 bytes --]

On Wed, 11 Jul 2007 23:20:47 +0200
Jan Kiszka <jan.kiszka@domain.hid> wrote:

> I've merge you changes (whitespaces...)
sorry for bad formatting, my dev. tool is emacs, which sometimes refuse to
understand tabs...

>http://www.rts.uni-hannover.de/rtaddon/patches/xenomai/enhance-thread-stats-v2.patch

this patch seems ok:
-patched against release 2764 (with 2 self-corrected hunks), compiled on a
2.6.20 kernel and test on a P3/UP

 -my former basic tests (2 periodic tasks providing remote or self
exectime probing) still give consistent measures (exectime.c in attachment)

-I am thinking about more demanding tests, with intertasks preemption and
overloads, but in that case the problem is how to assess the measurements?
Logic analyzer? Be care also with rt_timer_spin, which is not busy-sleeping for
all the specified time when it is preempted...

	Daniel
-- 
       Daniel SIMON    Projet NeCS  INRIA Rhone-Alpes
        Inovallee, 655 avenue de l'Europe, Montbonnot
             38 334 Saint Ismier Cedex France
 Daniel.Simon@domain.hid Phone:(33)476615328 Fax:(33)476615252
          http://necs.inrialpes.fr/people/simon/



[-- Attachment #2: exectime.c --]
[-- Type: text/x-csrc, Size: 12308 bytes --]

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <signal.h>
#include <math.h>
#include <sys/time.h>
#include <sys/io.h>
#include <sys/mman.h>
#include <native/types.h>
#include <native/task.h>
#include <native/queue.h>
#include <native/intr.h>
#include <native/timer.h>
#include <native/sem.h>
#include <native/alarm.h>
#include <native/heap.h>
#include <native/queue.h>
#include <native/syscall.h>
#define STACK_SIZE 8192
#define MIN_PRIO 1
#define MAX_PRIO 99
#define PRI_MT_MAX MAX_PRIO - 6
#define PRI_MT_MIN MIN_PRIO

typedef void * (*FUNCPTR) (void *);
typedef void (*SOSO) (void *); /**< Special type to be used for casting in task_create() */
#define ORCMSGQ RT_QUEUE *  /**< Message Queue Type */
#define ORCSEM_ID RT_SEM *  /**< Semaphore Type */
#define ORCFULL  1        /**< State of a Full Binary Semaphore */
#define ORCEMPTY 0        /**< State of a Empty Binary Semaphore */
#define ORCFOREVER TM_INFINITE     /**< Waiting forever in sem_wait */
#define SIZE_QUEUE  100       /**< Size of the Message Queue */
#define SIZE_MES_MAX 4056    /**< Maximum size of a message in Message Queue */
#define SIZE_MES_MIN 128     /**< Minimum size of a message in Message Queue */
/*-------Tasks----------*/
#define ORCTHR_ID RT_TASK * /**< Xeno RT-Task Type */
#define STACKSIZE int      /**< Stack size Type */
#define SMALL_STACK  1000           /**< Small task stack size PTHREAD_STACK_MIN not defined */
#define NORMAL_STACK (5*SMALL_STACK)  /**< Normal task stack size */
#define BIG_STACK    (15*SMALL_STACK) /**< Big task stack size */
//                     --s-ms-us-ns
RTIME task_period_ns = 500000000llu;
#define NSEC_PER_SEC 1000000000

#define OK 0
#define ERROR -1
#define STATUS int

#define FALSE 0
#define TRUE 1
#define POLICY 1

static int ji = 0;
static RTIME startime, now;
struct timespec clock_resolution;
static int message_counter = 0;

RT_ALARM BaseClk;
int status, err, end = 0, loops = 10;

char *dummy;

ORCTHR_ID thr_clockit;
ORCTHR_ID thr_loop;
ORCMSGQ Queue;

ORCSEM_ID SynchroSem;

static int cpt_sem = 10000;
char nameSem[10];
int crexec, cr;
long past = 0;
ORCTHR_ID MAIN_RT;

ORCMSGQ orcMsgQCreate()
{
        size_t size;
        ORCMSGQ OrcQueue;
        message_counter = 0;
        size = SIZE_MES_MAX;
        int err;

        OrcQueue = malloc(sizeof(RT_QUEUE));
        if (OrcQueue == 0) {
                printf("ERROR  orcMsgQCreate malloc\n");
                return 0;
        }
        memset(OrcQueue, 0, sizeof(RT_QUEUE));
        if ((err = rt_queue_create(OrcQueue, "OrcRTQ", SIZE_MES_MAX*SIZE_QUEUE, SIZE_QUEUE, Q_FIFO | Q_SHARED)) != 0) {
                printf("orcMsgQCreate ERROR %d \n", err);
        } else printf("orcMsgQCreate OK\n");
        return OrcQueue;
}

int orcMsgQSend(ORCMSGQ OrcQueue, int msg, int prio)
{
        int i;
        void * tmpbuf;
        size_t orcEventSize;
        orcEventSize = (size_t)sizeof(int);
        if ((tmpbuf = rt_queue_alloc(OrcQueue, orcEventSize)) == 0) {
                printf("ERROR orcMsgQSend tmpbuf not created \n");
                return ERROR;
        }
        memcpy(tmpbuf, &msg, orcEventSize);
        if ((i = rt_queue_send(OrcQueue, tmpbuf, orcEventSize, Q_NORMAL)) < 0) {
                printf("ERROR orcMsgQSend %d \n", i);
                return ERROR;
        }
        message_counter++;
        return OK;
}

int orcMsgQReceive(ORCMSGQ OrcQueue, int *msg)
{
        ssize_t i;
        void *message;

        if ((i = rt_queue_receive(OrcQueue, &message, TM_INFINITE )) < 0) {
                printf("ERREUR orcMsgQReceive %d \n", i);
                return ERROR;
        } else {
                memcpy(msg, message, i);
                rt_queue_free(OrcQueue, message);
                message_counter--;
                return OK;
        }
}

int orcMsgQClose(ORCMSGQ OrcQueue)
{
        int i;
        if (OrcQueue == 0)
                return ERROR;
        if ((i = rt_queue_delete(OrcQueue)) != 0) {
                printf("ERREUR orcMsgQClose %d \n", i);
                return ERROR;
        }

        else {
                free(OrcQueue);
                return OK;
        }
}

ORCSEM_ID orcSemCreate(int initState)
{
        RT_SEM * newSem;
        int status;

        sprintf(nameSem,"%d",cpt_sem);
        newSem = malloc(sizeof(RT_SEM));
        if (newSem == 0) {
                printf("ERROR SemCreate_count init \n");
                return 0;
        }
        memset(newSem, 0, sizeof(RT_SEM));

        status = rt_sem_create(newSem, nameSem, initState, S_FIFO);
        if (status == OK) {
                cpt_sem++;
                return newSem;
        } else {
                return NULL;
        }

}

int orcSemDelete(ORCSEM_ID sem)
{
        if (sem == 0)
                return ERROR;
        if (rt_sem_delete(sem) == 0) {
                free(sem);
                return OK;
        }
        printf("Erreur:orcSemDelete\n");
        return ERROR;
}

int orcSemGive(ORCSEM_ID sem)
{
        return (rt_sem_v(sem));
}

int orcSemTake(ORCSEM_ID sem, int timeout)
{
        return (rt_sem_p(sem, timeout));
}

int orcTaskIdVerify(ORCTHR_ID Id)
{
        if (Id != NULL) {
                return OK;
        }
        printf("orcTaskIdVerify ERROR \n");
        return ERROR;
}

int orcTaskDelete(ORCTHR_ID task)
{
        int result;

        if (task == 0) {
                printf("ERROR rt_task_delete, task == 0\n");
                return ERROR;
        }
        result = rt_task_delete(task);
        if (result != 0) {
                printf("ERROR rt_task_delete  %p error %d\n", task, result);
                return ERROR;
        }
        free(task);
        return OK;
}

int orcSpawn(ORCTHR_ID *tid, const char *name, int prio, STACKSIZE stackSize, SOSO funcptr, void * arg)
{
        int err;
        //Allocate memory
        if (((*tid) = (RT_TASK*) malloc (sizeof(RT_TASK))) == NULL) {
                printf("Error malloc orcspawn\n" );
                return ERROR;
        }
        if ((err = rt_task_spawn(*tid, name, stackSize, prio, T_FPU|T_JOINABLE|T_CPU(0), (SOSO) funcptr, arg)) != 0) {
                printf("ERROR %d rt_task_init\n", err);
                return ERROR;
        }
        printf("rt_task create %s prio %d StackSize %d Id %p \n", name, prio, stackSize, tid);
        return OK;
}
int orcSpawn1(ORCTHR_ID *tid, const char *name, int prio, STACKSIZE stackSize, SOSO funcptr, void * arg)
{
        int err;
        //Allocate memory
        if (((*tid) = (RT_TASK*) malloc (sizeof(RT_TASK))) == NULL) {
                printf("Error malloc orcspawn\n" );
                return ERROR;
        }
        if ((err = rt_task_spawn(*tid, name, stackSize, prio, T_FPU|T_JOINABLE|T_CPU(1), (SOSO) funcptr, arg)) != 0) {
                printf("ERROR %d rt_task_init\n", err);
                return ERROR;
        }
        printf("rt_task create %s prio %d StackSize %d Id %p \n", name, prio, stackSize, tid);
        return OK;
}


int orcTaskSuspend(ORCTHR_ID task)
{
        return rt_task_suspend(task);
}

///Function that returns the cpu time in nanoseconds
inline long long GetCpuTime(void)
{
        return (long long)rt_timer_ticks2ns(rt_timer_read());
}
///Function that returns the task accumulated excectime in nanoseconds
inline long long orcGetExecTime(ORCTHR_ID task)
{
        RT_TASK_INFO info;
        crexec = rt_task_inquire(task,&info);
        if (crexec != 0) {
                printf("rt_task_get_exectime error %d \n", crexec);
                return (long long)0;
        } else return (long long)info.exectime;
}
///Function that shadows main in real time
int orcMakeRealTime(void)
{
        int prio_main = PRI_MT_MAX + 1;
        mlockall(MCL_CURRENT | MCL_FUTURE);
        if ((cr = rt_task_shadow(MAIN_RT, "MAIN_PRR", prio_main, T_FPU | T_JOINABLE)) != 0) {
                printf("rt_task_shadow error %d \n", cr);
        } else {
                printf("rt_task_shadow done priority %d \n", prio_main);
        }
        return cr;
}

// Traps Ctrl C Interruption
void clean_exit(int dummy)
{
        printf("Ctrl C Interrupt\n");
        end = 1;
        err = rt_task_join(thr_clockit);
        if (err != 0)printf("rt_task_join() error %d \n", err);
        err = rt_task_join(thr_loop);
        if (err != 0)printf("rt_task_join() error %d \n", err);
        printf("deleting rt devices \n");
        err = rt_alarm_delete(&BaseClk);
        if (err != 0)printf("rt_alarm_delete() error %d \n", err);
        orcMsgQClose(Queue);
        return ;
}
/// Masking all signals but SIGINT and SIGTERM
int orcTimerSigMask(void)
{
        sigset_t set;
        sigfillset(&set);
        if ((err = pthread_sigmask(SIG_BLOCK, &set, NULL)) != OK) {
                printf("pthread_sigmask Failed %d \n", err);
                return ERROR;
        }
        sigemptyset(&set);
        sigaddset(&set, SIGINT);
        sigaddset(&set, SIGTERM);
        if ((err = pthread_sigmask(SIG_UNBLOCK, &set, NULL)) != OK) {
                printf("pthread_sigmask Failed %d \n", err);
                return ERROR;
        }

        return OK;
}

void setTimer(void)
{
        /***starting timer ***/
        err = rt_alarm_create(&BaseClk, "BaseClock");
        if (err != 0)printf("rt_alarm_create() error %d \n", err);
        err = rt_alarm_start(&BaseClk,
                             rt_timer_ns2ticks(task_period_ns),
                             rt_timer_ns2ticks(task_period_ns));
        if (err != 0)printf("rt_alarm_start() error %d \n", err);

        else printf("alarm started with period %llu ns \n", task_period_ns);
        printf("period in ticks %ld \n", (long)rt_timer_ns2ticks(task_period_ns));
        return ;

}
long long loopbusytime, clockbusytime;
void clock_it(void)
{
        int msg = 1;

        long long clockexectime, clockdiff;
        static long long clockpast = 0;
        while (!end) {
                err = rt_alarm_wait(&BaseClk);
                clockbusytime = llabs(30000000*(cos((double)GetCpuTime()/NSEC_PER_SEC)));
                //clockbusytime = 30000000;
                rt_timer_spin((RTIME)clockbusytime);
                clockexectime = orcGetExecTime(NULL);
                /*       clockexectime = orcGetExecTime(thr_loop); */
                if (msg > 2) {
                        clockdiff = clockexectime - clockpast;
                        clockpast  = clockexectime;
			/*clockdiff should me busytime + a handfull of usecs, be carefull to print the busytime of the measured task!!!*/
                        printf("clockexectime %lld clockdiff %lld  busytime %lld \n", clockexectime, clockdiff, clockbusytime );
                } else clockpast  = clockexectime;

                orcMsgQSend(Queue, msg, 0);
                msg++;
        }
        return ;
}
void func_loop()
{
        int msg;
        long long loopexectime, loopdiff;
        static long long looppast;
        while (!end) {
                orcMsgQReceive(Queue, &msg);
                loopbusytime = llabs(20000000*(cos((double)GetCpuTime()/NSEC_PER_SEC)));
                //loopbusytime = 20000000;
                rt_timer_spin((RTIME)loopbusytime);
                /*       loopexectime = orcGetExecTime(thr_clockit); */
                /*       loopexectime = orcGetExecTime(NULL); */
                /*       if(msg > 2){ */
                /* 	  loopdiff = loopexectime - looppast; */
                /* 	  looppast  = loopexectime; */
		/*clockdiff should me busytime + a handfull of usecs, be carefull to print the busytime of the measured task!!!*/
                /* 	  printf("loopexectime  %lld loopdiff %lld busytime %lld \n", loopexectime, loopdiff, loopbusytime );} */
                /*       else looppast  = loopexectime; */
                printf("received msg = %d \n", msg);
        }
        return;
}
int main(void)
{

        orcTimerSigMask();

        signal(SIGTERM, clean_exit);
        signal(SIGINT, clean_exit);

        orcMakeRealTime();

        setTimer();

        Queue = orcMsgQCreate();

        orcSpawn(&thr_clockit, "AlarmServer", MAX_PRIO -2, NORMAL_STACK, (SOSO) clock_it, NULL);
        orcSpawn(&thr_loop, "Loop", MAX_PRIO - 3, NORMAL_STACK, (SOSO) func_loop, NULL);

        pause();
        fflush(NULL);

        return 0;
}




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-07-12  9:30                               ` Daniel Simon
@ 2007-07-12 11:02                                 ` Jan Kiszka
  2007-07-16 16:19                                   ` Daniel Simon
  0 siblings, 1 reply; 33+ messages in thread
From: Jan Kiszka @ 2007-07-12 11:02 UTC (permalink / raw)
  To: Daniel Simon; +Cc: xenomai-core

[-- Attachment #1: Type: text/plain, Size: 1422 bytes --]

Daniel Simon wrote:
> On Wed, 11 Jul 2007 23:20:47 +0200
> Jan Kiszka <jan.kiszka@domain.hid> wrote:
> 
>> I've merge you changes (whitespaces...)
> sorry for bad formatting, my dev. tool is emacs, which sometimes refuse to
> understand tabs...
> 
>> http://www.rts.uni-hannover.de/rtaddon/patches/xenomai/enhance-thread-stats-v2.patch
> 
> this patch seems ok:
> -patched against release 2764 (with 2 self-corrected hunks), compiled on a
> 2.6.20 kernel and test on a P3/UP
> 
>  -my former basic tests (2 periodic tasks providing remote or self
> exectime probing) still give consistent measures (exectime.c in attachment)

Nice to hear.

> 
> -I am thinking about more demanding tests, with intertasks preemption and
> overloads, but in that case the problem is how to assess the measurements?
> Logic analyzer? Be care also with rt_timer_spin, which is not busy-sleeping for
> all the specified time when it is preempted...

You could play with the I-pipe tracer
(http://xenomai.org/index.php/I-pipe:Tracer). If you disable function
tracing (CONFIG_IPIPE_TRACE_MCOUNT), you will be left with far less
overwhelming data, specifically with the instrumentation points on every
Xenomai context switch. That should allow some estimation of the thread
execution times (minus noise due to the IRQs). And then there is highly
experimental LTTng, but it's... well, highly experimental.

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Xenomai-core] measuring tasks execution time
  2007-07-12 11:02                                 ` Jan Kiszka
@ 2007-07-16 16:19                                   ` Daniel Simon
  0 siblings, 0 replies; 33+ messages in thread
From: Daniel Simon @ 2007-07-16 16:19 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai-core

On Thu, 12 Jul 2007 13:02:35 +0200
Jan Kiszka <jan.kiszka@domain.hid> wrote:

Hi Jan,

> > -I am thinking about more demanding tests, with intertasks preemption and
> > overloads,

I have shaked my examples in various ways, with
preemptions, overruns and high load on the machine, and the exectime patch
behaves well, providing data consistent with the expectations (and with
the rt_timer_read() probe when usable).

	Daniel

-- 
       Daniel SIMON    Projet NeCS  INRIA Rhone-Alpes
        Inovallee, 655 avenue de l'Europe, Montbonnot
             38 334 Saint Ismier Cedex France
 Daniel.Simon@domain.hid Phone:(33)476615328 Fax:(33)476615252
          http://necs.inrialpes.fr/people/simon/




^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2007-07-16 16:19 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-06-07 16:23 [Xenomai-help] real time task disapears... memory problem ? desvages
2007-06-07 17:44 ` Jan Kiszka
2007-06-08 10:49   ` [Xenomai-help] measuring tasks execution time Daniel Simon
2007-06-08 11:20     ` [Xenomai-core] " Jan Kiszka
2007-06-08 13:09       ` Daniel Simon
2007-06-08 15:24         ` Jan Kiszka
2007-06-08 16:04           ` Jan Kiszka
2007-06-25 15:51       ` [Xenomai-core] " Daniel Simon
2007-06-25 16:55         ` Jan Kiszka
2007-06-27  8:57           ` Daniel Simon
2007-06-27 11:56             ` Jan Kiszka
2007-06-29 14:43               ` Daniel Simon
2007-06-29 15:00                 ` Jan Kiszka
2007-06-29 15:29                   ` Daniel Simon
2007-06-29 15:47                     ` Philippe Gerum
2007-06-29 15:56                       ` Gilles Chanteperdrix
2007-06-29 15:52                     ` Jan Kiszka
2007-07-08 10:11                 ` Jan Kiszka
2007-07-09  8:49                   ` Daniel Simon
2007-07-11 13:59                   ` Daniel Simon
2007-07-11 14:30                     ` Jan Kiszka
2007-07-11 15:35                       ` Daniel Simon
2007-07-11 15:56                         ` Jan Kiszka
2007-07-11 16:55                           ` Daniel Simon
2007-07-11 21:20                             ` Jan Kiszka
2007-07-12  9:30                               ` Daniel Simon
2007-07-12 11:02                                 ` Jan Kiszka
2007-07-16 16:19                                   ` Daniel Simon
     [not found]   ` <1753.194.254.210.7.1181246882.squirrel@domain.hid>
2007-06-08 15:19     ` [Xenomai-help] real time task disapears... memory problem ? Jan Kiszka
2007-06-09 16:06       ` desvages
2007-06-09 17:10         ` Jan Kiszka
  -- strict thread matches above, loose matches on Subject: below --
2007-06-06 11:59 DESVAGES Arnaud
2007-06-06 12:25 ` Jan Kiszka

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.