Messages in this thread | | | Date | Wed, 13 Jan 2010 09:22:40 +0000 (GMT) | From | richard parkins <> | Subject | Problems with futex |
| |
Please CC rparkins@undo-software.com with any responses
1. Various problems with futex 2. Test attached shows errors: FUTEX_WAKE_OP arg4 not decoded correctly in 32-bit (looks like fixed in linux-2.6.32.3) FUTEX_LOCK_PI(_PRIVATE) with non-NULL timeout returns ETIMEDOUT immediately without waiting (may be fixed in linux-2.6.32.3) FUTEX_WAIT_BITSET(_PRIVATE) with non-NULL timeout returns ETIMEDOUT immediately without waiting (patch suggested below) Definitions of FUTEX_WAIT_BITSET_PRIVATE and FUTEX_WAKE_BITSET_PRIVATE were bad in header file (fixed in linux-2.6.32.3) Definition of FUTEX_OP unsafe if actual arguments are expressions (safe one suggested below) 3. futex 4. Linux version 2.6.27.39-0.2-default (geeko@buildhost) (gcc version 4.3.2 [gcc-4_3-branch revision 141291] (SUSE Linux) ) #1 SMP 2009-11-23 12:57:38 +0100 5. not applicable 6. test attached 7.1 Linux rparkins64 2.6.27.39-0.2-default #1 SMP 2009-11-23 12:57:38 +0100 x86_64 x86_64 x86_64 GNU/Linux
Gnu C 4.3 Gnu make 3.81 binutils 11.1 2.19 util-linux ver_linux: line 23: fdformat: command not found mount support module-init-tools found Linux C Library 2.9 Dynamic linker (ldd) 2.9 Procps 3.2.7 Kbd 1.14.1 oprofile 0.9.4 Sh-utils 6.12 udev 128 Modules Loaded ip6t_LOG xt_tcpudp xt_pkttype ipt_LOG xt_limit af_packet snd_pcm_oss snd_mixer_oss snd_seq snd_seq_device ip6t_REJECT nf_conntrack_ipv6 ip6table_raw xt_NOTRACK ipt_REJECT xt_state iptable_raw iptable_filter ip6table_mangle nf_conntrack_netbios_ns nf_conntrack_ipv4 nf_conntrack ip_tables ip6table_filter ip6_tables x_tables ipv6 cpufreq_conservative cpufreq_userspace cpufreq_powersave acpi_cpufreq dm_crypt fuse loop dm_mod arc4 ecb snd_hda_intel crypto_blkcipher iwl3945 snd_pcm usbhid pcmcia video snd_timer rfkill iTCO_wdt hid mac80211 iTCO_vendor_support snd_page_alloc tg3 yenta_socket nvidia snd_hwdep ohci1394 i2c_i801 battery snd output rtc_cmos libphy led_class button ac rsrc_nonstatic pcspkr joydev ff_memless ieee1394 intel_agp wmi sr_mod irda rtc_core pcmcia_core dcdbas cdrom soundcore rtc_lib i2c_core cfg80211 crc_ccitt sg sd_mod crc_t10dif ehci_hcd uhci_hcd usbcore edd ext3 mbcache jbd fan ide_pci_generic ide_core ata_generic ata_piix libata scsi_mod dock thermal processor thermal_sys hwmon 7.2 processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 15 model name : Intel(R) Core(TM)2 CPU T7200 @ 2.00GHz stepping : 6 cpu MHz : 1000.000 cache size : 4096 KB physical id : 0 siblings : 2 core id : 0 cpu cores : 2 apicid : 0 initial apicid : 0 fpu : yes fpu_exception : yes cpuid level : 10 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good nopl pni monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr lahf_lm bogomips : 3989.97 clflush size : 64 cache_alignment : 64 address sizes : 36 bits physical, 48 bits virtual power management:
processor : 1 vendor_id : GenuineIntel cpu family : 6 model : 15 model name : Intel(R) Core(TM)2 CPU T7200 @ 2.00GHz stepping : 6 cpu MHz : 1000.000 cache size : 4096 KB physical id : 0 siblings : 2 core id : 1 cpu cores : 2 apicid : 1 initial apicid : 1 fpu : yes fpu_exception : yes cpuid level : 10 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good nopl pni monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr lahf_lm bogomips : 3990.05 clflush size : 64 cache_alignment : 64 address sizes : 36 bits physical, 48 bits virtual power management: 7.3 ip6t_LOG 7180 7 - Live 0xffffffffa0dbe000 xt_tcpudp 3608 4 - Live 0xffffffffa0dbc000 xt_pkttype 2152 3 - Live 0xffffffffa0dba000 ipt_LOG 6812 8 - Live 0xffffffffa0db7000 xt_limit 3180 15 - Live 0xffffffffa0db5000 af_packet 20232 4 - Live 0xffffffffa0daf000 snd_pcm_oss 48624 0 - Live 0xffffffffa0da2000 snd_mixer_oss 16808 1 snd_pcm_oss, Live 0xffffffffa0d9c000 snd_seq 61504 0 - Live 0xffffffffa0d8b000 snd_seq_device 8604 1 snd_seq, Live 0xffffffffa0d87000 ip6t_REJECT 6024 3 - Live 0xffffffffa0d84000 nf_conntrack_ipv6 24712 5 - Live 0xffffffffa0d7c000 ip6table_raw 2456 1 - Live 0xffffffffa0d7a000 xt_NOTRACK 2152 4 - Live 0xffffffffa0d78000 ipt_REJECT 3480 3 - Live 0xffffffffa0d76000 xt_state 2568 10 - Live 0xffffffffa0d74000 iptable_raw 2760 1 - Live 0xffffffffa0d72000 iptable_filter 3400 1 - Live 0xffffffffa0d70000 ip6table_mangle 3128 0 - Live 0xffffffffa0d6e000 nf_conntrack_netbios_ns 2840 0 - Live 0xffffffffa0219000 nf_conntrack_ipv4 12808 5 - Live 0xffffffffa0d69000 nf_conntrack 80352 5 nf_conntrack_ipv6,xt_NOTRACK,xt_state,nf_conntrack_netbios_ns,nf_conntrack_ipv4, Live 0xffffffffa0d54000 ip_tables 19464 2 iptable_raw,iptable_filter, Live 0xffffffffa0d4e000 ip6table_filter 3240 1 - Live 0xffffffffa01d3000 ip6_tables 21048 4 ip6t_LOG,ip6table_raw,ip6table_mangle,ip6table_filter, Live 0xffffffffa0d47000 x_tables 23376 11 ip6t_LOG,xt_tcpudp,xt_pkttype,ipt_LOG,xt_limit,ip6t_REJECT,xt_NOTRACK,ipt_REJECT,xt_state,ip_tables,ip6_tables, Live 0xffffffffa0d40000 ipv6 292472 23 ip6t_REJECT,nf_conntrack_ipv6,ip6table_mangle, Live 0xffffffffa0cf7000 cpufreq_conservative 8384 0 - Live 0xffffffffa0cf3000 cpufreq_userspace 4204 0 - Live 0xffffffffa0cf0000 cpufreq_powersave 2248 0 - Live 0xffffffffa015f000 acpi_cpufreq 8216 0 - Live 0xffffffffa0cec000 dm_crypt 14352 0 - Live 0xffffffffa0ce7000 fuse 57872 3 - Live 0xffffffffa0cd7000 loop 16660 0 - Live 0xffffffffa0cd1000 dm_mod 74064 1 dm_crypt, Live 0xffffffffa0cbd000 arc4 2216 2 - Live 0xffffffffa01ec000 ecb 3464 2 - Live 0xffffffffa01df000 snd_hda_intel 562228 2 - Live 0xffffffffa0c32000 crypto_blkcipher 19372 2 dm_crypt,ecb, Live 0xffffffffa0c2c000 iwl3945 97892 0 - Live 0xffffffffa0c13000 snd_pcm 92064 2 snd_pcm_oss,snd_hda_intel, Live 0xffffffffa0bfb000 usbhid 52544 0 - Live 0xffffffffa0bed000 pcmcia 38288 0 - Live 0xffffffffa0be2000 video 24316 6 - Live 0xffffffffa0bdb000 snd_timer 24968 2 snd_seq,snd_pcm, Live 0xffffffffa0bd3000 rfkill 10948 2 iwl3945, Live 0xffffffffa0bcf000 iTCO_wdt 12416 0 - Live 0xffffffffa0bca000 hid 41136 1 usbhid, Live 0xffffffffa0bbe000 mac80211 241360 1 iwl3945, Live 0xffffffffa0b82000 iTCO_vendor_support 4268 1 iTCO_wdt, Live 0xffffffffa0216000 snd_page_alloc 9800 2 snd_hda_intel,snd_pcm, Live 0xffffffffa0212000 tg3 125084 0 - Live 0xffffffffa0b62000 yenta_socket 26404 1 - Live 0xffffffffa0b5a000 nvidia 9616824 32 - Live 0xffffffffa022d000 (PX) snd_hwdep 9104 1 snd_hda_intel, Live 0xffffffffa0229000 ohci1394 31364 0 - Live 0xffffffffa0220000 i2c_i801 12756 0 - Live 0xffffffffa021b000 battery 13856 0 - Live 0xffffffffa01b4000 snd 73576 12 snd_pcm_oss,snd_mixer_oss,snd_seq,snd_seq_device,snd_hda_intel,snd_pcm,snd_timer,snd_hwdep, Live 0xffffffffa01ff000 output 3672 1 video, Live 0xffffffffa01fd000 rtc_cmos 13000 0 - Live 0xffffffffa01f8000 libphy 23080 1 tg3, Live 0xffffffffa01f1000 led_class 5008 1 iwl3945, Live 0xffffffffa01ee000 button 8328 0 - Live 0xffffffffa01e8000 ac 5776 0 - Live 0xffffffffa01e5000 rsrc_nonstatic 10920 1 yenta_socket, Live 0xffffffffa01e1000 pcspkr 3064 0 - Live 0xffffffffa01dd000 joydev 11376 0 - Live 0xffffffffa01d9000 ff_memless 8752 1 usbhid, Live 0xffffffffa01d5000 ieee1394 98464 1 ohci1394, Live 0xffffffffa01b9000 intel_agp 30400 0 - Live 0xffffffffa01ab000 wmi 8160 0 - Live 0xffffffffa01a8000 sr_mod 15860 0 - Live 0xffffffffa01a3000 irda 132756 0 - Live 0xffffffffa0181000 rtc_core 21396 1 rtc_cmos, Live 0xffffffffa017a000 pcmcia_core 39140 3 pcmcia,yenta_socket,rsrc_nonstatic, Live 0xffffffffa016f000 dcdbas 10984 0 - Live 0xffffffffa016b000 (X) cdrom 36200 1 sr_mod, Live 0xffffffffa0161000 soundcore 8368 1 snd, Live 0xffffffffa015b000 rtc_lib 3560 1 rtc_core, Live 0xffffffffa0131000 i2c_core 35296 2 nvidia,i2c_i801, Live 0xffffffffa0151000 cfg80211 28168 2 iwl3945,mac80211, Live 0xffffffffa0149000 crc_ccitt 2392 1 irda, Live 0xffffffffa0120000 sg 35376 0 - Live 0xffffffffa013f000 sd_mod 35240 6 - Live 0xffffffffa0135000 crc_t10dif 2152 1 sd_mod, Live 0xffffffffa0133000 ehci_hcd 54676 0 - Live 0xffffffffa0122000 uhci_hcd 26840 0 - Live 0xffffffffa0118000 usbcore 195808 4 usbhid,ehci_hcd,uhci_hcd, Live 0xffffffffa00e7000 edd 10272 0 - Live 0xffffffffa00e3000 ext3 140824 3 - Live 0xffffffffa00bf000 mbcache 9484 1 ext3, Live 0xffffffffa00bb000 jbd 61752 1 ext3, Live 0xffffffffa00aa000 fan 6016 0 - Live 0xffffffffa00a7000 ide_pci_generic 4652 0 - Live 0xffffffffa00a4000 ide_core 115068 1 ide_pci_generic, Live 0xffffffffa0086000 ata_generic 6044 0 - Live 0xffffffffa0083000 ata_piix 21980 5 - Live 0xffffffffa007c000 libata 183856 2 ata_generic,ata_piix, Live 0xffffffffa004e000 scsi_mod 178968 4 sr_mod,sg,sd_mod,libata, Live 0xffffffffa0021000 dock 14212 1 libata, Live 0xffffffffa001c000 thermal 24408 0 - Live 0xffffffffa0015000 processor 49472 4 acpi_cpufreq,thermal, Live 0xffffffffa0007000 thermal_sys 14336 4 video,fan,thermal,processor, Live 0xffffffffa0002000 hwmon 3720 1 thermal_sys, Live 0xffffffffa0000000 7.4 0000-001f : dma1 0020-0021 : pic1 0040-0043 : timer0 0050-0053 : timer1 0060-0060 : keyboard 0064-0064 : keyboard 0070-0071 : rtc0 0080-008f : dma page reg 00a0-00a1 : pic2 00c0-00df : dma2 00f0-00ff : fpu 0170-0177 : 0000:00:1f.2 0170-0177 : ata_piix 01f0-01f7 : 0000:00:1f.2 01f0-01f7 : ata_piix 02f8-02ff : serial 0376-0376 : 0000:00:1f.2 0376-0376 : ata_piix 03c0-03df : vga+ 03f6-03f6 : 0000:00:1f.2 03f6-03f6 : ata_piix 03f8-03ff : serial 04d0-04d1 : pnp 00:02 0809-0809 : pnp 00:03 0910-091f : pnp 00:08 0920-092f : pnp 00:08 0930-097f : pnp 00:08 0c80-0caf : pnp 00:08 0cb0-0cbb : pnp 00:0e 0cbc-0cbf : pnp 00:08 0cf8-0cff : PCI conf1 1000-107f : 0000:00:1f.0 1000-1003 : ACPI PM1a_EVT_BLK 1004-1005 : ACPI PM1a_CNT_BLK 1008-100b : ACPI PM_TMR 1010-1015 : ACPI CPU throttle 1020-1020 : ACPI PM2_CNT_BLK 1028-102f : ACPI GPE0_BLK 1060-107f : iTCO_wdt 1080-10bf : 0000:00:1f.0 1080-10bf : pnp 00:03 10c0-10df : 0000:00:1f.3 10c0-10df : pnp 00:03 10c0-10df : i801_smbus 2000-2fff : PCI Bus 0000:03 2000-20ff : PCI CardBus 0000:04 2400-24ff : PCI CardBus 0000:04 bf20-bf3f : 0000:00:1d.3 bf20-bf3f : uhci_hcd bf40-bf5f : 0000:00:1d.2 bf40-bf5f : uhci_hcd bf60-bf7f : 0000:00:1d.1 bf60-bf7f : uhci_hcd bf80-bf9f : 0000:00:1d.0 bf80-bf9f : uhci_hcd bfa0-bfaf : 0000:00:1f.2 bfa0-bfaf : ata_piix e000-efff : PCI Bus 0000:0d f400-f4fe : pnp 00:03 00000000-0009efff : System RAM 0009f000-0009ffff : reserved 000c0000-000cffff : pnp 00:00 000e0000-000fffff : pnp 00:00 00100000-7fe813ff : System RAM 00200000-004a420f : Kernel code 004a4210-007bd18f : Kernel data 00a36000-00bcc8b7 : Kernel bss 7fe81400-7fffffff : reserved 88000000-8bffffff : PCI Bus 0000:03 88000000-8bffffff : PCI CardBus 0000:04 8c000000-8fffffff : PCI CardBus 0000:04 d0000000-dfffffff : PCI Bus 0000:01 d0000000-dfffffff : 0000:01:00.0 e0000000-e01fffff : PCI Bus 0000:0d ecb00000-ecbfffff : PCI Bus 0000:03 ecb00000-ecb00fff : 0000:03:01.0 ecb00000-ecb00fff : yenta_socket ecbfe800-ecbfefff : 0000:03:01.4 ecbff000-ecbfffff : 0000:03:01.4 ecbff000-ecbff7ff : ohci1394 ecc00000-ecdfffff : PCI Bus 0000:0d ece00000-ecefffff : PCI Bus 0000:09 ecef0000-ecefffff : 0000:09:00.0 ecef0000-ecefffff : tg3 ecf00000-ecffffff : PCI Bus 0000:0c ecfff000-ecffffff : 0000:0c:00.0 ecfff000-ecffffff : iwl3945 ed000000-efefffff : PCI Bus 0000:01 ed000000-edffffff : 0000:01:00.0 ed000000-edffffff : nvidia ee000000-eeffffff : 0000:01:00.0 ef000000-ef01ffff : 0000:01:00.0 efffc000-efffffff : 0000:00:1b.0 efffc000-efffffff : ICH HD audio f0000000-f4006fff : reserved f0000000-f3ffffff : PCI MMCONFIG 0 f4008000-f400bfff : reserved fec00000-fec0ffff : reserved fec00000-fec00fff : IOAPIC 0 fed00000-fed003ff : HPET 0 fed00000-fed003ff : pnp 00:0b fed20000-fed9ffff : reserved fee00000-fee0ffff : reserved fee00000-fee00fff : Local APIC ffa80000-ffa803ff : 0000:00:1d.7 ffa80000-ffa803ff : ehci_hcd ffb00000-ffffffff : reserved 7.5 00:00.0 Host bridge: Intel Corporation Mobile 945GM/PM/GMS, 943/940GML and 945GT Express Memory Controller Hub (rev 03) Subsystem: Dell Device 01cc Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort+ >SERR- <PERR- INTx- Latency: 0 Capabilities: [e0] Vendor Specific Information <?> Kernel modules: intel-agp
00:01.0 PCI bridge: Intel Corporation Mobile 945GM/PM/GMS, 943/940GML and 945GT Express PCI Express Root Port (rev 03) (prog-if 00 [Normal decode]) Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0, Cache Line Size: 64 bytes Bus: primary=00, secondary=01, subordinate=01, sec-latency=0 I/O behind bridge: 0000f000-00000fff Memory behind bridge: ed000000-efefffff Prefetchable memory behind bridge: 00000000d0000000-00000000dfffffff Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR- BridgeCtl: Parity- SERR+ NoISA- VGA+ MAbort- >Reset- FastB2B- PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn- Capabilities: [88] Subsystem: Dell Device 01cc Capabilities: [80] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Capabilities: [90] Message Signalled Interrupts: Mask- 64bit- Count=1/1 Enable+ Address: fee0300c Data: 4169 Capabilities: [a0] Express (v1) Root Port (Slot+), MSI 00 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us ExtTag- RBE- FLReset- DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported- RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop- MaxPayload 128 bytes, MaxReadReq 128 bytes DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend- LnkCap: Port #2, Speed 2.5GT/s, Width x16, ASPM L0s L1, Latency L0 <256ns, L1 <4us ClockPM- Suprise- LLActRep- BwNot- LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+ ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- LnkSta: Speed 2.5GT/s, Width x16, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt- SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surpise- Slot # 1, PowerLimit 75.000000; Interlock- NoCompl- SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg- Control: AttnInd Off, PwrInd On, Power- Interlock- SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock- Changed: MRL- PresDet+ LinkState- RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible- RootCap: CRSVisible- RootSta: PME ReqID 0000, PMEStatus- PMEPending- Capabilities: [100] Virtual Channel <?> Capabilities: [140] Root Complex Link <?> Kernel driver in use: pcieport-driver Kernel modules: shpchp
00:1b.0 Audio device: Intel Corporation 82801G (ICH7 Family) High Definition Audio Controller (rev 01) Subsystem: Dell Device 01cc Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0, Cache Line Size: 64 bytes Interrupt: pin A routed to IRQ 21 Region 0: Memory at efffc000 (64-bit, non-prefetchable) [size=16K] Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=55mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Capabilities: [60] Message Signalled Interrupts: Mask- 64bit+ Count=1/1 Enable- Address: 0000000000000000 Data: 0000 Capabilities: [70] Express (v1) Root Complex Integrated Endpoint, MSI 00 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us ExtTag- RBE- FLReset- DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported- RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop+ MaxPayload 128 bytes, MaxReadReq 128 bytes DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend- LnkCap: Port #0, Speed unknown, Width x0, ASPM unknown, Latency L0 <64ns, L1 <1us ClockPM- Suprise- LLActRep- BwNot- LnkCtl: ASPM Disabled; Disabled- Retrain- CommClk- ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- LnkSta: Speed unknown, Width x0, TrErr- Train- SlotClk- DLActive- BWMgmt- ABWMgmt- Capabilities: [100] Virtual Channel <?> Capabilities: [130] Root Complex Link <?> Kernel driver in use: HDA Intel Kernel modules: snd-hda-intel
00:1c.0 PCI bridge: Intel Corporation 82801G (ICH7 Family) PCI Express Port 1 (rev 01) (prog-if 00 [Normal decode]) Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0, Cache Line Size: 64 bytes Bus: primary=00, secondary=0b, subordinate=0b, sec-latency=0 I/O behind bridge: 0000f000-00000fff Memory behind bridge: fff00000-000fffff Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort+ <SERR- <PERR- BridgeCtl: Parity- SERR+ NoISA- VGA- MAbort- >Reset- FastB2B- PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn- Capabilities: [40] Express (v1) Root Port (Slot+), MSI 00 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimited ExtTag- RBE- FLReset- DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported- RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop- MaxPayload 128 bytes, MaxReadReq 128 bytes DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend- LnkCap: Port #1, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <1us, L1 <4us ClockPM- Suprise- LLActRep+ BwNot- LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk- ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- LnkSta: Speed 2.5GT/s, Width x0, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt- SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug+ Surpise+ Slot # 2, PowerLimit 6.500000; Interlock- NoCompl- SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet+ CmdCplt- HPIrq- LinkChg- Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock- SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet- Interlock- Changed: MRL- PresDet- LinkState- RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible- RootCap: CRSVisible- RootSta: PME ReqID 0000, PMEStatus- PMEPending- Capabilities: [80] Message Signalled Interrupts: Mask- 64bit- Count=1/1 Enable+ Address: fee0300c Data: 4171 Capabilities: [90] Subsystem: Dell Device 01cc Capabilities: [a0] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Capabilities: [100] Virtual Channel <?> Capabilities: [180] Root Complex Link <?> Kernel driver in use: pcieport-driver Kernel modules: shpchp
00:1c.1 PCI bridge: Intel Corporation 82801G (ICH7 Family) PCI Express Port 2 (rev 01) (prog-if 00 [Normal decode]) Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0, Cache Line Size: 64 bytes Bus: primary=00, secondary=0c, subordinate=0c, sec-latency=0 I/O behind bridge: 0000f000-00000fff Memory behind bridge: ecf00000-ecffffff Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR- BridgeCtl: Parity- SERR+ NoISA- VGA- MAbort- >Reset- FastB2B- PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn- Capabilities: [40] Express (v1) Root Port (Slot+), MSI 00 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimited ExtTag- RBE- FLReset- DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported- RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop- MaxPayload 128 bytes, MaxReadReq 128 bytes DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend- LnkCap: Port #2, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <256ns, L1 <4us ClockPM- Suprise- LLActRep+ BwNot- LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+ ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt- ABWMgmt- SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug+ Surpise+ Slot # 3, PowerLimit 6.500000; Interlock- NoCompl- SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet+ CmdCplt- HPIrq- LinkChg- Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock- SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock- Changed: MRL- PresDet- LinkState- RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible- RootCap: CRSVisible- RootSta: PME ReqID 0000, PMEStatus- PMEPending- Capabilities: [80] Message Signalled Interrupts: Mask- 64bit- Count=1/1 Enable+ Address: fee0300c Data: 4179 Capabilities: [90] Subsystem: Dell Device 01cc Capabilities: [a0] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Capabilities: [100] Virtual Channel <?> Capabilities: [180] Root Complex Link <?> Kernel driver in use: pcieport-driver Kernel modules: shpchp
00:1c.2 PCI bridge: Intel Corporation 82801G (ICH7 Family) PCI Express Port 3 (rev 01) (prog-if 00 [Normal decode]) Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0, Cache Line Size: 64 bytes Bus: primary=00, secondary=09, subordinate=09, sec-latency=0 I/O behind bridge: 0000f000-00000fff Memory behind bridge: ece00000-ecefffff Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR- BridgeCtl: Parity- SERR+ NoISA- VGA- MAbort- >Reset- FastB2B- PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn- Capabilities: [40] Express (v1) Root Port (Slot+), MSI 00 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimited ExtTag- RBE- FLReset- DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported- RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop- MaxPayload 128 bytes, MaxReadReq 128 bytes DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend- LnkCap: Port #3, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <256ns, L1 <4us ClockPM- Suprise- LLActRep+ BwNot- LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+ ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt- ABWMgmt- SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug+ Surpise+ Slot # 4, PowerLimit 6.500000; Interlock- NoCompl- SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet+ CmdCplt- HPIrq- LinkChg- Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock- SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock- Changed: MRL- PresDet- LinkState- RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible- RootCap: CRSVisible- RootSta: PME ReqID 0000, PMEStatus- PMEPending- Capabilities: [80] Message Signalled Interrupts: Mask- 64bit- Count=1/1 Enable+ Address: fee0300c Data: 4189 Capabilities: [90] Subsystem: Dell Device 01cc Capabilities: [a0] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Capabilities: [100] Virtual Channel <?> Capabilities: [180] Root Complex Link <?> Kernel driver in use: pcieport-driver Kernel modules: shpchp
00:1c.3 PCI bridge: Intel Corporation 82801G (ICH7 Family) PCI Express Port 4 (rev 01) (prog-if 00 [Normal decode]) Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0, Cache Line Size: 64 bytes Bus: primary=00, secondary=0d, subordinate=0e, sec-latency=0 I/O behind bridge: 0000e000-0000efff Memory behind bridge: ecc00000-ecdfffff Prefetchable memory behind bridge: 00000000e0000000-00000000e01fffff Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR- BridgeCtl: Parity- SERR+ NoISA- VGA- MAbort- >Reset- FastB2B- PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn- Capabilities: [40] Express (v1) Root Port (Slot+), MSI 00 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimited ExtTag- RBE- FLReset- DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported- RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop- MaxPayload 128 bytes, MaxReadReq 128 bytes DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend- LnkCap: Port #4, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <1us, L1 <4us ClockPM- Suprise- LLActRep+ BwNot- LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk- ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- LnkSta: Speed 2.5GT/s, Width x0, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt- SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug+ Surpise+ Slot # 5, PowerLimit 6.500000; Interlock- NoCompl- SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet+ CmdCplt- HPIrq- LinkChg- Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock- SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet- Interlock- Changed: MRL- PresDet- LinkState- RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible- RootCap: CRSVisible- RootSta: PME ReqID 0000, PMEStatus- PMEPending- Capabilities: [80] Message Signalled Interrupts: Mask- 64bit- Count=1/1 Enable+ Address: fee0300c Data: 4191 Capabilities: [90] Subsystem: Dell Device 01cc Capabilities: [a0] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Capabilities: [100] Virtual Channel <?> Capabilities: [180] Root Complex Link <?> Kernel driver in use: pcieport-driver Kernel modules: shpchp
00:1d.0 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI Controller #1 (rev 01) (prog-if 00 [UHCI]) Subsystem: Dell Device 01cc Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin A routed to IRQ 20 Region 4: I/O ports at bf80 [size=32] Kernel driver in use: uhci_hcd Kernel modules: uhci-hcd
00:1d.1 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI Controller #2 (rev 01) (prog-if 00 [UHCI]) Subsystem: Dell Device 01cc Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin B routed to IRQ 21 Region 4: I/O ports at bf60 [size=32] Kernel driver in use: uhci_hcd Kernel modules: uhci-hcd
00:1d.2 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI Controller #3 (rev 01) (prog-if 00 [UHCI]) Subsystem: Dell Device 01cc Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin C routed to IRQ 22 Region 4: I/O ports at bf40 [size=32] Kernel driver in use: uhci_hcd Kernel modules: uhci-hcd
00:1d.3 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI Controller #4 (rev 01) (prog-if 00 [UHCI]) Subsystem: Dell Device 01cc Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin D routed to IRQ 23 Region 4: I/O ports at bf20 [size=32] Kernel driver in use: uhci_hcd Kernel modules: uhci-hcd
00:1d.7 USB Controller: Intel Corporation 82801G (ICH7 Family) USB2 EHCI Controller (rev 01) (prog-if 20 [EHCI]) Subsystem: Dell Device 01cc Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin A routed to IRQ 20 Region 0: Memory at ffa80000 (32-bit, non-prefetchable) [size=1K] Capabilities: [50] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=375mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Capabilities: [58] Debug port: BAR=1 offset=00a0 Kernel driver in use: ehci_hcd Kernel modules: ehci-hcd
00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev e1) (prog-if 01 [Subtractive decode]) Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Bus: primary=00, secondary=03, subordinate=07, sec-latency=32 I/O behind bridge: 00002000-00002fff Memory behind bridge: ecb00000-ecbfffff Prefetchable memory behind bridge: 0000000088000000-000000008bffffff Secondary status: 66MHz- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort+ <SERR- <PERR+ BridgeCtl: Parity- SERR+ NoISA- VGA- MAbort- >Reset- FastB2B- PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn- Capabilities: [50] Subsystem: Dell Device 01cc
00:1f.0 ISA bridge: Intel Corporation 82801GBM (ICH7-M) LPC Interface Bridge (rev 01) Subsystem: Dell Device 01cc Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Capabilities: [e0] Vendor Specific Information <?> Kernel modules: iTCO_wdt, intel-rng
00:1f.2 IDE interface: Intel Corporation 82801GBM/GHM (ICH7 Family) SATA IDE Controller (rev 01) (prog-if 80 [Master]) Subsystem: Dell Device 01cc Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin B routed to IRQ 17 Region 0: I/O ports at 01f0 [size=8] Region 1: I/O ports at 03f4 [size=1] Region 2: I/O ports at 0170 [size=8] Region 3: I/O ports at 0374 [size=1] Region 4: I/O ports at bfa0 [size=16] Capabilities: [70] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot+,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: ata_piix Kernel modules: ide-pci-generic, ata_generic, pata_acpi, ata_piix
00:1f.3 SMBus: Intel Corporation 82801G (ICH7 Family) SMBus Controller (rev 01) Subsystem: Dell Device 01cc Control: I/O+ Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx- Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Interrupt: pin B routed to IRQ 17 Region 4: I/O ports at 10c0 [size=32] Kernel driver in use: i801_smbus Kernel modules: i2c-i801
01:00.0 VGA compatible controller: nVidia Corporation G72M [Quadro NVS 110M/GeForce Go 7300] (rev a1) (prog-if 00 [VGA controller]) Subsystem: Dell Device 01cc Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0 Interrupt: pin A routed to IRQ 16 Region 0: Memory at ed000000 (32-bit, non-prefetchable) [size=16M] Region 1: Memory at d0000000 (64-bit, prefetchable) [size=256M] Region 3: Memory at ee000000 (64-bit, non-prefetchable) [size=16M] [virtual] Expansion ROM at ef000000 [disabled] [size=128K] Capabilities: [60] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Capabilities: [68] Message Signalled Interrupts: Mask- 64bit+ Count=1/1 Enable- Address: 0000000000000000 Data: 0000 Capabilities: [78] Express (v1) Endpoint, MSI 00 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <256ns, L1 <4us ExtTag- AttnBtn- AttnInd- PwrInd- RBE- FLReset- DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported- RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+ MaxPayload 128 bytes, MaxReadReq 512 bytes DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend- LnkCap: Port #0, Speed 2.5GT/s, Width x16, ASPM L0s L1, Latency L0 <256ns, L1 <4us ClockPM- Suprise- LLActRep- BwNot- LnkCtl: ASPM Disabled; RCB 128 bytes Disabled- Retrain- CommClk+ ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- LnkSta: Speed 2.5GT/s, Width x16, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt- Capabilities: [100] Virtual Channel <?> Capabilities: [128] Power Budgeting <?> Kernel driver in use: nvidia Kernel modules: nvidia, nvidiafb
03:01.0 CardBus bridge: O2 Micro, Inc. Cardbus bridge (rev 21) Subsystem: Dell Device 01cc Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping+ SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=slow >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 168 Interrupt: pin A routed to IRQ 19 Region 0: Memory at ecb00000 (32-bit, non-prefetchable) [size=4K] Bus: primary=03, secondary=04, subordinate=07, sec-latency=176 Memory window 0: 88000000-8bfff000 (prefetchable) Memory window 1: 8c000000-8ffff000 I/O window 0: 00002000-000020ff I/O window 1: 00002400-000024ff BridgeCtl: Parity- SERR- ISA- VGA- MAbort- >Reset+ 16bInt+ PostWrite+ 16-bit legacy interface ports at 0001 Kernel driver in use: yenta_cardbus Kernel modules: yenta_socket
03:01.4 FireWire (IEEE 1394): O2 Micro, Inc. Firewire (IEEE 1394) (rev 02) (prog-if 10 [OHCI]) Subsystem: Dell Device 01cc Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx+ Latency: 64, Cache Line Size: 64 bytes Interrupt: pin A routed to IRQ 19 Region 0: Memory at ecbff000 (32-bit, non-prefetchable) [size=4K] Region 1: Memory at ecbfe800 (32-bit, non-prefetchable) [size=2K] Capabilities: [60] Power Management version 2 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME+ Kernel driver in use: ohci1394 Kernel modules: ohci1394
09:00.0 Ethernet controller: Broadcom Corporation NetXtreme BCM5752 Gigabit Ethernet PCI Express (rev 02) Subsystem: Dell Device 01cc Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0, Cache Line Size: 64 bytes Interrupt: pin A routed to IRQ 4345 Region 0: Memory at ecef0000 (64-bit, non-prefetchable) [size=64K] Expansion ROM at <ignored> [disabled] Capabilities: [48] Power Management version 2 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=1 PME- Capabilities: [50] Vital Product Data <?> Capabilities: [58] Message Signalled Interrupts: Mask- 64bit+ Count=1/8 Enable+ Address: 00000000fee0300c Data: 41c1 Capabilities: [d0] Express (v1) Endpoint, MSI 00 DevCap: MaxPayload 512 bytes, PhantFunc 0, Latency L0s <4us, L1 unlimited ExtTag+ AttnBtn- AttnInd- PwrInd- RBE- FLReset- DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported- RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop- MaxPayload 128 bytes, MaxReadReq 4096 bytes DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend- LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <2us, L1 <64us ClockPM- Suprise- LLActRep- BwNot- LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+ ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt- Capabilities: [100] Advanced Error Reporting UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSVoil- UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSVoil- UESvrt: DLP+ SDES- TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSVoil- CESta: RxErr- BadTLP- BadDLLP+ Rollover- Timeout- NonFatalErr- CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr- AERCap: First Error Pointer: 00, GenCap+ CGenEn- ChkCap+ ChkEn- Capabilities: [13c] Virtual Channel <?> Kernel driver in use: tg3 Kernel modules: tg3
0c:00.0 Network controller: Intel Corporation PRO/Wireless 3945ABG [Golan] Network Connection (rev 02) Subsystem: Intel Corporation Device 1021 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0, Cache Line Size: 64 bytes Interrupt: pin A routed to IRQ 4346 Region 0: Memory at ecfff000 (32-bit, non-prefetchable) [size=4K] Capabilities: [c8] Power Management version 2 Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 PME-Enable- DSel=0 DScale=0 PME- Capabilities: [d0] Message Signalled Interrupts: Mask- 64bit+ Count=1/1 Enable+ Address: 00000000fee0100c Data: 41b9 Capabilities: [e0] Express (v1) Legacy Endpoint, MSI 00 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <512ns, L1 unlimited ExtTag- AttnBtn- AttnInd- PwrInd- RBE- FLReset- DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported- RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+ MaxPayload 128 bytes, MaxReadReq 128 bytes DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend- LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <128ns, L1 <64us ClockPM+ Suprise- LLActRep- BwNot- LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+ ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt- Capabilities: [100] Advanced Error Reporting UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSVoil- UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSVoil- UESvrt: DLP+ SDES- TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSVoil- CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr- CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr- AERCap: First Error Pointer: 00, GenCap- CGenEn- ChkCap- ChkEn- Capabilities: [140] Device Serial Number 07-0e-7b-ff-ff-d2-19-00 Kernel driver in use: iwl3945 Kernel modules: iwl3945 7.6 Attached devices: Host: scsi0 Channel: 00 Id: 00 Lun: 00 Vendor: ATA Model: Hitachi HTS54161 Rev: SBDO Type: Direct-Access ANSI SCSI revision: 05 Host: scsi1 Channel: 00 Id: 00 Lun: 00 Vendor: TSSTcorp Model: DVD+-RW TS-L632D Rev: DE03 Type: CD-ROM ANSI SCSI revision: 05
Here is the output from the attached test compiled with -m32 and run under 64-bit Linux 2.6.27.39.
Could not find undodb private space FUTEX_WAKE_PRIVATE with bad address succeeds FUTEX_WAKE with zero val woke a process FUTEX_WAKE with negative val woke a process FUTEX_REQUEUE returns 1 when waking no processes but requeueing one KERNELBUG? FUTEX_WAKE_OP arg4 not decoded correctly in 32-bit KERNELBUG? FUTEX_LOCK_PI with timer returns ETIMEDOUT immediately KERNELBUG? FUTEX_LOCK_PI_PRIVATE with timer returns ETIMEDOUT immediately KERNELBUG? FUTEX_WAIT_BITSET with timer returns ETIMEDOUT immediately KERNELBUG? FUTEX_WAIT_BITSET_PRIVATE with timer returns ETIMEDOUT immediately Test succeeded
If compiled in 64-bit mode the output is the same but without the line about FUTEX_WAKE_OP.
Here is the output again with my comments. >>>Could not find undodb private space Nothing to do with the kernel: it prints this if it isn't running under our debugger.
>>>FUTEX_WAKE_PRIVATE with bad address succeeds It isn't clear that this is a bug. FUTEX_WAKE always returns -EFAULT with a bad uaddr, because it looks for the vma and doesn't find one. FUTEX_WAIT_PRIVATE only does access_ok(), which is a weak test on x86 architecture. On 32-bit FUTEX_WAKE_PRIVATE always returns 0 because it doesn't find a waiter: on 64-bit it returns -EFAULT if uaddr is negative and otherwise 0. I can see the case for not doing a proper accessibility check since the kernel doesn't actually dereference uaddr for FUTEX_WAKE, but the existing behaviour is a bit inconsistent.
>>>FUTEX_WAKE with zero val woke a process >>>FUTEX_WAKE with negative val woke a process >>>FUTEX_REQUEUE returns 1 when waking no processes but requeueing one These messages are because the kernel doesn't do what the man page says it does. Maybe the man page is wrong.... The treatment of counts of processes to be woken or requeued is a bit inconsistent. Sometimes you wake a process before checking the count (so a zero or negative count is treated as 1) and sometimes you check the count first. Maybe there's some method in your madness, but if so the man page is wrong.
>>>KERNELBUG? FUTEX_WAKE_OP arg4 not decoded correctly in 32-bit Should already have been fixed by this diff in futex_compat.c from 2.6.27.39 to 2.6.32.3 191c195,196 < if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE) --- > if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE || > cmd == FUTEX_CMP_REQUEUE_PI || cmd == FUTEX_WAKE_OP)
>>>KERNELBUG? FUTEX_LOCK_PI with timer returns ETIMEDOUT immediately >>>KERNELBUG? FUTEX_LOCK_PI_PRIVATE with timer returns ETIMEDOUT immediately The problem was in rtmutex.c. The code has changed, so it may be fixed now.
>>>KERNELBUG? FUTEX_WAIT_BITSET with timer returns ETIMEDOUT immediately >>>KERNELBUG? FUTEX_WAIT_BITSET_PRIVATE with timer returns ETIMEDOUT immediately This doesn't seem to be fixed yet. I think it should be fixed by this diff to futex.c in version linux-2.6.32.3. 2611c2611 < if (cmd == FUTEX_WAIT) --- > if ((cmd == FUTEX_WAIT) || (cmd == FUTEX_WAIT_BITSET)) The same change is needed for futex_compat.c. 191c191 < if (cmd == FUTEX_WAIT) --- > if ((cmd == FUTEX_WAIT) || (cmd == FUTEX_WAIT_BITSET))
>>>Test succeeded It didn't find any problems that it didn't expect.
Definitions of FUTEX_WAIT_BITSET_PRIVATE and FUTEX_WAKE_BITSET_PRIVATE were bad in linux/futex.h, but have been fixed in linux-2.6.32.3.
The definition of FUTEX_OP in linux/futex.h doesn't protect against the actual arguments being expressions. Here is a safer one #define FUTEX_OP(op, oparg, cmp, cmparg) \ ((((op) & 0xf) << 28) | (((cmp) & 0xf) << 24) \ | (((oparg) & 0xfff) << 12) | ((cmparg) & 0xfff))
Richard P. Parkins, M. A. rparkins@undo-software.com
/* Written by Richard Parkins, rparkins@undo-software.com. */ /* Copyright 2009, Undo Ltd. */ /* Released under the GNU Public Licence. */
/* Futex test */
#define _GNU_SOURCE #include <sched.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #include <signal.h> #include <sys/syscall.h> #include <sys/time.h> #include <sys/mman.h> #include <sys/wait.h> #include <linux/futex.h>
/* Some distros have broken definitions of these. */ #undef FUTEX_WAIT_BITSET_PRIVATE #undef FUTEX_WAKE_BITSET_PRIVATE #undef FUTEX_OP #define FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG) #define FUTEX_WAKE_BITSET_PRIVATE (FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG) #define FUTEX_OP(op, oparg, cmp, cmparg) \ ((((op) & 0xf) << 28) | (((cmp) & 0xf) << 24) \ | (((oparg) & 0xfff) << 12) | ((cmparg) & 0xfff))
/* futex, tkill, and gettid system calls are not defined in header files. */ #define futex( arg1, arg2, arg3, arg4, arg5, arg6) \ syscall(SYS_futex, arg1, arg2, arg3, arg4, arg5, arg6) #define tkill( arg1, arg2) \ syscall(SYS_tkill, arg1, arg2) #define gettid() \ syscall(SYS_gettid)
static struct timespec TEN_ms = {0, 10*1000*1000};
static struct timespec ONE_sec = {1, 0};
static FILE * status;
static int f1, f2;
static int thread_action;
struct sha { int f3; int f4; int child_action; };
static struct sha * shmem;
static pid_t parent_pid, thread_pid, child_pid;
static char ths[0x20000];
#define thread_stack (ths + sizeof(ths) - sizeof(long))
static int parent_sleeping(void) { /* Note when called from the child (a forked process), this is a different * copy of the FILE object from that used when called from the thread. */ rewind(status); int i; char c; int r = fscanf(status, "%d %*s %c", &i, &c); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d fscanf failed %s\n", __LINE__, strerror(errno)); } else { fprintf(stderr, "At line %d fscanf returned %d instead of 2\n", __LINE__, r); } tkill(parent_pid, SIGKILL); tkill(child_pid, SIGKILL); exit(1); } return (c == 'S'); }
/* Thread waits for thread_action to be nonzero * (and for some actions for the parent to be waiting for it), * and then does the required action. */ static int thread(void * arg __attribute__ ((unused))) { int r; while (1) { switch (thread_action) { case -1: case 0: break; case 1: if (parent_sleeping()) { thread_action = 0; r = futex(&f1, FUTEX_WAKE, 2, NULL, NULL, 0); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); } else { fprintf(stderr, "At line %d futex returned %d instead of 1\n", __LINE__, r); } tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } } break; case 2: if (parent_sleeping()) { thread_action = 0; r = futex(&f1, FUTEX_WAKE_PRIVATE, 2, NULL, NULL, 0); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); } else { fprintf(stderr, "At line %d futex returned %d instead of 1\n", __LINE__, r); } tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } } break; case 3: if (parent_sleeping()) { thread_action = 0; r = futex(&(shmem->f3), FUTEX_WAKE, 2, NULL, NULL, 0); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); } else { fprintf(stderr, "At line %d futex returned %d instead of 1\n", __LINE__, r); } tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } } break; case 4: thread_action = -1; /* It is possible that a thread switch occurs here: * wait_for_thread() does an extra 10ms sleep to give this * thread a chance to start the wait, but on a busy machine * it may not get to run and the test on the number of * processes woken will fail. Of course futexes are designed * just to avoid this sort of race, but since we are testing * futexes here we can't use one. */ r = futex(&f1, FUTEX_WAIT, f1, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } break; case 5: thread_action = -1; r = futex(&f1, FUTEX_WAIT_PRIVATE, f1, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } break; case 6: thread_action = -1; r = futex(&(shmem->f3), FUTEX_WAIT, shmem->f3, &ONE_sec, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } break; case 7: thread_action = -1; r = futex(&f1, FUTEX_LOCK_PI, 0, &TEN_ms, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } break; case 8: thread_action = -1; r = futex(&f1, FUTEX_LOCK_PI_PRIVATE, 0, &TEN_ms, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } break; case 9: thread_action = -1; r = futex(&(shmem->f3), FUTEX_LOCK_PI, 0, &TEN_ms, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } break; case 10: if (parent_sleeping()) { thread_action = 0; r = futex(&f1, FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } } break; case 11: if (parent_sleeping()) { thread_action = 0; r = futex(&f1, FUTEX_UNLOCK_PI_PRIVATE, 0, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } } break; case 12: if (parent_sleeping()) { thread_action = 0; r = futex(&(shmem->f3), FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } } break; case 13: thread_action = -1; r = futex(&f1, FUTEX_WAIT_BITSET, f1, NULL, NULL, 0x3); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } break; case 14: thread_action = -1; r = futex(&f1, FUTEX_WAIT_BITSET_PRIVATE, f1, NULL, NULL, 0x30); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } break; case 15: thread_action = -1; r = futex(&(shmem->f3), FUTEX_WAIT_BITSET, shmem->f3, NULL, NULL, 0x300); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } break; case 16: thread_action = -1; r = futex(&f1, FUTEX_LOCK_PI, 0, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } break; case 17: thread_action = -1; r = futex(&f1, FUTEX_LOCK_PI_PRIVATE, 0, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_UNLOCK_PI_PRIVATE, 0, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } break; case 18: thread_action = -1; r = futex(&(shmem->f3), FUTEX_LOCK_PI, 0, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } break; case 19: thread_action = -1; break; default: fprintf(stderr, "At line %d invalid thread_action %d\n", __LINE__, thread_action); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } if (nanosleep(&TEN_ms, NULL)) { fprintf(stderr, "At line %d nanosleep failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); tkill(parent_pid, SIGKILL); exit(1); } } }
static void wft(long line) { int r; for (r = 0; thread_action; ++r) { if (r > 6000) { fprintf(stderr, "wait_for_thread from line %ld thread not responding\n", line); tkill(child_pid, SIGKILL); exit(1); } if (thread_action < 0) { thread_action = 0; } if (nanosleep(&TEN_ms, NULL)) { fprintf(stderr, "wait_for_thread from line %ld nanosleep failed %s\n", line, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } } #define wait_for_thread() wft(__LINE__)
/* Child process waits for shmem->child_action to be nonzero * (and for some actions for the parent to be waiting for it), * and then does the required action. */ static void child(void) { int r; while (1) { switch (shmem->child_action) { case 0: case -1: break; case 3: if (parent_sleeping()) { shmem->child_action = 0; r = futex(&(shmem->f3), FUTEX_WAKE, 2, NULL, NULL, 0); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); } else { fprintf(stderr, "At line %d futex returned %d instead of 1\n", __LINE__, r); } tkill(parent_pid, SIGKILL); exit(1); } } break; case 6: shmem->child_action = -1; r = futex(&(shmem->f3), FUTEX_WAIT, shmem->f3, &ONE_sec, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(parent_pid, SIGKILL); exit(1); } break; case 9: shmem->child_action = -1; r = futex(&(shmem->f3), FUTEX_LOCK_PI, 0, &TEN_ms, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(parent_pid, SIGKILL); exit(1); } break; case 12: if (parent_sleeping()) { shmem->child_action = 0; r = futex(&(shmem->f3), FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(parent_pid, SIGKILL); exit(1); } } break; case 15: shmem->child_action = -1; r = futex(&(shmem->f3), FUTEX_WAIT_BITSET, shmem->f3, NULL, NULL, 0x300); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(parent_pid, SIGKILL); exit(1); } break; case 16: shmem->child_action = -1; r = futex(&(shmem->f3), FUTEX_WAIT_BITSET, 0, NULL, NULL, 0x3000); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(parent_pid, SIGKILL); exit(1); } /* It is possible that a process switch occurs here: * The main program does a 10ms wait to give this process time * to set shmem->child_action, but on a busy machine it may not * get to run and the test will fail. Of course futexes are * designed just to avoid this sort of race, but since we are * testing futexes here we can't use one. */ shmem->child_action = 17; break; case 17: break; case 18: shmem->child_action = -1; r = futex(&(shmem->f3), FUTEX_LOCK_PI, 0, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(parent_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(parent_pid, SIGKILL); exit(1); } break; case 19: shmem->child_action = -1; break; default: fprintf(stderr, "At line %d invalid child_action %d\n", __LINE__, shmem->child_action); tkill(parent_pid, SIGKILL); exit(1); } if (nanosleep(&TEN_ms, NULL)) { fprintf(stderr, "At line %d nanosleep failed %s\n", __LINE__, strerror(errno)); tkill(parent_pid, SIGKILL); exit(1); } } }
static void wfc (long line) { int r; for (r = 0; shmem->child_action; ++r) { if (r > 6000) { fprintf(stderr, "wait_for_child from line %ld child not responding\n", line); tkill(child_pid, SIGKILL); exit(1); } if (shmem->child_action < 0) { shmem->child_action = 0; } if (nanosleep(&TEN_ms, NULL)) { fprintf(stderr, "wait_for_child from line %ld nanosleep failed %s\n", line, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } } #define wait_for_child() wfc(__LINE__)
int main(int argc __attribute__ ((unused)), char* argv[] __attribute__ ((unused))) { /* Get a handle on our status for the child to use. */ status = fopen("/proc/self/stat", "r"); if (!status) { fprintf(stderr, "At line %d fopen failed %s\n", __LINE__, strerror(errno)); exit(1); }
/* Allocate two shared memory pages. */ shmem = (struct sha *)mmap(NULL, 2 * 4096, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); if (shmem == MAP_FAILED) { fprintf(stderr, "At line %d mmap failed %s\n", __LINE__, strerror(errno)); exit(1); } /* Re-protect the second to ensure shmem+4096 is invalid. */ if (mprotect(4096 + (char *)shmem, 4096, PROT_NONE)) { fprintf(stderr, "At line %d mprotect failed %s\n", __LINE__, strerror(errno)); exit(1); } shmem->child_action = 0; thread_action = 0;
/* Get an address in undodb private space */ FILE *maps = fopen("/proc/self/maps", "r"); if (!maps) { fprintf(stderr, "At line %d fopen failed %s\n", __LINE__, strerror(errno)); exit(1); } char buff[1024]; char * upriv = (char *)8; while (fgets(buff, sizeof(buff), maps)) { size_t i; for (i = 0; i < strlen(buff); ++i) { if ( (strncmp("preload1", buff + i, 8) == 0) || (strncmp("gdbmacro-release", buff + i, 8) == 0)) { if (sscanf(buff, "%lx-", (unsigned long*)&upriv) == 1) { break; } else { fprintf(stderr, "sscanf(\"%s\", \"%%lx-\") != 1", buff); } } } } if (upriv == (char *)8) { fprintf(stderr, "Could not find undodb private space\n"); /* not fatal */ }
/* Create a child thread and a child process. */ parent_pid = gettid(); thread_pid = clone(thread, thread_stack, CLONE_VM | CLONE_THREAD | CLONE_SIGHAND, NULL, NULL, NULL, NULL); if (thread_pid < 0) { fprintf(stderr, "At line %d clone failed %s\n", __LINE__, strerror(errno)); exit(1); } child_pid = fork(); if (child_pid < 0) { fprintf(stderr, "At line %d fork failed %s\n", __LINE__, strerror(errno)); exit(1); } else if (child_pid == 0) { child(); } /* Otherwise continue with parent being debugged. */
int r = futex(NULL, FUTEX_WAIT, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(NULL, FUTEX_WAIT_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT_PRIVATE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)8, FUTEX_WAIT, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)8, FUTEX_WAIT_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT_PRIVATE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_WAIT, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_WAIT_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT_PRIVATE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&f1), FUTEX_WAIT, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAIT with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&f1), FUTEX_WAIT_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAIT_PRIVATE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&(shmem->f3)), FUTEX_WAIT, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAIT with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(4094 + (char *)&(shmem->f3)), FUTEX_WAIT, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAIT with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } f1 = 0; r = futex(&f1, FUTEX_WAIT, 1, NULL, NULL, 0); if ((r >= 0) || (errno != EWOULDBLOCK)) { fprintf(stderr, "At line %d FUTEX_WAIT with *uaddr != val returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EWOULDBLOCK)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAIT_PRIVATE, 1, NULL, NULL, 0); if ((r >= 0) || (errno != EWOULDBLOCK)) { fprintf(stderr, "At line %d FUTEX_WAIT_PRIVATE with *uaddr != val returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EWOULDBLOCK)); tkill(child_pid, SIGKILL); exit(1); } shmem->f3 = 0; r = futex(&(shmem->f3), FUTEX_WAIT, 1, NULL, NULL, 0); if ((r >= 0) || (errno != EWOULDBLOCK)) { fprintf(stderr, "At line %d FUTEX_WAIT with *uaddr != val returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EWOULDBLOCK)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAIT, 0, (struct timespec *)8, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT with bad timeout returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAIT_PRIVATE, 0, (struct timespec *)8, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT_PRIVATE with bad timeout returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_WAIT, 0, (struct timespec *)8, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT with bad timeout returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAIT, 0, (struct timespec *)upriv, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT with bad timeout returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAIT_PRIVATE, 0, (struct timespec *)upriv, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT_PRIVATE with bad timeout returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_WAIT, 0, (struct timespec *)upriv, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT with bad timeout returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAIT, 0, &TEN_ms, NULL, 0); if ((r >= 0) || (errno != ETIMEDOUT)) { fprintf(stderr, "At line %d FUTEX_WAIT which should time out returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ETIMEDOUT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAIT_PRIVATE, 0, &TEN_ms, NULL, 0); if ((r >= 0) || (errno != ETIMEDOUT)) { fprintf(stderr, "At line %d FUTEX_WAIT_PRIVATE which should time out returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ETIMEDOUT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_WAIT, 0, &TEN_ms, NULL, 0); if ((r >= 0) || (errno != ETIMEDOUT)) { fprintf(stderr, "At line %d FUTEX_WAIT which should time out returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ETIMEDOUT)); tkill(child_pid, SIGKILL); exit(1); } thread_action = 1; r = futex(&f1, FUTEX_WAIT, 0, &ONE_sec, &f2, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } thread_action = 1; r = futex(&f1, FUTEX_WAIT, 0, &ONE_sec, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } thread_action = 1; r = futex(&f1, FUTEX_WAIT, 0, &ONE_sec, (int *)8, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } thread_action = 1; r = futex(&f1, FUTEX_WAIT, 0, &ONE_sec, (int *)upriv, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } thread_action = 2; r = futex(&f1, FUTEX_WAIT_PRIVATE, 0, &ONE_sec, NULL, 1); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } thread_action = 3; r = futex(&(shmem->f3), FUTEX_WAIT, 0, &ONE_sec, NULL, 2); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } shmem->child_action = 3; r = futex(&(shmem->f3), FUTEX_WAIT, 0, &ONE_sec, NULL, 3); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } r = futex(NULL, FUTEX_WAKE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAKE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } /* Curiously, the kernel returns 0 on this call, although no process can be * wakened, since futex(NULL, FUTEX_WAIT_PRIVATE, ...) fails. */ r = futex(NULL, FUTEX_WAKE_PRIVATE, 0, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "FUTEX_WAKE_PRIVATE with bad address succeeds\n"); } r = futex((int *)8, FUTEX_WAKE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAKE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)8, FUTEX_WAKE_PRIVATE, 0, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_WAKE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAKE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_WAKE_PRIVATE, 0, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(-8), FUTEX_WAKE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAKE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(-8), FUTEX_WAKE_PRIVATE, 0, NULL, NULL, 0); #ifdef __i386__ if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } #else if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAKE_PRIVATE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } #endif r = futex((int *)(1 + (char *)&f1), FUTEX_WAKE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&f1), FUTEX_WAKE_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d futex with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&(shmem->f3)), FUTEX_WAKE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(4094 + (char *)&(shmem->f3)), FUTEX_WAKE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE, 3, (struct timespec *)upriv, (int *)upriv, 0); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when no processes to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f1, FUTEX_WAKE_PRIVATE, 3, (struct timespec *)upriv, (int *)upriv, 2); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_PRIVATE returned %d when no processes to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f3), FUTEX_WAKE, 3, (struct timespec *)upriv, (int *)upriv, 1); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when no processes to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f1, FUTEX_WAKE, 3, (struct timespec *)upriv, (int *)upriv, 3); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when 1 process to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f1, FUTEX_WAKE_PRIVATE, 3, (struct timespec *)upriv, (int *)upriv, 4); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_PRIVATE returned %d when 1 process to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_WAKE, 3, (struct timespec *)upriv, (int *)upriv, 5); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when 1 process to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_WAKE, 3, (struct timespec *)upriv, (int *)upriv, 6); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when 1 process to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_WAKE, 3, (struct timespec *)upriv, (int *)upriv, 7); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when 2 processes to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_WAKE, 1, (struct timespec *)upriv, (int *)upriv, 8); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when only waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f3), FUTEX_WAKE, 0, NULL, NULL, 9); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "FUTEX_WAKE with zero val woke a process\n"); /* It isn't clear whether this is a bug in the kernel or the * manual page, which says "wakes at most val processes". */ } } else { r = futex(&(shmem->f3), FUTEX_WAKE, 1, NULL, NULL, 10); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when only waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_WAKE, -1, NULL, NULL, 11); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "FUTEX_WAKE with negative val woke a process\n"); /* It isn't clear whether this is a bug in the kernel or the * manual page, which says "wakes at most val processes". */ } } else { r = futex(&(shmem->f3), FUTEX_WAKE, 1, NULL, NULL, 12); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when only waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } } r = futex(&(shmem->f3), FUTEX_WAKE, 1, NULL, NULL, 13); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when only waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } /* Note the man page says that the arg 5 (timeout) is ignored for * FUTEX_REQUEUE and FUTEX_CMP_REQUEUE, but the kernel does use it as * the maximum number of processes to requeue. However if it is 0, the * kernel still requeues one process. * Also the man page says it returns the number of processes woken up, * but actually it returns the number of processes woken or requeued. */ r = futex(&f1, FUTEX_REQUEUE, 1, NULL, &f2, 0); if ((r < 0) && (errno == ENOSYS)) { fprintf(stderr, "FUTEX_REQUEUE not supported in this kernel\n"); /* not fatal */ } else { if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when no process to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f1, FUTEX_REQUEUE_PRIVATE, 1, NULL, &f2, 1); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE_PRIVATE returned %d when no process to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f3), FUTEX_REQUEUE, 1, NULL, &(shmem->f4), 2); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when no process to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(NULL, FUTEX_REQUEUE, 1, NULL, &f2, 3); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_REQUEUE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(NULL, FUTEX_REQUEUE_PRIVATE, 1, (struct timespec *)2, &f2, 4); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_REQUEUE, 1, NULL, NULL, 5); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_REQUEUE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_REQUEUE_PRIVATE, 1, NULL, NULL, 6); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_REQUEUE, 1, NULL, &f2, 7); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_REQUEUE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)8, FUTEX_REQUEUE_PRIVATE, 1, NULL, &f2, 8); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)8, FUTEX_REQUEUE, 1, NULL, &f2, 9); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_REQUEUE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_REQUEUE_PRIVATE, 1, NULL, &f2, 10); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_REQUEUE, 1, NULL, (int *)8, 11); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_REQUEUE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_REQUEUE_PRIVATE, 1, NULL, (int *)8, 12); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_REQUEUE, 1, NULL, (int *)upriv, 13); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_REQUEUE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_REQUEUE_PRIVATE, 1, NULL, (int *)upriv, 14); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&f1), FUTEX_REQUEUE, 1, NULL, &f2, 15); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_REQUEUE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&f1), FUTEX_REQUEUE_PRIVATE, 1, NULL, &f2, 16); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_REQUEUE_PRIVATE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_REQUEUE, 1, NULL, (int *)(1 + (char *)&f1), 17); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_REQUEUE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_REQUEUE_PRIVATE, 1, NULL, (int *)(1 + (char *)&f1), 18); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_REQUEUE_PRIVATE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&(shmem->f3)), FUTEX_REQUEUE, 1, NULL, &f2, 19); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_REQUEUE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_REQUEUE, 1, NULL, (int *)(1 + (char *)&(shmem->f3)), 20); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_REQUEUE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(4094 + (char *)&(shmem->f3)), FUTEX_REQUEUE, 1, NULL, &f2, 21); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_REQUEUE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_REQUEUE, 1, NULL, (int *)(4094 + (char *)&(shmem->f3)), 22); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_REQUEUE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } thread_action = 4; wait_for_thread(); r = futex(&f1, FUTEX_REQUEUE, 0, NULL, &f2, 23); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when requeueing one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } else { fprintf(stderr, "FUTEX_REQUEUE returns 1 when waking no processes but requeueing one\n"); /* Probably a man page error. */ } /* We woke none, so one should be requeued on f2. */ r = futex(&f2, FUTEX_WAKE, 1, NULL, NULL, 24); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f1, FUTEX_REQUEUE_PRIVATE, 0, NULL, &f2, 25); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE_PRIVATE returned %d when requeueing one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } /* We woke none, so one should be requeued on f2. */ r = futex(&f2, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 26); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f1, FUTEX_REQUEUE, 1, NULL, &f2, 27); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f1, FUTEX_REQUEUE_PRIVATE, 1, NULL, &f2, 28); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f1, FUTEX_REQUEUE, 2, NULL, &f2, 29); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f1, FUTEX_REQUEUE_PRIVATE, 2, NULL, &f2, 30); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); /* Requeue to same futex is allowed. */ r = futex(&f1, FUTEX_REQUEUE, 0, NULL, &f1, 31); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when requeueing one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f1, FUTEX_WAKE, 1, NULL, NULL, 0); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f1, FUTEX_REQUEUE_PRIVATE, 0, NULL, &f1, 32); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE_PRIVATE returned %d when requeueing one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f1, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 0); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f1, FUTEX_REQUEUE, 1, NULL, &f1, 33); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f1, FUTEX_REQUEUE_PRIVATE, 1, NULL, &f1, 34); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f1, FUTEX_REQUEUE, 2, NULL, &f1, 35); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f1, FUTEX_REQUEUE_PRIVATE, 2, NULL, &f1, 36); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_REQUEUE, 0, NULL, &(shmem->f4), 37); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when requeueing one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE, 1, NULL, NULL, 38); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d futex returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_REQUEUE, 1, NULL, &(shmem->f4), 39); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_REQUEUE, 2, NULL, &(shmem->f4), 40); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_REQUEUE, 0, NULL, &(shmem->f3), 41); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when requeueing one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f3), FUTEX_WAKE, 1, NULL, NULL, 42); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_REQUEUE, 1, NULL, &(shmem->f3), 43); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_REQUEUE, 2, NULL, &(shmem->f3), 44); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_REQUEUE, 0, NULL, &(shmem->f4), 45); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when requeueing one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f3), FUTEX_WAKE, 2, NULL, NULL, 46); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE, 2, NULL, NULL, 47); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_REQUEUE, 0, (struct timeout *)1, &(shmem->f4), 48); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when requeueing one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f3), FUTEX_WAKE, 2, NULL, NULL, 49); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE, 2, NULL, NULL, 50); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_REQUEUE, 0, (struct timeout *)2, &(shmem->f4), 51); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when requeueing two processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE, 2, NULL, NULL, 52); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking two processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_REQUEUE, 1, NULL, &(shmem->f4), 53); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d instead of 2\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE, 2, NULL, NULL, 54); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_REQUEUE, 2, NULL, &(shmem->f4), 55); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when waking two processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_REQUEUE, 0, NULL, &(shmem->f3), 56); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when requeueing one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f3), FUTEX_WAKE, 2, NULL, NULL, 57); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking two processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_REQUEUE, 1, NULL, &(shmem->f3), 58); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d instead of 2\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f3), FUTEX_WAKE, 2, NULL, NULL, 59); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_REQUEUE, 2, NULL, &(shmem->f3), 60); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_REQUEUE returned %d when waking two processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } } f1 = 0; r = futex(&f1, FUTEX_CMP_REQUEUE, 1, NULL, &f2, 0); if ((r < 0) && (errno == ENOSYS)) { fprintf(stderr, "FUTEX_CMP_REQUEUE not supported in this kernel\n"); /* not fatal */ } else { if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when no process to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } f1 = 1; r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 1, NULL, &f2, 1); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE returned %d when no process to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } f1 = 2; r = futex(NULL, FUTEX_CMP_REQUEUE, 1, NULL, &f2, 2); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(NULL, FUTEX_CMP_REQUEUE_PRIVATE, 1, NULL, &f2, 2); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE, 1, NULL, NULL, 2); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 1, NULL, NULL, 2); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)8, FUTEX_CMP_REQUEUE, 1, NULL, &f2, 2); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)8, FUTEX_CMP_REQUEUE_PRIVATE, 1, NULL, &f2, 2); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE, 1, NULL, (int *)8, 2); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 1, NULL, (int *)8, 2); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_CMP_REQUEUE, 1, NULL, &f2, 2); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_CMP_REQUEUE_PRIVATE, 1, NULL, &f2, 2); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE, 1, NULL, (int *)upriv, 2); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 1, NULL, (int *)upriv, 2); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&f1), FUTEX_CMP_REQUEUE, 1, NULL, &f2, 2); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&f1), FUTEX_CMP_REQUEUE_PRIVATE, 1, NULL, &f2, 2); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE, 1, NULL, (int *)(1 + (char *)&f1), 2); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 1, NULL, (int *)(1 + (char *)&f1), 2); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&(shmem->f3)), FUTEX_CMP_REQUEUE, 1, NULL, &f2, 2); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE, 1, NULL, (int *)(1 + (char *)&(shmem->f3)), 2); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(4094 + (char *)&(shmem->f3)), FUTEX_CMP_REQUEUE, 1, NULL, &f2, 2); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE, 1, NULL, (int *)(4094 + (char *)&(shmem->f3)), 2); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } f1 = 3; thread_action = 4; wait_for_thread(); r = futex(&f1, FUTEX_CMP_REQUEUE, 0, NULL, &f2, 0); if ((r >= 0) || (errno != EAGAIN)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with non match returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EAGAIN)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE, 0, NULL, &f2, 3); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when requeueing one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE, 1, NULL, NULL, 0); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 0, NULL, &f2, 0); if ((r >= 0) || (errno != EAGAIN)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE with non match returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EAGAIN)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 0, NULL, &f2, 3); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE returned %d when requeueing one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 0); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f1, FUTEX_CMP_REQUEUE, 1, NULL, &f2, 0); if ((r >= 0) || (errno != EAGAIN)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with non match returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EAGAIN)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE, 1, NULL, &f2, 3); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 1, NULL, &f2, 0); if ((r >= 0) || (errno != EAGAIN)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE with non match returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EAGAIN)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 1, NULL, &f2, 3); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f1, FUTEX_CMP_REQUEUE, 2, NULL, &f2, 0); if ((r >= 0) || (errno != EAGAIN)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with non match returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EAGAIN)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE, 2, NULL, &f2, 3); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 2, NULL, &f2, 0); if ((r >= 0) || (errno != EAGAIN)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE with non match returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EAGAIN)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 2, NULL, &f2, 3); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f1, FUTEX_CMP_REQUEUE, 2, NULL, &f1, 4); if ((r >= 0) || (errno != EAGAIN)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with non match returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EAGAIN)); tkill(child_pid, SIGKILL); exit(1); } f1 = 4; r = futex(&f1, FUTEX_CMP_REQUEUE, 1, NULL, &f1, 4); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d futex returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 0, NULL, &f1, 3); if ((r >= 0) || (errno != EAGAIN)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE with non match returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EAGAIN)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 0, NULL, &f1, 4); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE returned %d when requeueing one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f1, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 0); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f1, FUTEX_CMP_REQUEUE, 1, NULL, &f1, 3); if ((r >= 0) || (errno != EAGAIN)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with non match returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EAGAIN)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE, 1, NULL, &f1, 4); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 1, NULL, &f1, 3); if ((r >= 0) || (errno != EAGAIN)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE with non match returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EAGAIN)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 1, NULL, &f1, 4); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f1, FUTEX_CMP_REQUEUE, 2, NULL, &f1, 3); if ((r >= 0) || (errno != EAGAIN)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with non match returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EAGAIN)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE, 2, NULL, &f1, 4); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 2, NULL, &f1, 3); if ((r >= 0) || (errno != EAGAIN)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE with non match returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EAGAIN)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 2, NULL, &f1, 4); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f1, FUTEX_CMP_REQUEUE, 0, NULL, &f1, 3); if ((r >= 0) || (errno != EAGAIN)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with non match returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EAGAIN)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE, 0, NULL, &f1, 4); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when requeueing one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f1, FUTEX_WAKE, 1, NULL, NULL, 0); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 0, NULL, &f1, 3); if ((r >= 0) || (errno != EAGAIN)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE with non match returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EAGAIN)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 0, NULL, &f1, 4); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE returned %d when requeueing one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f1, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 0); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f1, FUTEX_CMP_REQUEUE, 1, NULL, &f1, 3); if ((r >= 0) || (errno != EAGAIN)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with non match returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EAGAIN)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE, 1, NULL, &f1, 4); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 1, NULL, &f1, 3); if ((r >= 0) || (errno != EAGAIN)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE with non match returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EAGAIN)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 1, NULL, &f1, 4); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f1, FUTEX_CMP_REQUEUE, 2, NULL, &f1, 3); if ((r >= 0) || (errno != EAGAIN)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with non match returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE, 2, NULL, &f1, 4); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 2, NULL, &f1, 3); if ((r >= 0) || (errno != EAGAIN)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE with non match returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EAGAIN)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_CMP_REQUEUE_PRIVATE, 2, NULL, &f1, 4); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } shmem->f3 = 5; thread_action = 6; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_CMP_REQUEUE, 0, NULL, &(shmem->f4), 4); if ((r >= 0) || (errno != EAGAIN)) { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE with non match returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EAGAIN)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_CMP_REQUEUE, 0, NULL, &(shmem->f4), 5); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when requeueing one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE, 1, NULL, NULL, 0); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_CMP_REQUEUE, 1, NULL, &(shmem->f4), 5); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_CMP_REQUEUE, 2, NULL, &(shmem->f4), 5); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_CMP_REQUEUE, 0, NULL, &(shmem->f3), 5); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when requeueing one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f3), FUTEX_WAKE, 1, NULL, NULL, 0); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_CMP_REQUEUE, 1, NULL, &(shmem->f3), 5); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_CMP_REQUEUE, 2, NULL, &(shmem->f3), 5); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_CMP_REQUEUE, 0, NULL, &(shmem->f4), 5); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when requeueing one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f3), FUTEX_WAKE, 2, NULL, NULL, 0); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE, 2, NULL, NULL, 0); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_CMP_REQUEUE, 0, (struct timeout *)1, &(shmem->f4), 5); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when requeueing one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f3), FUTEX_WAKE, 2, NULL, NULL, 0); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE, 2, NULL, NULL, 0); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_CMP_REQUEUE, 0, (struct timeout *)2, &(shmem->f4), 5); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when requeueing two processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE, 2, NULL, NULL, 0); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking two processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_CMP_REQUEUE, 1, NULL, &(shmem->f4), 5); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d instead of 2\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE, 2, NULL, NULL, 0); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_CMP_REQUEUE, 2, NULL, &(shmem->f4), 5); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when waking two processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_CMP_REQUEUE, 0, NULL, &(shmem->f3), 5); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when requeueing one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f3), FUTEX_WAKE, 2, NULL, NULL, 0); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking two processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_CMP_REQUEUE, 1, NULL, &(shmem->f3), 5); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d instead of 2\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f3), FUTEX_WAKE, 2, NULL, NULL, 0); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_CMP_REQUEUE, 2, NULL, &(shmem->f3), 5); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_CMP_REQUEUE returned %d when waking two processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } } /* FUTEX_WAKE_OP isn't documented in the man page. From looking at the * kernel code, it does the following * arg6 encodes an operation, an operand, a comparison type, * and a comparisonn value. * Atomically perform the comparison and then the operation on *arg5 * Wake up to max(1, arg3) processess waiting on arg1 * If comparison succeeded * Wake up to (max(1, (int)arg4) processes waiting on arg5 * Returns total number of processes awakened. */ r = futex(&f1, FUTEX_WAKE_OP, 0, NULL, &f2, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if ((r < 0) && (errno == ENOSYS)) { fprintf(stderr, "FUTEX_WAKE_OP not supported in this kernel\n"); /* not fatal */ } else { if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } f1 = 0; f2 = 0; r = futex(NULL, FUTEX_WAKE_OP, 0, NULL, &f2, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(NULL, FUTEX_WAKE_OP_PRIVATE, 0, NULL, &f2, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)8, FUTEX_WAKE_OP, 0, NULL, &f2, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)8, FUTEX_WAKE_OP_PRIVATE, 0, NULL, &f2, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_WAKE_OP, 0, NULL, &f2, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_WAKE_OP_PRIVATE, 0, NULL, &f2, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&f1), FUTEX_WAKE_OP, 0, NULL, &f2, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&f1), FUTEX_WAKE_OP_PRIVATE, 0, NULL, &f2, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&(shmem->f3)), FUTEX_WAKE_OP, 0, NULL, &f2, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(4094 + (char *)&(shmem->f3)), FUTEX_WAKE_OP, 0, NULL, &f2, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_OP, 0, NULL, NULL, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_OP_PRIVATE, 0, NULL, NULL, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_OP, 0, NULL, (int *)8, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_OP_PRIVATE, 0, NULL, (int *)8, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_OP, 0, NULL, (int *)upriv, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_OP_PRIVATE, 0, NULL, (int *)upriv, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_OP, 0, NULL, (int *)(1 + (char *)&f2), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_OP_PRIVATE, 0, NULL, (int *)(1 + (char *)&f2), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_OP, 0, NULL, (int *)(1 + (char *)&(shmem->f3)), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_OP, 0, NULL, (int *)(4094 + (char *)&(shmem->f3)), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_OP, 0, NULL, &f2, FUTEX_OP(5, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != ENOSYS)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad operation returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ENOSYS)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_OP, 0, NULL, &f2, FUTEX_OP(6, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != ENOSYS)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad operation returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ENOSYS)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_OP, 0, NULL, &f2, FUTEX_OP(7, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != ENOSYS)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad operation returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ENOSYS)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_OP, 0, NULL, &f2, FUTEX_OP(13, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != ENOSYS)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad operation returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ENOSYS)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_OP, 0, NULL, &f2, FUTEX_OP(14, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != ENOSYS)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad operation returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ENOSYS)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_OP, 0, NULL, &f2, FUTEX_OP(15, 0, FUTEX_OP_CMP_EQ, 0)); if ((r >= 0) || (errno != ENOSYS)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad operation returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ENOSYS)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_OP, 0, NULL, &f2, FUTEX_OP(FUTEX_OP_SET, 0, 6, 0)); if ((r >= 0) || (errno != ENOSYS)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad comparison returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ENOSYS)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_OP, 0, NULL, &f2, FUTEX_OP(FUTEX_OP_SET, 0, 7, 0)); if ((r >= 0) || (errno != ENOSYS)) { fprintf(stderr, "At line %d FUTEX_WAKE_OP with bad comparison returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ENOSYS)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_OP_PRIVATE, 0, NULL, &f2, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f1, FUTEX_WAKE_OP, 2, (struct timespec *)2, &f2, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f1, FUTEX_WAKE_OP_PRIVATE, 2, (struct timespec *)2, &f2, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f1, FUTEX_WAKE_OP, 0, NULL, &f2, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f1, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f2, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f1, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f2, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f1, FUTEX_WAKE_OP_PRIVATE, 0, (struct timespec *)2, &f2, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP, 2, NULL, &f1, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP_PRIVATE, 2, NULL, &f1, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP_PRIVATE, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } shmem->f3 = 0; thread_action = 6; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f4), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_WAKE_OP, 2, NULL, &(shmem->f4), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f4), FUTEX_WAKE_OP, 2, NULL, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_WAKE_OP, 0, NULL, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_WAKE_OP, 2, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f4), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_WAKE_OP, 2, NULL, &(shmem->f4), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f4), FUTEX_WAKE_OP, 2, NULL, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_WAKE_OP, 0, NULL, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_WAKE_OP, 2, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f4), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one processs\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f3), FUTEX_WAKE_OP, 1, NULL, &(shmem->f4), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE_OP, 1, NULL, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_WAKE_OP, 3, NULL, &(shmem->f4), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking two processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)3, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } #ifdef __i386__ if (r == 1) { /* Wake the other one. */ (void)futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)3, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0)); fprintf(stderr, "KERNELBUG? FUTEX_WAKE_OP arg4 not decoded correctly in 32-bit\n"); } #endif else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking two processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_ADD, 1, FUTEX_OP_CMP_EQ, 1)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_ADD, 1, FUTEX_OP_CMP_EQ, 1)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_OR, 1, FUTEX_OP_CMP_EQ, 3)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_OR, 1, FUTEX_OP_CMP_EQ, 3)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_ANDN, 1, FUTEX_OP_CMP_EQ, 2)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_ANDN, 1, FUTEX_OP_CMP_EQ, 2)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_XOR, 3, FUTEX_OP_CMP_EQ, 1)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_XOR, 3, FUTEX_OP_CMP_EQ, 1)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP((FUTEX_OP_SET | FUTEX_OP_OPARG_SHIFT), 4, FUTEX_OP_CMP_EQ, (1 << 4))); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP((FUTEX_OP_SET | FUTEX_OP_OPARG_SHIFT), 4, FUTEX_OP_CMP_EQ, (1 << 4))); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (-1), FUTEX_OP_CMP_NE, (1 << 4))); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (-1), FUTEX_OP_CMP_NE, (1 << 4))); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (-2), FUTEX_OP_CMP_LT, (-1))); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (-2), FUTEX_OP_CMP_LT, (-1))); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (-3), FUTEX_OP_CMP_LE, (-3))); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (-3), FUTEX_OP_CMP_LE, (-3))); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (-5), FUTEX_OP_CMP_LE, (-4))); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (-5), FUTEX_OP_CMP_LE, (-4))); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, 4, FUTEX_OP_CMP_GT, (-5))); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, 4, FUTEX_OP_CMP_GT, (-5))); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, 6, FUTEX_OP_CMP_GE, 6)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, 6, FUTEX_OP_CMP_GE, 6)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (1 << 4), FUTEX_OP_CMP_NE, 6)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_OP, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (1 << 4), FUTEX_OP_CMP_NE, 6)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP_PRIVATE, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (-1), FUTEX_OP_CMP_NE, (1 << 4))); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_OP_PRIVATE, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (-1), FUTEX_OP_CMP_NE, (1 << 4))); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP_PRIVATE, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (-2), FUTEX_OP_CMP_LT, (-1))); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_OP_PRIVATE, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (-2), FUTEX_OP_CMP_LT, (-1))); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP_PRIVATE, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (-3), FUTEX_OP_CMP_LE, (-3))); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_OP_PRIVATE, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (-3), FUTEX_OP_CMP_LE, (-3))); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP_PRIVATE, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (-5), FUTEX_OP_CMP_LE, (-4))); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_OP_PRIVATE, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (-5), FUTEX_OP_CMP_LE, (-4))); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP_PRIVATE, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, 4, FUTEX_OP_CMP_GT, (-5))); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_OP_PRIVATE, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, 4, FUTEX_OP_CMP_GT, (-5))); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP_PRIVATE, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, 6, FUTEX_OP_CMP_GE, 6)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_OP_PRIVATE, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, 6, FUTEX_OP_CMP_GE, 6)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f2, FUTEX_WAKE_OP_PRIVATE, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (1 << 4), FUTEX_OP_CMP_NE, 6)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f2, FUTEX_WAKE_OP_PRIVATE, 0, (struct timespec *)2, &f1, FUTEX_OP(FUTEX_OP_SET, (1 << 4), FUTEX_OP_CMP_NE, 6)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP_PRIVATE returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0xfff, FUTEX_OP_CMP_NE, 0)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0xfff, FUTEX_OP_CMP_NE, 0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0xffe, FUTEX_OP_CMP_LT, 0xfff)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0xffe, FUTEX_OP_CMP_LT, 0xfff)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0xffc, FUTEX_OP_CMP_LE, 0xffc)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0xffc, FUTEX_OP_CMP_LE, 0xffc)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0xfc0, FUTEX_OP_CMP_LE, 0xfc1)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0xfc0, FUTEX_OP_CMP_LE, 0xfc1)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 98, FUTEX_OP_CMP_GT, 97)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 98, FUTEX_OP_CMP_GT, 97)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 100, FUTEX_OP_CMP_GE, 99)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 100, FUTEX_OP_CMP_GE, 99)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0xfff, FUTEX_OP_CMP_NE, 100)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0xfff, FUTEX_OP_CMP_NE, 100)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0xffe, FUTEX_OP_CMP_LT, 0xfff)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0xffe, FUTEX_OP_CMP_LT, 0xfff)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0xffc, FUTEX_OP_CMP_LE, 0xffc)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0xffc, FUTEX_OP_CMP_LE, 0xffc)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0xfc0, FUTEX_OP_CMP_LE, 0xff0)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 0xfc0, FUTEX_OP_CMP_LE, 0xff0)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 98, FUTEX_OP_CMP_GT, 97)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 98, FUTEX_OP_CMP_GT, 97)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 100, FUTEX_OP_CMP_GE, 99)); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking no processes\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f4), FUTEX_WAKE_OP, 0, (struct timespec *)2, &(shmem->f3), FUTEX_OP(FUTEX_OP_SET, 100, FUTEX_OP_CMP_GE, 99)); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_OP returned %d when waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } } /* FUTEX_LOCK_PI, FUTEX_UNLOCK_PI, and FUTEX_TRYLOCK_PI are also not documented. * Looking at Documentation/pi-futex.txt and the kernel code, * we find that FUTEX_LOCK_PI does:- * If *arg1 is 0, it is set to this task's TID and 0 is returned. * If *arg1 is already this task's TID, -EDEADLK is returned. * If *arg1 is not some other task's TID, -ESRCH is returned. * If *arg1 is some other task's TID, * That task's priority is raised if necessary to this task's priority, * (we don't test this). * This task waits until the other task does FUTEX_UNLOCK_PI. * If arg4 is not NULL it is a timeout and if it times out ETIMEDOUT * is returned * When the other task does FUTEX_UNLOCK_PI. * *arg1 is set to this task's TID * 0 is returned. * Looking at Documentation/pi-futex.txt and the kernel code, * we find that FUTEX_UNLOCK_PI does:- * If *arg1 is this task's TID, 0 is returned and *arg1 is cleared.. * If *arg1 is this task's TID + FUTEX_WAITERS,. * That task's priority is lowered if necessary to what is was before, * (we don't test this). * The highest priority task waiting for arg1 is wakened, *arg1 is set * to its TID. and its FUTEX_LOCK_PI operation returns 0. * Meanwhile this task's FUTEX_UNLOCK_PI returns 0. * If *arg1 is anything else, -EPERM is returned * Looking at Documentation/pi-futex.txt and the kernel code, * we find that FUTEX_TRYLOCK_PI does:- * If *arg1 is 0, it is set to this task's TID and 0 is returned. * If *arg1 is already this task's TID, -EDEADLK is returned. * If *arg1 is not some other task's TID, -ESRCH is returned. * If *arg1 is some other task's TID, -EWOULDBLOCK is returned. */ f1 = 0; int trylock = futex(&f1, FUTEX_TRYLOCK_PI, 0, NULL, NULL, 0); if (trylock) { if (errno == ENOSYS) { fprintf(stderr, "FUTEX_TRYLOCK_PI not supported in this kernel\n"); /* not fatal */ } else { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } else { if (f1 != parent_pid) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI set *arg1 to %d instead of %d\n", __LINE__, f1, parent_pid); tkill(child_pid, SIGKILL); exit(1); } /* It isn't plausible that a kernel supports FUTEX_TRYLOCK_PI but not * FUTEX_UNLOCK_PI. If this happens, we catch it below. */ (void)futex(&f1, FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); } r = futex(&f1, FUTEX_LOCK_PI, 0, NULL, NULL, 0); if ((r < 0) && (errno == ENOSYS)) { fprintf(stderr, "FUTEX_LOCK_PI not supported in this kernel\n"); /* not fatal */ } else { if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_LOCK_PI returned %d instead of 0\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } if (f1 != parent_pid) { fprintf(stderr, "At line %d FUTEX_LOCK_PI set *arg1 to %d instead of %d\n", __LINE__, f1, parent_pid); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_LOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EDEADLK)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI with deadlock returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EDEADLK)); tkill(child_pid, SIGKILL); exit(1); } if (trylock) { r = futex(&f1, FUTEX_TRYLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EDEADLK)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI with deadlock returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EDEADLK)); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f1, FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); if ((r < 0) && (errno == ENOSYS)) { fprintf(stderr, "FUTEX_UNLOCK_PI not supported in this kernel\n"); /* not fatal */ } else { if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI returned %d instead of 0\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } if (f1) { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI with no waiters did not clear *arg1 (%i)\n", __LINE__, f1); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EPERM)) { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI with no lock returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EPERM)); tkill(child_pid, SIGKILL); exit(1); } r = futex(NULL, FUTEX_LOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(NULL, FUTEX_LOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI_PRIVATE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)8, FUTEX_LOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)8, FUTEX_LOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI_PRIVATE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_LOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_LOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI_PRIVATE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&f1), FUTEX_LOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&f1), FUTEX_LOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI_PRIVATE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&(shmem->f3)), FUTEX_LOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(4094 + (char *)&(shmem->f3)), FUTEX_LOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_LOCK_PI, 0, (struct timespec *)8, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_LOCK_PI_PRIVATE, 0, (struct timespec *)8, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI_PRIVATE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_LOCK_PI, 0, (struct timespec *)upriv, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_LOCK_PI_PRIVATE, 0, (struct timespec *)upriv, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI_PRIVATE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } if (trylock) { r = futex(NULL, FUTEX_TRYLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(NULL, FUTEX_TRYLOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI_PRIVATE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)8, FUTEX_TRYLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)8, FUTEX_TRYLOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI_PRIVATE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_TRYLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_TRYLOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI_PRIVATE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&f1), FUTEX_TRYLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&f1), FUTEX_TRYLOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI_PRIVATE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&(shmem->f3)), FUTEX_TRYLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(4094 + (char *)&(shmem->f3)), FUTEX_TRYLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f1, FUTEX_LOCK_PI_PRIVATE, 0, NULL, NULL, 0); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_LOCK_PI_PRIVATE returned %d instead of 0\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } if (f1 != parent_pid) { fprintf(stderr, "At line %d FUTEX_LOCK_PI_PRIVATE set *arg1 to %d instead of %d\n", __LINE__, f1, parent_pid); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_LOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EDEADLK)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI_PRIVATE with deadlock returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EDEADLK)); tkill(child_pid, SIGKILL); exit(1); } if (trylock) { r = futex(&f1, FUTEX_TRYLOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EDEADLK)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI_PRIVATE with deadlock returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EDEADLK)); tkill(child_pid, SIGKILL); exit(1); } } r = futex(NULL, FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(NULL, FUTEX_UNLOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI_PRIVATE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)8, FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)8, FUTEX_UNLOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI_PRIVATE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_UNLOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI_PRIVATE with bad address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } *(int *)(1 + (char *)&f1) = parent_pid; r = futex((int *)(1 + (char *)&f1), FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&f1), FUTEX_UNLOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI_PRIVATE with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } *(int *)(1 + (char *)&(shmem->f3)) = parent_pid; r = futex((int *)(1 + (char *)&(shmem->f3)), FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI with misaligned address returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } f1 = parent_pid; r = futex(&f1, FUTEX_UNLOCK_PI_PRIVATE, 0, NULL, NULL, 0); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI_PRIVATE returned %d instead of 0\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } if (f1) { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI_PRIVATE with no waiters did not clear *arg1 (%i)\n", __LINE__, f1); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_UNLOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EPERM)) { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI_PRIVATE with no lock returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EPERM)); tkill(child_pid, SIGKILL); exit(1); } if (trylock) { r = futex(&f1, FUTEX_TRYLOCK_PI_PRIVATE, 0, NULL, NULL, 0); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI_PRIVATE returned %d instead of 0\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } if (f1 != parent_pid) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI_PRIVATE set *arg1 to %d instead of %d\n", __LINE__, f1, parent_pid); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_LOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (r != EDEADLK)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI_PRIVATE with deadlock returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EDEADLK)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_TRYLOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (r != EDEADLK)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI_PRIVATE with deadlock returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EDEADLK)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_UNLOCK_PI_PRIVATE, 0, NULL, NULL, 0); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI_PRIVATE returned %d instead of 0\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } if (f1) { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI_PRIVATE with no waiters did not clear *arg1 (%i)\n", __LINE__, f1); tkill(child_pid, SIGKILL); exit(1); } } shmem->f3 = 0; r = futex((int *)&(shmem->f3), FUTEX_LOCK_PI, 0, NULL, NULL, 0); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_LOCK_PI returned %d instead of 0\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } if (shmem->f3 != parent_pid) { fprintf(stderr, "At line %d FUTEX_LOCK_PI set *arg1 to %d instead of %d\n", __LINE__, shmem->f3, parent_pid); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_LOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EDEADLK)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI with deadlock returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EDEADLK)); tkill(child_pid, SIGKILL); exit(1); } if (trylock) { r = futex(&(shmem->f3), FUTEX_TRYLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EDEADLK)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI with deadlock returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EDEADLK)); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f3), FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI returned %d instead of 0\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } if (shmem->f3) { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI with no waiters did not clear *arg1 (%i)\n", __LINE__, shmem->f3); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EPERM)) { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI with no lock returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EPERM)); tkill(child_pid, SIGKILL); exit(1); } if (trylock) { r = futex((int *)&(shmem->f3), FUTEX_TRYLOCK_PI, 0, NULL, NULL, 0); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI returned %d instead of 0\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } if (shmem->f3 != parent_pid) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI set *arg1 to %d instead of %d\n", __LINE__, shmem->f3, parent_pid); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_LOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (r != EDEADLK)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI with deadlock returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EDEADLK)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_TRYLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (r != EDEADLK)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI with deadlock returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EDEADLK)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI returned %d instead of 0\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } if (shmem->f3) { fprintf(stderr, "At line %d FUTEX_UNLOCK_PI with no waiters did not clear *arg1 (%i)\n", __LINE__, shmem->f3); tkill(child_pid, SIGKILL); exit(1); } } f1 = fork(); if (f1 < 0) { fprintf(stderr, "At line %d fork failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else if (f1 == 0) { exit(0); } else { int status; r = waitpid(f1, &status, 0); if (r < 0) { fprintf(stderr, "At line %d waitpid failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } /* At this point f1 is the pid of a process which has just exited. * Unless the system is *very* busy and has already recycled it. * f1 is not the pid of any process. */ shmem->f3 = f1; r = futex(&f1, FUTEX_LOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != ESRCH)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI with invalid pid returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ESRCH)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_LOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != ESRCH)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI with invalid pid returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ESRCH)); tkill(child_pid, SIGKILL); exit(1); } if (trylock) { f1 = fork(); if (f1 < 0) { fprintf(stderr, "At line %d fork failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else if (f1 == 0) { exit(0); } else { int status; r = waitpid(f1, &status, 0); if (r < 0) { fprintf(stderr, "At line %d waitpid failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } shmem->f3 = f1; r = futex(&f1, FUTEX_TRYLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != ESRCH)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI with invalid pid returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ESRCH)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_TRYLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != ESRCH)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI with invalid pid returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ESRCH)); tkill(child_pid, SIGKILL); exit(1); } } f1 = fork(); if (f1 < 0) { fprintf(stderr, "At line %d fork failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else if (f1 == 0) { exit(0); } else { int status; r = waitpid(f1, &status, 0); if (r < 0) { fprintf(stderr, "At line %d waitpid failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f1, FUTEX_LOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != ESRCH)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI_PRIVATE with invalid pid returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ESRCH)); tkill(child_pid, SIGKILL); exit(1); } if (trylock) { f1 = fork(); if (f1 < 0) { fprintf(stderr, "At line %d fork failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else if (f1 == 0) { exit(0); } else { int status; r = waitpid(f1, &status, 0); if (r < 0) { fprintf(stderr, "At line %d waitpid failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f1, FUTEX_TRYLOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != ESRCH)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI_PRIVATE with invalid pid returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ESRCH)); tkill(child_pid, SIGKILL); exit(1); } } f1 = 0; thread_action = 7; wait_for_thread(); r = futex(&f1, FUTEX_LOCK_PI, 0, &TEN_ms, NULL, 0); if ((r >= 0) || (errno != ETIMEDOUT)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI should time out returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ETIMEDOUT)); tkill(child_pid, SIGKILL); exit(1); } if (trylock) { r = futex(&f1, FUTEX_TRYLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EWOULDBLOCK)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EWOULDBLOCK)); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 10; int count; for (count = 0; count < 100; ++count) { r = futex(&f1, FUTEX_LOCK_PI, 0, &ONE_sec, NULL, 0); if (r) { if ((errno == ETIMEDOUT) && (count < 99)) { if ((count == 0) && (thread_action == 10)) { fprintf(stderr, "KERNELBUG? FUTEX_LOCK_PI with timer returns ETIMEDOUT immediately\n"); } /* Give the thread some time to do it. */ if (nanosleep(&TEN_ms, NULL)) { fprintf(stderr, "At line %d nanosleep failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } continue; } else { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } break; } thread_action = 16; wait_for_thread(); r = futex(&f1, FUTEX_WAKE, 1, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE on pi-locked returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_BITSET, 1, NULL, NULL, 1); if ((r >= 0) || ((errno != EINVAL) && (errno != ENOSYS))) { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET on pi-locked returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } thread_action = 19; wait_for_thread(); if (f1) { fprintf(stderr, "At line %d f1 is %d instead of zero after unlocking\n", __LINE__, f1); tkill(child_pid, SIGKILL); exit(1); } thread_action = 8; wait_for_thread(); r = futex(&f1, FUTEX_LOCK_PI_PRIVATE, 0, &TEN_ms, NULL, 0); if ((r >= 0) || (errno != ETIMEDOUT)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI_PRIVATE should time out returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ETIMEDOUT)); tkill(child_pid, SIGKILL); exit(1); } if (trylock) { r = futex(&f1, FUTEX_TRYLOCK_PI_PRIVATE, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EWOULDBLOCK)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI_PRIVATE returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EWOULDBLOCK)); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 11; for (count = 0; count < 100; ++count) { r = futex(&f1, FUTEX_LOCK_PI_PRIVATE, 0, &ONE_sec, NULL, 0); if (r) { if ((errno == ETIMEDOUT) && (count < 99)) { if ((count == 0) && (thread_action == 11)) { fprintf(stderr, "KERNELBUG? FUTEX_LOCK_PI_PRIVATE with timer returns ETIMEDOUT immediately\n"); } /* Give the thread some time to do it. */ if (nanosleep(&TEN_ms, NULL)) { fprintf(stderr, "At line %d nanosleep failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } continue; } else { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } break; } thread_action = 17; wait_for_thread(); r = futex(&f1, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE_PRIVATE on pi-locked returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_BITSET_PRIVATE, 1, NULL, NULL, 1); if ((r >= 0) || ((errno != EINVAL) && (errno != ENOSYS))) { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET_PRIVATE on pi-locked returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_UNLOCK_PI_PRIVATE, 0, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } thread_action = 19; wait_for_thread(); if (f1) { fprintf(stderr, "At line %d f1 is %d instead of zero after unlocking\n", __LINE__, f1); tkill(child_pid, SIGKILL); exit(1); } shmem->f3 = 0; thread_action = 9; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_LOCK_PI, 0, &TEN_ms, NULL, 0); if ((r >= 0) || (errno != ETIMEDOUT)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI should time out returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ETIMEDOUT)); tkill(child_pid, SIGKILL); exit(1); } if (trylock) { r = futex(&(shmem->f3), FUTEX_TRYLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EWOULDBLOCK)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EWOULDBLOCK)); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 12; for (count = 0; count < 100; ++count) { r = futex(&(shmem->f3), FUTEX_LOCK_PI, 0, &ONE_sec, NULL, 0); if (r) { if ((errno == ETIMEDOUT) && (count < 99)) { /* Give the thread some time to do it. */ if (nanosleep(&TEN_ms, NULL)) { fprintf(stderr, "At line %d nanosleep failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } continue; } else { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } break; } thread_action = 18; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_WAKE, 1, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE on pi-locked returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_WAKE_BITSET, 1, NULL, NULL, 1); if ((r >= 0) || ((errno != EINVAL) && (errno != ENOSYS))) { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET on pi-locked returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } thread_action = 19; wait_for_thread(); if (shmem->f3) { fprintf(stderr, "At line %d shmem->f3 is %d instead of zero after unlocking\n", __LINE__, f1); tkill(child_pid, SIGKILL); exit(1); } shmem->child_action = 9; wait_for_child(); r = futex(&(shmem->f3), FUTEX_LOCK_PI, 0, &TEN_ms, NULL, 0); if ((r >= 0) || (errno != ETIMEDOUT)) { fprintf(stderr, "At line %d FUTEX_LOCK_PI should time out returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ETIMEDOUT)); tkill(child_pid, SIGKILL); exit(1); } if (trylock) { r = futex(&(shmem->f3), FUTEX_TRYLOCK_PI, 0, NULL, NULL, 0); if ((r >= 0) || (errno != EWOULDBLOCK)) { fprintf(stderr, "At line %d FUTEX_TRYLOCK_PI returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EWOULDBLOCK)); tkill(child_pid, SIGKILL); exit(1); } } shmem->child_action = 12; for (count = 0; count < 100; ++count) { r = futex(&(shmem->f3), FUTEX_LOCK_PI, 0, &ONE_sec, NULL, 0); if (r) { if ((errno == ETIMEDOUT) && (count < 99)) { /* Give the child some time to do it. */ if (nanosleep(&TEN_ms, NULL)) { fprintf(stderr, "At line %d nanosleep failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } continue; } else { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } break; } shmem->child_action = 18; wait_for_child(); r = futex(&(shmem->f3), FUTEX_WAKE, 1, NULL, NULL, 0); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE on pi-locked returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_WAKE_BITSET, 1, NULL, NULL, 1); if ((r >= 0) || ((errno != EINVAL) && (errno != ENOSYS))) { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET on pi-locked returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_UNLOCK_PI, 0, NULL, NULL, 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } shmem->child_action = 19; wait_for_child(); if (shmem->f3) { fprintf(stderr, "At line %d shmem->f3 is %d instead of zero after unlocking\n", __LINE__, shmem->f3); tkill(child_pid, SIGKILL); exit(1); } } } /* FUTEX_WAIT_BITSET and FUTEX_WAKE_BITSET are also not documented. * Looking at the kernel code, * we find that FUTEX_WAIT_BITSET does:- * If arg6 is zero, -EINVAL is returned. * If *arg1 is not equal to arg3, -EWOULDBLOCK is returned. * If arg4 is not NULL it is pointer to a timeout: if the timeout expires * before we are woken as below, -ETIMEDOUT is returned. * Otherwise wait for some other process to do FUTEX_WAKE_BITSET * on arg1 with its arg6 having some bit(s) set which were also * set in our arg6. If that happens, we return 0. * we find that FUTEX_WAIT_BITSET does:- * If arg6 is zero, -EINVAL is returned. * If some process holds a PI lock on arg1, -EINVAL is returned * (this is tested under FUTEX_LOCK_PI above). * Otherwise, wake up to arg3 processes which were waiting in * FUTEX_WAIT_BITSET for the same arg1 with their arg6 having some * bit(s) set which were also set in our arg6, and return the number * of processes awakened. * Note all this is exactly like FUTEX_WAIT and FUTEX_WAKE except for * the arg6 masking, and in fact these are implemented by the kernel as * if they were FUTEX_WAIT_BITSET and FUTEX_WAKE_BITSET with arg6 set to * all ones: thus it is possible for FUTEX_WAKE_BITSET to wake a process * which is sleeping in FUTEX_WAIT or FUTEX_WAKE to wake a process which * is sleeping in FUTEX_WAIT_BITSET. */ f1 = 0; r = futex(&f1, FUTEX_WAIT_BITSET, 0, NULL, NULL, 0); if ((r < 0) && (errno == ENOSYS)) { fprintf(stderr, "FUTEX_WAIT_BITSET not supported in this kernel\n"); /* not fatal */ } else { if (r >= 0) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET returned %d instead of EINVAL\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } else if (errno != EINVAL) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_BITSET, 0, NULL, NULL, 0); if ((r < 0) && (errno == ENOSYS)) { fprintf(stderr, "FUTEX_WAKE_BITSET not supported in this kernel\n"); /* not fatal */ } else { if (r >= 0) { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %d instead of EINVAL\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } else if (errno != EINVAL) { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(NULL, FUTEX_WAIT_BITSET, 0, NULL, NULL, 1 << 0); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(NULL, FUTEX_WAIT_BITSET_PRIVATE, 0, NULL, NULL, 1 << 1); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET_PRIVATE returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)8, FUTEX_WAIT_BITSET, 0, NULL, NULL, 1 << 2); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)8, FUTEX_WAIT_BITSET_PRIVATE, 0, NULL, NULL, 1 << 3); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET_PRIVATE returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_WAIT_BITSET, 0, NULL, NULL, 1 << 4); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_WAIT_BITSET_PRIVATE, 0, NULL, NULL, 1 << 5); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET_PRIVATE returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&f1), FUTEX_WAIT_BITSET, 0, NULL, NULL, 1 << 6); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&f1), FUTEX_WAIT_BITSET_PRIVATE, 0, NULL, NULL, 1 << 7); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET_PRIVATE returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } shmem->f3 = 0; r = futex((int *)(1 + (char *)&(shmem->f3)), FUTEX_WAIT_BITSET, 0, NULL, NULL, 1 << 8); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(4094 + (char *)&(shmem->f3)), FUTEX_WAIT_BITSET, 0, NULL, NULL, 1 << 8); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAIT_BITSET, 1, NULL, NULL, 1 << 9); if ((r >= 0) || (errno != EWOULDBLOCK)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EWOULDBLOCK)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAIT_BITSET_PRIVATE, 1, NULL, NULL, 1 << 10); if ((r >= 0) || (errno != EWOULDBLOCK)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET_PRIVATE returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EWOULDBLOCK)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_WAIT_BITSET, 2, NULL, NULL, 1 << 11); if ((r >= 0) || (errno != EWOULDBLOCK)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EWOULDBLOCK)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAIT_BITSET, 0, (struct timespec *)8, NULL, 1 << 12); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAIT_BITSET_PRIVATE, 0, (struct timespec *)8, NULL, 1 << 13); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET_PRIVATE returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_WAIT_BITSET, 0, (struct timespec *)8, NULL, 1 << 14); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAIT_BITSET, 0, (struct timespec *)upriv, NULL, 1 << 15); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAIT_BITSET_PRIVATE, 0, (struct timespec *)upriv, NULL, 1 << 16); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET_PRIVATE returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_WAIT_BITSET, 0, (struct timespec *)upriv, NULL, 1 << 17); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAIT_BITSET, 0, &TEN_ms, NULL, 1 << 19); if ((r >= 0) || (errno != ETIMEDOUT)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ETIMEDOUT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAIT_BITSET_PRIVATE, 0, &TEN_ms, NULL, 1 << 20); if ((r >= 0) || (errno != ETIMEDOUT)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET_PRIVATE returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ETIMEDOUT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_WAIT_BITSET, 0, &TEN_ms, NULL, 1 << 21); if ((r >= 0) || (errno != ETIMEDOUT)) { fprintf(stderr, "At line %d FUTEX_WAIT_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(ETIMEDOUT)); tkill(child_pid, SIGKILL); exit(1); } thread_action = 1; r = futex(&f1, FUTEX_WAIT_BITSET, 0, &ONE_sec, &f2, 1 << 22); if (r) { if (errno == ETIMEDOUT) { int ta = thread_action; /* Try without timer, may wait forever. */ r = futex(&f1, FUTEX_WAIT_BITSET, 0, NULL, &f2, 1 << 22); if (ta == 1) { fprintf(stderr, "KERNELBUG? FUTEX_WAIT_BITSET with timer returns ETIMEDOUT immediately\n"); } if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } else { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 1; r = futex(&f1, FUTEX_WAIT_BITSET, 0, &ONE_sec, NULL, 1 << 23); if (r) { if (errno == ETIMEDOUT) { r = futex(&f1, FUTEX_WAIT_BITSET, 0, NULL, NULL, 1 << 23); } else { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 1; r = futex(&f1, FUTEX_WAIT_BITSET, 0, &ONE_sec, (int *)8, 1 << 24); if (r) { if ((errno == ETIMEDOUT) && (thread_action == 1)) { r = futex(&f1, FUTEX_WAIT_BITSET, 0, NULL, (int *)8, 1 << 24); } else { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 1; r = futex(&f1, FUTEX_WAIT_BITSET, 0, &ONE_sec, (int *)upriv, 1 << 25); if (r) { if (errno == ETIMEDOUT) { r = futex(&f1, FUTEX_WAIT_BITSET, 0, NULL, (int *)upriv, 1 << 25); } else { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 2; r = futex(&f1, FUTEX_WAIT_BITSET_PRIVATE, 0, &ONE_sec, NULL, 1 << 26); if (r) { if (errno == ETIMEDOUT) { if (thread_action == 2) { fprintf(stderr, "KERNELBUG? FUTEX_WAIT_BITSET_PRIVATE with timer returns ETIMEDOUT immediately\n"); } r = futex(&f1, FUTEX_WAIT_BITSET_PRIVATE, 0, NULL, NULL, 1 << 26); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } else { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 3; r = futex(&(shmem->f3), FUTEX_WAIT_BITSET, 0, &ONE_sec, NULL, 1 << 27); if (r) { if (errno == ETIMEDOUT) { r = futex(&(shmem->f3), FUTEX_WAIT_BITSET, 0, NULL, NULL, 1 << 27); } else { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } shmem->child_action = 3; r = futex(&(shmem->f3), FUTEX_WAIT_BITSET, 0, &ONE_sec, NULL, 1 << 28); if (r) { if (errno == ETIMEDOUT) { /* Give the thread some time to do it. */ r = futex(&(shmem->f3), FUTEX_WAIT_BITSET, 0, NULL, NULL, 1 << 28); } else { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } } r = futex(NULL, FUTEX_WAKE_BITSET, 0, NULL, NULL, 1 << 29); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex(NULL, FUTEX_WAKE_BITSET_PRIVATE, 0, NULL, NULL, 1 << 30); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)8, FUTEX_WAKE_BITSET, 0, NULL, NULL, 1 << 31); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)8, FUTEX_WAKE_BITSET_PRIVATE, 0, NULL, NULL, 3 << 0); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_WAKE_BITSET, 0, NULL, NULL, 3 << 1); if ((r >= 0) || (errno != EFAULT)) { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EFAULT)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)upriv, FUTEX_WAKE_BITSET_PRIVATE, 0, NULL, NULL, 3 << 2); if (r) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&f1), FUTEX_WAKE_BITSET, 0, NULL, NULL, 3 << 3); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&f1), FUTEX_WAKE_BITSET_PRIVATE, 0, NULL, NULL, 3 << 4); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET_PRIVATE returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&(shmem->f3)), FUTEX_WAKE_BITSET, 0, NULL, NULL, 3 << 5); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(1 + (char *)&(shmem->f3)), FUTEX_WAKE_BITSET_PRIVATE, 0, NULL, NULL, 3 << 6); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET_PRIVATE returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(4094 + (char *)&(shmem->f3)), FUTEX_WAKE_BITSET, 0, NULL, NULL, 3 << 5); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex((int *)(4094 + (char *)&(shmem->f3)), FUTEX_WAKE_BITSET_PRIVATE, 0, NULL, NULL, 3 << 6); if ((r >= 0) || (errno != EINVAL)) { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET_PRIVATE returned %s instead of %s\n", __LINE__, strerror(errno), strerror(EINVAL)); tkill(child_pid, SIGKILL); exit(1); } r = futex(&f1, FUTEX_WAKE_BITSET, 3, (struct timespec *)upriv, (int *)upriv, 3 << 7); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %d when no processes to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f1, FUTEX_WAKE_BITSET_PRIVATE, 3, (struct timespec *)upriv, (int *)upriv, 3 << 8); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET_PRIVATE returned %d when no processes to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f3), FUTEX_WAKE_BITSET, 3, (struct timespec *)upriv, (int *)upriv, 3 << 9); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %d when no processes to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 4; wait_for_thread(); r = futex(&f1, FUTEX_WAKE_BITSET, 3, (struct timespec *)upriv, (int *)upriv, 3 << 10); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %d when 1 process to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 5; wait_for_thread(); r = futex(&f1, FUTEX_WAKE_BITSET_PRIVATE, 3, (struct timespec *)upriv, (int *)upriv, 3 << 11); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET_PRIVATE returned %d when 1 process to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_WAKE_BITSET, 3, (struct timespec *)upriv, (int *)upriv, 3 << 12); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %d when 1 process to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_WAKE_BITSET, 3, (struct timespec *)upriv, (int *)upriv, 3 << 13); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %d when 1 process to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_WAKE_BITSET, 3, (struct timespec *)upriv, (int *)upriv, 3 << 14); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %d when 2 processes to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 6; wait_for_thread(); shmem->child_action = 6; wait_for_child(); r = futex(&(shmem->f3), FUTEX_WAKE_BITSET, 1, (struct timespec *)upriv, (int *)upriv, 3 << 15); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %d when only waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f3), FUTEX_WAKE_BITSET, 0, (struct timespec *)upriv, (int *)upriv, 3 << 16); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %d when only waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 13; wait_for_thread(); r = futex(&f1, FUTEX_WAKE_BITSET, 3, NULL, NULL, 0xFFFFFFFC); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %d when waking no process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f1, FUTEX_WAKE_BITSET, 3, NULL, NULL, 0x6); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %d when only waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 14; wait_for_thread(); r = futex(&f1, FUTEX_WAKE_BITSET_PRIVATE, 3, NULL, NULL, 0xFFFFFFC0); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET_PRIVATE returned %d when waking no process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&f1, FUTEX_WAKE_BITSET_PRIVATE, 3, NULL, NULL, 0x1F); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET_PRIVATE returned %d when only waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 15; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_WAKE_BITSET, 3, NULL, NULL, 0xFFFFFC00); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %d when waking no process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f3), FUTEX_WAKE_BITSET, 3, NULL, NULL, 0xFFFFFD00); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %d when only waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 15; wait_for_thread(); shmem->child_action = 15; wait_for_child(); r = futex(&(shmem->f3), FUTEX_WAKE_BITSET, 3, NULL, NULL, 0xFFFFFC00); if (r) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %d when waking no process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } r = futex(&(shmem->f3), FUTEX_WAKE_BITSET, 3, NULL, NULL, 0xFFFFFD00); if (r != 2) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %d when 2 processes to wake\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } thread_action = 15; wait_for_thread(); shmem->child_action = 16; wait_for_child(); r = futex(&(shmem->f3), FUTEX_WAKE_BITSET, 3, NULL, NULL, 0x300); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %d when only waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } if (shmem->child_action) { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET woke wrong process\n", __LINE__); tkill(child_pid, SIGKILL); exit(1); } thread_action = 15; wait_for_thread(); r = futex(&(shmem->f3), FUTEX_WAKE_BITSET, 3, NULL, NULL, 0x3000); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %d only waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } if (nanosleep(&TEN_ms, NULL)) { fprintf(stderr, "At line %d nanosleep failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } if (shmem->child_action != 17) { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET woke wrong process\n", __LINE__); tkill(child_pid, SIGKILL); exit(1); } r = futex(&(shmem->f3), FUTEX_WAKE_BITSET, 3, NULL, NULL, 0x300); if (r != 1) { if (r < 0) { fprintf(stderr, "At line %d futex failed %s\n", __LINE__, strerror(errno)); tkill(child_pid, SIGKILL); exit(1); } else { fprintf(stderr, "At line %d FUTEX_WAKE_BITSET returned %d only waking one process\n", __LINE__, r); tkill(child_pid, SIGKILL); exit(1); } } } } fprintf(stdout, "Test succeeded\n"); exit(0); }
| |