diff options
Diffstat (limited to 'src/VBox/Runtime/testcase')
106 files changed, 3558 insertions, 2212 deletions
diff --git a/src/VBox/Runtime/testcase/Makefile.kmk b/src/VBox/Runtime/testcase/Makefile.kmk index 212d9022..3ceb9f04 100644 --- a/src/VBox/Runtime/testcase/Makefile.kmk +++ b/src/VBox/Runtime/testcase/Makefile.kmk @@ -4,7 +4,7 @@ # # -# Copyright (C) 2006-2012 Oracle Corporation +# Copyright (C) 2006-2013 Oracle Corporation # # This file is part of VirtualBox Open Source Edition (OSE), as # available from http://www.virtualbox.org. This file is free software; @@ -50,6 +50,7 @@ PROGRAMS += \ tstRTBitOperations \ tstRTCidr \ tstRTCritSect \ + tstRTCritSectRw \ tstRTCType \ tstRTDigest \ tstDir \ @@ -62,6 +63,7 @@ PROGRAMS += \ tstRTFileAio \ tstRTFileAppend-1 \ tstRTFileGetSize-1 \ + tstRTFileModeStringToFlags \ tstFileLock \ tstFork \ tstRTFsQueries \ @@ -85,7 +87,7 @@ PROGRAMS += \ tstRTMemPool \ tstRTMemWipe \ tstMove \ - tstMp-1 \ + tstRTMp-1 \ tstOnce \ tstRTPath \ tstRTPipe \ @@ -120,7 +122,7 @@ PROGRAMS += \ tstThread-1 \ tstRTThreadPoke \ tstRTThreadExecutionTime \ - tstTime \ + tstRTTime \ tstTime-2 \ tstTime-3 \ tstTime-4 \ @@ -135,8 +137,9 @@ PROGRAMS += \ tstVector PROGRAMS.win += \ - tstRTProcWait \ tstRTCritSectW32 \ + tstRTLocalIpc \ + tstRTProcWait \ tstFileAppendWin-1 \ ntGetTimerResolution PROGRAMS.linux += \ @@ -147,13 +150,12 @@ PROGRAMS.linux += \ tstRTInlineAsmPIC3 PROGRAMS.solaris += \ tstRTCoreDump -PROGRAMS.l4 += \ - tstIoCtl PROGRAMS.darwin += \ tstDarwinSched \ tstRTDarwinMachKernel ifdef VBOX_WITH_LIBCURL PROGRAMS += \ + tstRTHttp \ tstRTS3 endif if1of ($(KBUILD_TARGET_ARCH), amd64 x86) @@ -215,6 +217,9 @@ tstRTCidr_SOURCES = tstRTCidr.cpp tstRTCritSect_TEMPLATE = VBOXR3TSTEXE tstRTCritSect_SOURCES = tstRTCritSect.cpp +tstRTCritSectRw_TEMPLATE = VBOXR3TSTEXE +tstRTCritSectRw_SOURCES = tstRTCritSectRw.cpp + tstRTCritSectW32_TEMPLATE = VBOXR3TSTEXE tstRTCritSectW32_SOURCES = tstRTCritSect.cpp tstRTCritSectW32_DEFS = TRY_WIN32_CRIT @@ -224,6 +229,12 @@ tstRTCType_SOURCES = tstRTCType.cpp tstRTDigest_SOURCES = tstRTDigest.cpp +ifdef VBOX_WITH_LIBCURL +tstRTHttp_TEMPLATE = VBOXR3TSTEXE +tstRTHttp_SOURCES = tstRTHttp.cpp +tstRTHttp_SDKS = VBOX_LIBCURL +endif + tstDir_TEMPLATE = VBOXR3TSTEXE tstDir_SOURCES = tstDir.cpp @@ -255,6 +266,9 @@ tstRTFileAppend-1_SOURCES = tstRTFileAppend-1.cpp tstRTFileGetSize-1_TEMPLATE = VBOXR3TSTEXE tstRTFileGetSize-1_SOURCES = tstRTFileGetSize-1.cpp +tstRTFileModeStringToFlags_TEMPLATE = VBOXR3TSTEXE +tstRTFileModeStringToFlags_SOURCES = tstRTFileModeStringToFlags.cpp + tstFileAppendWin-1_TEMPLATE = VBOXR3TSTEXE tstFileAppendWin-1_SOURCES = tstFileAppendWin-1.cpp @@ -284,9 +298,6 @@ tstRTHeapOffset_SOURCES = tstRTHeapOffset.cpp tstRTHeapSimple_TEMPLATE = VBOXR3TSTEXE tstRTHeapSimple_SOURCES = tstRTHeapSimple.cpp -tstIoCtl_TEMPLATE = VBOXR3TSTEXE -tstIoCtl_SOURCES = tstIoCtl.cpp - tstRTInlineAsm_TEMPLATE = VBOXR3TSTEXE tstRTInlineAsm_SOURCES = tstRTInlineAsm.cpp @@ -393,6 +404,9 @@ tstLdrLoad_SOURCES = tstLdrLoad.cpp tstRTList_TEMPLATE = VBOXR3TSTEXE tstRTList_SOURCES = tstRTList.cpp +tstRTLocalIpc_TEMPLATE = VBOXR3TSTEXE +tstRTLocalIpc_SOURCES = tstRTLocalIpc.cpp + tstRTLockValidator_TEMPLATE = VBOXR3TSTEXE tstRTLockValidator_SOURCES = tstRTLockValidator.cpp @@ -417,8 +431,8 @@ tstRTMemWipe_SOURCES = tstRTMemWipe.cpp tstMove_TEMPLATE = VBOXR3TSTEXE tstMove_SOURCES = tstMove.cpp -tstMp-1_TEMPLATE = VBOXR3TSTEXE -tstMp-1_SOURCES = tstMp-1.cpp +tstRTMp-1_TEMPLATE = VBOXR3TSTEXE +tstRTMp-1_SOURCES = tstRTMp-1.cpp tstNoCrt-1_TEMPLATE = VBOXR3TSTEXE tstNoCrt-1_DEFS = RT_WITHOUT_NOCRT_WRAPPER_ALIASES @@ -546,8 +560,8 @@ tstRTThreadPoke_SOURCES = tstRTThreadPoke.cpp tstRTThreadExecutionTime_TEMPLATE = VBOXR3TSTEXE tstRTThreadExecutionTime_SOURCES = tstRTThreadExecutionTime.cpp -tstTime_TEMPLATE = VBOXR3TSTEXE -tstTime_SOURCES = tstTime.cpp +tstRTTime_TEMPLATE = VBOXR3TSTEXE +tstRTTime_SOURCES = tstRTTime.cpp tstTime-2_TEMPLATE = VBOXR3TSTEXE tstTime-2_SOURCES = tstTime-2.cpp diff --git a/src/VBox/Runtime/testcase/ioctl.h b/src/VBox/Runtime/testcase/ioctl.h deleted file mode 100644 index f9a5273e..00000000 --- a/src/VBox/Runtime/testcase/ioctl.h +++ /dev/null @@ -1,48 +0,0 @@ -/* $Id: ioctl.h $ */ -/** @file - * VBox L4/OSS audio - header for Linux IoCtls. - */ - -/* - * Copyright (C) 2006-2007 Oracle Corporation - * - * This file is part of VirtualBox Open Source Edition (OSE), as - * available from http://www.virtualbox.org. This file is free software; - * you can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) as published by the Free Software - * Foundation, in version 2 as it comes in the "COPYING" file of the - * VirtualBox OSE distribution. VirtualBox OSE is distributed in the - * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. - * - * The contents of this file may alternatively be used under the terms - * of the Common Development and Distribution License Version 1.0 - * (CDDL) only, as it comes in the "COPYING.CDDL" file of the - * VirtualBox OSE distribution, in which case the provisions of the - * CDDL are applicable instead of those of the GPL. - * - * You may elect to license modified versions of this file under the - * terms and conditions of either the GPL or the CDDL or both. - */ - -#ifndef ___VBOX_L4_OSS_IOCTL -#define ___VBOX_L4_OSS_IOCTL - -#define IOCPARM_MASK 0x3fff /* parameters must be < 16383 bytes */ -#define IOC_VOID 0U << 30 /* no parameters */ -#define IOC_IN 1U << 30 /* copy out parameters */ -#define IOC_OUT 2U << 30 /* copy in parameters */ -#define IOC_INOUT (IOC_IN|IOC_OUT) -/* the 0x20000000 is so we can distinguish new ioctl's from old */ -#define _IO(x,y) ((int)(IOC_VOID|(x<<8)|y)) -#define _IOR(x,y,t) ((int)(IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)) -#define _IOW(x,y,t) ((int)(IOC_IN|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)) -/* this should be _IORW, but stdio got there first */ -#define _IOWR(x,y,t) ((int)(IOC_INOUT|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)) -#define _IOC_SIZE(x) ((x>>16)&IOCPARM_MASK) -#define _IOC_DIR(x) (x & 0xf0000000) -#define _IOC_NONE IOC_VOID -#define _IOC_READ IOC_OUT -#define _IOC_WRITE IOC_IN - -#endif /* !___VBOX_L4_OSS_IOCTL */ - diff --git a/src/VBox/Runtime/testcase/ntGetTimerResolution.cpp b/src/VBox/Runtime/testcase/ntGetTimerResolution.cpp index 7e12327c..96ccfa63 100644 --- a/src/VBox/Runtime/testcase/ntGetTimerResolution.cpp +++ b/src/VBox/Runtime/testcase/ntGetTimerResolution.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/soundcard.h b/src/VBox/Runtime/testcase/soundcard.h deleted file mode 100644 index b3fda91a..00000000 --- a/src/VBox/Runtime/testcase/soundcard.h +++ /dev/null @@ -1,1300 +0,0 @@ -#ifndef SOUNDCARD_H -#define SOUNDCARD_H -/* - * Copyright by Hannu Savolainen 1993-1997 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. 2. - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* Minor modification for L4VM */ - - -/* - * OSS interface version. With versions earlier than 3.6 this value is - * an integer with value less than 361. In versions 3.6 and later - * it's a six digit hexadecimal value. For example value - * of 0x030600 represents OSS version 3.6.0. - * Use ioctl(fd, OSS_GETVERSION, &int) to get the version number of - * the currently active driver. - */ -#define SOUND_VERSION 0x030802 -#define OPEN_SOUND_SYSTEM - -/* In Linux we need to be prepared for cross compiling */ -/* Our own local version of linux/ioctl.h. */ -#include "ioctl.h" - -/* - * Supported card ID numbers (Should be somewhere else?) - */ - -#define SNDCARD_ADLIB 1 -#define SNDCARD_SB 2 -#define SNDCARD_PAS 3 -#define SNDCARD_GUS 4 -#define SNDCARD_MPU401 5 -#define SNDCARD_SB16 6 -#define SNDCARD_SB16MIDI 7 -#define SNDCARD_UART6850 8 -#define SNDCARD_GUS16 9 -#define SNDCARD_MSS 10 -#define SNDCARD_PSS 11 -#define SNDCARD_SSCAPE 12 -#define SNDCARD_PSS_MPU 13 -#define SNDCARD_PSS_MSS 14 -#define SNDCARD_SSCAPE_MSS 15 -#define SNDCARD_TRXPRO 16 -#define SNDCARD_TRXPRO_SB 17 -#define SNDCARD_TRXPRO_MPU 18 -#define SNDCARD_MAD16 19 -#define SNDCARD_MAD16_MPU 20 -#define SNDCARD_CS4232 21 -#define SNDCARD_CS4232_MPU 22 -#define SNDCARD_MAUI 23 -#define SNDCARD_PSEUDO_MSS 24 -#define SNDCARD_GUSPNP 25 -#define SNDCARD_UART401 26 -/* Sound card numbers 27 to N are reserved. Don't add more numbers here. */ - -/*********************************** - * IOCTL Commands for /dev/sequencer - */ - -#ifndef _SIOWR -#if defined(_IOWR) && (defined(_AIX) || (!defined(sun) && !defined(sparc) && !defined(__sparc__) && !defined(__INCioctlh) && !defined(__Lynx__))) -/* Use already defined ioctl defines if they exist (except with Sun or Sparc) */ -#define SIOCPARM_MASK IOCPARM_MASK -#define SIOC_VOID IOC_VOID -#define SIOC_OUT IOC_OUT -#define SIOC_IN IOC_IN -#define SIOC_INOUT IOC_INOUT -#define _SIOC_SIZE _IOC_SIZE -#define _SIOC_DIR _IOC_DIR -#define _SIOC_NONE _IOC_NONE -#define _SIOC_READ _IOC_READ -#define _SIOC_WRITE _IOC_WRITE -#define _SIO _IO -#define _SIOR _IOR -#define _SIOW _IOW -#define _SIOWR _IOWR -#else - -/* Ioctl's have the command encoded in the lower word, - * and the size of any in or out parameters in the upper - * word. The high 2 bits of the upper word are used - * to encode the in/out status of the parameter; for now - * we restrict parameters to at most 8191 bytes. - */ -/* #define SIOCTYPE (0xff<<8) */ -#define SIOCPARM_MASK 0x1fff /* parameters must be < 8192 bytes */ -#define SIOC_VOID 0x00000000 /* no parameters */ -#define SIOC_OUT 0x20000000 /* copy out parameters */ -#define SIOC_IN 0x40000000 /* copy in parameters */ -#define SIOC_INOUT (SIOC_IN|SIOC_OUT) -/* the 0x20000000 is so we can distinguish new ioctl's from old */ -#define _SIO(x,y) ((int)(SIOC_VOID|(x<<8)|y)) -#define _SIOR(x,y,t) ((int)(SIOC_OUT|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y)) -#define _SIOW(x,y,t) ((int)(SIOC_IN|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y)) -/* this should be _SIORW, but stdio got there first */ -#define _SIOWR(x,y,t) ((int)(SIOC_INOUT|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y)) -#define _SIOC_SIZE(x) ((x>>16)&SIOCPARM_MASK) -#define _SIOC_DIR(x) (x & 0xf0000000) -#define _SIOC_NONE SIOC_VOID -#define _SIOC_READ SIOC_OUT -#define _SIOC_WRITE SIOC_IN -# endif /* _IOWR */ -#endif /* !_SIOWR */ - -#define SNDCTL_SEQ_RESET _SIO ('Q', 0) -#define SNDCTL_SEQ_SYNC _SIO ('Q', 1) -#define SNDCTL_SYNTH_INFO _SIOWR('Q', 2, struct synth_info) -#define SNDCTL_SEQ_CTRLRATE _SIOWR('Q', 3, int) /* Set/get timer resolution (HZ) */ -#define SNDCTL_SEQ_GETOUTCOUNT _SIOR ('Q', 4, int) -#define SNDCTL_SEQ_GETINCOUNT _SIOR ('Q', 5, int) -#define SNDCTL_SEQ_PERCMODE _SIOW ('Q', 6, int) -#define SNDCTL_FM_LOAD_INSTR _SIOW ('Q', 7, struct sbi_instrument) /* Obsolete. Don't use!!!!!! */ -#define SNDCTL_SEQ_TESTMIDI _SIOW ('Q', 8, int) -#define SNDCTL_SEQ_RESETSAMPLES _SIOW ('Q', 9, int) -#define SNDCTL_SEQ_NRSYNTHS _SIOR ('Q',10, int) -#define SNDCTL_SEQ_NRMIDIS _SIOR ('Q',11, int) -#define SNDCTL_MIDI_INFO _SIOWR('Q',12, struct midi_info) -#define SNDCTL_SEQ_THRESHOLD _SIOW ('Q',13, int) -#define SNDCTL_SYNTH_MEMAVL _SIOWR('Q',14, int) /* in=dev#, out=memsize */ -#define SNDCTL_FM_4OP_ENABLE _SIOW ('Q',15, int) /* in=dev# */ -#define SNDCTL_SEQ_PANIC _SIO ('Q',17) -#define SNDCTL_SEQ_OUTOFBAND _SIOW ('Q',18, struct seq_event_rec) -#define SNDCTL_SEQ_GETTIME _SIOR ('Q',19, int) -#define SNDCTL_SYNTH_ID _SIOWR('Q',20, struct synth_info) -#define SNDCTL_SYNTH_CONTROL _SIOWR('Q',21, struct synth_control) -#define SNDCTL_SYNTH_REMOVESAMPLE _SIOWR('Q',22, struct remove_sample) - -typedef struct synth_control -{ - int devno; /* Synthesizer # */ - char data[4000]; /* Device specific command/data record */ -}synth_control; - -typedef struct remove_sample -{ - int devno; /* Synthesizer # */ - int bankno; /* MIDI bank # (0=General MIDI) */ - int instrno; /* MIDI instrument number */ -} remove_sample; - -typedef struct seq_event_rec { - unsigned char arr[8]; -} seq_event_rec; - -#define SNDCTL_TMR_TIMEBASE _SIOWR('T', 1, int) -#define SNDCTL_TMR_START _SIO ('T', 2) -#define SNDCTL_TMR_STOP _SIO ('T', 3) -#define SNDCTL_TMR_CONTINUE _SIO ('T', 4) -#define SNDCTL_TMR_TEMPO _SIOWR('T', 5, int) -#define SNDCTL_TMR_SOURCE _SIOWR('T', 6, int) -# define TMR_INTERNAL 0x00000001 -# define TMR_EXTERNAL 0x00000002 -# define TMR_MODE_MIDI 0x00000010 -# define TMR_MODE_FSK 0x00000020 -# define TMR_MODE_CLS 0x00000040 -# define TMR_MODE_SMPTE 0x00000080 -#define SNDCTL_TMR_METRONOME _SIOW ('T', 7, int) -#define SNDCTL_TMR_SELECT _SIOW ('T', 8, int) - -/* - * Some big endian/little endian handling macros - */ - -#if defined(_AIX) || defined(AIX) || defined(sparc) || defined(__sparc__) || defined(HPPA) || defined(PPC) || defined(__powerpc64__) || defined(__mc68000__) -/* Big endian machines */ -# define _PATCHKEY(id) (0xfd00|id) -# define AFMT_S16_NE AFMT_S16_BE -#else -# define _PATCHKEY(id) ((id<<8)|0xfd) -# define AFMT_S16_NE AFMT_S16_LE -#endif - -/* - * Sample loading mechanism for internal synthesizers (/dev/sequencer) - * The following patch_info structure has been designed to support - * Gravis UltraSound. It tries to be universal format for uploading - * sample based patches but is probably too limited. - * - * (PBD) As Hannu guessed, the GUS structure is too limited for - * the WaveFront, but this is the right place for a constant definition. - */ - -struct patch_info { - unsigned short key; /* Use WAVE_PATCH here */ -#define WAVE_PATCH _PATCHKEY(0x04) -#define GUS_PATCH WAVE_PATCH -#define WAVEFRONT_PATCH _PATCHKEY(0x06) - - short device_no; /* Synthesizer number */ - short instr_no; /* Midi pgm# */ - - unsigned int mode; -/* - * The least significant byte has the same format than the GUS .PAT - * files - */ -#define WAVE_16_BITS 0x01 /* bit 0 = 8 or 16 bit wave data. */ -#define WAVE_UNSIGNED 0x02 /* bit 1 = Signed - Unsigned data. */ -#define WAVE_LOOPING 0x04 /* bit 2 = looping enabled-1. */ -#define WAVE_BIDIR_LOOP 0x08 /* bit 3 = Set is bidirectional looping. */ -#define WAVE_LOOP_BACK 0x10 /* bit 4 = Set is looping backward. */ -#define WAVE_SUSTAIN_ON 0x20 /* bit 5 = Turn sustaining on. (Env. pts. 3)*/ -#define WAVE_ENVELOPES 0x40 /* bit 6 = Enable envelopes - 1 */ -#define WAVE_FAST_RELEASE 0x80 /* bit 7 = Shut off immediately after note off */ - /* (use the env_rate/env_offs fields). */ -/* Linux specific bits */ -#define WAVE_VIBRATO 0x00010000 /* The vibrato info is valid */ -#define WAVE_TREMOLO 0x00020000 /* The tremolo info is valid */ -#define WAVE_SCALE 0x00040000 /* The scaling info is valid */ -#define WAVE_FRACTIONS 0x00080000 /* Fraction information is valid */ -/* Reserved bits */ -#define WAVE_ROM 0x40000000 /* For future use */ -#define WAVE_MULAW 0x20000000 /* For future use */ -/* Other bits must be zeroed */ - - int len; /* Size of the wave data in bytes */ - int loop_start, loop_end; /* Byte offsets from the beginning */ - -/* - * The base_freq and base_note fields are used when computing the - * playback speed for a note. The base_note defines the tone frequency - * which is heard if the sample is played using the base_freq as the - * playback speed. - * - * The low_note and high_note fields define the minimum and maximum note - * frequencies for which this sample is valid. It is possible to define - * more than one samples for an instrument number at the same time. The - * low_note and high_note fields are used to select the most suitable one. - * - * The fields base_note, high_note and low_note should contain - * the note frequency multiplied by 1000. For example value for the - * middle A is 440*1000. - */ - - unsigned int base_freq; - unsigned int base_note; - unsigned int high_note; - unsigned int low_note; - int panning; /* -128=left, 127=right */ - int detuning; - -/* New fields introduced in version 1.99.5 */ - - /* Envelope. Enabled by mode bit WAVE_ENVELOPES */ - unsigned char env_rate[ 6 ]; /* GUS HW ramping rate */ - unsigned char env_offset[ 6 ]; /* 255 == 100% */ - - /* - * The tremolo, vibrato and scale info are not supported yet. - * Enable by setting the mode bits WAVE_TREMOLO, WAVE_VIBRATO or - * WAVE_SCALE - */ - - unsigned char tremolo_sweep; - unsigned char tremolo_rate; - unsigned char tremolo_depth; - - unsigned char vibrato_sweep; - unsigned char vibrato_rate; - unsigned char vibrato_depth; - - int scale_frequency; - unsigned int scale_factor; /* from 0 to 2048 or 0 to 2 */ - - int volume; - int fractions; - int reserved1; - int spare[2]; - char data[1]; /* The waveform data starts here */ - }; - -struct sysex_info { - short key; /* Use SYSEX_PATCH or MAUI_PATCH here */ -#define SYSEX_PATCH _PATCHKEY(0x05) -#define MAUI_PATCH _PATCHKEY(0x06) - short device_no; /* Synthesizer number */ - int len; /* Size of the sysex data in bytes */ - unsigned char data[1]; /* Sysex data starts here */ - }; - -/* - * /dev/sequencer input events. - * - * The data written to the /dev/sequencer is a stream of events. Events - * are records of 4 or 8 bytes. The first byte defines the size. - * Any number of events can be written with a write call. There - * is a set of macros for sending these events. Use these macros if you - * want to maximize portability of your program. - * - * Events SEQ_WAIT, SEQ_MIDIPUTC and SEQ_ECHO. Are also input events. - * (All input events are currently 4 bytes long. Be prepared to support - * 8 byte events also. If you receive any event having first byte >= 128, - * it's a 8 byte event. - * - * The events are documented at the end of this file. - * - * Normal events (4 bytes) - * There is also a 8 byte version of most of the 4 byte events. The - * 8 byte one is recommended. - */ -#define SEQ_NOTEOFF 0 -#define SEQ_FMNOTEOFF SEQ_NOTEOFF /* Just old name */ -#define SEQ_NOTEON 1 -#define SEQ_FMNOTEON SEQ_NOTEON -#define SEQ_WAIT TMR_WAIT_ABS -#define SEQ_PGMCHANGE 3 -#define SEQ_FMPGMCHANGE SEQ_PGMCHANGE -#define SEQ_SYNCTIMER TMR_START -#define SEQ_MIDIPUTC 5 -#define SEQ_DRUMON 6 /*** OBSOLETE ***/ -#define SEQ_DRUMOFF 7 /*** OBSOLETE ***/ -#define SEQ_ECHO TMR_ECHO /* For syncing programs with output */ -#define SEQ_AFTERTOUCH 9 -#define SEQ_CONTROLLER 10 - -/******************************************* - * Midi controller numbers - ******************************************* - * Controllers 0 to 31 (0x00 to 0x1f) and - * 32 to 63 (0x20 to 0x3f) are continuous - * controllers. - * In the MIDI 1.0 these controllers are sent using - * two messages. Controller numbers 0 to 31 are used - * to send the MSB and the controller numbers 32 to 63 - * are for the LSB. Note that just 7 bits are used in MIDI bytes. - */ - -#define CTL_BANK_SELECT 0x00 -#define CTL_MODWHEEL 0x01 -#define CTL_BREATH 0x02 -/* undefined 0x03 */ -#define CTL_FOOT 0x04 -#define CTL_PORTAMENTO_TIME 0x05 -#define CTL_DATA_ENTRY 0x06 -#define CTL_MAIN_VOLUME 0x07 -#define CTL_BALANCE 0x08 -/* undefined 0x09 */ -#define CTL_PAN 0x0a -#define CTL_EXPRESSION 0x0b -/* undefined 0x0c */ -/* undefined 0x0d */ -/* undefined 0x0e */ -/* undefined 0x0f */ -#define CTL_GENERAL_PURPOSE1 0x10 -#define CTL_GENERAL_PURPOSE2 0x11 -#define CTL_GENERAL_PURPOSE3 0x12 -#define CTL_GENERAL_PURPOSE4 0x13 -/* undefined 0x14 - 0x1f */ - -/* undefined 0x20 */ -/* The controller numbers 0x21 to 0x3f are reserved for the */ -/* least significant bytes of the controllers 0x00 to 0x1f. */ -/* These controllers are not recognised by the driver. */ - -/* Controllers 64 to 69 (0x40 to 0x45) are on/off switches. */ -/* 0=OFF and 127=ON (intermediate values are possible) */ -#define CTL_DAMPER_PEDAL 0x40 -#define CTL_SUSTAIN 0x40 /* Alias */ -#define CTL_HOLD 0x40 /* Alias */ -#define CTL_PORTAMENTO 0x41 -#define CTL_SOSTENUTO 0x42 -#define CTL_SOFT_PEDAL 0x43 -/* undefined 0x44 */ -#define CTL_HOLD2 0x45 -/* undefined 0x46 - 0x4f */ - -#define CTL_GENERAL_PURPOSE5 0x50 -#define CTL_GENERAL_PURPOSE6 0x51 -#define CTL_GENERAL_PURPOSE7 0x52 -#define CTL_GENERAL_PURPOSE8 0x53 -/* undefined 0x54 - 0x5a */ -#define CTL_EXT_EFF_DEPTH 0x5b -#define CTL_TREMOLO_DEPTH 0x5c -#define CTL_CHORUS_DEPTH 0x5d -#define CTL_DETUNE_DEPTH 0x5e -#define CTL_CELESTE_DEPTH 0x5e /* Alias for the above one */ -#define CTL_PHASER_DEPTH 0x5f -#define CTL_DATA_INCREMENT 0x60 -#define CTL_DATA_DECREMENT 0x61 -#define CTL_NONREG_PARM_NUM_LSB 0x62 -#define CTL_NONREG_PARM_NUM_MSB 0x63 -#define CTL_REGIST_PARM_NUM_LSB 0x64 -#define CTL_REGIST_PARM_NUM_MSB 0x65 -/* undefined 0x66 - 0x78 */ -/* reserved 0x79 - 0x7f */ - -/* Pseudo controllers (not midi compatible) */ -#define CTRL_PITCH_BENDER 255 -#define CTRL_PITCH_BENDER_RANGE 254 -#define CTRL_EXPRESSION 253 /* Obsolete */ -#define CTRL_MAIN_VOLUME 252 /* Obsolete */ -#define SEQ_BALANCE 11 -#define SEQ_VOLMODE 12 - -/* - * Volume mode decides how volumes are used - */ - -#define VOL_METHOD_ADAGIO 1 -#define VOL_METHOD_LINEAR 2 - -/* - * Note! SEQ_WAIT, SEQ_MIDIPUTC and SEQ_ECHO are used also as - * input events. - */ - -/* - * Event codes 0xf0 to 0xfc are reserved for future extensions. - */ - -#define SEQ_FULLSIZE 0xfd /* Long events */ -/* - * SEQ_FULLSIZE events are used for loading patches/samples to the - * synthesizer devices. These events are passed directly to the driver - * of the associated synthesizer device. There is no limit to the size - * of the extended events. These events are not queued but executed - * immediately when the write() is called (execution can take several - * seconds of time). - * - * When a SEQ_FULLSIZE message is written to the device, it must - * be written using exactly one write() call. Other events cannot - * be mixed to the same write. - * - * For FM synths (YM3812/OPL3) use struct sbi_instrument and write it to the - * /dev/sequencer. Don't write other data together with the instrument structure - * Set the key field of the structure to FM_PATCH. The device field is used to - * route the patch to the corresponding device. - * - * For wave table use struct patch_info. Initialize the key field - * to WAVE_PATCH. - */ -#define SEQ_PRIVATE 0xfe /* Low level HW dependent events (8 bytes) */ -#define SEQ_EXTENDED 0xff /* Extended events (8 bytes) OBSOLETE */ - -/* - * Record for FM patches - */ - -typedef unsigned char sbi_instr_data[32]; - -struct sbi_instrument { - unsigned short key; /* FM_PATCH or OPL3_PATCH */ -#define FM_PATCH _PATCHKEY(0x01) -#define OPL3_PATCH _PATCHKEY(0x03) - short device; /* Synth# (0-4) */ - int channel; /* Program# to be initialized */ - sbi_instr_data operators; /* Register settings for operator cells (.SBI format) */ - }; - -struct synth_info { /* Read only */ - char name[30]; - int device; /* 0-N. INITIALIZE BEFORE CALLING */ - int synth_type; -#define SYNTH_TYPE_FM 0 -#define SYNTH_TYPE_SAMPLE 1 -#define SYNTH_TYPE_MIDI 2 /* Midi interface */ - - int synth_subtype; -#define FM_TYPE_ADLIB 0x00 -#define FM_TYPE_OPL3 0x01 -#define MIDI_TYPE_MPU401 0x401 - -#define SAMPLE_TYPE_BASIC 0x10 -#define SAMPLE_TYPE_GUS SAMPLE_TYPE_BASIC -#define SAMPLE_TYPE_WAVEFRONT 0x11 - - int perc_mode; /* No longer supported */ - int nr_voices; - int nr_drums; /* Obsolete field */ - int instr_bank_size; - unsigned int capabilities; -#define SYNTH_CAP_PERCMODE 0x00000001 /* No longer used */ -#define SYNTH_CAP_OPL3 0x00000002 /* Set if OPL3 supported */ -#define SYNTH_CAP_INPUT 0x00000004 /* Input (MIDI) device */ - int dummies[19]; /* Reserve space */ - }; - -struct sound_timer_info { - char name[32]; - int caps; - }; - -#define MIDI_CAP_MPU401 1 /* MPU-401 intelligent mode */ - -struct midi_info { - char name[30]; - int device; /* 0-N. INITIALIZE BEFORE CALLING */ - unsigned int capabilities; /* To be defined later */ - int dev_type; - int dummies[18]; /* Reserve space */ - }; - -/******************************************** - * ioctl commands for the /dev/midi## - */ -typedef struct { - unsigned char cmd; - char nr_args, nr_returns; - unsigned char data[30]; - } mpu_command_rec; - -#define SNDCTL_MIDI_PRETIME _SIOWR('m', 0, int) -#define SNDCTL_MIDI_MPUMODE _SIOWR('m', 1, int) -#define SNDCTL_MIDI_MPUCMD _SIOWR('m', 2, mpu_command_rec) - -/******************************************** - * IOCTL commands for /dev/dsp and /dev/audio - */ - -#define SNDCTL_DSP_RESET _SIO ('P', 0) -#define SNDCTL_DSP_SYNC _SIO ('P', 1) -#define SNDCTL_DSP_SPEED _SIOWR('P', 2, int) -#define SNDCTL_DSP_STEREO _SIOWR('P', 3, int) -#define SNDCTL_DSP_GETBLKSIZE _SIOWR('P', 4, int) -#define SNDCTL_DSP_SAMPLESIZE SNDCTL_DSP_SETFMT -#define SNDCTL_DSP_CHANNELS _SIOWR('P', 6, int) -#define SOUND_PCM_WRITE_CHANNELS SNDCTL_DSP_CHANNELS -#define SOUND_PCM_WRITE_FILTER _SIOWR('P', 7, int) -#define SNDCTL_DSP_POST _SIO ('P', 8) -#define SNDCTL_DSP_SUBDIVIDE _SIOWR('P', 9, int) -#define SNDCTL_DSP_SETFRAGMENT _SIOWR('P',10, int) - -/* Audio data formats (Note! U8=8 and S16_LE=16 for compatibility) */ -#define SNDCTL_DSP_GETFMTS _SIOR ('P',11, int) /* Returns a mask */ -#define SNDCTL_DSP_SETFMT _SIOWR('P',5, int) /* Selects ONE fmt*/ -# define AFMT_QUERY 0x00000000 /* Return current fmt */ -# define AFMT_MU_LAW 0x00000001 -# define AFMT_A_LAW 0x00000002 -# define AFMT_IMA_ADPCM 0x00000004 -# define AFMT_U8 0x00000008 -# define AFMT_S16_LE 0x00000010 /* Little endian signed 16*/ -# define AFMT_S16_BE 0x00000020 /* Big endian signed 16 */ -# define AFMT_S8 0x00000040 -# define AFMT_U16_LE 0x00000080 /* Little endian U16 */ -# define AFMT_U16_BE 0x00000100 /* Big endian U16 */ -# define AFMT_MPEG 0x00000200 /* MPEG (2) audio */ -# define AFMT_AC3 0x00000400 /* Dolby Digital AC3 */ - -/* - * Buffer status queries. - */ -typedef struct audio_buf_info { - int fragments; /* # of available fragments (partially usend ones not counted) */ - int fragstotal; /* Total # of fragments allocated */ - int fragsize; /* Size of a fragment in bytes */ - - int bytes; /* Available space in bytes (includes partially used fragments) */ - /* Note! 'bytes' could be more than fragments*fragsize */ - } audio_buf_info; - -#define SNDCTL_DSP_GETOSPACE _SIOR ('P',12, audio_buf_info) -#define SNDCTL_DSP_GETISPACE _SIOR ('P',13, audio_buf_info) -#define SNDCTL_DSP_NONBLOCK _SIO ('P',14) -#define SNDCTL_DSP_GETCAPS _SIOR ('P',15, int) -# define DSP_CAP_REVISION 0x000000ff /* Bits for revision level (0 to 255) */ -# define DSP_CAP_DUPLEX 0x00000100 /* Full duplex record/playback */ -# define DSP_CAP_REALTIME 0x00000200 /* Real time capability */ -# define DSP_CAP_BATCH 0x00000400 /* Device has some kind of */ - /* internal buffers which may */ - /* cause some delays and */ - /* decrease precision of timing */ -# define DSP_CAP_COPROC 0x00000800 /* Has a coprocessor */ - /* Sometimes it's a DSP */ - /* but usually not */ -# define DSP_CAP_TRIGGER 0x00001000 /* Supports SETTRIGGER */ -# define DSP_CAP_MMAP 0x00002000 /* Supports mmap() */ -# define DSP_CAP_MULTI 0x00004000 /* support multiple open */ -# define DSP_CAP_BIND 0x00008000 /* channel binding to front/rear/cneter/lfe */ - - -#define SNDCTL_DSP_GETTRIGGER _SIOR ('P',16, int) -#define SNDCTL_DSP_SETTRIGGER _SIOW ('P',16, int) -# define PCM_ENABLE_INPUT 0x00000001 -# define PCM_ENABLE_OUTPUT 0x00000002 - -typedef struct count_info { - int bytes; /* Total # of bytes processed */ - int blocks; /* # of fragment transitions since last time */ - int ptr; /* Current DMA pointer value */ - } count_info; - -#define SNDCTL_DSP_GETIPTR _SIOR ('P',17, count_info) -#define SNDCTL_DSP_GETOPTR _SIOR ('P',18, count_info) - -typedef struct buffmem_desc { - unsigned *buffer; - int size; - } buffmem_desc; -#define SNDCTL_DSP_MAPINBUF _SIOR ('P', 19, buffmem_desc) -#define SNDCTL_DSP_MAPOUTBUF _SIOR ('P', 20, buffmem_desc) -#define SNDCTL_DSP_SETSYNCRO _SIO ('P', 21) -#define SNDCTL_DSP_SETDUPLEX _SIO ('P', 22) -#define SNDCTL_DSP_GETODELAY _SIOR ('P', 23, int) - -#define SNDCTL_DSP_GETCHANNELMASK _SIOWR('P', 64, int) -#define SNDCTL_DSP_BIND_CHANNEL _SIOWR('P', 65, int) -# define DSP_BIND_QUERY 0x00000000 -# define DSP_BIND_FRONT 0x00000001 -# define DSP_BIND_SURR 0x00000002 -# define DSP_BIND_CENTER_LFE 0x00000004 -# define DSP_BIND_HANDSET 0x00000008 -# define DSP_BIND_MIC 0x00000010 -# define DSP_BIND_MODEM1 0x00000020 -# define DSP_BIND_MODEM2 0x00000040 -# define DSP_BIND_I2S 0x00000080 -# define DSP_BIND_SPDIF 0x00000100 - -#define SNDCTL_DSP_SETSPDIF _SIOW ('P', 66, int) -#define SNDCTL_DSP_GETSPDIF _SIOR ('P', 67, int) -# define SPDIF_PRO 0x0001 -# define SPDIF_N_AUD 0x0002 -# define SPDIF_COPY 0x0004 -# define SPDIF_PRE 0x0008 -# define SPDIF_CC 0x07f0 -# define SPDIF_L 0x0800 -# define SPDIF_DRS 0x4000 -# define SPDIF_V 0x8000 - -/* - * Application's profile defines the way how playback underrun situations should be handled. - * - * APF_NORMAL (the default) and APF_NETWORK make the driver to cleanup the - * playback buffer whenever an underrun occurs. This consumes some time - * prevents looping the existing buffer. - * APF_CPUINTENS is intended to be set by CPU intensive applications which - * are likely to run out of time occasionally. In this mode the buffer cleanup is - * disabled which saves CPU time but also let's the previous buffer content to - * be played during the "pause" after the underrun. - */ -#define SNDCTL_DSP_PROFILE _SIOW ('P', 23, int) -#define APF_NORMAL 0 /* Normal applications */ -#define APF_NETWORK 1 /* Underruns probably caused by an "external" delay */ -#define APF_CPUINTENS 2 /* Underruns probably caused by "overheating" the CPU */ - -#define SOUND_PCM_READ_RATE _SIOR ('P', 2, int) -#define SOUND_PCM_READ_CHANNELS _SIOR ('P', 6, int) -#define SOUND_PCM_READ_BITS _SIOR ('P', 5, int) -#define SOUND_PCM_READ_FILTER _SIOR ('P', 7, int) - -/* Some alias names */ -#define SOUND_PCM_WRITE_BITS SNDCTL_DSP_SETFMT -#define SOUND_PCM_WRITE_RATE SNDCTL_DSP_SPEED -#define SOUND_PCM_POST SNDCTL_DSP_POST -#define SOUND_PCM_RESET SNDCTL_DSP_RESET -#define SOUND_PCM_SYNC SNDCTL_DSP_SYNC -#define SOUND_PCM_SUBDIVIDE SNDCTL_DSP_SUBDIVIDE -#define SOUND_PCM_SETFRAGMENT SNDCTL_DSP_SETFRAGMENT -#define SOUND_PCM_GETFMTS SNDCTL_DSP_GETFMTS -#define SOUND_PCM_SETFMT SNDCTL_DSP_SETFMT -#define SOUND_PCM_GETOSPACE SNDCTL_DSP_GETOSPACE -#define SOUND_PCM_GETISPACE SNDCTL_DSP_GETISPACE -#define SOUND_PCM_NONBLOCK SNDCTL_DSP_NONBLOCK -#define SOUND_PCM_GETCAPS SNDCTL_DSP_GETCAPS -#define SOUND_PCM_GETTRIGGER SNDCTL_DSP_GETTRIGGER -#define SOUND_PCM_SETTRIGGER SNDCTL_DSP_SETTRIGGER -#define SOUND_PCM_SETSYNCRO SNDCTL_DSP_SETSYNCRO -#define SOUND_PCM_GETIPTR SNDCTL_DSP_GETIPTR -#define SOUND_PCM_GETOPTR SNDCTL_DSP_GETOPTR -#define SOUND_PCM_MAPINBUF SNDCTL_DSP_MAPINBUF -#define SOUND_PCM_MAPOUTBUF SNDCTL_DSP_MAPOUTBUF - -/* - * ioctl calls to be used in communication with coprocessors and - * DSP chips. - */ - -typedef struct copr_buffer { - int command; /* Set to 0 if not used */ - int flags; -#define CPF_NONE 0x0000 -#define CPF_FIRST 0x0001 /* First block */ -#define CPF_LAST 0x0002 /* Last block */ - int len; - int offs; /* If required by the device (0 if not used) */ - - unsigned char data[4000]; /* NOTE! 4000 is not 4k */ - } copr_buffer; - -typedef struct copr_debug_buf { - int command; /* Used internally. Set to 0 */ - int parm1; - int parm2; - int flags; - int len; /* Length of data in bytes */ - } copr_debug_buf; - -typedef struct copr_msg { - int len; - unsigned char data[4000]; - } copr_msg; - -#define SNDCTL_COPR_RESET _SIO ('C', 0) -#define SNDCTL_COPR_LOAD _SIOWR('C', 1, copr_buffer) -#define SNDCTL_COPR_RDATA _SIOWR('C', 2, copr_debug_buf) -#define SNDCTL_COPR_RCODE _SIOWR('C', 3, copr_debug_buf) -#define SNDCTL_COPR_WDATA _SIOW ('C', 4, copr_debug_buf) -#define SNDCTL_COPR_WCODE _SIOW ('C', 5, copr_debug_buf) -#define SNDCTL_COPR_RUN _SIOWR('C', 6, copr_debug_buf) -#define SNDCTL_COPR_HALT _SIOWR('C', 7, copr_debug_buf) -#define SNDCTL_COPR_SENDMSG _SIOWR('C', 8, copr_msg) -#define SNDCTL_COPR_RCVMSG _SIOR ('C', 9, copr_msg) - -/********************************************* - * IOCTL commands for /dev/mixer - */ - -/* - * Mixer devices - * - * There can be up to 20 different analog mixer channels. The - * SOUND_MIXER_NRDEVICES gives the currently supported maximum. - * The SOUND_MIXER_READ_DEVMASK returns a bitmask which tells - * the devices supported by the particular mixer. - */ - -#define SOUND_MIXER_NRDEVICES 25 -#define SOUND_MIXER_VOLUME 0 -#define SOUND_MIXER_BASS 1 -#define SOUND_MIXER_TREBLE 2 -#define SOUND_MIXER_SYNTH 3 -#define SOUND_MIXER_PCM 4 -#define SOUND_MIXER_SPEAKER 5 -#define SOUND_MIXER_LINE 6 -#define SOUND_MIXER_MIC 7 -#define SOUND_MIXER_CD 8 -#define SOUND_MIXER_IMIX 9 /* Recording monitor */ -#define SOUND_MIXER_ALTPCM 10 -#define SOUND_MIXER_RECLEV 11 /* Recording level */ -#define SOUND_MIXER_IGAIN 12 /* Input gain */ -#define SOUND_MIXER_OGAIN 13 /* Output gain */ -/* - * The AD1848 codec and compatibles have three line level inputs - * (line, aux1 and aux2). Since each card manufacturer have assigned - * different meanings to these inputs, it's impractical to assign - * specific meanings (line, cd, synth etc.) to them. - */ -#define SOUND_MIXER_LINE1 14 /* Input source 1 (aux1) */ -#define SOUND_MIXER_LINE2 15 /* Input source 2 (aux2) */ -#define SOUND_MIXER_LINE3 16 /* Input source 3 (line) */ -#define SOUND_MIXER_DIGITAL1 17 /* Digital (input) 1 */ -#define SOUND_MIXER_DIGITAL2 18 /* Digital (input) 2 */ -#define SOUND_MIXER_DIGITAL3 19 /* Digital (input) 3 */ -#define SOUND_MIXER_PHONEIN 20 /* Phone input */ -#define SOUND_MIXER_PHONEOUT 21 /* Phone output */ -#define SOUND_MIXER_VIDEO 22 /* Video/TV (audio) in */ -#define SOUND_MIXER_RADIO 23 /* Radio in */ -#define SOUND_MIXER_MONITOR 24 /* Monitor (usually mic) volume */ - -/* Some on/off settings (SOUND_SPECIAL_MIN - SOUND_SPECIAL_MAX) */ -/* Not counted to SOUND_MIXER_NRDEVICES, but use the same number space */ -#define SOUND_ONOFF_MIN 28 -#define SOUND_ONOFF_MAX 30 - -/* Note! Number 31 cannot be used since the sign bit is reserved */ -#define SOUND_MIXER_NONE 31 - -/* - * The following unsupported macros are no longer functional. - * Use SOUND_MIXER_PRIVATE# macros in future. - */ -#define SOUND_MIXER_ENHANCE SOUND_MIXER_NONE -#define SOUND_MIXER_MUTE SOUND_MIXER_NONE -#define SOUND_MIXER_LOUD SOUND_MIXER_NONE - - -#define SOUND_DEVICE_LABELS {"Vol ", "Bass ", "Trebl", "Synth", "Pcm ", "Spkr ", "Line ", \ - "Mic ", "CD ", "Mix ", "Pcm2 ", "Rec ", "IGain", "OGain", \ - "Line1", "Line2", "Line3", "Digital1", "Digital2", "Digital3", \ - "PhoneIn", "PhoneOut", "Video", "Radio", "Monitor"} - -#define SOUND_DEVICE_NAMES {"vol", "bass", "treble", "synth", "pcm", "speaker", "line", \ - "mic", "cd", "mix", "pcm2", "rec", "igain", "ogain", \ - "line1", "line2", "line3", "dig1", "dig2", "dig3", \ - "phin", "phout", "video", "radio", "monitor"} - -/* Device bitmask identifiers */ - -#define SOUND_MIXER_RECSRC 0xff /* Arg contains a bit for each recording source */ -#define SOUND_MIXER_DEVMASK 0xfe /* Arg contains a bit for each supported device */ -#define SOUND_MIXER_RECMASK 0xfd /* Arg contains a bit for each supported recording source */ -#define SOUND_MIXER_CAPS 0xfc -# define SOUND_CAP_EXCL_INPUT 0x00000001 /* Only one recording source at a time */ -#define SOUND_MIXER_STEREODEVS 0xfb /* Mixer channels supporting stereo */ -#define SOUND_MIXER_OUTSRC 0xfa /* Arg contains a bit for each input source to output */ -#define SOUND_MIXER_OUTMASK 0xf9 /* Arg contains a bit for each supported input source to output */ - -/* Device mask bits */ - -#define SOUND_MASK_VOLUME (1 << SOUND_MIXER_VOLUME) -#define SOUND_MASK_BASS (1 << SOUND_MIXER_BASS) -#define SOUND_MASK_TREBLE (1 << SOUND_MIXER_TREBLE) -#define SOUND_MASK_SYNTH (1 << SOUND_MIXER_SYNTH) -#define SOUND_MASK_PCM (1 << SOUND_MIXER_PCM) -#define SOUND_MASK_SPEAKER (1 << SOUND_MIXER_SPEAKER) -#define SOUND_MASK_LINE (1 << SOUND_MIXER_LINE) -#define SOUND_MASK_MIC (1 << SOUND_MIXER_MIC) -#define SOUND_MASK_CD (1 << SOUND_MIXER_CD) -#define SOUND_MASK_IMIX (1 << SOUND_MIXER_IMIX) -#define SOUND_MASK_ALTPCM (1 << SOUND_MIXER_ALTPCM) -#define SOUND_MASK_RECLEV (1 << SOUND_MIXER_RECLEV) -#define SOUND_MASK_IGAIN (1 << SOUND_MIXER_IGAIN) -#define SOUND_MASK_OGAIN (1 << SOUND_MIXER_OGAIN) -#define SOUND_MASK_LINE1 (1 << SOUND_MIXER_LINE1) -#define SOUND_MASK_LINE2 (1 << SOUND_MIXER_LINE2) -#define SOUND_MASK_LINE3 (1 << SOUND_MIXER_LINE3) -#define SOUND_MASK_DIGITAL1 (1 << SOUND_MIXER_DIGITAL1) -#define SOUND_MASK_DIGITAL2 (1 << SOUND_MIXER_DIGITAL2) -#define SOUND_MASK_DIGITAL3 (1 << SOUND_MIXER_DIGITAL3) -#define SOUND_MASK_PHONEIN (1 << SOUND_MIXER_PHONEIN) -#define SOUND_MASK_PHONEOUT (1 << SOUND_MIXER_PHONEOUT) -#define SOUND_MASK_RADIO (1 << SOUND_MIXER_RADIO) -#define SOUND_MASK_VIDEO (1 << SOUND_MIXER_VIDEO) -#define SOUND_MASK_MONITOR (1 << SOUND_MIXER_MONITOR) - -/* Obsolete macros */ -#define SOUND_MASK_MUTE (1 << SOUND_MIXER_MUTE) -#define SOUND_MASK_ENHANCE (1 << SOUND_MIXER_ENHANCE) -#define SOUND_MASK_LOUD (1 << SOUND_MIXER_LOUD) - -#define MIXER_READ(dev) _SIOR('M', dev, int) -#define SOUND_MIXER_READ_VOLUME MIXER_READ(SOUND_MIXER_VOLUME) -#define SOUND_MIXER_READ_BASS MIXER_READ(SOUND_MIXER_BASS) -#define SOUND_MIXER_READ_TREBLE MIXER_READ(SOUND_MIXER_TREBLE) -#define SOUND_MIXER_READ_SYNTH MIXER_READ(SOUND_MIXER_SYNTH) -#define SOUND_MIXER_READ_PCM MIXER_READ(SOUND_MIXER_PCM) -#define SOUND_MIXER_READ_SPEAKER MIXER_READ(SOUND_MIXER_SPEAKER) -#define SOUND_MIXER_READ_LINE MIXER_READ(SOUND_MIXER_LINE) -#define SOUND_MIXER_READ_MIC MIXER_READ(SOUND_MIXER_MIC) -#define SOUND_MIXER_READ_CD MIXER_READ(SOUND_MIXER_CD) -#define SOUND_MIXER_READ_IMIX MIXER_READ(SOUND_MIXER_IMIX) -#define SOUND_MIXER_READ_ALTPCM MIXER_READ(SOUND_MIXER_ALTPCM) -#define SOUND_MIXER_READ_RECLEV MIXER_READ(SOUND_MIXER_RECLEV) -#define SOUND_MIXER_READ_IGAIN MIXER_READ(SOUND_MIXER_IGAIN) -#define SOUND_MIXER_READ_OGAIN MIXER_READ(SOUND_MIXER_OGAIN) -#define SOUND_MIXER_READ_LINE1 MIXER_READ(SOUND_MIXER_LINE1) -#define SOUND_MIXER_READ_LINE2 MIXER_READ(SOUND_MIXER_LINE2) -#define SOUND_MIXER_READ_LINE3 MIXER_READ(SOUND_MIXER_LINE3) - -/* Obsolete macros */ -#define SOUND_MIXER_READ_MUTE MIXER_READ(SOUND_MIXER_MUTE) -#define SOUND_MIXER_READ_ENHANCE MIXER_READ(SOUND_MIXER_ENHANCE) -#define SOUND_MIXER_READ_LOUD MIXER_READ(SOUND_MIXER_LOUD) - -#define SOUND_MIXER_READ_RECSRC MIXER_READ(SOUND_MIXER_RECSRC) -#define SOUND_MIXER_READ_DEVMASK MIXER_READ(SOUND_MIXER_DEVMASK) -#define SOUND_MIXER_READ_RECMASK MIXER_READ(SOUND_MIXER_RECMASK) -#define SOUND_MIXER_READ_STEREODEVS MIXER_READ(SOUND_MIXER_STEREODEVS) -#define SOUND_MIXER_READ_CAPS MIXER_READ(SOUND_MIXER_CAPS) - -#define MIXER_WRITE(dev) _SIOWR('M', dev, int) -#define SOUND_MIXER_WRITE_VOLUME MIXER_WRITE(SOUND_MIXER_VOLUME) -#define SOUND_MIXER_WRITE_BASS MIXER_WRITE(SOUND_MIXER_BASS) -#define SOUND_MIXER_WRITE_TREBLE MIXER_WRITE(SOUND_MIXER_TREBLE) -#define SOUND_MIXER_WRITE_SYNTH MIXER_WRITE(SOUND_MIXER_SYNTH) -#define SOUND_MIXER_WRITE_PCM MIXER_WRITE(SOUND_MIXER_PCM) -#define SOUND_MIXER_WRITE_SPEAKER MIXER_WRITE(SOUND_MIXER_SPEAKER) -#define SOUND_MIXER_WRITE_LINE MIXER_WRITE(SOUND_MIXER_LINE) -#define SOUND_MIXER_WRITE_MIC MIXER_WRITE(SOUND_MIXER_MIC) -#define SOUND_MIXER_WRITE_CD MIXER_WRITE(SOUND_MIXER_CD) -#define SOUND_MIXER_WRITE_IMIX MIXER_WRITE(SOUND_MIXER_IMIX) -#define SOUND_MIXER_WRITE_ALTPCM MIXER_WRITE(SOUND_MIXER_ALTPCM) -#define SOUND_MIXER_WRITE_RECLEV MIXER_WRITE(SOUND_MIXER_RECLEV) -#define SOUND_MIXER_WRITE_IGAIN MIXER_WRITE(SOUND_MIXER_IGAIN) -#define SOUND_MIXER_WRITE_OGAIN MIXER_WRITE(SOUND_MIXER_OGAIN) -#define SOUND_MIXER_WRITE_LINE1 MIXER_WRITE(SOUND_MIXER_LINE1) -#define SOUND_MIXER_WRITE_LINE2 MIXER_WRITE(SOUND_MIXER_LINE2) -#define SOUND_MIXER_WRITE_LINE3 MIXER_WRITE(SOUND_MIXER_LINE3) - -/* Obsolete macros */ -#define SOUND_MIXER_WRITE_MUTE MIXER_WRITE(SOUND_MIXER_MUTE) -#define SOUND_MIXER_WRITE_ENHANCE MIXER_WRITE(SOUND_MIXER_ENHANCE) -#define SOUND_MIXER_WRITE_LOUD MIXER_WRITE(SOUND_MIXER_LOUD) - -#define SOUND_MIXER_WRITE_RECSRC MIXER_WRITE(SOUND_MIXER_RECSRC) - -typedef struct mixer_info -{ - char id[16]; - char name[32]; - int modify_counter; - int fillers[10]; -} mixer_info; - -typedef struct _old_mixer_info /* Obsolete */ -{ - char id[16]; - char name[32]; -} _old_mixer_info; - -#define SOUND_MIXER_INFO _SIOR ('M', 101, mixer_info) -#define SOUND_OLD_MIXER_INFO _SIOR ('M', 101, _old_mixer_info) - -/* - * A mechanism for accessing "proprietary" mixer features. This method - * permits passing 128 bytes of arbitrary data between a mixer application - * and the mixer driver. Interpretation of the record is defined by - * the particular mixer driver. - */ -typedef unsigned char mixer_record[128]; - -#define SOUND_MIXER_ACCESS _SIOWR('M', 102, mixer_record) - -/* - * Two ioctls for special soundcard function - */ -#define SOUND_MIXER_AGC _SIOWR('M', 103, int) -#define SOUND_MIXER_3DSE _SIOWR('M', 104, int) - -/* - * The SOUND_MIXER_PRIVATE# commands can be redefined by low level drivers. - * These features can be used when accessing device specific features. - */ -#define SOUND_MIXER_PRIVATE1 _SIOWR('M', 111, int) -#define SOUND_MIXER_PRIVATE2 _SIOWR('M', 112, int) -#define SOUND_MIXER_PRIVATE3 _SIOWR('M', 113, int) -#define SOUND_MIXER_PRIVATE4 _SIOWR('M', 114, int) -#define SOUND_MIXER_PRIVATE5 _SIOWR('M', 115, int) - -/* - * SOUND_MIXER_GETLEVELS and SOUND_MIXER_SETLEVELS calls can be used - * for querying current mixer settings from the driver and for loading - * default volume settings _prior_ activating the mixer (loading - * doesn't affect current state of the mixer hardware). These calls - * are for internal use only. - */ - -typedef struct mixer_vol_table { - int num; /* Index to volume table */ - char name[32]; - int levels[32]; -} mixer_vol_table; - -#define SOUND_MIXER_GETLEVELS _SIOWR('M', 116, mixer_vol_table) -#define SOUND_MIXER_SETLEVELS _SIOWR('M', 117, mixer_vol_table) - -/* - * An ioctl for identifying the driver version. It will return value - * of the SOUND_VERSION macro used when compiling the driver. - * This call was introduced in OSS version 3.6 and it will not work - * with earlier versions (returns EINVAL). - */ -#define OSS_GETVERSION _SIOR ('M', 118, int) - -/* - * Level 2 event types for /dev/sequencer - */ - -/* - * The 4 most significant bits of byte 0 specify the class of - * the event: - * - * 0x8X = system level events, - * 0x9X = device/port specific events, event[1] = device/port, - * The last 4 bits give the subtype: - * 0x02 = Channel event (event[3] = chn). - * 0x01 = note event (event[4] = note). - * (0x01 is not used alone but always with bit 0x02). - * event[2] = MIDI message code (0x80=note off etc.) - * - */ - -#define EV_SEQ_LOCAL 0x80 -#define EV_TIMING 0x81 -#define EV_CHN_COMMON 0x92 -#define EV_CHN_VOICE 0x93 -#define EV_SYSEX 0x94 -/* - * Event types 200 to 220 are reserved for application use. - * These numbers will not be used by the driver. - */ - -/* - * Events for event type EV_CHN_VOICE - */ - -#define MIDI_NOTEOFF 0x80 -#define MIDI_NOTEON 0x90 -#define MIDI_KEY_PRESSURE 0xA0 - -/* - * Events for event type EV_CHN_COMMON - */ - -#define MIDI_CTL_CHANGE 0xB0 -#define MIDI_PGM_CHANGE 0xC0 -#define MIDI_CHN_PRESSURE 0xD0 -#define MIDI_PITCH_BEND 0xE0 - -#define MIDI_SYSTEM_PREFIX 0xF0 - -/* - * Timer event types - */ -#define TMR_WAIT_REL 1 /* Time relative to the prev time */ -#define TMR_WAIT_ABS 2 /* Absolute time since TMR_START */ -#define TMR_STOP 3 -#define TMR_START 4 -#define TMR_CONTINUE 5 -#define TMR_TEMPO 6 -#define TMR_ECHO 8 -#define TMR_CLOCK 9 /* MIDI clock */ -#define TMR_SPP 10 /* Song position pointer */ -#define TMR_TIMESIG 11 /* Time signature */ - -/* - * Local event types - */ -#define LOCL_STARTAUDIO 1 - -#if (!defined(__KERNEL__) && !defined(KERNEL) && !defined(INKERNEL) && !defined(_KERNEL)) || defined(USE_SEQ_MACROS) -/* - * Some convenience macros to simplify programming of the - * /dev/sequencer interface - * - * These macros define the API which should be used when possible. - */ -#define SEQ_DECLAREBUF() SEQ_USE_EXTBUF() - -void seqbuf_dump(void); /* This function must be provided by programs */ - -extern int OSS_init(int seqfd, int buflen); -extern void OSS_seqbuf_dump(int fd, unsigned char *buf, int buflen); -extern void OSS_seq_advbuf(int len, int fd, unsigned char *buf, int buflen); -extern void OSS_seq_needbuf(int len, int fd, unsigned char *buf, int buflen); -extern void OSS_patch_caching(int dev, int chn, int patch, - int fd, unsigned char *buf, int buflen); -extern void OSS_drum_caching(int dev, int chn, int patch, - int fd, unsigned char *buf, int buflen); -extern void OSS_write_patch(int fd, unsigned char *buf, int len); -extern int OSS_write_patch2(int fd, unsigned char *buf, int len); - -#define SEQ_PM_DEFINES int __foo_bar___ -#ifdef OSSLIB -# define SEQ_USE_EXTBUF() \ - extern unsigned char *_seqbuf; \ - extern int _seqbuflen;extern int _seqbufptr -# define SEQ_DEFINEBUF(len) SEQ_USE_EXTBUF();static int _requested_seqbuflen=len -# define _SEQ_ADVBUF(len) OSS_seq_advbuf(len, seqfd, _seqbuf, _seqbuflen) -# define _SEQ_NEEDBUF(len) OSS_seq_needbuf(len, seqfd, _seqbuf, _seqbuflen) -# define SEQ_DUMPBUF() OSS_seqbuf_dump(seqfd, _seqbuf, _seqbuflen) - -# define SEQ_LOAD_GMINSTR(dev, instr) \ - OSS_patch_caching(dev, -1, instr, seqfd, _seqbuf, _seqbuflen) -# define SEQ_LOAD_GMDRUM(dev, drum) \ - OSS_drum_caching(dev, -1, drum, seqfd, _seqbuf, _seqbuflen) -#else /* !OSSLIB */ - -# define SEQ_LOAD_GMINSTR(dev, instr) -# define SEQ_LOAD_GMDRUM(dev, drum) - -# define SEQ_USE_EXTBUF() \ - extern unsigned char _seqbuf[]; \ - extern int _seqbuflen;extern int _seqbufptr - -#ifndef USE_SIMPLE_MACROS -/* Sample seqbuf_dump() implementation: - * - * SEQ_DEFINEBUF (2048); -- Defines a buffer for 2048 bytes - * - * int seqfd; -- The file descriptor for /dev/sequencer. - * - * void - * seqbuf_dump () - * { - * if (_seqbufptr) - * if (write (seqfd, _seqbuf, _seqbufptr) == -1) - * { - * perror ("write /dev/sequencer"); - * exit (-1); - * } - * _seqbufptr = 0; - * } - */ - -#define SEQ_DEFINEBUF(len) unsigned char _seqbuf[len]; int _seqbuflen = len;int _seqbufptr = 0 -#define _SEQ_NEEDBUF(len) if ((_seqbufptr+(len)) > _seqbuflen) seqbuf_dump() -#define _SEQ_ADVBUF(len) _seqbufptr += len -#define SEQ_DUMPBUF seqbuf_dump -#else -/* - * This variation of the sequencer macros is used just to format one event - * using fixed buffer. - * - * The program using the macro library must define the following macros before - * using this library. - * - * #define _seqbuf name of the buffer (unsigned char[]) - * #define _SEQ_ADVBUF(len) If the applic needs to know the exact - * size of the event, this macro can be used. - * Otherwise this must be defined as empty. - * #define _seqbufptr Define the name of index variable or 0 if - * not required. - */ -#define _SEQ_NEEDBUF(len) /* empty */ -#endif -#endif /* !OSSLIB */ - -#define SEQ_VOLUME_MODE(dev, mode) {_SEQ_NEEDBUF(8);\ - _seqbuf[_seqbufptr] = SEQ_EXTENDED;\ - _seqbuf[_seqbufptr+1] = SEQ_VOLMODE;\ - _seqbuf[_seqbufptr+2] = (dev);\ - _seqbuf[_seqbufptr+3] = (mode);\ - _seqbuf[_seqbufptr+4] = 0;\ - _seqbuf[_seqbufptr+5] = 0;\ - _seqbuf[_seqbufptr+6] = 0;\ - _seqbuf[_seqbufptr+7] = 0;\ - _SEQ_ADVBUF(8);} - -/* - * Midi voice messages - */ - -#define _CHN_VOICE(dev, event, chn, note, parm) \ - {_SEQ_NEEDBUF(8);\ - _seqbuf[_seqbufptr] = EV_CHN_VOICE;\ - _seqbuf[_seqbufptr+1] = (dev);\ - _seqbuf[_seqbufptr+2] = (event);\ - _seqbuf[_seqbufptr+3] = (chn);\ - _seqbuf[_seqbufptr+4] = (note);\ - _seqbuf[_seqbufptr+5] = (parm);\ - _seqbuf[_seqbufptr+6] = (0);\ - _seqbuf[_seqbufptr+7] = 0;\ - _SEQ_ADVBUF(8);} - -#define SEQ_START_NOTE(dev, chn, note, vol) \ - _CHN_VOICE(dev, MIDI_NOTEON, chn, note, vol) - -#define SEQ_STOP_NOTE(dev, chn, note, vol) \ - _CHN_VOICE(dev, MIDI_NOTEOFF, chn, note, vol) - -#define SEQ_KEY_PRESSURE(dev, chn, note, pressure) \ - _CHN_VOICE(dev, MIDI_KEY_PRESSURE, chn, note, pressure) - -/* - * Midi channel messages - */ - -#define _CHN_COMMON(dev, event, chn, p1, p2, w14) \ - {_SEQ_NEEDBUF(8);\ - _seqbuf[_seqbufptr] = EV_CHN_COMMON;\ - _seqbuf[_seqbufptr+1] = (dev);\ - _seqbuf[_seqbufptr+2] = (event);\ - _seqbuf[_seqbufptr+3] = (chn);\ - _seqbuf[_seqbufptr+4] = (p1);\ - _seqbuf[_seqbufptr+5] = (p2);\ - *(short *)&_seqbuf[_seqbufptr+6] = (w14);\ - _SEQ_ADVBUF(8);} -/* - * SEQ_SYSEX permits sending of sysex messages. (It may look that it permits - * sending any MIDI bytes but it's absolutely not possible. Trying to do - * so _will_ cause problems with MPU401 intelligent mode). - * - * Sysex messages are sent in blocks of 1 to 6 bytes. Longer messages must be - * sent by calling SEQ_SYSEX() several times (there must be no other events - * between them). First sysex fragment must have 0xf0 in the first byte - * and the last byte (buf[len-1] of the last fragment must be 0xf7. No byte - * between these sysex start and end markers cannot be larger than 0x7f. Also - * lengths of each fragments (except the last one) must be 6. - * - * Breaking the above rules may work with some MIDI ports but is likely to - * cause fatal problems with some other devices (such as MPU401). - */ -#define SEQ_SYSEX(dev, buf, len) \ - {int ii, ll=(len); \ - unsigned char *bufp=buf;\ - if (ll>6)ll=6;\ - _SEQ_NEEDBUF(8);\ - _seqbuf[_seqbufptr] = EV_SYSEX;\ - _seqbuf[_seqbufptr+1] = (dev);\ - for(ii=0;ii<ll;ii++)\ - _seqbuf[_seqbufptr+ii+2] = bufp[ii];\ - for(ii=ll;ii<6;ii++)\ - _seqbuf[_seqbufptr+ii+2] = 0xff;\ - _SEQ_ADVBUF(8);} - -#define SEQ_CHN_PRESSURE(dev, chn, pressure) \ - _CHN_COMMON(dev, MIDI_CHN_PRESSURE, chn, pressure, 0, 0) - -#define SEQ_SET_PATCH SEQ_PGM_CHANGE -#ifdef OSSLIB -# define SEQ_PGM_CHANGE(dev, chn, patch) \ - {OSS_patch_caching(dev, chn, patch, seqfd, _seqbuf, _seqbuflen); \ - _CHN_COMMON(dev, MIDI_PGM_CHANGE, chn, patch, 0, 0);} -#else -# define SEQ_PGM_CHANGE(dev, chn, patch) \ - _CHN_COMMON(dev, MIDI_PGM_CHANGE, chn, patch, 0, 0) -#endif - -#define SEQ_CONTROL(dev, chn, controller, value) \ - _CHN_COMMON(dev, MIDI_CTL_CHANGE, chn, controller, 0, value) - -#define SEQ_BENDER(dev, chn, value) \ - _CHN_COMMON(dev, MIDI_PITCH_BEND, chn, 0, 0, value) - - -#define SEQ_V2_X_CONTROL(dev, voice, controller, value) {_SEQ_NEEDBUF(8);\ - _seqbuf[_seqbufptr] = SEQ_EXTENDED;\ - _seqbuf[_seqbufptr+1] = SEQ_CONTROLLER;\ - _seqbuf[_seqbufptr+2] = (dev);\ - _seqbuf[_seqbufptr+3] = (voice);\ - _seqbuf[_seqbufptr+4] = (controller);\ - _seqbuf[_seqbufptr+5] = ((value)&0xff);\ - _seqbuf[_seqbufptr+6] = ((value>>8)&0xff);\ - _seqbuf[_seqbufptr+7] = 0;\ - _SEQ_ADVBUF(8);} -/* - * The following 5 macros are incorrectly implemented and obsolete. - * Use SEQ_BENDER and SEQ_CONTROL (with proper controller) instead. - */ -#define SEQ_PITCHBEND(dev, voice, value) SEQ_V2_X_CONTROL(dev, voice, CTRL_PITCH_BENDER, value) -#define SEQ_BENDER_RANGE(dev, voice, value) SEQ_V2_X_CONTROL(dev, voice, CTRL_PITCH_BENDER_RANGE, value) -#define SEQ_EXPRESSION(dev, voice, value) SEQ_CONTROL(dev, voice, CTL_EXPRESSION, value*128) -#define SEQ_MAIN_VOLUME(dev, voice, value) SEQ_CONTROL(dev, voice, CTL_MAIN_VOLUME, (value*16383)/100) -#define SEQ_PANNING(dev, voice, pos) SEQ_CONTROL(dev, voice, CTL_PAN, (pos+128) / 2) - -/* - * Timing and synchronization macros - */ - -#define _TIMER_EVENT(ev, parm) {_SEQ_NEEDBUF(8);\ - _seqbuf[_seqbufptr+0] = EV_TIMING; \ - _seqbuf[_seqbufptr+1] = (ev); \ - _seqbuf[_seqbufptr+2] = 0;\ - _seqbuf[_seqbufptr+3] = 0;\ - *(unsigned int *)&_seqbuf[_seqbufptr+4] = (parm); \ - _SEQ_ADVBUF(8);} - -#define SEQ_START_TIMER() _TIMER_EVENT(TMR_START, 0) -#define SEQ_STOP_TIMER() _TIMER_EVENT(TMR_STOP, 0) -#define SEQ_CONTINUE_TIMER() _TIMER_EVENT(TMR_CONTINUE, 0) -#define SEQ_WAIT_TIME(ticks) _TIMER_EVENT(TMR_WAIT_ABS, ticks) -#define SEQ_DELTA_TIME(ticks) _TIMER_EVENT(TMR_WAIT_REL, ticks) -#define SEQ_ECHO_BACK(key) _TIMER_EVENT(TMR_ECHO, key) -#define SEQ_SET_TEMPO(value) _TIMER_EVENT(TMR_TEMPO, value) -#define SEQ_SONGPOS(pos) _TIMER_EVENT(TMR_SPP, pos) -#define SEQ_TIME_SIGNATURE(sig) _TIMER_EVENT(TMR_TIMESIG, sig) - -/* - * Local control events - */ - -#define _LOCAL_EVENT(ev, parm) {_SEQ_NEEDBUF(8);\ - _seqbuf[_seqbufptr+0] = EV_SEQ_LOCAL; \ - _seqbuf[_seqbufptr+1] = (ev); \ - _seqbuf[_seqbufptr+2] = 0;\ - _seqbuf[_seqbufptr+3] = 0;\ - *(unsigned int *)&_seqbuf[_seqbufptr+4] = (parm); \ - _SEQ_ADVBUF(8);} - -#define SEQ_PLAYAUDIO(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO, devmask) -/* - * Events for the level 1 interface only - */ - -#define SEQ_MIDIOUT(device, byte) {_SEQ_NEEDBUF(4);\ - _seqbuf[_seqbufptr] = SEQ_MIDIPUTC;\ - _seqbuf[_seqbufptr+1] = (byte);\ - _seqbuf[_seqbufptr+2] = (device);\ - _seqbuf[_seqbufptr+3] = 0;\ - _SEQ_ADVBUF(4);} - -/* - * Patch loading. - */ -#ifdef OSSLIB -# define SEQ_WRPATCH(patchx, len) \ - OSS_write_patch(seqfd, (char*)(patchx), len) -# define SEQ_WRPATCH2(patchx, len) \ - OSS_write_patch2(seqfd, (char*)(patchx), len) -#else -# define SEQ_WRPATCH(patchx, len) \ - {if (_seqbufptr) SEQ_DUMPBUF();\ - if (write(seqfd, (char*)(patchx), len)==-1) \ - perror("Write patch: /dev/sequencer");} -# define SEQ_WRPATCH2(patchx, len) \ - (SEQ_DUMPBUF(), write(seqfd, (char*)(patchx), len)) -#endif - -#endif -#endif diff --git a/src/VBox/Runtime/testcase/tstDir-2.cpp b/src/VBox/Runtime/testcase/tstDir-2.cpp index a8213cf5..aea861fe 100644 --- a/src/VBox/Runtime/testcase/tstDir-2.cpp +++ b/src/VBox/Runtime/testcase/tstDir-2.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstDir-3.cpp b/src/VBox/Runtime/testcase/tstDir-3.cpp index 45aa691c..5b453d0b 100644 --- a/src/VBox/Runtime/testcase/tstDir-3.cpp +++ b/src/VBox/Runtime/testcase/tstDir-3.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2008 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstDir.cpp b/src/VBox/Runtime/testcase/tstDir.cpp index fe9907db..470414ef 100644 --- a/src/VBox/Runtime/testcase/tstDir.cpp +++ b/src/VBox/Runtime/testcase/tstDir.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -39,8 +39,10 @@ int main(int argc, char **argv) /* * Iterate arguments. */ - bool fLong = false; + bool fLong = false; bool fShortName = false; + bool fFiltered = false; + bool fQuiet = false; for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') @@ -55,6 +57,12 @@ int main(int argc, char **argv) case 's': fShortName = true; break; + case 'f': + fFiltered = true; + break; + case 'q': + fQuiet = true; + break; default: RTPrintf("Unknown option '%c' ignored!\n", argv[i][j]); break; @@ -65,7 +73,11 @@ int main(int argc, char **argv) { /* open */ PRTDIR pDir; - int rc = RTDirOpen(&pDir, argv[i]); + int rc; + if (!fFiltered) + rc = RTDirOpen(&pDir, argv[i]); + else + rc = RTDirOpenFiltered(&pDir, argv[i], RTDIRFILTER_WINNT, 0); if (RT_SUCCESS(rc)) { /* list */ @@ -77,24 +89,27 @@ int main(int argc, char **argv) rc = RTDirRead(pDir, &DirEntry, NULL); if (RT_FAILURE(rc)) break; - switch (DirEntry.enmType) + if (!fQuiet) { - case RTDIRENTRYTYPE_UNKNOWN: RTPrintf("u"); break; - case RTDIRENTRYTYPE_FIFO: RTPrintf("f"); break; - case RTDIRENTRYTYPE_DEV_CHAR: RTPrintf("c"); break; - case RTDIRENTRYTYPE_DIRECTORY: RTPrintf("d"); break; - case RTDIRENTRYTYPE_DEV_BLOCK: RTPrintf("b"); break; - case RTDIRENTRYTYPE_FILE: RTPrintf("-"); break; - case RTDIRENTRYTYPE_SYMLINK: RTPrintf("l"); break; - case RTDIRENTRYTYPE_SOCKET: RTPrintf("s"); break; - case RTDIRENTRYTYPE_WHITEOUT: RTPrintf("w"); break; - default: - rcRet = 1; - RTPrintf("?"); - break; + switch (DirEntry.enmType) + { + case RTDIRENTRYTYPE_UNKNOWN: RTPrintf("u"); break; + case RTDIRENTRYTYPE_FIFO: RTPrintf("f"); break; + case RTDIRENTRYTYPE_DEV_CHAR: RTPrintf("c"); break; + case RTDIRENTRYTYPE_DIRECTORY: RTPrintf("d"); break; + case RTDIRENTRYTYPE_DEV_BLOCK: RTPrintf("b"); break; + case RTDIRENTRYTYPE_FILE: RTPrintf("-"); break; + case RTDIRENTRYTYPE_SYMLINK: RTPrintf("l"); break; + case RTDIRENTRYTYPE_SOCKET: RTPrintf("s"); break; + case RTDIRENTRYTYPE_WHITEOUT: RTPrintf("w"); break; + default: + rcRet = 1; + RTPrintf("?"); + break; + } + RTPrintf(" %#18llx %3d %s\n", (uint64_t)DirEntry.INodeId, + DirEntry.cbName, DirEntry.szName); } - RTPrintf(" %#18llx %3d %s\n", (uint64_t)DirEntry.INodeId, - DirEntry.cbName, DirEntry.szName); } } else @@ -106,64 +121,66 @@ int main(int argc, char **argv) if (RT_FAILURE(rc)) break; - RTFMODE fMode = DirEntry.Info.Attr.fMode; - switch (fMode & RTFS_TYPE_MASK) + if (!fQuiet) { - case RTFS_TYPE_FIFO: RTPrintf("f"); break; - case RTFS_TYPE_DEV_CHAR: RTPrintf("c"); break; - case RTFS_TYPE_DIRECTORY: RTPrintf("d"); break; - case RTFS_TYPE_DEV_BLOCK: RTPrintf("b"); break; - case RTFS_TYPE_FILE: RTPrintf("-"); break; - case RTFS_TYPE_SYMLINK: RTPrintf("l"); break; - case RTFS_TYPE_SOCKET: RTPrintf("s"); break; - case RTFS_TYPE_WHITEOUT: RTPrintf("w"); break; - default: - rcRet = 1; - RTPrintf("?"); - break; - } - /** @todo sticy bits++ */ - RTPrintf("%c%c%c", - fMode & RTFS_UNIX_IRUSR ? 'r' : '-', - fMode & RTFS_UNIX_IWUSR ? 'w' : '-', - fMode & RTFS_UNIX_IXUSR ? 'x' : '-'); - RTPrintf("%c%c%c", - fMode & RTFS_UNIX_IRGRP ? 'r' : '-', - fMode & RTFS_UNIX_IWGRP ? 'w' : '-', - fMode & RTFS_UNIX_IXGRP ? 'x' : '-'); - RTPrintf("%c%c%c", - fMode & RTFS_UNIX_IROTH ? 'r' : '-', - fMode & RTFS_UNIX_IWOTH ? 'w' : '-', - fMode & RTFS_UNIX_IXOTH ? 'x' : '-'); - RTPrintf(" %c%c%c%c%c%c%c%c%c%c%c%c%c%c", - fMode & RTFS_DOS_READONLY ? 'R' : '-', - fMode & RTFS_DOS_HIDDEN ? 'H' : '-', - fMode & RTFS_DOS_SYSTEM ? 'S' : '-', - fMode & RTFS_DOS_DIRECTORY ? 'D' : '-', - fMode & RTFS_DOS_ARCHIVED ? 'A' : '-', - fMode & RTFS_DOS_NT_DEVICE ? 'd' : '-', - fMode & RTFS_DOS_NT_NORMAL ? 'N' : '-', - fMode & RTFS_DOS_NT_TEMPORARY ? 'T' : '-', - fMode & RTFS_DOS_NT_SPARSE_FILE ? 'P' : '-', - fMode & RTFS_DOS_NT_REPARSE_POINT ? 'J' : '-', - fMode & RTFS_DOS_NT_COMPRESSED ? 'C' : '-', - fMode & RTFS_DOS_NT_OFFLINE ? 'O' : '-', - fMode & RTFS_DOS_NT_NOT_CONTENT_INDEXED ? 'I' : '-', - fMode & RTFS_DOS_NT_ENCRYPTED ? 'E' : '-'); - RTPrintf(" %d %4d %4d %10lld %10lld %#llx %#llx %#llx %#llx", - DirEntry.Info.Attr.u.Unix.cHardlinks, - DirEntry.Info.Attr.u.Unix.uid, - DirEntry.Info.Attr.u.Unix.gid, - DirEntry.Info.cbObject, - DirEntry.Info.cbAllocated, - DirEntry.Info.BirthTime, - DirEntry.Info.ChangeTime, - DirEntry.Info.ModificationTime, - DirEntry.Info.AccessTime); - if (fShortName && DirEntry.cwcShortName) - RTPrintf(" %2d %ls\n", DirEntry.cwcShortName, DirEntry.wszShortName); - else + RTFMODE fMode = DirEntry.Info.Attr.fMode; + switch (fMode & RTFS_TYPE_MASK) + { + case RTFS_TYPE_FIFO: RTPrintf("f"); break; + case RTFS_TYPE_DEV_CHAR: RTPrintf("c"); break; + case RTFS_TYPE_DIRECTORY: RTPrintf("d"); break; + case RTFS_TYPE_DEV_BLOCK: RTPrintf("b"); break; + case RTFS_TYPE_FILE: RTPrintf("-"); break; + case RTFS_TYPE_SYMLINK: RTPrintf("l"); break; + case RTFS_TYPE_SOCKET: RTPrintf("s"); break; + case RTFS_TYPE_WHITEOUT: RTPrintf("w"); break; + default: + rcRet = 1; + RTPrintf("?"); + break; + } + /** @todo sticy bits++ */ + RTPrintf("%c%c%c", + fMode & RTFS_UNIX_IRUSR ? 'r' : '-', + fMode & RTFS_UNIX_IWUSR ? 'w' : '-', + fMode & RTFS_UNIX_IXUSR ? 'x' : '-'); + RTPrintf("%c%c%c", + fMode & RTFS_UNIX_IRGRP ? 'r' : '-', + fMode & RTFS_UNIX_IWGRP ? 'w' : '-', + fMode & RTFS_UNIX_IXGRP ? 'x' : '-'); + RTPrintf("%c%c%c", + fMode & RTFS_UNIX_IROTH ? 'r' : '-', + fMode & RTFS_UNIX_IWOTH ? 'w' : '-', + fMode & RTFS_UNIX_IXOTH ? 'x' : '-'); + RTPrintf(" %c%c%c%c%c%c%c%c%c%c%c%c%c%c", + fMode & RTFS_DOS_READONLY ? 'R' : '-', + fMode & RTFS_DOS_HIDDEN ? 'H' : '-', + fMode & RTFS_DOS_SYSTEM ? 'S' : '-', + fMode & RTFS_DOS_DIRECTORY ? 'D' : '-', + fMode & RTFS_DOS_ARCHIVED ? 'A' : '-', + fMode & RTFS_DOS_NT_DEVICE ? 'd' : '-', + fMode & RTFS_DOS_NT_NORMAL ? 'N' : '-', + fMode & RTFS_DOS_NT_TEMPORARY ? 'T' : '-', + fMode & RTFS_DOS_NT_SPARSE_FILE ? 'P' : '-', + fMode & RTFS_DOS_NT_REPARSE_POINT ? 'J' : '-', + fMode & RTFS_DOS_NT_COMPRESSED ? 'C' : '-', + fMode & RTFS_DOS_NT_OFFLINE ? 'O' : '-', + fMode & RTFS_DOS_NT_NOT_CONTENT_INDEXED ? 'I' : '-', + fMode & RTFS_DOS_NT_ENCRYPTED ? 'E' : '-'); + RTPrintf(" %d %4d %4d %10lld %10lld %#llx %#llx %#llx %#llx", + DirEntry.Info.Attr.u.Unix.cHardlinks, + DirEntry.Info.Attr.u.Unix.uid, + DirEntry.Info.Attr.u.Unix.gid, + DirEntry.Info.cbObject, + DirEntry.Info.cbAllocated, + DirEntry.Info.BirthTime, + DirEntry.Info.ChangeTime, + DirEntry.Info.ModificationTime, + DirEntry.Info.AccessTime); + if (fShortName) + RTPrintf(" %2d %-12ls ", DirEntry.cwcShortName, DirEntry.wszShortName); RTPrintf(" %2d %s\n", DirEntry.cbName, DirEntry.szName); + } if (rc != VINF_SUCCESS) RTPrintf("^^ %Rrc\n", rc); } diff --git a/src/VBox/Runtime/testcase/tstEnv.cpp b/src/VBox/Runtime/testcase/tstEnv.cpp index 6c7ea9f3..2ffa30d8 100644 --- a/src/VBox/Runtime/testcase/tstEnv.cpp +++ b/src/VBox/Runtime/testcase/tstEnv.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2007 Oracle Corporation + * Copyright (C) 2007-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstFile.cpp b/src/VBox/Runtime/testcase/tstFile.cpp index f2f675d3..61d57a78 100644 --- a/src/VBox/Runtime/testcase/tstFile.cpp +++ b/src/VBox/Runtime/testcase/tstFile.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstFileAppendWin-1.cpp b/src/VBox/Runtime/testcase/tstFileAppendWin-1.cpp index 7ffd7fe1..25ab780e 100644 --- a/src/VBox/Runtime/testcase/tstFileAppendWin-1.cpp +++ b/src/VBox/Runtime/testcase/tstFileAppendWin-1.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2008 Oracle Corporation + * Copyright (C) 2008-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstFileLock.cpp b/src/VBox/Runtime/testcase/tstFileLock.cpp index fc4c0bfc..63942450 100644 --- a/src/VBox/Runtime/testcase/tstFileLock.cpp +++ b/src/VBox/Runtime/testcase/tstFileLock.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstFork.cpp b/src/VBox/Runtime/testcase/tstFork.cpp index 8d511f7c..61ccb48f 100644 --- a/src/VBox/Runtime/testcase/tstFork.cpp +++ b/src/VBox/Runtime/testcase/tstFork.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstHandleTable.cpp b/src/VBox/Runtime/testcase/tstHandleTable.cpp index ab0dce0f..1759ca00 100644 --- a/src/VBox/Runtime/testcase/tstHandleTable.cpp +++ b/src/VBox/Runtime/testcase/tstHandleTable.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2008 Oracle Corporation + * Copyright (C) 2008-2014 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -119,7 +119,7 @@ static int tstHandleTableTest1(uint32_t uBase, uint32_t cMax, uint32_t cDelta, u RTPrintf(" c=%#x\n", c); if (fCallbacks && cRetainerCalls != 0) { - RTPrintf("tstHandleTable: FAILURE (%d) - cRetainerCalls=%#x expected 0!\n", __LINE__, i, cRetainerCalls); + RTPrintf("tstHandleTable: FAILURE (%d) - cRetainerCalls=%#x expected 0!\n", __LINE__, cRetainerCalls); g_cErrors++; } @@ -243,7 +243,7 @@ static int tstHandleTableTest1(uint32_t uBase, uint32_t cMax, uint32_t cDelta, u && RTHandleTableLookupWithCtx(hHT, hLookup, &i)) { RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, j=%d, RTHandleTableLookupWithCtx: succeeded with bad context\n", - __LINE__, i, j, pvObj, pvExpect); + __LINE__, i, j); g_cErrors++; } } @@ -487,7 +487,7 @@ int main(int argc, char **argv) return 1; case 'V': - RTPrintf("$Revision: $\n"); + RTPrintf("$Revision: 92648 $\n"); return 0; default: diff --git a/src/VBox/Runtime/testcase/tstIoCtl.cpp b/src/VBox/Runtime/testcase/tstIoCtl.cpp deleted file mode 100644 index 31e901ef..00000000 --- a/src/VBox/Runtime/testcase/tstIoCtl.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* $Id: tstIoCtl.cpp $ */ -/** @file - * IPRT Testcase - file IoCtl. - */ - -/* - * Copyright (C) 2006-2007 Oracle Corporation - * - * This file is part of VirtualBox Open Source Edition (OSE), as - * available from http://www.virtualbox.org. This file is free software; - * you can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) as published by the Free Software - * Foundation, in version 2 as it comes in the "COPYING" file of the - * VirtualBox OSE distribution. VirtualBox OSE is distributed in the - * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. - * - * The contents of this file may alternatively be used under the terms - * of the Common Development and Distribution License Version 1.0 - * (CDDL) only, as it comes in the "COPYING.CDDL" file of the - * VirtualBox OSE distribution, in which case the provisions of the - * CDDL are applicable instead of those of the GPL. - * - * You may elect to license modified versions of this file under the - * terms and conditions of either the GPL or the CDDL or both. - */ - -/******************************************************************************* -* Header Files * -*******************************************************************************/ -//#include <sys/types.h> -#include "soundcard.h" -//#include <VBox/pdm.h> -#include <VBox/err.h> - -#include <iprt/log.h> -#include <VBox/log.h> -#define LOG_GROUP LOG_GROUP_DEV_AUDIO -//#include <iprt/assert.h> -//#include <iprt/uuid.h> -//#include <iprt/string.h> -//#include <iprt/alloc.h> -#include <iprt/file.h> - -//#include "audio.h" -//#include "audio_int.h" - -#include <stdio.h> -#include <iprt/uuid.h> - -#ifdef RT_OS_L4 -extern char **__environ; -char *myenv[] = { "+all.e", NULL }; -#endif - -int main() -{ -#ifdef RT_OS_L4 - __environ = myenv; -#endif - int rcRet = 0; - int ret, err; - printf("tstIoCtl: TESTING\n"); - - RTFILE File; - - err = RTFileOpen(&File, "/dev/dsp", RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_NON_BLOCK); - if (RT_FAILURE(err)) { - printf("Fatal error: failed to open /dev/dsp:\n" - "VBox error code: %d\n", err); - return 1; - } - - int rate = 100; - - if (RT_FAILURE(err = RTFileIoCtl(File, SNDCTL_DSP_SPEED, &rate, sizeof(rate), &ret)) || ret) { - printf("Failed to set playback speed on /dev/dsp\n" - "VBox error code: %d, IOCTL return value: %d\n", - err, ret); - rcRet++; - } else printf("Playback speed successfully set to 100, reported speed is %d\n", - rate); - - rate = 48000; - - if (RT_FAILURE(err = RTFileIoCtl(File, SNDCTL_DSP_SPEED, &rate, sizeof(rate), &ret)) || ret) { - printf("Failed to set playback speed on /dev/dsp\n" - "VBox error code: %d, IOCTL return value: %d\n", - err, ret); - rcRet++; - } else printf("Playback speed successfully set to 48000, reported speed is %d\n", - rate); - - /* - * Cleanup. - */ - ret = RTFileClose(File); - if (RT_FAILURE(ret)) - { - printf("Failed to close /dev/dsp. ret=%d\n", ret); - rcRet++; - } - - /* Under Linux and L4, this involves ioctls internally */ - RTUUID TestUuid; - if (RT_FAILURE(RTUuidCreate(&TestUuid))) - { - printf("Failed to create a UUID. ret=%d\n", ret); - rcRet++; - } - - /* - * Summary - */ - if (rcRet == 0) - printf("tstIoCtl: SUCCESS\n"); - else - printf("tstIoCtl: FAILURE - %d errors\n", rcRet); - return rcRet; -} diff --git a/src/VBox/Runtime/testcase/tstIprtList.cpp b/src/VBox/Runtime/testcase/tstIprtList.cpp index eb5785fc..283807d6 100644 --- a/src/VBox/Runtime/testcase/tstIprtList.cpp +++ b/src/VBox/Runtime/testcase/tstIprtList.cpp @@ -33,6 +33,7 @@ #include <iprt/test.h> #include <iprt/rand.h> #include <iprt/thread.h> +#include <iprt/time.h> /******************************************************************************* @@ -165,7 +166,7 @@ static void test1(const char *pcszDesc, T3 paTestData[], size_t cTestItems) /* Create a test list */ L<T1, T2> testList; - const size_t defCap = L<T1, T2>::DefaultCapacity; + const size_t defCap = L<T1, T2>::kDefaultCapacity; RTTESTI_CHECK(testList.isEmpty()); RTTESTI_CHECK(testList.size() == 0); RTTESTI_CHECK(testList.capacity() == defCap); @@ -375,13 +376,116 @@ static void test1(const char *pcszDesc, T3 paTestData[], size_t cTestItems) RTTESTI_CHECK_RETV(testList5.size() == 0); RTTESTI_CHECK(testList5.capacity() == 0); + /* + * Negative testing. + */ + bool fMayPanic = RTAssertMayPanic(); + bool fQuiet = RTAssertAreQuiet(); + RTAssertSetMayPanic(false); + RTAssertSetQuiet(true); + + L<T1, T2> testList6; + for (size_t i = 0; i < cTestItems; ++i) + testList6.insert(i, paTestData[i]); + RTTESTI_CHECK(testList6.size() == cTestItems); + + /* Insertion beyond the end of the array ends up at the end. */ + size_t cBefore = testList6.size(); + testList6.insert(cBefore + 3, paTestData[0]); + RTTESTI_CHECK(testList6.size() == cBefore + 1); + RTTESTI_CHECK(testList6.at(cBefore) == paTestData[0]); + + cBefore = testList6.size(); + L<T1, T2> testList7(testList6); + testList6.insert(testList6.size() + 42, testList7); + RTTESTI_CHECK(testList6.size() == cBefore + testList7.size()); + + /* Inserting, appending or prepending a list to itself is not supported. */ + cBefore = testList6.size(); + testList6.insert(3, testList6); + RTTESTI_CHECK(testList6.size() == cBefore); + + cBefore = testList6.size(); + testList6.append(testList6); + RTTESTI_CHECK(testList6.size() == cBefore); + + cBefore = testList6.size(); + testList6.prepend(testList6); + RTTESTI_CHECK(testList6.size() == cBefore); + + /* Replace does nothing if the index is bad. */ + cBefore = testList6.size(); + testList6.replace(cBefore, testList6[6]); + RTTESTI_CHECK(testList6.size() == cBefore); + + cBefore = testList6.size(); + testList6.replace(cBefore + 64, testList6[6]); + RTTESTI_CHECK(testList6.size() == cBefore); + + /* Indexing beyond the array returns the last element. */ + cBefore = testList6.size(); + RTTESTI_CHECK(testList6[cBefore] == testList6.last()); + RTTESTI_CHECK(testList6[cBefore + 42] == testList6.last()); + + RTTESTI_CHECK(&testList6[cBefore] == &testList6[cBefore - 1]); + RTTESTI_CHECK(&testList6[cBefore + 42] == &testList6[cBefore - 1]); + + /* removeAt does nothing if the index is bad. */ + cBefore = testList6.size(); + testList6.removeAt(cBefore); + RTTESTI_CHECK(testList6.size() == cBefore); + + cBefore = testList6.size(); + testList6.removeAt(cBefore + 42); + RTTESTI_CHECK(testList6.size() == cBefore); + + L<T1, T2> testListEmpty1; RTTESTI_CHECK(!testListEmpty1.size()); + testListEmpty1.removeFirst(); + RTTESTI_CHECK(!testListEmpty1.size()); + + testListEmpty1.removeLast(); + RTTESTI_CHECK(!testListEmpty1.size()); + + testListEmpty1.removeAt(128); + RTTESTI_CHECK(!testListEmpty1.size()); + + /* removeRange interprets indexes beyond the end as the end of array (asserted). */ + testListEmpty1.removeRange(42, 128); + RTTESTI_CHECK(!testListEmpty1.size()); + + cBefore = testList6.size(); + testList6.removeRange(cBefore, cBefore); + RTTESTI_CHECK(testList6.size() == cBefore); + + cBefore = testList6.size(); + testList6.removeRange(cBefore + 12, cBefore + 128); + RTTESTI_CHECK(testList6.size() == cBefore); + + /* If end is less or equal to the start, nothing is done. */ + testListEmpty1.removeRange(128, 0); + RTTESTI_CHECK(!testListEmpty1.size()); + + cBefore = testList6.size(); + testList6.removeRange(cBefore, 0); + RTTESTI_CHECK(testList6.size() == cBefore); + + cBefore = testList6.size(); + testList6.removeRange(0, 0); + RTTESTI_CHECK(testList6.size() == cBefore); + + cBefore = testList6.size(); + testList6.removeRange(0, 0); + RTTESTI_CHECK(testList6.size() == cBefore); + + RTAssertSetQuiet(fQuiet); + RTAssertSetMayPanic(fMayPanic); } /* define RTCList here to see what happens without MT support ;) * (valgrind is the preferred tool to check). */ -#define MTTESTLISTTYPE RTCMTList -#define MTTESTTYPE uint32_t -#define MTTESTITEMS 1000 +#define MTTESTLISTTYPE RTCMTList +#define MTTESTTYPE uint32_t +#define MTTESTITEMS 1000 /** * Thread for prepending items to a shared list. @@ -389,7 +493,7 @@ static void test1(const char *pcszDesc, T3 paTestData[], size_t cTestItems) * @param hSelf The thread handle. * @param pvUser The provided user data. */ -DECLCALLBACK(int) mttest1(RTTHREAD hSelf, void *pvUser) +static DECLCALLBACK(int) MtTest1ThreadProc(RTTHREAD hSelf, void *pvUser) { MTTESTLISTTYPE<MTTESTTYPE> *pTestList = (MTTESTLISTTYPE<MTTESTTYPE> *)pvUser; @@ -406,7 +510,7 @@ DECLCALLBACK(int) mttest1(RTTHREAD hSelf, void *pvUser) * @param hSelf The thread handle. * @param pvUser The provided user data. */ -DECLCALLBACK(int) mttest2(RTTHREAD hSelf, void *pvUser) +static DECLCALLBACK(int) MtTest2ThreadProc(RTTHREAD hSelf, void *pvUser) { MTTESTLISTTYPE<MTTESTTYPE> *pTestList = (MTTESTLISTTYPE<MTTESTTYPE> *)pvUser; @@ -423,7 +527,7 @@ DECLCALLBACK(int) mttest2(RTTHREAD hSelf, void *pvUser) * @param hSelf The thread handle. * @param pvUser The provided user data. */ -DECLCALLBACK(int) mttest3(RTTHREAD hSelf, void *pvUser) +static DECLCALLBACK(int) MtTest3ThreadProc(RTTHREAD hSelf, void *pvUser) { MTTESTLISTTYPE<MTTESTTYPE> *pTestList = (MTTESTLISTTYPE<MTTESTTYPE> *)pvUser; @@ -440,7 +544,7 @@ DECLCALLBACK(int) mttest3(RTTHREAD hSelf, void *pvUser) * @param hSelf The thread handle. * @param pvUser The provided user data. */ -DECLCALLBACK(int) mttest4(RTTHREAD hSelf, void *pvUser) +static DECLCALLBACK(int) MtTest4ThreadProc(RTTHREAD hSelf, void *pvUser) { MTTESTLISTTYPE<MTTESTTYPE> *pTestList = (MTTESTLISTTYPE<MTTESTTYPE> *)pvUser; @@ -449,7 +553,8 @@ DECLCALLBACK(int) mttest4(RTTHREAD hSelf, void *pvUser) for (size_t i = 0; i < MTTESTITEMS; ++i) { /* Make sure there is at least one item in the list. */ - while (pTestList->isEmpty()) {}; + while (pTestList->isEmpty()) + RTThreadYield(); a = pTestList->at(RTRandU32Ex(0, (uint32_t)pTestList->size() - 1)); } @@ -462,7 +567,7 @@ DECLCALLBACK(int) mttest4(RTTHREAD hSelf, void *pvUser) * @param hSelf The thread handle. * @param pvUser The provided user data. */ -DECLCALLBACK(int) mttest5(RTTHREAD hSelf, void *pvUser) +static DECLCALLBACK(int) MtTest5ThreadProc(RTTHREAD hSelf, void *pvUser) { MTTESTLISTTYPE<MTTESTTYPE> *pTestList = (MTTESTLISTTYPE<MTTESTTYPE> *)pvUser; @@ -470,7 +575,8 @@ DECLCALLBACK(int) mttest5(RTTHREAD hSelf, void *pvUser) for (size_t i = 0; i < MTTESTITEMS; ++i) { /* Make sure there is at least one item in the list. */ - while (pTestList->isEmpty()) {}; + while (pTestList->isEmpty()) + RTThreadYield(); pTestList->replace(RTRandU32Ex(0, (uint32_t)pTestList->size() - 1), 0xFF00FF00); } @@ -483,7 +589,7 @@ DECLCALLBACK(int) mttest5(RTTHREAD hSelf, void *pvUser) * @param hSelf The thread handle. * @param pvUser The provided user data. */ -DECLCALLBACK(int) mttest6(RTTHREAD hSelf, void *pvUser) +static DECLCALLBACK(int) MtTest6ThreadProc(RTTHREAD hSelf, void *pvUser) { MTTESTLISTTYPE<MTTESTTYPE> *pTestList = (MTTESTLISTTYPE<MTTESTTYPE> *)pvUser; @@ -491,7 +597,8 @@ DECLCALLBACK(int) mttest6(RTTHREAD hSelf, void *pvUser) for (size_t i = 0; i < MTTESTITEMS; ++i) { /* Make sure there is at least one item in the list. */ - while (pTestList->isEmpty()) {}; + while (pTestList->isEmpty()) + RTThreadYield(); pTestList->removeAt(RTRandU32Ex(0, (uint32_t)pTestList->size() - 1)); } @@ -507,35 +614,27 @@ static void test2() { RTTestISubF("MT test with 6 threads (%u tests per thread).", MTTESTITEMS); - RTTHREAD hThread1, hThread2, hThread3, hThread4, hThread5, hThread6; - int rc = VINF_SUCCESS; - - MTTESTLISTTYPE<MTTESTTYPE> testList; - rc = RTThreadCreate(&hThread1, &mttest1, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest1"); - AssertRC(rc); - rc = RTThreadCreate(&hThread2, &mttest2, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest2"); - AssertRC(rc); - rc = RTThreadCreate(&hThread3, &mttest3, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest3"); - AssertRC(rc); - rc = RTThreadCreate(&hThread4, &mttest4, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest4"); - AssertRC(rc); - rc = RTThreadCreate(&hThread5, &mttest5, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest5"); - AssertRC(rc); - rc = RTThreadCreate(&hThread6, &mttest6, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest6"); - AssertRC(rc); - - rc = RTThreadWait(hThread1, RT_INDEFINITE_WAIT, 0); - AssertRC(rc); - rc = RTThreadWait(hThread2, RT_INDEFINITE_WAIT, 0); - AssertRC(rc); - rc = RTThreadWait(hThread3, RT_INDEFINITE_WAIT, 0); - AssertRC(rc); - rc = RTThreadWait(hThread4, RT_INDEFINITE_WAIT, 0); - AssertRC(rc); - rc = RTThreadWait(hThread5, RT_INDEFINITE_WAIT, 0); - AssertRC(rc); - rc = RTThreadWait(hThread6, RT_INDEFINITE_WAIT, 0); - AssertRC(rc); + int rc; + MTTESTLISTTYPE<MTTESTTYPE> testList; + RTTHREAD ahThreads[6]; + static PFNRTTHREAD apfnThreads[6] = + { + MtTest1ThreadProc, MtTest2ThreadProc, MtTest3ThreadProc, MtTest4ThreadProc, MtTest5ThreadProc, MtTest6ThreadProc + }; + + for (unsigned i = 0; i < RT_ELEMENTS(ahThreads); i++) + { + RTTESTI_CHECK_RC_RETV(RTThreadCreateF(&ahThreads[i], apfnThreads[i], &testList, 0, + RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest%u", i), VINF_SUCCESS); + } + + uint64_t tsMsDeadline = RTTimeMilliTS() + 60000; + for (unsigned i = 0; i < RT_ELEMENTS(ahThreads); i++) + { + uint64_t tsNow = RTTimeMilliTS(); + uint32_t cWait = tsNow > tsMsDeadline ? 5000 : tsMsDeadline - tsNow; + RTTESTI_CHECK_RC(RTThreadWait(ahThreads[i], tsNow, NULL), VINF_SUCCESS); + } RTTESTI_CHECK_RETV(testList.size() == MTTESTITEMS * 2); for (size_t i = 0; i < testList.size(); ++i) @@ -556,13 +655,6 @@ int main() return rcExit; RTTestBanner(hTest); - /* Some host info. */ - RTTestIPrintf(RTTESTLVL_ALWAYS, "sizeof(void*)=%d", sizeof(void*)); - - /* - * The tests. - */ - /* * Native types. */ diff --git a/src/VBox/Runtime/testcase/tstLdr-2.cpp b/src/VBox/Runtime/testcase/tstLdr-2.cpp index d52bcbeb..7253680f 100644 --- a/src/VBox/Runtime/testcase/tstLdr-2.cpp +++ b/src/VBox/Runtime/testcase/tstLdr-2.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstLdr-3.cpp b/src/VBox/Runtime/testcase/tstLdr-3.cpp index acf0e981..90856bfd 100644 --- a/src/VBox/Runtime/testcase/tstLdr-3.cpp +++ b/src/VBox/Runtime/testcase/tstLdr-3.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstLdr-4.cpp b/src/VBox/Runtime/testcase/tstLdr-4.cpp index 9b6db489..fa3768a4 100644 --- a/src/VBox/Runtime/testcase/tstLdr-4.cpp +++ b/src/VBox/Runtime/testcase/tstLdr-4.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -125,7 +125,7 @@ static int testLdrOne(const char *pszFilename) */ for (i = 0; i < RT_ELEMENTS(aLoads); i++) { - if (!strncmp(aLoads[i].pszName, "kLdr-", sizeof("kLdr-") - 1)) + if (!strncmp(aLoads[i].pszName, RT_STR_TUPLE("kLdr-"))) rc = RTLdrOpenkLdr(pszFilename, 0, RTLDRARCH_WHATEVER, &aLoads[i].hLdrMod); else rc = RTLdrOpen(pszFilename, 0, RTLDRARCH_WHATEVER, &aLoads[i].hLdrMod); diff --git a/src/VBox/Runtime/testcase/tstLdr-4Imp-os2.def b/src/VBox/Runtime/testcase/tstLdr-4Imp-os2.def index 1dd8d2af..9d92af4b 100644 --- a/src/VBox/Runtime/testcase/tstLdr-4Imp-os2.def +++ b/src/VBox/Runtime/testcase/tstLdr-4Imp-os2.def @@ -2,7 +2,7 @@ ; tstLdr-4 fake DLL - Definition file. ; -; Copyright (C) 2006-2007 Oracle Corporation +; Copyright (C) 2006-2010 Oracle Corporation ; ; This file is part of VirtualBox Open Source Edition (OSE), as ; available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstLdr-4Imp-win.def b/src/VBox/Runtime/testcase/tstLdr-4Imp-win.def index 7508275c..e58384a1 100644 --- a/src/VBox/Runtime/testcase/tstLdr-4Imp-win.def +++ b/src/VBox/Runtime/testcase/tstLdr-4Imp-win.def @@ -2,7 +2,7 @@ ; tstLdr-4 fake DLL - Definition file. ; -; Copyright (C) 2006-2007 Oracle Corporation +; Copyright (C) 2006-2010 Oracle Corporation ; ; This file is part of VirtualBox Open Source Edition (OSE), as ; available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstLdr.cpp b/src/VBox/Runtime/testcase/tstLdr.cpp index 9a02f67f..2757c4c8 100644 --- a/src/VBox/Runtime/testcase/tstLdr.cpp +++ b/src/VBox/Runtime/testcase/tstLdr.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -121,7 +121,7 @@ static int testLdrOne(const char *pszFilename) /* open it */ int rc; - if (!strncmp(aLoads[i].pszName, "kLdr-", sizeof("kLdr-") - 1)) + if (!strncmp(aLoads[i].pszName, RT_STR_TUPLE("kLdr-"))) rc = RTLdrOpenkLdr(pszFilename, 0, RTLDRARCH_WHATEVER, &aLoads[i].hLdrMod); else rc = RTLdrOpen(pszFilename, 0, RTLDRARCH_WHATEVER, &aLoads[i].hLdrMod); diff --git a/src/VBox/Runtime/testcase/tstLdrDisasmTest.cpp b/src/VBox/Runtime/testcase/tstLdrDisasmTest.cpp index 1cb7654f..bc14072d 100644 --- a/src/VBox/Runtime/testcase/tstLdrDisasmTest.cpp +++ b/src/VBox/Runtime/testcase/tstLdrDisasmTest.cpp @@ -9,7 +9,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstLdrLoad.cpp b/src/VBox/Runtime/testcase/tstLdrLoad.cpp index 5be78da8..57b2bb70 100644 --- a/src/VBox/Runtime/testcase/tstLdrLoad.cpp +++ b/src/VBox/Runtime/testcase/tstLdrLoad.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstLdrObj.cpp b/src/VBox/Runtime/testcase/tstLdrObj.cpp index 26435222..2424e9da 100644 --- a/src/VBox/Runtime/testcase/tstLdrObj.cpp +++ b/src/VBox/Runtime/testcase/tstLdrObj.cpp @@ -9,7 +9,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstLdrObjR0.cpp b/src/VBox/Runtime/testcase/tstLdrObjR0.cpp index 5471d4e6..94e6edaf 100644 --- a/src/VBox/Runtime/testcase/tstLdrObjR0.cpp +++ b/src/VBox/Runtime/testcase/tstLdrObjR0.cpp @@ -9,7 +9,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstLog.cpp b/src/VBox/Runtime/testcase/tstLog.cpp index 75813604..348aa2cf 100644 --- a/src/VBox/Runtime/testcase/tstLog.cpp +++ b/src/VBox/Runtime/testcase/tstLog.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstMemAutoPtr.cpp b/src/VBox/Runtime/testcase/tstMemAutoPtr.cpp index 1c6de939..2354d7b0 100644 --- a/src/VBox/Runtime/testcase/tstMemAutoPtr.cpp +++ b/src/VBox/Runtime/testcase/tstMemAutoPtr.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2008-2010 Oracle Corporation + * Copyright (C) 2008-2014 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -100,12 +100,12 @@ void tstMemAutoPtrDestructorCounter(T *aMem) { if (aMem == NULL) { - RTPrintf("tstMemAutoPtr(%d): Destructor called with NILL handle!\n"); + RTPrintf("tstMemAutoPtr(): Destructor called with NULL handle!\n"); g_cErrors++; } else if (!VALID_PTR(aMem)) { - RTPrintf("tstMemAutoPtr(%d): Destructor called with a bad handle %p\n", aMem); + RTPrintf("tstMemAutoPtr(): Destructor called with a bad handle %p\n", aMem); g_cErrors++; } RTMemEfFreeNP(aMem); diff --git a/src/VBox/Runtime/testcase/tstMove.cpp b/src/VBox/Runtime/testcase/tstMove.cpp index 98117800..e92dde7e 100644 --- a/src/VBox/Runtime/testcase/tstMove.cpp +++ b/src/VBox/Runtime/testcase/tstMove.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstMp-1.cpp b/src/VBox/Runtime/testcase/tstMp-1.cpp deleted file mode 100644 index 6039762b..00000000 --- a/src/VBox/Runtime/testcase/tstMp-1.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/* $Id: tstMp-1.cpp $ */ -/** @file - * IPRT Testcase - RTMp. - */ - -/* - * Copyright (C) 2008 Oracle Corporation - * - * This file is part of VirtualBox Open Source Edition (OSE), as - * available from http://www.virtualbox.org. This file is free software; - * you can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) as published by the Free Software - * Foundation, in version 2 as it comes in the "COPYING" file of the - * VirtualBox OSE distribution. VirtualBox OSE is distributed in the - * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. - * - * The contents of this file may alternatively be used under the terms - * of the Common Development and Distribution License Version 1.0 - * (CDDL) only, as it comes in the "COPYING.CDDL" file of the - * VirtualBox OSE distribution, in which case the provisions of the - * CDDL are applicable instead of those of the GPL. - * - * You may elect to license modified versions of this file under the - * terms and conditions of either the GPL or the CDDL or both. - */ - -/******************************************************************************* -* Header Files * -*******************************************************************************/ -#include <iprt/mp.h> -#include <iprt/cpuset.h> -#include <iprt/err.h> -#include <iprt/initterm.h> -#include <iprt/stream.h> -#include <iprt/string.h> - - -/******************************************************************************* -* Global Variables * -*******************************************************************************/ -static unsigned g_cErrors = 0; - - -int main() -{ - RTR3InitExeNoArguments(0); - RTPrintf("tstMp-1: TESTING...\n"); - - /* - * Present and possible CPUs. - */ - RTCPUID cCpus = RTMpGetCount(); - if (cCpus > 0) - RTPrintf("tstMp-1: RTMpGetCount -> %d\n", (int)cCpus); - else - { - RTPrintf("tstMp-1: FAILURE: RTMpGetCount -> %d\n", (int)cCpus); - g_cErrors++; - cCpus = 1; - } - - RTCPUSET Set; - PRTCPUSET pSet = RTMpGetSet(&Set); - if (pSet == &Set) - { - if ((RTCPUID)RTCpuSetCount(&Set) != cCpus) - { - RTPrintf("tstMp-1: FAILURE: RTMpGetSet returned a set with a different cpu count; %d, expected %d\n", - RTCpuSetCount(&Set), cCpus); - g_cErrors++; - } - RTPrintf("tstMp-1: Possible CPU mask:\n"); - for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++) - { - RTCPUID idCpu = RTMpCpuIdFromSetIndex(iCpu); - if (RTCpuSetIsMemberByIndex(&Set, iCpu)) - { - RTPrintf("tstMp-1: %2d - id %d: %u/%u MHz", iCpu, (int)idCpu, - RTMpGetCurFrequency(idCpu), RTMpGetMaxFrequency(idCpu)); - if (RTMpIsCpuPresent(idCpu)) - RTPrintf(RTMpIsCpuOnline(idCpu) ? " online\n" : " offline\n"); - else - { - if (!RTMpIsCpuOnline(idCpu)) - RTPrintf(" absent\n"); - else - { - RTPrintf(" online but absent!\n"); - RTPrintf("tstMp-1: FAILURE: Cpu with index %d is report as !RTIsCpuPresent while RTIsCpuOnline returns true!\n", iCpu); - g_cErrors++; - } - } - if (!RTMpIsCpuPossible(idCpu)) - { - RTPrintf("tstMp-1: FAILURE: Cpu with index %d is returned by RTCpuSet but not RTMpIsCpuPossible!\n", iCpu); - g_cErrors++; - } - } - else if (RTMpIsCpuPossible(idCpu)) - { - RTPrintf("tstMp-1: FAILURE: Cpu with index %d is returned by RTMpIsCpuPossible but not RTCpuSet!\n", iCpu); - g_cErrors++; - } - else if (RTMpGetCurFrequency(idCpu) != 0) - { - RTPrintf("tstMp-1: FAILURE: RTMpGetCurFrequency(%d[idx=%d]) didn't return 0 as it should\n", (int)idCpu, iCpu); - g_cErrors++; - } - else if (RTMpGetMaxFrequency(idCpu) != 0) - { - RTPrintf("tstMp-1: FAILURE: RTMpGetMaxFrequency(%d[idx=%d]) didn't return 0 as it should\n", (int)idCpu, iCpu); - g_cErrors++; - } - } - } - else - { - RTPrintf("tstMp-1: FAILURE: RTMpGetSet -> %p, expected %p\n", pSet, &Set); - g_cErrors++; - RTCpuSetEmpty(&Set); - RTCpuSetAdd(&Set, RTMpCpuIdFromSetIndex(0)); - } - - /* - * Online CPUs. - */ - RTCPUID cCpusOnline = RTMpGetOnlineCount(); - if (cCpusOnline > 0) - { - if (cCpusOnline <= cCpus) - RTPrintf("tstMp-1: RTMpGetOnlineCount -> %d\n", (int)cCpusOnline); - else - { - RTPrintf("tstMp-1: FAILURE: RTMpGetOnlineCount -> %d, expected <= %d\n", (int)cCpusOnline, (int)cCpus); - g_cErrors++; - cCpusOnline = cCpus; - } - } - else - { - RTPrintf("tstMp-1: FAILURE: RTMpGetOnlineCount -> %d\n", (int)cCpusOnline); - g_cErrors++; - cCpusOnline = 1; - } - - RTCPUSET SetOnline; - pSet = RTMpGetOnlineSet(&SetOnline); - if (pSet == &SetOnline) - { - if (RTCpuSetCount(&SetOnline) <= 0) - { - RTPrintf("tstMp-1: FAILURE: RTMpGetOnlineSet returned an empty set!\n"); - g_cErrors++; - } - else if ((RTCPUID)RTCpuSetCount(&SetOnline) > cCpus) - { - RTPrintf("tstMp-1: FAILURE: RTMpGetOnlineSet returned a too high value; %d, expected <= %d\n", - RTCpuSetCount(&SetOnline), cCpus); - g_cErrors++; - } - RTPrintf("tstMp-1: Online CPU mask:\n"); - for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++) - if (RTCpuSetIsMemberByIndex(&SetOnline, iCpu)) - { - RTCPUID idCpu = RTMpCpuIdFromSetIndex(iCpu); - RTPrintf("tstMp-1: %2d - id %d: %u/%u MHz %s\n", iCpu, (int)idCpu, RTMpGetCurFrequency(idCpu), - RTMpGetMaxFrequency(idCpu), RTMpIsCpuOnline(idCpu) ? "online" : "offline"); - if (!RTCpuSetIsMemberByIndex(&Set, iCpu)) - { - RTPrintf("tstMp-1: FAILURE: online cpu with index %2d is not a member of the possible cpu set!\n", iCpu); - g_cErrors++; - } - } - - /* There isn't any sane way of testing RTMpIsCpuOnline really... :-/ */ - } - else - { - RTPrintf("tstMp-1: FAILURE: RTMpGetOnlineSet -> %p, expected %p\n", pSet, &Set); - g_cErrors++; - } - - /* - * Present CPUs. - */ - RTCPUID cCpusPresent = RTMpGetPresentCount(); - if (cCpusPresent > 0) - { - if ( cCpusPresent <= cCpus - && cCpusPresent >= cCpusOnline) - RTPrintf("tstMp-1: RTMpGetPresentCount -> %d\n", (int)cCpusPresent); - else - { - RTPrintf("tstMp-1: FAILURE: RTMpGetPresentCount -> %d, expected <= %d and >= %d\n", (int)cCpusPresent, (int)cCpus, (int)cCpusOnline); - g_cErrors++; - } - } - else - { - RTPrintf("tstMp-1: FAILURE: RTMpGetPresentCount -> %d\n", (int)cCpusPresent); - g_cErrors++; - cCpusPresent = 1; - } - - RTCPUSET SetPresent; - pSet = RTMpGetPresentSet(&SetPresent); - if (pSet == &SetPresent) - { - if (RTCpuSetCount(&SetPresent) <= 0) - { - RTPrintf("tstMp-1: FAILURE: RTMpGetPresentSet returned an empty set!\n"); - g_cErrors++; - } - else if ((RTCPUID)RTCpuSetCount(&SetPresent) != cCpusPresent) - { - RTPrintf("tstMp-1: FAILURE: RTMpGetPresentSet returned a bad value; %d, expected = %d\n", - RTCpuSetCount(&SetPresent), cCpusPresent); - g_cErrors++; - } - RTPrintf("tstMp-1: Present CPU mask:\n"); - for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++) - if (RTCpuSetIsMemberByIndex(&SetPresent, iCpu)) - { - RTCPUID idCpu = RTMpCpuIdFromSetIndex(iCpu); - RTPrintf("tstMp-1: %2d - id %d: %u/%u MHz %s\n", iCpu, (int)idCpu, RTMpGetCurFrequency(idCpu), - RTMpGetMaxFrequency(idCpu), RTMpIsCpuPresent(idCpu) ? "present" : "absent"); - if (!RTCpuSetIsMemberByIndex(&Set, iCpu)) - { - RTPrintf("tstMp-1: FAILURE: online cpu with index %2d is not a member of the possible cpu set!\n", iCpu); - g_cErrors++; - } - } - - /* There isn't any sane way of testing RTMpIsCpuPresent really... :-/ */ - } - else - { - RTPrintf("tstMp-1: FAILURE: RTMpGetPresentSet -> %p, expected %p\n", pSet, &Set); - g_cErrors++; - } - - - /* Find an online cpu for the next test. */ - RTCPUID idCpuOnline; - for (idCpuOnline = 0; idCpuOnline < RTCPUSET_MAX_CPUS; idCpuOnline++) - if (RTMpIsCpuOnline(idCpuOnline)) - break; - - /* - * Quick test of RTMpGetDescription. - */ - char szBuf[64]; - int rc = RTMpGetDescription(idCpuOnline, &szBuf[0], sizeof(szBuf)); - if (RT_SUCCESS(rc)) - { - RTPrintf("tstMp-1: RTMpGetDescription -> '%s'\n", szBuf); - - size_t cch = strlen(szBuf); - rc = RTMpGetDescription(idCpuOnline, &szBuf[0], cch); - if (rc != VERR_BUFFER_OVERFLOW) - { - RTPrintf("tstMp-1: FAILURE: RTMpGetDescription -> %Rrc, expected VERR_BUFFER_OVERFLOW\n", rc); - g_cErrors++; - } - rc = RTMpGetDescription(idCpuOnline, &szBuf[0], cch + 1); - if (RT_FAILURE(rc)) - { - RTPrintf("tstMp-1: FAILURE: RTMpGetDescription -> %Rrc, expected VINF_SUCCESS\n", rc); - g_cErrors++; - } - } - else - { - RTPrintf("tstMp-1: FAILURE: RTMpGetDescription -> %Rrc\n", rc); - g_cErrors++; - } - - - if (!g_cErrors) - RTPrintf("tstMp-1: SUCCESS\n", g_cErrors); - else - RTPrintf("tstMp-1: FAILURE - %d errors\n", g_cErrors); - return !!g_cErrors; -} - diff --git a/src/VBox/Runtime/testcase/tstNoCrt-1.cpp b/src/VBox/Runtime/testcase/tstNoCrt-1.cpp index 9131b6c1..52e2099a 100644 --- a/src/VBox/Runtime/testcase/tstNoCrt-1.cpp +++ b/src/VBox/Runtime/testcase/tstNoCrt-1.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2008-2010 Oracle Corporation + * Copyright (C) 2008-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstOnce.cpp b/src/VBox/Runtime/testcase/tstOnce.cpp index b6c05551..e09d93bd 100644 --- a/src/VBox/Runtime/testcase/tstOnce.cpp +++ b/src/VBox/Runtime/testcase/tstOnce.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2008 Oracle Corporation + * Copyright (C) 2008-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -48,13 +48,13 @@ static RTONCE g_Once2 = RTONCE_INITIALIZER; static RTSEMEVENTMULTI g_hEventMulti = NIL_RTSEMEVENTMULTI; -static DECLCALLBACK(int) Once1CB(void *pvUser1, void *pvUser2) +static DECLCALLBACK(int) Once1CB(void *pvUser) { if (g_fOnceCB1) return VERR_WRONG_ORDER; - if (pvUser1 != (void *)1 || pvUser2 != (void *)42) + if (pvUser != (void *)1) { - RTPrintf("tstOnce: ERROR - Once1CB: pvUser1=%p pvUser2=%p!\n", pvUser1, pvUser2); + RTPrintf("tstOnce: ERROR - Once1CB: pvUser=%p!\n", pvUser); g_cErrors++; return VERR_INVALID_PARAMETER; } @@ -62,7 +62,7 @@ static DECLCALLBACK(int) Once1CB(void *pvUser1, void *pvUser2) } -static DECLCALLBACK(int) Once2CB(void *pvUser1, void *pvUser2) +static DECLCALLBACK(int) Once2CB(void *pvUser) { if (ASMAtomicIncU32(&g_cOnce2CB) != 1) { @@ -70,9 +70,9 @@ static DECLCALLBACK(int) Once2CB(void *pvUser1, void *pvUser2) g_cErrors++; return VERR_WRONG_ORDER; } - if (pvUser1 != (void *)42 || pvUser2 != (void *)1) + if (pvUser != (void *)42) { - RTPrintf("tstOnce: ERROR - Once2CB: pvUser1=%p pvUser2=%p!\n", pvUser1, pvUser2); + RTPrintf("tstOnce: ERROR - Once2CB: pvUser=%p!\n", pvUser); g_cErrors++; return VERR_INVALID_PARAMETER; } @@ -89,7 +89,7 @@ static DECLCALLBACK(int) Once2Thread(RTTHREAD hThread, void *pvUser) int rc = RTSemEventMultiWait(g_hEventMulti, RT_INDEFINITE_WAIT); if (RT_FAILURE(rc)) return rc; - rc = RTOnce(&g_Once2, Once2CB, (void *)42, (void *)1); + rc = RTOnce(&g_Once2, Once2CB, (void *)42); if (RT_SUCCESS(rc)) { if (!ASMAtomicUoReadBool(&g_fOnce2Ready)) @@ -112,11 +112,11 @@ int main() RTPrintf("tstOnce: TESTING - smoke...\n"); RTONCE Once1 = RTONCE_INITIALIZER; g_fOnceCB1 = false; - int rc = RTOnce(&Once1, Once1CB, (void *)1, (void *)42); + int rc = RTOnce(&Once1, Once1CB, (void *)1); if (rc != VINF_SUCCESS) RTPrintf("tstOnce: ERROR - Once1, 1 failed, rc=%Rrc\n", rc); g_fOnceCB1 = false; - rc = RTOnce(&Once1, Once1CB, (void *)1, (void *)42); + rc = RTOnce(&Once1, Once1CB, (void *)1); if (rc != VINF_SUCCESS) RTPrintf("tstOnce: ERROR - Once1, 2 failed, rc=%Rrc\n", rc); diff --git a/src/VBox/Runtime/testcase/tstPrfRT.cpp b/src/VBox/Runtime/testcase/tstPrfRT.cpp index 27a26e9a..05a08836 100644 --- a/src/VBox/Runtime/testcase/tstPrfRT.cpp +++ b/src/VBox/Runtime/testcase/tstPrfRT.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstR0ThreadPreemption.cpp b/src/VBox/Runtime/testcase/tstR0ThreadPreemption.cpp index ad2dccda..85b66668 100644 --- a/src/VBox/Runtime/testcase/tstR0ThreadPreemption.cpp +++ b/src/VBox/Runtime/testcase/tstR0ThreadPreemption.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -31,12 +31,127 @@ #include <iprt/asm-amd64-x86.h> #include <iprt/err.h> +#include <iprt/mem.h> #include <iprt/time.h> #include <iprt/string.h> #include <VBox/sup.h> #include "tstR0ThreadPreemption.h" +#define TSTRTR0THREADCTXDATA_MAGIC 0xc01a50da + +/** + * Thread-context hook data. + */ +typedef struct TSTRTR0THREADCTXDATA +{ + uint32_t volatile u32Magic; + RTCPUID uSourceCpuId; + RTNATIVETHREAD hSourceThread; + RTTHREADCTX hThreadCtx; + + /* For RTTHREADCTXEVENT_PREEMPTING. */ + bool fPreemptingSuccess; + volatile bool fPreemptingInvoked; + + /* For RTTHREADCTXEVENT_RESUMED. */ + bool fResumedSuccess; + volatile bool fResumedInvoked; + + char achResult[512]; +} TSTRTR0THREADCTXDATA, *PTSTRTR0THREADCTXDATA; + + +/** + * Thread-context hook function. + * + * @param enmEvent The thread-context event. + * @param pvUser Pointer to the user argument. + */ +static DECLCALLBACK(void) tstR0ThreadCtxHook(RTTHREADCTXEVENT enmEvent, void *pvUser) +{ + PTSTRTR0THREADCTXDATA pData = (PTSTRTR0THREADCTXDATA)pvUser; + AssertPtrReturnVoid(pData); + + if (pData->u32Magic != TSTRTR0THREADCTXDATA_MAGIC) + { + RTStrPrintf(pData->achResult, sizeof(pData->achResult), "!tstR0ThreadCtxHook: Invalid magic."); + return; + } + + switch (enmEvent) + { + case RTTHREADCTXEVENT_PREEMPTING: + { + ASMAtomicWriteBool(&pData->fPreemptingInvoked, true); + + /* We've already been called once, we now might very well be on another CPU. Nothing to do here. */ + if (pData->fPreemptingSuccess) + return; + + if (RTThreadPreemptIsEnabled(NIL_RTTHREAD)) + { + RTStrPrintf(pData->achResult, sizeof(pData->achResult), + "!tstR0ThreadCtxHook[RTTHREADCTXEVENT_PREEMPTING]: Called with preemption enabled"); + break; + } + + RTNATIVETHREAD hCurrentThread = RTThreadNativeSelf(); + if (pData->hSourceThread != hCurrentThread) + { + RTStrPrintf(pData->achResult, sizeof(pData->achResult), + "!tstR0ThreadCtxHook[RTTHREADCTXEVENT_PREEMPTING]: Thread switched! Source=%RTnthrd Current=%RTnthrd.", + pData->hSourceThread, hCurrentThread); + break; + } + + RTCPUID uCurrentCpuId = RTMpCpuId(); + if (pData->uSourceCpuId != uCurrentCpuId) + { + RTStrPrintf(pData->achResult, sizeof(pData->achResult), + "!tstR0ThreadCtxHook[RTTHREADCTXEVENT_PREEMPTING]: migrated uSourceCpuId=%RU32 uCurrentCpuId=%RU32", + pData->uSourceCpuId, uCurrentCpuId); + break; + } + + pData->fPreemptingSuccess = true; + break; + } + + case RTTHREADCTXEVENT_RESUMED: + { + ASMAtomicWriteBool(&pData->fResumedInvoked, true); + + /* We've already been called once successfully, nothing more to do. */ + if (ASMAtomicReadBool(&pData->fResumedSuccess)) + return; + + if (!pData->fPreemptingSuccess) + { + RTStrPrintf(pData->achResult, sizeof(pData->achResult), + "!tstR0ThreadCtxHook[RTTHREADCTXEVENT_RESUMED]: Called before preempting callback was invoked."); + break; + } + + RTNATIVETHREAD hCurrentThread = RTThreadNativeSelf(); + if (pData->hSourceThread != hCurrentThread) + { + RTStrPrintf(pData->achResult, sizeof(pData->achResult), + "!tstR0ThreadCtxHook[RTTHREADCTXEVENT_RESUMED]: Thread switched! Source=%RTnthrd Current=%RTnthrd.", + pData->hSourceThread, hCurrentThread); + break; + } + + ASMAtomicWriteBool(&pData->fResumedSuccess, true); + break; + } + + default: + AssertMsgFailed(("Invalid event %#x\n", enmEvent)); + break; + } +} + /** * Service request callback function. @@ -91,12 +206,22 @@ DECLEXPORT(int) TSTR0ThreadPreemptionSrvReqHandler(PSUPDRVSESSION pSession, uint break; } + case TSTR0THREADPREMEPTION_IS_TRUSTY: + if (!RTThreadPreemptIsPendingTrusty()) + RTStrPrintf(pszErr, cchErr, "!Untrusty"); + break; + case TSTR0THREADPREMEPTION_IS_PENDING: { RTTHREADPREEMPTSTATE State = RTTHREADPREEMPTSTATE_INITIALIZER; RTThreadPreemptDisable(&State); if (!RTThreadPreemptIsEnabled(NIL_RTTHREAD)) { +#ifdef RT_OS_DARWIN + uint64_t const cNsMax = UINT64_C(8)*1000U*1000U*1000U; +#else + uint64_t const cNsMax = UINT64_C(2)*1000U*1000U*1000U; +#endif if (ASMIntAreEnabled()) { uint64_t u64StartTS = RTTimeNanoTS(); @@ -112,8 +237,8 @@ DECLEXPORT(int) TSTR0ThreadPreemptionSrvReqHandler(PSUPDRVSESSION pSession, uint cNanosSysElapsed = RTTimeSystemNanoTS() - u64StartSysTS; cLoops++; } while ( !fPending - && cNanosElapsed < UINT64_C(2)*1000U*1000U*1000U - && cNanosSysElapsed < UINT64_C(2)*1000U*1000U*1000U + && cNanosElapsed < cNsMax + && cNanosSysElapsed < cNsMax && cLoops < 100U*_1M); if (!fPending) RTStrPrintf(pszErr, cchErr, "!Preempt not pending after %'llu loops / %'llu ns / %'llu ns (sys)", @@ -168,6 +293,159 @@ DECLEXPORT(int) TSTR0ThreadPreemptionSrvReqHandler(PSUPDRVSESSION pSession, uint break; } + case TSTR0THREADPREEMPTION_CTXHOOKS: + { + if (!RTThreadPreemptIsEnabled(NIL_RTTHREAD)) + { + RTStrPrintf(pszErr, cchErr, "!RTThreadCtxHooksCreate must be called with preemption enabled"); + break; + } + + bool fRegistered = RTThreadCtxHooksAreRegistered(NIL_RTTHREADCTX); + if (fRegistered) + { + RTStrPrintf(pszErr, cchErr, "!RTThreadCtxHooksAreRegistered returns true before creating any hooks"); + break; + } + + RTTHREADCTX hThreadCtx; + int rc = RTThreadCtxHooksCreate(&hThreadCtx); + if (RT_FAILURE(rc)) + { + if (rc == VERR_NOT_SUPPORTED) + RTStrPrintf(pszErr, cchErr, "RTThreadCtxHooksCreate returns VERR_NOT_SUPPORTED"); + else + RTStrPrintf(pszErr, cchErr, "!RTThreadCtxHooksCreate returns %Rrc", rc); + break; + } + + fRegistered = RTThreadCtxHooksAreRegistered(hThreadCtx); + if (fRegistered) + { + RTStrPrintf(pszErr, cchErr, "!RTThreadCtxHooksAreRegistered returns true before registering any hooks"); + RTThreadCtxHooksRelease(hThreadCtx); + break; + } + + PTSTRTR0THREADCTXDATA pCtxData = (PTSTRTR0THREADCTXDATA)RTMemAllocZ(sizeof(*pCtxData)); + AssertReturn(pCtxData, VERR_NO_MEMORY); + pCtxData->u32Magic = TSTRTR0THREADCTXDATA_MAGIC; + pCtxData->hThreadCtx = hThreadCtx; + pCtxData->fPreemptingSuccess = false; + pCtxData->fPreemptingInvoked = false; + pCtxData->fResumedInvoked = false; + pCtxData->fResumedSuccess = false; + pCtxData->hSourceThread = RTThreadNativeSelf(); + RT_ZERO(pCtxData->achResult); + + RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER; + RTThreadPreemptDisable(&PreemptState); + Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD)); + + pCtxData->uSourceCpuId = RTMpCpuId(); + + rc = RTThreadCtxHooksRegister(hThreadCtx, &tstR0ThreadCtxHook, pCtxData); + if (RT_FAILURE(rc)) + { + RTThreadPreemptRestore(&PreemptState); + RTMemFree(pCtxData); + RTStrPrintf(pszErr, cchErr, "!RTThreadCtxHooksRegister returns %Rrc", rc); + break; + } + + fRegistered = RTThreadCtxHooksAreRegistered(hThreadCtx); + if (!fRegistered) + { + RTThreadPreemptRestore(&PreemptState); + RTMemFree(pCtxData); + RTStrPrintf(pszErr, cchErr, "!RTThreadCtxHooksAreRegistered return false when hooks are supposedly registered"); + break; + } + + RTThreadPreemptRestore(&PreemptState); + + /* Check if the preempting callback has/will been invoked. */ + const uint32_t cMsTimeout = 10000; + const uint32_t cMsSleepGranularity = 50; + uint32_t cMsSlept = 0; + RTCPUID uCurrentCpuId = NIL_RTCPUID; + for (;;) + { + RTThreadYield(); + RTThreadPreemptDisable(&PreemptState); + uCurrentCpuId = RTMpCpuId(); + RTThreadPreemptRestore(&PreemptState); + + if ( pCtxData->uSourceCpuId != uCurrentCpuId + || cMsSlept >= cMsTimeout) + { + break; + } + + RTThreadSleep(cMsSleepGranularity); + cMsSlept += cMsSleepGranularity; + } + + if (!ASMAtomicReadBool(&pCtxData->fPreemptingInvoked)) + { + if (pCtxData->uSourceCpuId != uCurrentCpuId) + { + RTStrPrintf(pszErr, cchErr, + "!tstR0ThreadCtxHooks[RTTHREADCTXEVENT_PREEMPTING] not invoked before migrating from CPU %RU32 to %RU32", + pCtxData->uSourceCpuId, uCurrentCpuId); + } + else + { + RTStrPrintf(pszErr, cchErr, "!tstR0ThreadCtxHooks[RTTHREADCTXEVENT_PREEMPTING] not invoked after ca. %u ms", + cMsSlept); + } + } + else if (!pCtxData->fPreemptingSuccess) + RTStrCopy(pszErr, cchErr, pCtxData->achResult); + else + { + /* Preempting callback succeeded, now check if the resumed callback has/will been invoked. */ + cMsSlept = 0; + for (;;) + { + if ( ASMAtomicReadBool(&pCtxData->fResumedInvoked) + || cMsSlept >= cMsTimeout) + { + break; + } + + RTThreadSleep(cMsSleepGranularity); + cMsSlept += cMsSleepGranularity; + } + + if (!ASMAtomicReadBool(&pCtxData->fResumedInvoked)) + { + RTStrPrintf(pszErr, cchErr, "!tstR0ThreadCtxHooks[RTTHREADCTXEVENT_RESUMED] not invoked after ca. %u ms", + cMsSlept); + } + else if (!pCtxData->fResumedSuccess) + RTStrCopy(pszErr, cchErr, pCtxData->achResult); + } + + RTThreadCtxHooksDeregister(hThreadCtx); + + fRegistered = RTThreadCtxHooksAreRegistered(hThreadCtx); + if (fRegistered) + { + RTMemFree(pCtxData); + RTStrPrintf(pszErr, cchErr, "!RTThreadCtxHooksAreRegistered return true when hooks are deregistered"); + break; + } + + Assert(RTThreadPreemptIsEnabled(NIL_RTTHREAD)); + uint32_t cRefs = RTThreadCtxHooksRelease(hThreadCtx); + if (cRefs == UINT32_MAX) + RTStrPrintf(pszErr, cchErr, "!RTThreadCtxHooksRelease returns invalid cRefs!"); + + RTMemFree(pCtxData); + break; + } + default: RTStrPrintf(pszErr, cchErr, "!Unknown test #%d", uOperation); break; diff --git a/src/VBox/Runtime/testcase/tstR0ThreadPreemption.h b/src/VBox/Runtime/testcase/tstR0ThreadPreemption.h index f3737642..a6e716ba 100644 --- a/src/VBox/Runtime/testcase/tstR0ThreadPreemption.h +++ b/src/VBox/Runtime/testcase/tstR0ThreadPreemption.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -36,7 +36,9 @@ typedef enum TSTR0THREADPREMEPTION TSTR0THREADPREMEPTION_SANITY_OK = 1, TSTR0THREADPREMEPTION_SANITY_FAILURE, TSTR0THREADPREMEPTION_BASIC, + TSTR0THREADPREMEPTION_IS_TRUSTY, TSTR0THREADPREMEPTION_IS_PENDING, - TSTR0THREADPREMEPTION_NESTED + TSTR0THREADPREMEPTION_NESTED, + TSTR0THREADPREEMPTION_CTXHOOKS } TSTR0THREADPREMEPTION; diff --git a/src/VBox/Runtime/testcase/tstR0ThreadPreemptionDriver.cpp b/src/VBox/Runtime/testcase/tstR0ThreadPreemptionDriver.cpp index 92126939..98263305 100644 --- a/src/VBox/Runtime/testcase/tstR0ThreadPreemptionDriver.cpp +++ b/src/VBox/Runtime/testcase/tstR0ThreadPreemptionDriver.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -29,18 +29,50 @@ *******************************************************************************/ #include <iprt/initterm.h> +#include <iprt/asm.h> +#include <iprt/cpuset.h> #include <iprt/err.h> #include <iprt/path.h> #include <iprt/param.h> #include <iprt/stream.h> #include <iprt/string.h> #include <iprt/test.h> +#include <iprt/time.h> #include <iprt/thread.h> #ifdef VBOX # include <VBox/sup.h> # include "tstR0ThreadPreemption.h" #endif +/******************************************************************************* +* Global Variables * +*******************************************************************************/ +static bool volatile g_fTerminate = false; + + +/** + * Try make sure all online CPUs will be engaged. + */ +static DECLCALLBACK(int) MyThreadProc(RTTHREAD hSelf, void *pvCpuIdx) +{ + RTCPUSET Affinity; + RTCpuSetEmpty(&Affinity); + RTCpuSetAddByIndex(&Affinity, (intptr_t)pvCpuIdx); + RTThreadSetAffinity(&Affinity); /* ignore return code as it's not supported on all hosts. */ + + while (!g_fTerminate) + { + uint64_t tsStart = RTTimeMilliTS(); + do + { + ASMNopPause(); + } while (RTTimeMilliTS() - tsStart < 8); + RTThreadSleep(4); + } + + return VINF_SUCCESS; +} + int main(int argc, char **argv) { @@ -114,8 +146,8 @@ int main(int argc, char **argv) TSTR0THREADPREMEPTION_SANITY_FAILURE, 0, &Req.Hdr), VINF_SUCCESS); if (RT_FAILURE(rc)) return RTTestSummaryAndDestroy(hTest); - RTTESTI_CHECK_MSG(!strncmp(Req.szMsg, "!42failure42", sizeof("!42failure42") - 1), ("%s", Req.szMsg)); - if (strncmp(Req.szMsg, "!42failure42", sizeof("!42failure42") - 1)) + RTTESTI_CHECK_MSG(!strncmp(Req.szMsg, RT_STR_TUPLE("!42failure42")), ("%s", Req.szMsg)); + if (strncmp(Req.szMsg, RT_STR_TUPLE("!42failure42"))) return RTTestSummaryAndDestroy(hTest); /* @@ -138,10 +170,39 @@ int main(int argc, char **argv) RTTestIPrintf(RTTESTLVL_ALWAYS, "%s", Req.szMsg); /* + * Is it trusty. + */ + RTTestSub(hTest, "RTThreadPreemptIsPendingTrusty"); + Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC; + Req.Hdr.cbReq = sizeof(Req); + Req.szMsg[0] = '\0'; + RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR0ThreadPreemption", sizeof("tstR0ThreadPreemption") - 1, + TSTR0THREADPREMEPTION_IS_TRUSTY, 0, &Req.Hdr), VINF_SUCCESS); + if (RT_FAILURE(rc)) + return RTTestSummaryAndDestroy(hTest); + if (Req.szMsg[0] == '!') + RTTestIFailed("%s", &Req.szMsg[1]); + else if (Req.szMsg[0]) + RTTestIPrintf(RTTESTLVL_ALWAYS, "%s", Req.szMsg); + + /* * Stay in ring-0 until preemption is pending. */ -RTThreadSleep(250); /** @todo fix GIP initialization? */ + RTTHREAD ahThreads[RTCPUSET_MAX_CPUS]; + uint32_t cThreads = RTMpGetCount(); + RTCPUSET OnlineSet; + RTMpGetOnlineSet(&OnlineSet); + for (uint32_t i = 0; i < RT_ELEMENTS(ahThreads); i++) + { + ahThreads[i] = NIL_RTTHREAD; + if (RTCpuSetIsMemberByIndex(&OnlineSet, i)) + RTThreadCreateF(&ahThreads[i], MyThreadProc, (void *)(uintptr_t)i, 0, RTTHREADTYPE_DEFAULT, + RTTHREADFLAGS_WAITABLE, "cpu=%u", i); + } + + RTTestSub(hTest, "Pending Preemption"); + RTThreadSleep(250); /** @todo fix GIP initialization? */ for (int i = 0; ; i++) { Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC; @@ -149,7 +210,7 @@ RTThreadSleep(250); /** @todo fix GIP initialization? */ Req.szMsg[0] = '\0'; RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR0ThreadPreemption", sizeof("tstR0ThreadPreemption") - 1, TSTR0THREADPREMEPTION_IS_PENDING, 0, &Req.Hdr), VINF_SUCCESS); - if ( strcmp(Req.szMsg, "cLoops=1\n") + if ( strcmp(Req.szMsg, "!cLoops=1\n") || i >= 64) { if (Req.szMsg[0] == '!') @@ -160,8 +221,15 @@ RTThreadSleep(250); /** @todo fix GIP initialization? */ } if ((i % 3) == 0) RTThreadYield(); + else if ((i % 16) == 0) + RTThreadSleep(8); } + ASMAtomicWriteBool(&g_fTerminate, true); + for (uint32_t i = 0; i < RT_ELEMENTS(ahThreads); i++) + if (ahThreads[i] != NIL_RTTHREAD) + RTThreadWait(ahThreads[i], 5000, NULL); + /* * Test nested RTThreadPreemptDisable calls. */ @@ -176,6 +244,40 @@ RTThreadSleep(250); /** @todo fix GIP initialization? */ else if (Req.szMsg[0]) RTTestIPrintf(RTTESTLVL_ALWAYS, "%s", Req.szMsg); + + /* + * Test thread-context hooks. + */ + RTTestSub(hTest, "RTThreadCtxHooks"); + uint64_t u64StartTS = RTTimeMilliTS(); + uint64_t cMsMax = 60000; /* ca. 1 minute timeout. */ + uint64_t cMsElapsed; + for (unsigned i = 0; i < 50; i++) + { + Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC; + Req.Hdr.cbReq = sizeof(Req); + Req.szMsg[0] = '\0'; + RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR0ThreadPreemption", sizeof("tstR0ThreadPreemption") - 1, + TSTR0THREADPREEMPTION_CTXHOOKS, 0, &Req.Hdr), VINF_SUCCESS); + if (RT_FAILURE(rc)) + return RTTestSummaryAndDestroy(hTest); + if (Req.szMsg[0] == '!') + RTTestIFailed("%s", &Req.szMsg[1]); + else if (Req.szMsg[0]) + RTTestIPrintf(RTTESTLVL_ALWAYS, "%s", Req.szMsg); + if (!(i % 10)) + RTTestIPrintf(RTTESTLVL_ALWAYS, "RTThreadCtxHooks passed %u iteration(s)\n", i); + + /* Check timeout and bail. */ + cMsElapsed = RTTimeMilliTS() - u64StartTS; + if (cMsElapsed > cMsMax) + { + RTTestIPrintf(RTTESTLVL_INFO, "RTThreadCtxHooks Stopping iterations. %RU64 ms. for %u iterations.\n", + cMsElapsed, i); + break; + } + } + /* * Done. */ diff --git a/src/VBox/Runtime/testcase/tstRTAssertCompile.cpp b/src/VBox/Runtime/testcase/tstRTAssertCompile.cpp index 4749e495..a14f86e3 100644 --- a/src/VBox/Runtime/testcase/tstRTAssertCompile.cpp +++ b/src/VBox/Runtime/testcase/tstRTAssertCompile.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTAvl.cpp b/src/VBox/Runtime/testcase/tstRTAvl.cpp index e77f6811..b460946d 100644 --- a/src/VBox/Runtime/testcase/tstRTAvl.cpp +++ b/src/VBox/Runtime/testcase/tstRTAvl.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2009 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTBase64.cpp b/src/VBox/Runtime/testcase/tstRTBase64.cpp index 57dc7d0a..6f86c6be 100644 --- a/src/VBox/Runtime/testcase/tstRTBase64.cpp +++ b/src/VBox/Runtime/testcase/tstRTBase64.cpp @@ -174,31 +174,31 @@ int main() /* * Test for buffer overruns. */ + RTTestSubF(hTest, "Test 3"); static uint8_t s_abData4[32768]; for (size_t i = 0; i < sizeof(s_abData4); i++) s_abData4[i] = i % 256; for (size_t cbSrc = 1; cbSrc <= sizeof(s_abData4); cbSrc++) { - RTTestSubF(hTest, "Test 3-%zu", cbSrc); char szEnc[49152]; memset(szEnc, '\0', sizeof(szEnc)); size_t cchEnc = RTBase64EncodedLength(cbSrc); if (cchEnc >= sizeof(szEnc)) - RTTestIFailed("RTBase64EncodedLength returned %zu bytes, too big\n", cchEnc); + RTTestIFailed("RTBase64EncodedLength(%zu) returned %zu bytes, too big\n", cbSrc, cchEnc); size_t cchOut = 0; rc = RTBase64Encode(s_abData4, cbSrc, szEnc, cchEnc, &cchOut); if (rc != VERR_BUFFER_OVERFLOW) - RTTestIFailed("RTBase64Encode has no buffer overflow with too small buffer -> %Rrc\n", rc); + RTTestIFailed("RTBase64Encode(,%zu,) has no buffer overflow with too small buffer -> %Rrc\n", cbSrc, rc); rc = RTBase64Encode(s_abData4, cbSrc, szEnc, cchEnc + 1, &cchOut); if (RT_FAILURE(rc)) RTTestIFailed("RTBase64Encode -> %Rrc\n", rc); if (cchOut != cchEnc) - RTTestIFailed("RTBase64EncodedLength returned %zu bytes, expected %zu.\n", - cchEnc, cchOut); + RTTestIFailed("RTBase64EncodedLength(%zu) returned %zu bytes, expected %zu.\n", + cbSrc, cchEnc, cchOut); if (szEnc[cchOut + 1] != '\0') - RTTestIFailed("RTBase64Encode returned string which is not zero terminated\n"); + RTTestIFailed("RTBase64Encode(,%zu,) returned string which is not zero terminated\n", cbSrc); if (strlen(szEnc) != cchOut) - RTTestIFailed("RTBase64Encode returned incorrect string, length %lu\n", cchOut); + RTTestIFailed("RTBase64Encode(,%zu,) returned incorrect string, length %lu\n", cbSrc, cchOut); } /* diff --git a/src/VBox/Runtime/testcase/tstRTBitOperations.cpp b/src/VBox/Runtime/testcase/tstRTBitOperations.cpp index a38f389e..d45bfcd7 100644 --- a/src/VBox/Runtime/testcase/tstRTBitOperations.cpp +++ b/src/VBox/Runtime/testcase/tstRTBitOperations.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2009 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTCidr.cpp b/src/VBox/Runtime/testcase/tstRTCidr.cpp index 48c5ed37..ab132585 100644 --- a/src/VBox/Runtime/testcase/tstRTCidr.cpp +++ b/src/VBox/Runtime/testcase/tstRTCidr.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2008-2009 Oracle Corporation + * Copyright (C) 2008-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -40,7 +40,7 @@ *******************************************************************************/ #define CHECKNETWORK(String, rcExpected, ExpectedNetwork, ExpectedNetMask) \ do { \ - RTIPV4ADDR Network, NetMask; \ + RTNETADDRIPV4 Network, NetMask; \ int rc2 = RTCidrStrToIPv4(String, &Network, &NetMask); \ if ((rcExpected) && !rc2) \ { \ @@ -49,11 +49,11 @@ } \ else if ( (rcExpected) != rc2 \ || ( rc2 == VINF_SUCCESS \ - && ( (ExpectedNetwork) != Network \ - || (ExpectedNetMask) != NetMask))) \ + && ( (ExpectedNetwork) != Network.u \ + || (ExpectedNetMask) != NetMask.u))) \ { \ - RTTestIFailed("at line %d: '%s': expected %Rrc got %Rrc, expected network %08x got %08x, expected netmask %08x got %08x\n", \ - __LINE__, String, rcExpected, rc2, (ExpectedNetwork), Network, (ExpectedNetMask), NetMask); \ + RTTestIFailed("at line %d: '%s': expected %Rrc got %Rrc, expected network %RTnaipv4 got %RTnaipv4, expected netmask %RTnaipv4 got %RTnaipv4\n", \ + __LINE__, String, rcExpected, rc2, (ExpectedNetwork), Network.u, (ExpectedNetMask), NetMask.u); \ } \ } while (0) diff --git a/src/VBox/Runtime/testcase/tstRTCircBuf.cpp b/src/VBox/Runtime/testcase/tstRTCircBuf.cpp index 60b2c177..be82ed56 100644 --- a/src/VBox/Runtime/testcase/tstRTCircBuf.cpp +++ b/src/VBox/Runtime/testcase/tstRTCircBuf.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTCritSect.cpp b/src/VBox/Runtime/testcase/tstRTCritSect.cpp index 0f046cd0..c143a8b7 100644 --- a/src/VBox/Runtime/testcase/tstRTCritSect.cpp +++ b/src/VBox/Runtime/testcase/tstRTCritSect.cpp @@ -491,7 +491,7 @@ int main(int argc, char **argv) return 1; case 'V': - RTPrintf("$Revision: $\n"); + RTPrintf("$Revision: 89632 $\n"); return 0; default: diff --git a/src/VBox/Runtime/testcase/tstRTCritSectRw.cpp b/src/VBox/Runtime/testcase/tstRTCritSectRw.cpp new file mode 100644 index 00000000..f946a1b1 --- /dev/null +++ b/src/VBox/Runtime/testcase/tstRTCritSectRw.cpp @@ -0,0 +1,491 @@ +/* $Id: tstRTCritSectRw.cpp $ */ +/** @file + * IPRT Testcase - Reader/Writer Critical Sections. + */ + +/* + * Copyright (C) 2009-2013 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL) only, as it comes in the "COPYING.CDDL" file of the + * VirtualBox OSE distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + */ + +/******************************************************************************* +* Header Files * +*******************************************************************************/ +#include <iprt/critsect.h> + +#include <iprt/asm.h> +#include <iprt/assert.h> +#include <iprt/err.h> +#include <iprt/initterm.h> +#include <iprt/lockvalidator.h> +#include <iprt/rand.h> +#include <iprt/semaphore.h> +#include <iprt/string.h> +#include <iprt/stream.h> +#include <iprt/test.h> +#include <iprt/time.h> +#include <iprt/thread.h> + + +/******************************************************************************* +* Global Variables * +*******************************************************************************/ +static RTTEST g_hTest; +static RTCRITSECTRW g_CritSectRw; +static bool volatile g_fTerminate; +static bool g_fYield; +static bool g_fQuiet; +static unsigned g_uWritePercent; +static uint32_t volatile g_cConcurrentWriters; +static uint32_t volatile g_cConcurrentReaders; + + +static DECLCALLBACK(int) Test4Thread(RTTHREAD ThreadSelf, void *pvUser) +{ + /* Use randomization to get a little more variation of the sync pattern. + We use a pseudo random generator here so that we don't end up testing + the speed of the /dev/urandom implementation, but rather the read-write + semaphores. */ + int rc; + RTRAND hRand; + RTTEST_CHECK_RC_OK_RET(g_hTest, rc = RTRandAdvCreateParkMiller(&hRand), rc); + RTTEST_CHECK_RC_OK_RET(g_hTest, rc = RTRandAdvSeed(hRand, (uintptr_t)ThreadSelf), rc); + unsigned c100 = RTRandAdvU32Ex(hRand, 0, 99); + + uint64_t *pcItr = (uint64_t *)pvUser; + bool fWrite; + for (;;) + { + unsigned readrec = RTRandAdvU32Ex(hRand, 0, 3); + unsigned writerec = RTRandAdvU32Ex(hRand, 0, 3); + /* Don't overdo recursion testing. */ + if (readrec > 1) + readrec--; + if (writerec > 1) + writerec--; + + fWrite = (c100 < g_uWritePercent); + if (fWrite) + { + for (unsigned i = 0; i <= writerec; i++) + { + rc = RTCritSectRwEnterExcl(&g_CritSectRw); + if (RT_FAILURE(rc)) + { + RTTestFailed(g_hTest, "Write recursion %u on %s failed with rc=%Rrc", i, RTThreadSelfName(), rc); + break; + } + } + if (RT_FAILURE(rc)) + break; + if (ASMAtomicIncU32(&g_cConcurrentWriters) != 1) + { + RTTestFailed(g_hTest, "g_cConcurrentWriters=%u on %s after write locking it", + g_cConcurrentWriters, RTThreadSelfName()); + break; + } + if (g_cConcurrentReaders != 0) + { + RTTestFailed(g_hTest, "g_cConcurrentReaders=%u on %s after write locking it", + g_cConcurrentReaders, RTThreadSelfName()); + break; + } + } + else + { + rc = RTCritSectRwEnterShared(&g_CritSectRw); + if (RT_FAILURE(rc)) + { + RTTestFailed(g_hTest, "Read locking on %s failed with rc=%Rrc", RTThreadSelfName(), rc); + break; + } + ASMAtomicIncU32(&g_cConcurrentReaders); + if (g_cConcurrentWriters != 0) + { + RTTestFailed(g_hTest, "g_cConcurrentWriters=%u on %s after read locking it", + g_cConcurrentWriters, RTThreadSelfName()); + break; + } + } + for (unsigned i = 0; i < readrec; i++) + { + rc = RTCritSectRwEnterShared(&g_CritSectRw); + if (RT_FAILURE(rc)) + { + RTTestFailed(g_hTest, "Read recursion %u on %s failed with rc=%Rrc", i, RTThreadSelfName(), rc); + break; + } + } + if (RT_FAILURE(rc)) + break; + + /* + * Check for fairness: The values of the threads should not differ too much + */ + (*pcItr)++; + + /* + * Check for correctness: Give other threads a chance. If the implementation is + * correct, no other thread will be able to enter this lock now. + */ + if (g_fYield) + RTThreadYield(); + + for (unsigned i = 0; i < readrec; i++) + { + rc = RTCritSectRwLeaveShared(&g_CritSectRw); + if (RT_FAILURE(rc)) + { + RTTestFailed(g_hTest, "Read release %u on %s failed with rc=%Rrc", i, RTThreadSelfName(), rc); + break; + } + } + if (RT_FAILURE(rc)) + break; + + if (fWrite) + { + if (ASMAtomicDecU32(&g_cConcurrentWriters) != 0) + { + RTTestFailed(g_hTest, "g_cConcurrentWriters=%u on %s before write release", + g_cConcurrentWriters, RTThreadSelfName()); + break; + } + if (g_cConcurrentReaders != 0) + { + RTTestFailed(g_hTest, "g_cConcurrentReaders=%u on %s before write release", + g_cConcurrentReaders, RTThreadSelfName()); + break; + } + for (unsigned i = 0; i <= writerec; i++) + { + rc = RTCritSectRwLeaveExcl(&g_CritSectRw); + if (RT_FAILURE(rc)) + { + RTTestFailed(g_hTest, "Write release %u on %s failed with rc=%Rrc", i, RTThreadSelfName(), rc); + break; + } + } + } + else + { + if (g_cConcurrentWriters != 0) + { + RTTestFailed(g_hTest, "g_cConcurrentWriters=%u on %s before read release", + g_cConcurrentWriters, RTThreadSelfName()); + break; + } + ASMAtomicDecU32(&g_cConcurrentReaders); + rc = RTCritSectRwLeaveShared(&g_CritSectRw); + if (RT_FAILURE(rc)) + { + RTTestFailed(g_hTest, "Read release on %s failed with rc=%Rrc", RTThreadSelfName(), rc); + break; + } + } + + if (g_fTerminate) + break; + + c100++; + c100 %= 100; + } + if (!g_fQuiet) + RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Thread %s exited with %lld\n", RTThreadSelfName(), *pcItr); + RTRandAdvDestroy(hRand); + return VINF_SUCCESS; +} + + +static void Test4(unsigned cThreads, unsigned cSeconds, unsigned uWritePercent, bool fYield, bool fQuiet) +{ + unsigned i; + uint64_t acIterations[32]; + RTTHREAD aThreads[RT_ELEMENTS(acIterations)]; + AssertRelease(cThreads <= RT_ELEMENTS(acIterations)); + + RTTestSubF(g_hTest, "Test4 - %u threads, %u sec, %u%% writes, %syielding", + cThreads, cSeconds, uWritePercent, fYield ? "" : "non-"); + + /* + * Init globals. + */ + g_fYield = fYield; + g_fQuiet = fQuiet; + g_fTerminate = false; + g_uWritePercent = uWritePercent; + g_cConcurrentWriters = 0; + g_cConcurrentReaders = 0; + + RTTEST_CHECK_RC_RETV(g_hTest, RTCritSectRwInit(&g_CritSectRw), VINF_SUCCESS); + + /* + * Create the threads and let them block on the semrw. + */ + RTTEST_CHECK_RC_RETV(g_hTest, RTCritSectRwEnterExcl(&g_CritSectRw), VINF_SUCCESS); + + for (i = 0; i < cThreads; i++) + { + acIterations[i] = 0; + RTTEST_CHECK_RC_RETV(g_hTest, RTThreadCreateF(&aThreads[i], Test4Thread, &acIterations[i], 0, + RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, + "test-%u", i), VINF_SUCCESS); + } + + /* + * Do the test run. + */ + uint32_t cErrorsBefore = RTTestErrorCount(g_hTest); + uint64_t u64StartTS = RTTimeNanoTS(); + RTTEST_CHECK_RC(g_hTest, RTCritSectRwLeaveExcl(&g_CritSectRw), VINF_SUCCESS); + RTThreadSleep(cSeconds * 1000); + ASMAtomicWriteBool(&g_fTerminate, true); + uint64_t ElapsedNS = RTTimeNanoTS() - u64StartTS; + + /* + * Clean up the threads and semaphore. + */ + for (i = 0; i < cThreads; i++) + RTTEST_CHECK_RC(g_hTest, RTThreadWait(aThreads[i], 5000, NULL), VINF_SUCCESS); + + RTTEST_CHECK_MSG(g_hTest, g_cConcurrentWriters == 0, (g_hTest, "g_cConcurrentWriters=%u at end of test\n", g_cConcurrentWriters)); + RTTEST_CHECK_MSG(g_hTest, g_cConcurrentReaders == 0, (g_hTest, "g_cConcurrentReaders=%u at end of test\n", g_cConcurrentReaders)); + + RTTEST_CHECK_RC(g_hTest, RTCritSectRwDelete(&g_CritSectRw), VINF_SUCCESS); + + if (RTTestErrorCount(g_hTest) != cErrorsBefore) + RTThreadSleep(100); + + /* + * Collect and display the results. + */ + uint64_t cItrTotal = acIterations[0]; + for (i = 1; i < cThreads; i++) + cItrTotal += acIterations[i]; + + uint64_t cItrNormal = cItrTotal / cThreads; + uint64_t cItrMinOK = cItrNormal / 20; /* 5% */ + uint64_t cItrMaxDeviation = 0; + for (i = 0; i < cThreads; i++) + { + uint64_t cItrDelta = RT_ABS((int64_t)(acIterations[i] - cItrNormal)); + if (acIterations[i] < cItrMinOK) + RTTestFailed(g_hTest, "Thread %u did less than 5%% of the iterations - %llu (it) vs. %llu (5%%) - %llu%%\n", + i, acIterations[i], cItrMinOK, cItrDelta * 100 / cItrNormal); + else if (cItrDelta > cItrNormal / 2) + RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, + "Warning! Thread %u deviates by more than 50%% - %llu (it) vs. %llu (avg) - %llu%%\n", + i, acIterations[i], cItrNormal, cItrDelta * 100 / cItrNormal); + if (cItrDelta > cItrMaxDeviation) + cItrMaxDeviation = cItrDelta; + + } + + //RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, + // "Threads: %u Total: %llu Per Sec: %llu Avg: %llu ns Max dev: %llu%%\n", + // cThreads, + // cItrTotal, + // cItrTotal / cSeconds, + // ElapsedNS / cItrTotal, + // cItrMaxDeviation * 100 / cItrNormal + // ); + // + RTTestValue(g_hTest, "Thruput", cItrTotal * UINT32_C(1000000000) / ElapsedNS, RTTESTUNIT_CALLS_PER_SEC); + RTTestValue(g_hTest, "Max diviation", cItrMaxDeviation * 100 / cItrNormal, RTTESTUNIT_PCT); +} + + +static void TestNegative(void) +{ + RTTestSub(g_hTest, "Negative"); + bool fSavedAssertQuiet = RTAssertSetQuiet(true); + bool fSavedAssertMayPanic = RTAssertSetMayPanic(false); + bool fSavedLckValEnabled = RTLockValidatorSetEnabled(false); + + RTCRITSECTRW CritSectRw; + RTTEST_CHECK_RC_RETV(g_hTest, RTCritSectRwInit(&CritSectRw), VINF_SUCCESS); + + RTTEST_CHECK_RC(g_hTest, RTCritSectRwLeaveShared(&CritSectRw), VERR_NOT_OWNER); + RTTEST_CHECK_RC(g_hTest, RTCritSectRwLeaveExcl(&CritSectRw), VERR_NOT_OWNER); + + RTTEST_CHECK_RC(g_hTest, RTCritSectRwEnterExcl(&CritSectRw), VINF_SUCCESS); + RTTEST_CHECK_RC(g_hTest, RTCritSectRwLeaveShared(&CritSectRw), VERR_NOT_OWNER); + + RTTEST_CHECK_RC(g_hTest, RTCritSectRwEnterShared(&CritSectRw), VINF_SUCCESS); + RTTEST_CHECK_RC(g_hTest, RTCritSectRwLeaveExcl(&CritSectRw), VERR_WRONG_ORDER); /* cannot release the final write before the reads. */ + RTTEST_CHECK_RC(g_hTest, RTCritSectRwLeaveShared(&CritSectRw), VINF_SUCCESS); + RTTEST_CHECK_RC(g_hTest, RTCritSectRwLeaveExcl(&CritSectRw), VINF_SUCCESS); + + RTTEST_CHECK_RC(g_hTest, RTCritSectRwDelete(&CritSectRw), VINF_SUCCESS); + + RTLockValidatorSetEnabled(fSavedLckValEnabled); + RTAssertSetMayPanic(fSavedAssertMayPanic); + RTAssertSetQuiet(fSavedAssertQuiet); +} + + +static bool Test1(void) +{ + RTTestSub(g_hTest, "Basics"); + + RTCRITSECTRW CritSectRw; + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwInit(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwIsInitialized(&CritSectRw), false); + + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwEnterShared(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveShared(&CritSectRw), VINF_SUCCESS, false); + + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwEnterShared(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwEnterShared(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveShared(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveShared(&CritSectRw), VINF_SUCCESS, false); + + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwEnterExcl(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveExcl(&CritSectRw), VINF_SUCCESS, false); + + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwEnterExcl(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwEnterExcl(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveExcl(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveExcl(&CritSectRw), VINF_SUCCESS, false); + + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwEnterExcl(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwEnterShared(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveShared(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveExcl(&CritSectRw), VINF_SUCCESS, false); + + for (int iRun = 0; iRun < 3; iRun++) + { + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwEnterExcl(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwGetWriteRecursion(&CritSectRw) == 1, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwGetWriterReadRecursion(&CritSectRw) == 0, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwIsWriteOwner(&CritSectRw) == true, false); + + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwEnterExcl(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwGetWriteRecursion(&CritSectRw) == 2, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwGetWriterReadRecursion(&CritSectRw) == 0, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwIsWriteOwner(&CritSectRw) == true, false); + + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwEnterShared(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwGetWriteRecursion(&CritSectRw) == 2, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwGetWriterReadRecursion(&CritSectRw) == 1, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwIsWriteOwner(&CritSectRw) == true, false); + + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwEnterExcl(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwGetWriteRecursion(&CritSectRw) == 3, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwGetWriterReadRecursion(&CritSectRw) == 1, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwIsWriteOwner(&CritSectRw) == true, false); + + /* midway */ + + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveExcl(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwGetWriteRecursion(&CritSectRw) == 2, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwGetWriterReadRecursion(&CritSectRw) == 1, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwIsWriteOwner(&CritSectRw) == true, false); + + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveShared(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwGetWriteRecursion(&CritSectRw) == 2, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwGetWriterReadRecursion(&CritSectRw) == 0, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwIsWriteOwner(&CritSectRw) == true, false); + + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveExcl(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwGetWriteRecursion(&CritSectRw) == 1, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwGetWriterReadRecursion(&CritSectRw) == 0, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwIsWriteOwner(&CritSectRw) == true, false); + + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveExcl(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwGetWriteRecursion(&CritSectRw) == 0, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwGetWriterReadRecursion(&CritSectRw) == 0, false); + RTTEST_CHECK_RET(g_hTest, RTCritSectRwIsWriteOwner(&CritSectRw) == false, false); + } + + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwTryEnterShared(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveShared(&CritSectRw), VINF_SUCCESS, false); + + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwTryEnterShared(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwTryEnterShared(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveShared(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveShared(&CritSectRw), VINF_SUCCESS, false); + + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwTryEnterExcl(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveExcl(&CritSectRw), VINF_SUCCESS, false); + + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwTryEnterExcl(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwTryEnterExcl(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveExcl(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveExcl(&CritSectRw), VINF_SUCCESS, false); + + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwTryEnterExcl(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwTryEnterShared(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveShared(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwLeaveExcl(&CritSectRw), VINF_SUCCESS, false); + + + RTTEST_CHECK_RET(g_hTest, RTCritSectRwIsInitialized(&CritSectRw), false); + RTTEST_CHECK_RC_RET(g_hTest, RTCritSectRwDelete(&CritSectRw), VINF_SUCCESS, false); + RTTEST_CHECK_RET(g_hTest, !RTCritSectRwIsInitialized(&CritSectRw), false); + + return true; +} + +int main(int argc, char **argv) +{ + int rc = RTTestInitAndCreate("tstRTCritSectRw", &g_hTest); + if (rc) + return 1; + RTTestBanner(g_hTest); + + if (Test1()) + { + if (argc == 1) + { + TestNegative(); + + /* threads, seconds, writePercent, yield, quiet */ + Test4( 1, 1, 0, true, false); + Test4( 1, 1, 1, true, false); + Test4( 1, 1, 5, true, false); + Test4( 2, 1, 3, true, false); + Test4( 10, 1, 5, true, false); + Test4( 10, 10, 10, false, false); + + RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "benchmarking...\n"); + for (unsigned cThreads = 1; cThreads < 32; cThreads++) + Test4(cThreads, 2, 1, false, true); + + /** @todo add a testcase where some stuff times out. */ + } + else + { + /* threads, seconds, writePercent, yield, quiet */ + RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "benchmarking...\n"); + Test4( 1, 3, 1, false, true); + Test4( 1, 3, 1, false, true); + Test4( 1, 3, 1, false, true); + Test4( 2, 3, 1, false, true); + Test4( 2, 3, 1, false, true); + Test4( 2, 3, 1, false, true); + Test4( 3, 3, 1, false, true); + Test4( 3, 3, 1, false, true); + Test4( 3, 3, 1, false, true); + } + } + + return RTTestSummaryAndDestroy(g_hTest); +} + diff --git a/src/VBox/Runtime/testcase/tstRTDigest.cpp b/src/VBox/Runtime/testcase/tstRTDigest.cpp index bd579892..5092ea20 100644 --- a/src/VBox/Runtime/testcase/tstRTDigest.cpp +++ b/src/VBox/Runtime/testcase/tstRTDigest.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -159,6 +159,16 @@ int main(int argc, char **argv) break; } + case kDigestType_SHA256: + { + char *pszDigest; + int rc = RTSha256DigestFromFile(ValueUnion.psz, &pszDigest, NULL, NULL); + if (RT_FAILURE(rc)) + return Error("RTSha256Digest(%s,) -> %Rrc\n", ValueUnion.psz, rc); + RTPrintf("%s %s\n", pszDigest, ValueUnion.psz); + RTStrFree(pszDigest); + break; + } default: return Error("The file method isn't implemented for this digest\n"); } diff --git a/src/VBox/Runtime/testcase/tstRTDirCreateUniqueNumbered.cpp b/src/VBox/Runtime/testcase/tstRTDirCreateUniqueNumbered.cpp index 448c52e5..076a3c85 100644 --- a/src/VBox/Runtime/testcase/tstRTDirCreateUniqueNumbered.cpp +++ b/src/VBox/Runtime/testcase/tstRTDirCreateUniqueNumbered.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTDvm.cpp b/src/VBox/Runtime/testcase/tstRTDvm.cpp index 7b2cc132..561b4ee1 100644 --- a/src/VBox/Runtime/testcase/tstRTDvm.cpp +++ b/src/VBox/Runtime/testcase/tstRTDvm.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTFileAio.cpp b/src/VBox/Runtime/testcase/tstRTFileAio.cpp index b164083f..0eec4720 100644 --- a/src/VBox/Runtime/testcase/tstRTFileAio.cpp +++ b/src/VBox/Runtime/testcase/tstRTFileAio.cpp @@ -84,7 +84,7 @@ void tstFileAioTestReadWriteBasic(RTFILE File, bool fWrite, void *pvTestBuf, /* Create a context and associate the file handle with it. */ RTFILEAIOCTX hAioContext; - RTTESTI_CHECK_RC_RETV(RTFileAioCtxCreate(&hAioContext, cMaxReqsInFlight), VINF_SUCCESS); + RTTESTI_CHECK_RC_RETV(RTFileAioCtxCreate(&hAioContext, cMaxReqsInFlight, 0 /* fFlags */), VINF_SUCCESS); RTTESTI_CHECK_RC_RETV(RTFileAioCtxAssociateWithFile(hAioContext, File), VINF_SUCCESS); /* Initialize requests. */ diff --git a/src/VBox/Runtime/testcase/tstRTFileGetSize-1.cpp b/src/VBox/Runtime/testcase/tstRTFileGetSize-1.cpp index 168a949b..923b5194 100644 --- a/src/VBox/Runtime/testcase/tstRTFileGetSize-1.cpp +++ b/src/VBox/Runtime/testcase/tstRTFileGetSize-1.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -60,7 +60,7 @@ static void test1(const char *pszSubTest, const char *pszFilename) if (RT_SUCCESS(rc)) { RTTESTI_CHECK(cbFile != UINT64_MAX - 42); - RTTestIValue(pszFilename, cbFile, RTTESTUNIT_BYTES); + RTTestIValue(pszSubTest, cbFile, RTTESTUNIT_BYTES); } RTFileClose(hFile); @@ -85,15 +85,15 @@ int main(int argc, char **argv) } #ifdef RT_OS_WINDOWS - test1("PhysicalDrive0", "//./PhysicalDrive0"); - test1("HarddiskVolume1", "//./HarddiskVolume1"); - test1("null", "//./nul"); + test1("//./PhysicalDrive0", "//./PhysicalDrive0"); + test1("//./HarddiskVolume1", "//./HarddiskVolume1"); + test1("//./null", "//./nul"); #else - test1("null", "/dev/null"); + test1("/dev/null", "/dev/null"); # ifdef RT_OS_LINUX - test1("sda", "/dev/sda"); - test1("sda1", "/dev/sda1"); - test1("sda5", "/dev/sda5"); + test1("/dev/sda", "/dev/sda"); + test1("/dev/sda1", "/dev/sda1"); + test1("/dev/sda5", "/dev/sda5"); # endif #endif diff --git a/src/VBox/Runtime/testcase/tstRTFileModeStringToFlags.cpp b/src/VBox/Runtime/testcase/tstRTFileModeStringToFlags.cpp new file mode 100644 index 00000000..dab42031 --- /dev/null +++ b/src/VBox/Runtime/testcase/tstRTFileModeStringToFlags.cpp @@ -0,0 +1,222 @@ +/* $Id: tstRTFileModeStringToFlags.cpp $ */ +/** @file + * IPRT Testcase - File mode string to IPRT file mode flags. + */ + +/* + * Copyright (C) 2013 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL) only, as it comes in the "COPYING.CDDL" file of the + * VirtualBox OSE distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + */ + +/******************************************************************************* +* Header Files * +*******************************************************************************/ +#include <iprt/file.h> +#include <iprt/stream.h> +#include <iprt/string.h> +#include <iprt/test.h> + + +int main() +{ + RTTEST hTest; + int rc = RTTestInitAndCreate("tstRTStrVersion", &hTest); + if (rc) + return rc; + RTTestBanner(hTest); + + RTTestSub(hTest, "RTFileModeToFlags"); + static struct + { + int iResult; + const char *pszMode; + uint64_t uMode; + } const aTests[] = + { + /* Invalid parameters. */ + { VERR_INVALID_PARAMETER, "", 0 }, + { VERR_INVALID_PARAMETER, "foo", 0 }, + { VERR_INVALID_PARAMETER, "--", 0 }, + { VERR_INVALID_PARAMETER, "++", 0 }, + { VERR_INVALID_PARAMETER, "++", 0 }, + /* Missing action. */ + { VERR_INVALID_PARAMETER, "z", 0 }, + /* Open for reading ("r"). */ + { VINF_SUCCESS , "r", RTFILE_O_OPEN | RTFILE_O_READ }, + { VINF_SUCCESS , "r+", RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_WRITE }, + { VINF_SUCCESS , "r+++", RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_WRITE }, + { VINF_SUCCESS , "+++r", RTFILE_O_OPEN | RTFILE_O_READ }, + { VINF_SUCCESS , "r+t", RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_WRITE }, + { VINF_SUCCESS , "r+b", RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_WRITE }, + /* Open / append ("a"). */ + { VINF_SUCCESS , "a", RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_APPEND }, + { VINF_SUCCESS , "a+", RTFILE_O_OPEN_CREATE | RTFILE_O_READ | RTFILE_O_WRITE | RTFILE_O_APPEND }, + { VINF_SUCCESS , "a+++", RTFILE_O_OPEN_CREATE | RTFILE_O_READ | RTFILE_O_WRITE | RTFILE_O_APPEND }, + { VINF_SUCCESS , "+++a", RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_APPEND }, + { VINF_SUCCESS , "a+t", RTFILE_O_OPEN_CREATE | RTFILE_O_READ | RTFILE_O_WRITE | RTFILE_O_APPEND }, + { VINF_SUCCESS , "a+b", RTFILE_O_OPEN_CREATE | RTFILE_O_READ | RTFILE_O_WRITE | RTFILE_O_APPEND }, + /* Create / open ("c"). */ + { VINF_SUCCESS , "c", RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE }, + { VINF_SUCCESS , "c+", RTFILE_O_OPEN_CREATE | RTFILE_O_READ | RTFILE_O_WRITE }, + { VINF_SUCCESS , "c+++", RTFILE_O_OPEN_CREATE | RTFILE_O_READ | RTFILE_O_WRITE }, + { VERR_INVALID_PARAMETER, "cr", 0 }, + { VERR_INVALID_PARAMETER, "cr+", 0 }, + /* Create / replace ("w"). */ + { VINF_SUCCESS , "w", RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_TRUNCATE }, + { VERR_INVALID_PARAMETER, "ww", 0 }, + { VERR_INVALID_PARAMETER, "wc", 0 }, + { VINF_SUCCESS , "wb", RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_TRUNCATE }, + { VINF_SUCCESS , "wb+", RTFILE_O_CREATE_REPLACE | RTFILE_O_READ | RTFILE_O_WRITE | RTFILE_O_TRUNCATE }, + { VINF_SUCCESS , "w+", RTFILE_O_CREATE_REPLACE | RTFILE_O_READ | RTFILE_O_WRITE | RTFILE_O_TRUNCATE }, + { VINF_SUCCESS , "w++", RTFILE_O_CREATE_REPLACE | RTFILE_O_READ | RTFILE_O_WRITE | RTFILE_O_TRUNCATE }, + /* Create only ("x"). */ + { VINF_SUCCESS , "x", RTFILE_O_CREATE | RTFILE_O_WRITE }, + { VERR_INVALID_PARAMETER, "xx", 0 }, + { VERR_INVALID_PARAMETER, "xc", 0 }, + { VINF_SUCCESS , "xb", RTFILE_O_CREATE | RTFILE_O_WRITE }, + { VINF_SUCCESS , "xb+", RTFILE_O_CREATE | RTFILE_O_READ | RTFILE_O_WRITE }, + { VINF_SUCCESS , "x+", RTFILE_O_CREATE | RTFILE_O_READ | RTFILE_O_WRITE }, + { VINF_SUCCESS , "x++", RTFILE_O_CREATE | RTFILE_O_READ | RTFILE_O_WRITE } + }; + + for (unsigned iTest = 0; iTest < RT_ELEMENTS(aTests); iTest++) + { + uint64_t uMode; + int iResult = RTFileModeToFlags(aTests[iTest].pszMode, &uMode); + if (iResult != aTests[iTest].iResult) + { + RTTestFailed(hTest, "#%u: mode string '%s', result is %Rrc, expected %Rrc", + iTest, aTests[iTest].pszMode, iResult, aTests[iTest].iResult); + break; + } + + /** @todo Testing sharing modes are not implemented yet, + * so just remove them from testing. */ + uMode &= ~RTFILE_O_DENY_NONE; + + if ( RT_SUCCESS(iResult) + && uMode != aTests[iTest].uMode) + { + RTTestFailed(hTest, "#%u: mode string '%s', got 0x%x, expected 0x%x", + iTest, aTests[iTest].pszMode, uMode, aTests[iTest].uMode); + break; + } + } + + RTTestSub(hTest, "RTFileModeToFlagsEx"); + static struct + { + int iResult; + const char *pszDisposition; + const char *pszMode; + /** @todo pszSharing not used yet. */ + uint64_t uMode; + } const aTestsEx[] = + { + /* Invalid parameters. */ + { VERR_INVALID_PARAMETER, "", "", 0 }, + { VERR_INVALID_PARAMETER, "foo", "", 0 }, + { VERR_INVALID_PARAMETER, "--", "", 0 }, + { VERR_INVALID_PARAMETER, "++", "", 0 }, + { VERR_INVALID_PARAMETER, "++", "", 0 }, + /* Missing action. */ + { VERR_INVALID_PARAMETER, "z", "", 0 }, + /* Open existing ("oe"). */ + { VINF_SUCCESS , "oe", "r", RTFILE_O_OPEN | RTFILE_O_READ }, + { VINF_SUCCESS , "oe", "w", RTFILE_O_OPEN | RTFILE_O_WRITE }, + { VINF_SUCCESS , "oe", "rw", RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_WRITE }, + { VINF_SUCCESS , "oe", "rw+", RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_WRITE }, + { VINF_SUCCESS , "oe", "++r", RTFILE_O_OPEN | RTFILE_O_READ }, + { VINF_SUCCESS , "oe", "r+t", RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_WRITE }, + { VINF_SUCCESS , "oe", "r+b", RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_WRITE }, + /* Open / create ("oc"). */ + { VINF_SUCCESS , "oc", "r", RTFILE_O_OPEN_CREATE | RTFILE_O_READ }, + { VINF_SUCCESS , "oc", "r+", RTFILE_O_OPEN_CREATE | RTFILE_O_READ | RTFILE_O_WRITE }, + { VINF_SUCCESS , "oc", "r+++", RTFILE_O_OPEN_CREATE | RTFILE_O_READ | RTFILE_O_WRITE }, + { VINF_SUCCESS , "oc", "+++r", RTFILE_O_OPEN_CREATE | RTFILE_O_READ }, + { VINF_SUCCESS , "oc", "w+t", RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_READ }, + { VINF_SUCCESS , "oc", "w+b", RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_READ }, + { VINF_SUCCESS , "oc", "w+t", RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_READ }, + { VINF_SUCCESS , "oc", "wr", RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_READ }, + { VINF_SUCCESS , "oc", "rw", RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_READ }, + /* Open and truncate ("ot"). */ + { VINF_SUCCESS , "ot", "r", RTFILE_O_OPEN | RTFILE_O_TRUNCATE | RTFILE_O_READ }, + { VINF_SUCCESS , "ot", "r+", RTFILE_O_OPEN | RTFILE_O_TRUNCATE | RTFILE_O_READ | RTFILE_O_WRITE }, + { VINF_SUCCESS , "ot", "r+++", RTFILE_O_OPEN | RTFILE_O_TRUNCATE | RTFILE_O_READ | RTFILE_O_WRITE }, + { VINF_SUCCESS , "ot", "+++r", RTFILE_O_OPEN | RTFILE_O_TRUNCATE | RTFILE_O_READ }, + { VINF_SUCCESS , "ot", "w+t", RTFILE_O_OPEN | RTFILE_O_TRUNCATE | RTFILE_O_WRITE | RTFILE_O_READ }, + { VINF_SUCCESS , "ot", "w+b", RTFILE_O_OPEN | RTFILE_O_TRUNCATE | RTFILE_O_WRITE | RTFILE_O_READ }, + { VINF_SUCCESS , "ot", "w+t", RTFILE_O_OPEN | RTFILE_O_TRUNCATE | RTFILE_O_WRITE | RTFILE_O_READ }, + { VINF_SUCCESS , "ot", "wr", RTFILE_O_OPEN | RTFILE_O_TRUNCATE | RTFILE_O_WRITE | RTFILE_O_READ }, + { VINF_SUCCESS , "ot", "rw", RTFILE_O_OPEN | RTFILE_O_TRUNCATE | RTFILE_O_WRITE | RTFILE_O_READ }, + /* Create always ("ca"). */ + { VINF_SUCCESS , "ca", "r", RTFILE_O_CREATE_REPLACE | RTFILE_O_READ }, + { VINF_SUCCESS , "ca", "r+", RTFILE_O_CREATE_REPLACE | RTFILE_O_READ | RTFILE_O_WRITE }, + { VINF_SUCCESS , "ca", "r+++", RTFILE_O_CREATE_REPLACE | RTFILE_O_READ | RTFILE_O_WRITE }, + { VINF_SUCCESS , "ca", "+++r", RTFILE_O_CREATE_REPLACE | RTFILE_O_READ }, + { VINF_SUCCESS , "ca", "w+t", RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_READ }, + { VINF_SUCCESS , "ca", "w+b", RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_READ }, + { VINF_SUCCESS , "ca", "w+t", RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_READ }, + { VINF_SUCCESS , "ca", "wr", RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_READ }, + { VINF_SUCCESS , "ca", "rw", RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_READ }, + /* Create if not exist ("ce"). */ + { VINF_SUCCESS , "ce", "r", RTFILE_O_CREATE | RTFILE_O_READ }, + { VINF_SUCCESS , "ce", "r+", RTFILE_O_CREATE | RTFILE_O_READ | RTFILE_O_WRITE }, + { VINF_SUCCESS , "ce", "r+++", RTFILE_O_CREATE | RTFILE_O_READ | RTFILE_O_WRITE }, + { VINF_SUCCESS , "ce", "+++r", RTFILE_O_CREATE | RTFILE_O_READ }, + { VINF_SUCCESS , "ce", "w+t", RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_READ }, + { VINF_SUCCESS , "ce", "w+b", RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_READ }, + { VINF_SUCCESS , "ce", "w+t", RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_READ }, + { VINF_SUCCESS , "ce", "wr", RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_READ }, + { VINF_SUCCESS , "ce", "rw", RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_READ } + }; + + for (unsigned iTest = 0; iTest < RT_ELEMENTS(aTestsEx); iTest++) + { + uint64_t uMode; + int iResult = RTFileModeToFlagsEx(aTestsEx[iTest].pszMode, aTestsEx[iTest].pszDisposition, + NULL /* pszSharing */, &uMode); + if (iResult != aTestsEx[iTest].iResult) + { + RTTestFailed(hTest, "#%u: disp '%s', mode '%s', result is %Rrc, expected %Rrc", + iTest, aTestsEx[iTest].pszDisposition, aTestsEx[iTest].pszMode, + iResult, aTestsEx[iTest].iResult); + break; + } + + /** @todo Testing sharing modes are not implemented yet, + * so just remove them from testing. */ + uMode &= ~RTFILE_O_DENY_NONE; + + if ( RT_SUCCESS(iResult) + && uMode != aTestsEx[iTest].uMode) + { + RTTestFailed(hTest, "#%u: disp '%s', mode '%s', got 0x%x, expected 0x%x", + iTest, aTestsEx[iTest].pszDisposition, aTestsEx[iTest].pszMode, + uMode, aTestsEx[iTest].uMode); + break; + } + } + + /* + * Summary. + */ + return RTTestSummaryAndDestroy(hTest); +} + diff --git a/src/VBox/Runtime/testcase/tstRTFsQueries.cpp b/src/VBox/Runtime/testcase/tstRTFsQueries.cpp index 5a6640c5..e1410939 100644 --- a/src/VBox/Runtime/testcase/tstRTFsQueries.cpp +++ b/src/VBox/Runtime/testcase/tstRTFsQueries.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTHeapOffset.cpp b/src/VBox/Runtime/testcase/tstRTHeapOffset.cpp index 467619a2..25574239 100644 --- a/src/VBox/Runtime/testcase/tstRTHeapOffset.cpp +++ b/src/VBox/Runtime/testcase/tstRTHeapOffset.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2009 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTHeapSimple.cpp b/src/VBox/Runtime/testcase/tstRTHeapSimple.cpp index ef763466..930e48be 100644 --- a/src/VBox/Runtime/testcase/tstRTHeapSimple.cpp +++ b/src/VBox/Runtime/testcase/tstRTHeapSimple.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTHttp.cpp b/src/VBox/Runtime/testcase/tstRTHttp.cpp new file mode 100644 index 00000000..10ad1840 --- /dev/null +++ b/src/VBox/Runtime/testcase/tstRTHttp.cpp @@ -0,0 +1,253 @@ +/* $Id: tstRTHttp.cpp $ */ +/** @file + * IPRT Testcase - Simple cURL testcase. + */ + +/* + * Copyright (C) 2012-2013 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL) only, as it comes in the "COPYING.CDDL" file of the + * VirtualBox OSE distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + */ + +/******************************************************************************* +* Header Files * +*******************************************************************************/ +#include <iprt/err.h> +#include <iprt/http.h> +#include <iprt/mem.h> +#include <iprt/file.h> +#include <iprt/stream.h> +#include <iprt/string.h> +#include <iprt/initterm.h> + +#define CAFILE_NAME "tstHttp-tempcafile.crt" + +int main(int argc, char **argv) +{ + unsigned cErrors = 0; + + RTR3InitExe(argc, &argv, 0); + + if (argc <= 1) + { + RTPrintf("usage: %s default\n", argv[0]); + return 1; + } + + for (int i = 1; i < argc; i++) + { + if (!strcmp(argv[i], "default")) + ; + else + { + RTPrintf("Unknown parameter '%s'\n", argv[i]); + return 1; + } + } + + RTHTTP hHttp; + char *pszBuf = NULL; + PRTSTREAM CAFile = NULL; + + int rc = RTHttpCreate(&hHttp); + + // create certificate file + if (RT_SUCCESS(rc)) + rc = RTStrmOpen(CAFILE_NAME, "w+b", &CAFile); + + // fetch root CA certificate (new one, often avoided in cert chains by + // using an intermediate cert which is signed by old root) + if (RT_SUCCESS(rc)) + rc = RTHttpGet(hHttp, + "http://www.verisign.com/repository/roots/root-certificates/PCA-3G5.pem", + &pszBuf); + if (RT_SUCCESS(rc) && pszBuf) + { + uint8_t *abSha1; + size_t cbSha1; + uint8_t *abSha512; + size_t cbSha512; + size_t cbBuf = strlen(pszBuf); + const uint8_t abSha1PCA3G5[] = + { + 0x4e, 0xb6, 0xd5, 0x78, 0x49, 0x9b, 0x1c, 0xcf, 0x5f, 0x58, + 0x1e, 0xad, 0x56, 0xbe, 0x3d, 0x9b, 0x67, 0x44, 0xa5, 0xe5 + }; + const uint8_t abSha512PCA3G5[] = + { + 0xd4, 0xf8, 0x10, 0x54, 0x72, 0x77, 0x0a, 0x2d, + 0xe3, 0x17, 0xb3, 0xcf, 0xed, 0x61, 0xae, 0x5c, + 0x5d, 0x3e, 0xde, 0xa1, 0x41, 0x35, 0xb2, 0xdf, + 0x60, 0xe2, 0x61, 0xfe, 0x3a, 0xc1, 0x66, 0xa3, + 0x3c, 0x88, 0x54, 0x04, 0x4f, 0x1d, 0x13, 0x46, + 0xe3, 0x8c, 0x06, 0x92, 0x9d, 0x70, 0x54, 0xc3, + 0x44, 0xeb, 0x2c, 0x74, 0x25, 0x9e, 0x5d, 0xfb, + 0xd2, 0x6b, 0xa8, 0x9a, 0xf0, 0xb3, 0x6a, 0x01 + }; + rc = RTHttpCertDigest(hHttp, pszBuf, cbBuf, + &abSha1, &cbSha1, &abSha512, &cbSha512); + if (RT_SUCCESS(rc)) + { + if (cbSha1 != sizeof(abSha1PCA3G5)) + { + RTPrintf("Wrong SHA1 digest size of PCA-3G5\n"); + rc = VERR_INTERNAL_ERROR; + } + else if (memcmp(abSha1PCA3G5, abSha1, cbSha1)) + { + RTPrintf("Wrong SHA1 digest for PCA-3G5:\n" + "Got: %.*Rhxs\n" + "Expected: %.*Rhxs\n", + cbSha1, abSha1, sizeof(abSha1PCA3G5), abSha1PCA3G5); + rc = VERR_INTERNAL_ERROR; + } + if (cbSha512 != sizeof(abSha512PCA3G5)) + { + RTPrintf("Wrong SHA512 digest size of PCA-3G5\n"); + rc = VERR_INTERNAL_ERROR; + } + else if (memcmp(abSha512PCA3G5, abSha512, cbSha512)) + { + RTPrintf("Wrong SHA512 digest for PCA-3G5:\n" + "Got: %.*Rhxs\n" + "Expected: %.*Rhxs\n", + cbSha512, abSha512, sizeof(abSha512PCA3G5), abSha512PCA3G5); + rc = VERR_INTERNAL_ERROR; + } + RTMemFree(abSha1); + RTMemFree(abSha512); + if (RT_SUCCESS(rc)) + rc = RTStrmWrite(CAFile, pszBuf, cbBuf); + if (RT_SUCCESS(rc)) + rc = RTStrmWrite(CAFile, RTFILE_LINEFEED, strlen(RTFILE_LINEFEED)); + } + } + if (pszBuf) + { + RTMemFree(pszBuf); + pszBuf = NULL; + } + + // fetch root CA certificate (old one, but still very widely used) + if (RT_SUCCESS(rc)) + rc = RTHttpGet(hHttp, + "http://www.verisign.com/repository/roots/root-certificates/PCA-3.pem", + &pszBuf); + if (RT_SUCCESS(rc) && pszBuf) + { + uint8_t *abSha1; + size_t cbSha1; + uint8_t *abSha512; + size_t cbSha512; + size_t cbBuf = strlen(pszBuf); + const uint8_t abSha1PCA3[] = + { + 0xa1, 0xdb, 0x63, 0x93, 0x91, 0x6f, 0x17, 0xe4, 0x18, 0x55, + 0x09, 0x40, 0x04, 0x15, 0xc7, 0x02, 0x40, 0xb0, 0xae, 0x6b + }; + const uint8_t abSha512PCA3[] = + { + 0xbb, 0xf7, 0x8a, 0x19, 0x9f, 0x37, 0xee, 0xa2, + 0xce, 0xc8, 0xaf, 0xe3, 0xd6, 0x22, 0x54, 0x20, + 0x74, 0x67, 0x6e, 0xa5, 0x19, 0xb7, 0x62, 0x1e, + 0xc1, 0x2f, 0xd5, 0x08, 0xf4, 0x64, 0xc4, 0xc6, + 0xbb, 0xc2, 0xf2, 0x35, 0xe7, 0xbe, 0x32, 0x0b, + 0xde, 0xb2, 0xfc, 0x44, 0x92, 0x5b, 0x8b, 0x9b, + 0x77, 0xa5, 0x40, 0x22, 0x18, 0x12, 0xcb, 0x3d, + 0x0a, 0x67, 0x83, 0x87, 0xc5, 0x45, 0xc4, 0x99 + }; + rc = RTHttpCertDigest(hHttp, pszBuf, cbBuf, + &abSha1, &cbSha1, &abSha512, &cbSha512); + if (RT_SUCCESS(rc)) + { + if (cbSha1 != sizeof(abSha1PCA3)) + { + RTPrintf("Wrong SHA1 digest size of PCA-3\n"); + rc = VERR_INTERNAL_ERROR; + } + else if (memcmp(abSha1PCA3, abSha1, cbSha1)) + { + RTPrintf("Wrong SHA1 digest for PCA-3:\n" + "Got: %.*Rhxs\n" + "Expected: %.*Rhxs\n", + cbSha1, abSha1, sizeof(abSha1PCA3), abSha1PCA3); + rc = VERR_INTERNAL_ERROR; + } + if (cbSha512 != sizeof(abSha512PCA3)) + { + RTPrintf("Wrong SHA512 digest size of PCA-3\n"); + rc = VERR_INTERNAL_ERROR; + } + else if (memcmp(abSha512PCA3, abSha512, cbSha512)) + { + RTPrintf("Wrong SHA512 digest for PCA-3:\n" + "Got: %.*Rhxs\n" + "Expected: %.*Rhxs\n", + cbSha512, abSha512, sizeof(abSha512PCA3), abSha512PCA3); + rc = VERR_INTERNAL_ERROR; + } + RTMemFree(abSha1); + RTMemFree(abSha512); + if (RT_SUCCESS(rc)) + rc = RTStrmWrite(CAFile, pszBuf, cbBuf); + if (RT_SUCCESS(rc)) + rc = RTStrmWrite(CAFile, RTFILE_LINEFEED, strlen(RTFILE_LINEFEED)); + } + } + if (pszBuf) + { + RTMemFree(pszBuf); + pszBuf = NULL; + } + + // close certificate file + if (CAFile) + { + RTStrmClose(CAFile); + CAFile = NULL; + } + + if (RT_SUCCESS(rc)) + rc = RTHttpSetCAFile(hHttp, CAFILE_NAME); + + if (RT_SUCCESS(rc)) + rc = RTHttpGet(hHttp, + "https://update.virtualbox.org/query.php?platform=LINUX_32BITS_UBUNTU_12_04&version=4.1.18", + &pszBuf); + + if ( RT_FAILURE(rc) + && rc != VERR_HTTP_COULDNT_CONNECT) + cErrors++; + + if (RT_FAILURE(rc)) + RTPrintf("Error code: %Rrc\n", rc); + else + RTPrintf("Success!\n"); + RTPrintf("Got: %s\n", pszBuf); + if (pszBuf) + { + RTMemFree(pszBuf); + pszBuf = NULL; + } + + RTHttpDestroy(hHttp); + +// RTFileDelete(CAFILE_NAME); + + return !!cErrors; +} diff --git a/src/VBox/Runtime/testcase/tstRTInlineAsm.cpp b/src/VBox/Runtime/testcase/tstRTInlineAsm.cpp index 925b23b5..c78a511a 100644 --- a/src/VBox/Runtime/testcase/tstRTInlineAsm.cpp +++ b/src/VBox/Runtime/testcase/tstRTInlineAsm.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -191,6 +191,16 @@ void tstASMCpuId(void) CHECKVAL(uECX2, s.uECX, "%x"); CHECKVAL(uEDX2, s.uEDX, "%x"); + uint32_t uEAX2 = s.uEAX - 1; + uint32_t uEBX2 = s.uEBX - 1; + uECX2 = s.uECX - 1; + uEDX2 = s.uEDX - 1; + ASMCpuIdExSlow(0, 0, 0, 0, &uEAX2, &uEBX2, &uECX2, &uEDX2); + CHECKVAL(uEAX2, s.uEAX, "%x"); + CHECKVAL(uEBX2, s.uEBX, "%x"); + CHECKVAL(uECX2, s.uECX, "%x"); + CHECKVAL(uEDX2, s.uEDX, "%x"); + /* * Done testing, dump the information. */ @@ -209,24 +219,54 @@ void tstASMCpuId(void) RTTestIPrintf(RTTESTLVL_ALWAYS, "%08x %08x %08x %08x %08x%s\n", iStd, s.uEAX, s.uEBX, s.uECX, s.uEDX, iStd <= cFunctions ? "" : "*"); - if (iStd == 0x04 || iStd == 0x0b || iStd == 0x0d || iStd > cFunctions) - continue; /* Leaf 04 and leaf 0d output depend on the initial value of ECX - * The same seems to apply to invalid standard functions */ - - u32 = ASMCpuId_EAX(iStd); - CHECKVAL(u32, s.uEAX, "%x"); - u32 = ASMCpuId_EBX(iStd); - CHECKVAL(u32, s.uEBX, "%x"); - u32 = ASMCpuId_ECX(iStd); - CHECKVAL(u32, s.uECX, "%x"); - u32 = ASMCpuId_EDX(iStd); - CHECKVAL(u32, s.uEDX, "%x"); - - uECX2 = s.uECX - 1; - uEDX2 = s.uEDX - 1; - ASMCpuId_ECX_EDX(iStd, &uECX2, &uEDX2); - CHECKVAL(uECX2, s.uECX, "%x"); - CHECKVAL(uEDX2, s.uEDX, "%x"); + /* Leaf 04 and leaf 0d output depend on the initial value of ECX + * The same seems to apply to invalid standard functions */ + if (iStd > cFunctions) + continue; + if (iStd != 0x04 && iStd != 0x0b && iStd != 0x0d) + { + u32 = ASMCpuId_EAX(iStd); + CHECKVAL(u32, s.uEAX, "%x"); + + uint32_t u32EbxMask = UINT32_MAX; + if (iStd == 1) + u32EbxMask = UINT32_C(0x00ffffff); /* Omit the local apic ID in case we're rescheduled. */ + u32 = ASMCpuId_EBX(iStd); + CHECKVAL(u32 & u32EbxMask, s.uEBX & u32EbxMask, "%x"); + + u32 = ASMCpuId_ECX(iStd); + CHECKVAL(u32, s.uECX, "%x"); + u32 = ASMCpuId_EDX(iStd); + CHECKVAL(u32, s.uEDX, "%x"); + + uECX2 = s.uECX - 1; + uEDX2 = s.uEDX - 1; + ASMCpuId_ECX_EDX(iStd, &uECX2, &uEDX2); + CHECKVAL(uECX2, s.uECX, "%x"); + CHECKVAL(uEDX2, s.uEDX, "%x"); + } + + if (iStd == 0x04) + for (uint32_t uECX = 1; s.uEAX & 0x1f; uECX++) + { + ASMCpuId_Idx_ECX(iStd, uECX, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX); + RTTestIPrintf(RTTESTLVL_ALWAYS, " [%02x] %08x %08x %08x %08x\n", uECX, s.uEAX, s.uEBX, s.uECX, s.uEDX); + RTTESTI_CHECK_BREAK(uECX < 128); + } + else if (iStd == 0x0b) + for (uint32_t uECX = 1; (s.uEAX & 0x1f) && (s.uEBX & 0xffff); uECX++) + { + ASMCpuId_Idx_ECX(iStd, uECX, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX); + RTTestIPrintf(RTTESTLVL_ALWAYS, " [%02x] %08x %08x %08x %08x\n", uECX, s.uEAX, s.uEBX, s.uECX, s.uEDX); + RTTESTI_CHECK_BREAK(uECX < 128); + } + else if (iStd == 0x0d) + for (uint32_t uECX = 1; s.uEAX != 0 || s.uEBX != 0 || s.uECX != 0 || s.uEDX != 0; uECX++) + { + ASMCpuId_Idx_ECX(iStd, uECX, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX); + RTTestIPrintf(RTTESTLVL_ALWAYS, " [%02x] %08x %08x %08x %08x\n", uECX, s.uEAX, s.uEBX, s.uECX, s.uEDX); + RTTESTI_CHECK_BREAK(uECX < 128); + } } /* @@ -338,6 +378,8 @@ void tstASMCpuId(void) if (iExt > cExtFunctions) continue; /* Invalid extended functions seems change the value if ECX changes */ + if (iExt == 0x8000001d) + continue; /* Takes cache level in ecx. */ u32 = ASMCpuId_EAX(iExt); CHECKVAL(u32, s.uEAX, "%x"); @@ -1519,6 +1561,7 @@ int main(int argc, char *argv[]) #if !defined(GCC44_32BIT_PIC) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)) tstASMCpuId(); #endif +#if 1 tstASMAtomicXchgU8(); tstASMAtomicXchgU16(); tstASMAtomicXchgU32(); @@ -1549,6 +1592,7 @@ int main(int argc, char *argv[]) tstASMByteSwap(); tstASMBench(); +#endif /* * Show the result. diff --git a/src/VBox/Runtime/testcase/tstRTList.cpp b/src/VBox/Runtime/testcase/tstRTList.cpp index 12f31751..bfa8884c 100644 --- a/src/VBox/Runtime/testcase/tstRTList.cpp +++ b/src/VBox/Runtime/testcase/tstRTList.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTLocalIpc.cpp b/src/VBox/Runtime/testcase/tstRTLocalIpc.cpp new file mode 100644 index 00000000..476cc042 --- /dev/null +++ b/src/VBox/Runtime/testcase/tstRTLocalIpc.cpp @@ -0,0 +1,644 @@ +/* $Id: tstRTLocalIpc.cpp $ */ +/** @file + * IPRT Testcase - RTLocalIpc. + */ + +/* + * Copyright (C) 2013 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL) only, as it comes in the "COPYING.CDDL" file of the + * VirtualBox OSE distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + */ + + +/******************************************************************************* +* Header Files * +*******************************************************************************/ +#include <iprt/env.h> +#include <iprt/localipc.h> +#include <iprt/mem.h> +#include <iprt/path.h> +#include <iprt/process.h> +#include <iprt/rand.h> +#include <iprt/string.h> +#include <iprt/test.h> +#include <iprt/thread.h> +#include <iprt/time.h> + + +typedef struct LOCALIPCTHREADCTX +{ + /** The IPC server handle. */ + RTLOCALIPCSERVER hServer; + /** The test handle. */ + RTTEST hTest; +} LOCALIPCTHREADCTX, *PLOCALIPCTHREADCTX; + +static int testServerListenAndCancel2(const char *pszExecPath) +{ + const char *apszArgs[4] = { pszExecPath, "child", "testServerListenAndCancel", NULL }; + RTPROCESS hProc; + int rc = RTProcCreate(pszExecPath, apszArgs, RTENV_DEFAULT, 0 /* fFlags*/, &hProc); + + return rc; +} + +static DECLCALLBACK(int) testServerListenAndCancelThread(RTTHREAD hSelf, void *pvUser) +{ + PRTLOCALIPCSERVER pServer = (PRTLOCALIPCSERVER)pvUser; + AssertPtr(pServer); + + RTThreadSleep(5000); /* Wait a bit to simulate waiting in main thread. */ + + int rc = RTLocalIpcServerCancel(*pServer); + AssertRC(rc); + + return 0; +} + +static int testServerListenAndCancel(RTTEST hTest, const char *pszExecPath) +{ + RTTestSub(hTest, "testServerListenAndCancel"); + + RTLOCALIPCSERVER ipcServer; + int rc = RTLocalIpcServerCreate(&ipcServer, "testServerListenAndCancel", + RTLOCALIPC_FLAGS_MULTI_SESSION); + if (RT_SUCCESS(rc)) + { + /* Spawn a simple worker thread and let it listen for incoming connections. + * In the meanwhile we try to cancel the server and see what happens. */ + RTTHREAD hThread; + rc = RTThreadCreate(&hThread, testServerListenAndCancelThread, + &ipcServer, 0 /* Stack */, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tstIpc1"); + if (RT_SUCCESS(rc)) + { + do + { + RTTestPrintf(hTest, RTTESTLVL_INFO, "Listening for incoming connections ...\n"); + RTLOCALIPCSESSION ipcSession; + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcServerListen(ipcServer, &ipcSession), VERR_CANCELLED); + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcServerCancel(ipcServer), VINF_SUCCESS); + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcServerDestroy(ipcServer), VINF_SUCCESS); + + RTTestPrintf(hTest, RTTESTLVL_INFO, "Waiting for thread to exit ...\n"); + RTTEST_CHECK_RC(hTest, RTThreadWait(hThread, + 30 * 1000 /* 30s timeout */, NULL), VINF_SUCCESS); + } while (0); + } + else + RTTestIFailed("Unable to create thread for cancelling server, rc=%Rrc\n", rc); + } + else + RTTestIFailed("Unable to create IPC server, rc=%Rrc\n", rc); + + return VINF_SUCCESS; +} + +static DECLCALLBACK(int) testSessionConnectionThread(RTTHREAD hSelf, void *pvUser) +{ + PLOCALIPCTHREADCTX pCtx = (PLOCALIPCTHREADCTX)pvUser; + AssertPtr(pCtx); + + int rc; + RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionConnectionThread: Listening for incoming connections ...\n"); + for (;;) + { + RTLOCALIPCSESSION ipcSession; + rc = RTLocalIpcServerListen(pCtx->hServer, &ipcSession); + RTTestPrintf(pCtx->hTest, RTTESTLVL_DEBUG, "testSessionConnectionThread: Listening returned with rc=%Rrc\n", rc); + if (RT_SUCCESS(rc)) + { + RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionConnectionThread: Got new client connection\n"); + } + else + break; + } + + RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionConnectionThread: Ended with rc=%Rrc\n", rc); + return rc; +} + +static RTEXITCODE testSessionConnectionChild(int argc, char **argv, RTTEST hTest) +{ + do + { + RTThreadSleep(2000); /* Fudge */ + RTLOCALIPCSESSION clientSession; + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionConnect(&clientSession, "tstRTLocalIpcSessionConnection", + 0 /* Flags */), VINF_SUCCESS); + RTThreadSleep(5000); /* Fudge */ + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionClose(clientSession), VINF_SUCCESS); + + } while (0); + + return !RTTestErrorCount(hTest) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; +} + +static int testSessionConnection(RTTEST hTest, const char *pszExecPath) +{ + RTTestSub(hTest, "testSessionConnection"); + + RTLOCALIPCSERVER ipcServer; + int rc = RTLocalIpcServerCreate(&ipcServer, "tstRTLocalIpcSessionConnection", + RTLOCALIPC_FLAGS_MULTI_SESSION); + if (RT_SUCCESS(rc)) + { +#ifndef VBOX_TESTCASES_WITH_NO_THREADING + LOCALIPCTHREADCTX threadCtx = { ipcServer, hTest }; + + /* Spawn a simple worker thread and let it listen for incoming connections. + * In the meanwhile we try to cancel the server and see what happens. */ + RTTHREAD hThread; + rc = RTThreadCreate(&hThread, testSessionConnectionThread, + &threadCtx, 0 /* Stack */, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tstIpc2"); + if (RT_SUCCESS(rc)) + { + do + { + RTPROCESS hProc; + const char *apszArgs[4] = { pszExecPath, "child", "tstRTLocalIpcSessionConnectionFork", NULL }; + RTTEST_CHECK_RC_BREAK(hTest, RTProcCreate(pszExecPath, apszArgs, + RTENV_DEFAULT, 0 /* fFlags*/, &hProc), VINF_SUCCESS); + RTPROCSTATUS stsChild; + RTTEST_CHECK_RC_BREAK(hTest, RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &stsChild), VINF_SUCCESS); + RTTestPrintf(hTest, RTTESTLVL_INFO, "Child terminated, waiting for server thread ...\n"); + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcServerCancel(ipcServer), VINF_SUCCESS); + int threadRc; + RTTEST_CHECK_RC(hTest, RTThreadWait(hThread, + 30 * 1000 /* 30s timeout */, &threadRc), VINF_SUCCESS); + RTTEST_CHECK_RC_BREAK(hTest, threadRc, VERR_CANCELLED); + RTTestPrintf(hTest, RTTESTLVL_INFO, "Server thread terminated successfully\n"); + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcServerDestroy(ipcServer), VINF_SUCCESS); + RTTEST_CHECK_BREAK(hTest, stsChild.enmReason == RTPROCEXITREASON_NORMAL); + RTTEST_CHECK_BREAK(hTest, stsChild.iStatus == 0); + } + while (0); + } + else + RTTestFailed(hTest, "Unable to create thread for cancelling server, rc=%Rrc\n", rc); +#else + do + { + RTPROCESS hProc; + const char *apszArgs[4] = { pszExecPath, "child", "tstRTLocalIpcSessionConnectionFork", NULL }; + RTTEST_CHECK_RC_BREAK(hTest, RTProcCreate(pszExecPath, apszArgs, + RTENV_DEFAULT, 0 /* fFlags*/, &hProc), VINF_SUCCESS); + RTLOCALIPCSESSION ipcSession; + rc = RTLocalIpcServerListen(ipcServer, &ipcSession); + if (RT_SUCCESS(rc)) + { + RTTestPrintf(hTest, RTTESTLVL_INFO, "testSessionConnectionThread: Got new client connection\n"); + } + else + RTTestFailed(hTest, "Error while listening, rc=%Rrc\n", rc); + + } while (0); +#endif + } + else + RTTestFailed(hTest, "Unable to create IPC server, rc=%Rrc\n", rc); + + return VINF_SUCCESS; +} + +static DECLCALLBACK(int) testSessionWaitThread(RTTHREAD hSelf, void *pvUser) +{ + PLOCALIPCTHREADCTX pCtx = (PLOCALIPCTHREADCTX)pvUser; + AssertPtr(pCtx); + + int rc; + for (;;) + { + RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionWaitThread: Listening for incoming connections ...\n"); + RTLOCALIPCSESSION ipcSession; + rc = RTLocalIpcServerListen(pCtx->hServer, &ipcSession); + if (RT_SUCCESS(rc)) + { + RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionWaitThread: Got new client connection, waiting a bit ...\n"); + RTThreadSleep(2000); + rc = RTLocalIpcSessionClose(ipcSession); + } + else + { + RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionWaitThread: Listening ended with rc=%Rrc\n", rc); + break; + } + } + + RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionWaitThread: Ended with rc=%Rrc\n", rc); + return rc; +} + +static RTEXITCODE testSessionWaitChild(int argc, char **argv, RTTEST hTest) +{ + do + { + RTThreadSleep(2000); /* Fudge. */ + RTLOCALIPCSESSION clientSession; + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionConnect(&clientSession, "tstRTLocalIpcSessionWait", + 0 /* Flags */), VINF_SUCCESS); + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionWaitForData(clientSession, 100 /* 100ms timeout */), + VERR_TIMEOUT); + /* Next, try 60s timeout. Should be returning way earlier because the server closed the + * connection after the first client connected. */ + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionWaitForData(clientSession, 60 * 1000), + VERR_BROKEN_PIPE); + /* Last try, also should fail because the server should be not around anymore. */ + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionWaitForData(clientSession, 5 * 1000), + VERR_BROKEN_PIPE); + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionClose(clientSession), VINF_SUCCESS); + + } while (0); + + return !RTTestErrorCount(hTest) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; +} + +static int testSessionWait(RTTEST hTest, const char *pszExecPath) +{ + RTTestSub(hTest, "testSessionWait"); + + RTLOCALIPCSERVER ipcServer; + int rc = RTLocalIpcServerCreate(&ipcServer, "tstRTLocalIpcSessionWait", + RTLOCALIPC_FLAGS_MULTI_SESSION); + if (RT_SUCCESS(rc)) + { + LOCALIPCTHREADCTX threadCtx = { ipcServer, hTest }; + + /* Spawn a simple worker thread and let it listen for incoming connections. + * In the meanwhile we try to cancel the server and see what happens. */ + RTTHREAD hThread; + rc = RTThreadCreate(&hThread, testSessionWaitThread, + &threadCtx, 0 /* Stack */, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tstIpc3"); + if (RT_SUCCESS(rc)) + { + do + { + RTPROCESS hProc; + const char *apszArgs[4] = { pszExecPath, "child", "tstRTLocalIpcSessionWaitFork", NULL }; + RTTEST_CHECK_RC_BREAK(hTest, RTProcCreate(pszExecPath, apszArgs, + RTENV_DEFAULT, 0 /* fFlags*/, &hProc), VINF_SUCCESS); + RTThreadSleep(5000); /* Let the server run for some time ... */ + RTTestPrintf(hTest, RTTESTLVL_INFO, "Cancelling server listening\n"); + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcServerCancel(ipcServer), VINF_SUCCESS); + /* Wait for the server thread to terminate. */ + int threadRc; + RTTEST_CHECK_RC(hTest, RTThreadWait(hThread, + 30 * 1000 /* 30s timeout */, &threadRc), VINF_SUCCESS); + RTTEST_CHECK_RC_BREAK(hTest, threadRc, VERR_CANCELLED); + RTTEST_CHECK_RC(hTest, RTLocalIpcServerDestroy(ipcServer), VINF_SUCCESS); + RTTestPrintf(hTest, RTTESTLVL_INFO, "Server thread terminated successfully\n"); + /* Check if the child ran successfully. */ + RTPROCSTATUS stsChild; + RTTEST_CHECK_RC_BREAK(hTest, RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &stsChild), VINF_SUCCESS); + RTTestPrintf(hTest, RTTESTLVL_INFO, "Child terminated\n"); + RTTEST_CHECK_BREAK(hTest, stsChild.enmReason == RTPROCEXITREASON_NORMAL); + RTTEST_CHECK_BREAK(hTest, stsChild.iStatus == 0); + } + while (0); + } + else + RTTestFailed(hTest, "Unable to create thread for cancelling server, rc=%Rrc\n", rc); + } + else + RTTestFailed(hTest, "Unable to create IPC server, rc=%Rrc\n", rc); + + return VINF_SUCCESS; +} + +/** + * Simple structure holding the test IPC messages. + */ +typedef struct LOCALIPCTESTMSG +{ + /** The actual message. */ + char szOp[255]; +} LOCALIPCTESTMSG, *PLOCALIPCTESTMSG; + +static int testSessionDataReadTestMsg(RTTEST hTest, RTLOCALIPCSESSION hSession, + void *pvBuffer, size_t cbBuffer, const char *pszMsg) +{ + AssertPtrReturn(pvBuffer, VERR_INVALID_POINTER); + AssertPtrReturn(pszMsg, VERR_INVALID_POINTER); + + void *pvBufCur = pvBuffer; + size_t cbReadTotal = 0; + for (;;) + { + size_t cbRead = RTRandU32Ex(1, sizeof(LOCALIPCTESTMSG) - cbReadTotal); /* Force a bit of fragmentation. */ + RTTEST_CHECK_BREAK(hTest, cbRead); + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionRead(hSession, pvBufCur, + cbBuffer, + &cbRead), VINF_SUCCESS); + RTTEST_CHECK_BREAK(hTest, cbRead); + pvBufCur = (uint8_t *)pvBufCur + cbRead; /* Advance. */ + cbReadTotal += cbRead; + RTTEST_CHECK_BREAK(hTest, cbReadTotal <= cbBuffer); + if (cbReadTotal >= sizeof(LOCALIPCTESTMSG)) /* Got a complete test message? */ + { + RTTEST_CHECK_BREAK(hTest, cbReadTotal == sizeof(LOCALIPCTESTMSG)); + PLOCALIPCTESTMSG pMsg = (PLOCALIPCTESTMSG)pvBuffer; + RTTEST_CHECK_BREAK(hTest, pMsg != NULL); + RTTEST_CHECK_BREAK(hTest, !RTStrCmp(pMsg->szOp, pszMsg)); + break; + } + /* Try receiving next part of the message in another round. */ + } + + return !RTTestErrorCount(hTest) ? VINF_SUCCESS : VERR_GENERAL_FAILURE /* Doesn't matter */; +} + +static int testSessionDataThreadWorker(PLOCALIPCTHREADCTX pCtx) +{ + AssertPtr(pCtx); + + size_t cbScratchBuf = _1K; /** @todo Make this random in future. */ + uint8_t *pvScratchBuf = (uint8_t*)RTMemAlloc(cbScratchBuf); + RTTEST_CHECK_RET(pCtx->hTest, pvScratchBuf != NULL, VERR_NO_MEMORY); + + do + { + /* Note: At the moment we only support one client per run. */ + RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionDataThread: Listening for incoming connections ...\n"); + RTLOCALIPCSESSION hSession; + RTTEST_CHECK_RC_BREAK(pCtx->hTest, RTLocalIpcServerListen(pCtx->hServer, &hSession), VINF_SUCCESS); + RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionDataThread: Got new client connection\n"); + uint32_t cRounds = 256; /** @todo Use RTRand(). */ + /* Write how many rounds we're going to send data. */ + RTTEST_CHECK_RC_BREAK(pCtx->hTest, RTLocalIpcSessionWrite(hSession, &cRounds, sizeof(cRounds)), VINF_SUCCESS); + RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionDataThread: Written number of rounds\n"); + for (uint32_t i = 0; i < cRounds; i++) + { + LOCALIPCTESTMSG msg; + RTTEST_CHECK_BREAK(pCtx->hTest, RTStrPrintf(msg.szOp, sizeof(msg.szOp), + "YayIGotRound%RU32FromTheServer", i) > 0); + RTTEST_CHECK_RC_BREAK(pCtx->hTest, RTLocalIpcSessionWrite(hSession, &msg, sizeof(msg)), VINF_SUCCESS); + } + if (!RTTestErrorCount(pCtx->hTest)) + RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionDataThread: Data successfully written\n"); + /* Try to receive the same amount of rounds from the client. */ + for (uint32_t i = 0; i < cRounds; i++) + { + RTTEST_CHECK_RC_BREAK(pCtx->hTest, RTLocalIpcSessionWaitForData(hSession, RT_INDEFINITE_WAIT), + VINF_SUCCESS); + char szMsg[32]; + RTTEST_CHECK_BREAK(pCtx->hTest, RTStrPrintf(szMsg, sizeof(szMsg), "YayIGotRound%RU32FromTheClient", i) > 0); + RTTEST_CHECK_RC_BREAK(pCtx->hTest, testSessionDataReadTestMsg(pCtx->hTest, hSession, + pvScratchBuf, cbScratchBuf, + szMsg), VINF_SUCCESS); + if (RTTestErrorCount(pCtx->hTest)) + break; + } + if (!RTTestErrorCount(pCtx->hTest)) + RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionDataThread: Data successfully read\n"); + RTTEST_CHECK_RC_BREAK(pCtx->hTest, RTLocalIpcSessionClose(hSession), VINF_SUCCESS); + + } while (0); + + RTMemFree(pvScratchBuf); + return !RTTestErrorCount(pCtx->hTest) ? VINF_SUCCESS : VERR_GENERAL_FAILURE /* Doesn't matter */; +} + +static DECLCALLBACK(int) testSessionDataThread(RTTHREAD hSelf, void *pvUser) +{ + PLOCALIPCTHREADCTX pCtx = (PLOCALIPCTHREADCTX)pvUser; + AssertPtr(pCtx); + + return testSessionDataThreadWorker(pCtx); +} + +static int testSessionDataChildWorker(RTTEST hTest) +{ + size_t cbScratchBuf = _1K; /** @todo Make this random in future. */ + uint8_t *pvScratchBuf = (uint8_t*)RTMemAlloc(cbScratchBuf); + RTTEST_CHECK_RET(hTest, pvScratchBuf != NULL, RTEXITCODE_FAILURE); + + do + { + RTThreadSleep(2000); /* Fudge. */ + RTLOCALIPCSESSION hSession; + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionConnect(&hSession, "tstRTLocalIpcSessionData", + 0 /* Flags */), VINF_SUCCESS); + /* Get number of rounds we want to read/write. */ + uint32_t cRounds = 0; + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionWaitForData(hSession, RT_INDEFINITE_WAIT), + VINF_SUCCESS); + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionRead(hSession, &cRounds, sizeof(cRounds), + NULL /* Get exactly sizeof(cRounds) bytes */), VINF_SUCCESS); + RTTEST_CHECK_BREAK(hTest, cRounds == 256); /** @todo Check for != 0 when using RTRand(). */ + /* Receive all rounds. */ + for (uint32_t i = 0; i < cRounds; i++) + { + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionWaitForData(hSession, RT_INDEFINITE_WAIT), + VINF_SUCCESS); + char szMsg[32]; + RTTEST_CHECK_BREAK(hTest, RTStrPrintf(szMsg, sizeof(szMsg), "YayIGotRound%RU32FromTheServer", i) > 0); + RTTEST_CHECK_RC_BREAK(hTest, testSessionDataReadTestMsg(hTest, hSession, + pvScratchBuf, cbScratchBuf, + szMsg), VINF_SUCCESS); + if (RTTestErrorCount(hTest)) + break; + } + /* Send all rounds back to the server. */ + for (uint32_t i = 0; i < cRounds; i++) + { + LOCALIPCTESTMSG msg; + RTTEST_CHECK_BREAK(hTest, RTStrPrintf(msg.szOp, sizeof(msg.szOp), + "YayIGotRound%RU32FromTheClient", i) > 0); + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionWrite(hSession, &msg, sizeof(msg)), VINF_SUCCESS); + } + RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionClose(hSession), VINF_SUCCESS); + + } while (0); + + RTMemFree(pvScratchBuf); + return !RTTestErrorCount(hTest) ? VINF_SUCCESS : VERR_GENERAL_FAILURE /* Doesn't matter */; +} + +static DECLCALLBACK(int) testSessionDataChildAsThread(RTTHREAD hSelf, void *pvUser) +{ + PRTTEST phTest = (PRTTEST)pvUser; + AssertPtr(phTest); + return testSessionDataChildWorker(*phTest); +} + +static RTEXITCODE testSessionDataChild(int argc, char **argv, RTTEST hTest) +{ + return RT_SUCCESS(testSessionDataChildWorker(hTest)) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; +} + +static int testSessionData(RTTEST hTest, const char *pszExecPath) +{ + RTTestSub(hTest, "testSessionData"); + + RTLOCALIPCSERVER ipcServer; + int rc = RTLocalIpcServerCreate(&ipcServer, "tstRTLocalIpcSessionData", + RTLOCALIPC_FLAGS_MULTI_SESSION); + if (RT_SUCCESS(rc)) + { + LOCALIPCTHREADCTX threadCtx = { ipcServer, hTest }; +#if 0 + /* Run server + client in threads instead of fork'ed processes (useful for debugging). */ + RTTHREAD hThreadServer, hThreadClient; + rc = RTThreadCreate(&hThreadServer, testSessionDataThread, + &threadCtx, 0 /* Stack */, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tstIpc4"); + if (RT_SUCCESS(rc)) + rc = RTThreadCreate(&hThreadClient, testSessionDataChildAsThread, + &hTest, 0 /* Stack */, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tstIpc5"); + if (RT_SUCCESS(rc)) + { + do + { + int threadRc; + RTTEST_CHECK_RC(hTest, RTThreadWait(hThreadServer, + 5 * 60 * 1000 /* 5 minutes timeout */, &threadRc), VINF_SUCCESS); + RTTEST_CHECK_RC_BREAK(hTest, threadRc, VINF_SUCCESS); + RTTEST_CHECK_RC(hTest, RTThreadWait(hThreadClient, + 5 * 60 * 1000 /* 5 minutes timeout */, &threadRc), VINF_SUCCESS); + RTTEST_CHECK_RC_BREAK(hTest, threadRc, VINF_SUCCESS); + + } while (0); + } +#else + /* Spawn a simple worker thread and let it listen for incoming connections. + * In the meanwhile we try to cancel the server and see what happens. */ + RTTHREAD hThread; + rc = RTThreadCreate(&hThread, testSessionDataThread, + &threadCtx, 0 /* Stack */, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tstIpc4"); + if (RT_SUCCESS(rc)) + { + do + { + RTPROCESS hProc; + const char *apszArgs[4] = { pszExecPath, "child", "tstRTLocalIpcSessionDataFork", NULL }; + RTTEST_CHECK_RC_BREAK(hTest, RTProcCreate(pszExecPath, apszArgs, + RTENV_DEFAULT, 0 /* fFlags*/, &hProc), VINF_SUCCESS); + /* Wait for the server thread to terminate. */ + int threadRc; + RTTEST_CHECK_RC(hTest, RTThreadWait(hThread, + 5 * 60 * 1000 /* 5 minutes timeout */, &threadRc), VINF_SUCCESS); + RTTEST_CHECK_RC_BREAK(hTest, threadRc, VINF_SUCCESS); + RTTEST_CHECK_RC(hTest, RTLocalIpcServerDestroy(ipcServer), VINF_SUCCESS); + RTTestPrintf(hTest, RTTESTLVL_INFO, "Server thread terminated successfully\n"); + /* Check if the child ran successfully. */ + RTPROCSTATUS stsChild; + RTTEST_CHECK_RC_BREAK(hTest, RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &stsChild), VINF_SUCCESS); + RTTestPrintf(hTest, RTTESTLVL_INFO, "Child terminated\n"); + RTTEST_CHECK_BREAK(hTest, stsChild.enmReason == RTPROCEXITREASON_NORMAL); + RTTEST_CHECK_BREAK(hTest, stsChild.iStatus == 0); + } + while (0); + } + else + RTTestFailed(hTest, "Unable to create thread for cancelling server, rc=%Rrc\n", rc); +#endif + } + else + RTTestFailed(hTest, "Unable to create IPC server, rc=%Rrc\n", rc); + + return !RTTestErrorCount(hTest) ? VINF_SUCCESS : VERR_GENERAL_FAILURE /* Doesn't matter */; +} + +static RTEXITCODE mainChild(int argc, char **argv) +{ + if (argc < 3) /* Safety first. */ + return RTEXITCODE_FAILURE; + /* Note: We assume argv[2] always contains the actual test type to perform. */ + RTTEST hTest; + RTEXITCODE rcExit = RTTestInitAndCreate(argv[2], &hTest); + if (rcExit) + return rcExit; + RTTestBanner(hTest); + + RTAssertSetMayPanic(false); +#ifdef DEBUG_andy + RTAssertSetQuiet(false); +#endif + + if (!RTStrICmp(argv[2], "tstRTLocalIpcSessionConnectionFork")) + rcExit = testSessionConnectionChild(argc, argv, hTest); + else if (!RTStrICmp(argv[2], "tstRTLocalIpcSessionWaitFork")) + rcExit = testSessionWaitChild(argc, argv, hTest); + else if (!RTStrICmp(argv[2], "tstRTLocalIpcSessionDataFork")) + rcExit = testSessionDataChild(argc, argv, hTest); + + return RTTestSummaryAndDestroy(hTest); +} + +int main(int argc, char **argv) +{ + if ( argc > 2 + && !RTStrICmp(argv[1], "child")) + return mainChild(argc, argv); + + RTTEST hTest; + RTEXITCODE rcExit = RTTestInitAndCreate("tstRTLocalIpc", &hTest); + if (rcExit) + return rcExit; + RTTestBanner(hTest); + + char szExecPath[RTPATH_MAX]; + if (!RTProcGetExecutablePath(szExecPath, sizeof(szExecPath))) + RTStrCopy(szExecPath, sizeof(szExecPath), argv[0]); + + RTTestISub("Basics"); + + RTAssertSetMayPanic(false); +#ifdef DEBUG_andy + RTAssertSetQuiet(false); +#endif + + /* Server-side. */ + RTTESTI_CHECK_RC_RET(RTLocalIpcServerCreate(NULL, NULL, 0), VERR_INVALID_POINTER, 1); + RTLOCALIPCSERVER ipcServer; + RTTESTI_CHECK_RC_RET(RTLocalIpcServerCreate(&ipcServer, NULL, 0), VERR_INVALID_POINTER, 1); + RTTESTI_CHECK_RC_RET(RTLocalIpcServerCreate(&ipcServer, "", 0), VERR_INVALID_PARAMETER, 1); + RTTESTI_CHECK_RC_RET(RTLocalIpcServerCreate(&ipcServer, "BasicTest", 0 /* Invalid flags */), VERR_INVALID_PARAMETER, 1); + RTTESTI_CHECK_RC_RET(RTLocalIpcServerCreate(&ipcServer, "BasicTest", 1234 /* Invalid flags */), VERR_INVALID_PARAMETER, 1); + RTTESTI_CHECK_RC_RET(RTLocalIpcServerCancel(NULL), VERR_INVALID_HANDLE, 1); + RTTESTI_CHECK_RC_RET(RTLocalIpcServerDestroy(NULL), VINF_SUCCESS, 1); + /* Basic server creation / destruction. */ + RTTESTI_CHECK_RC_RET(RTLocalIpcServerCreate(&ipcServer, "BasicTest", RTLOCALIPC_FLAGS_MULTI_SESSION), VINF_SUCCESS, 1); + RTTESTI_CHECK_RC_RET(RTLocalIpcServerCancel(ipcServer), VINF_SUCCESS, 1); + RTTESTI_CHECK_RC_RET(RTLocalIpcServerDestroy(ipcServer), VINF_SUCCESS, 1); + + /* Client-side (per session). */ + RTTESTI_CHECK_RC_RET(RTLocalIpcSessionConnect(NULL, NULL, 0), VERR_INVALID_POINTER, 1); + RTLOCALIPCSESSION ipcSession; + RTTESTI_CHECK_RC_RET(RTLocalIpcSessionConnect(&ipcSession, NULL, 0), VERR_INVALID_POINTER, 1); + RTTESTI_CHECK_RC_RET(RTLocalIpcSessionConnect(&ipcSession, "", 0), VERR_INVALID_PARAMETER, 1); + RTTESTI_CHECK_RC_RET(RTLocalIpcSessionConnect(&ipcSession, "BasicTest", 1234 /* Invalid flags */), VERR_INVALID_PARAMETER, 1); + RTTESTI_CHECK_RC_RET(RTLocalIpcSessionCancel(NULL), VERR_INVALID_HANDLE, 1); + RTTESTI_CHECK_RC_RET(RTLocalIpcSessionClose(NULL), VINF_SUCCESS, 1); + /* Basic client creation / destruction. */ + RTTESTI_CHECK_RC_RET(RTLocalIpcSessionConnect(&ipcSession, "BasicTest", 0), VERR_FILE_NOT_FOUND, 1); + RTTESTI_CHECK_RC_RET(RTLocalIpcServerCancel(ipcServer), VERR_INVALID_MAGIC, 1); + RTTESTI_CHECK_RC_RET(RTLocalIpcServerDestroy(ipcServer), VERR_INVALID_MAGIC, 1); + + if (RTTestErrorCount(hTest) == 0) + { + RTTESTI_CHECK_RC_RET(testServerListenAndCancel(hTest, szExecPath), VINF_SUCCESS, 1); + RTTESTI_CHECK_RC_RET(testSessionConnection(hTest, szExecPath), VINF_SUCCESS, 1); + RTTESTI_CHECK_RC_RET(testSessionWait(hTest, szExecPath), VINF_SUCCESS, 1); + RTTESTI_CHECK_RC_RET(testSessionData(hTest, szExecPath), VINF_SUCCESS, 1); + } + + /* + * Summary. + */ + return RTTestSummaryAndDestroy(hTest); +} + diff --git a/src/VBox/Runtime/testcase/tstRTLockValidator.cpp b/src/VBox/Runtime/testcase/tstRTLockValidator.cpp index 7a323833..bda75195 100644 --- a/src/VBox/Runtime/testcase/tstRTLockValidator.cpp +++ b/src/VBox/Runtime/testcase/tstRTLockValidator.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2009 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTManifest.cpp b/src/VBox/Runtime/testcase/tstRTManifest.cpp index 65e5c26e..766d36f4 100644 --- a/src/VBox/Runtime/testcase/tstRTManifest.cpp +++ b/src/VBox/Runtime/testcase/tstRTManifest.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTMemEf.cpp b/src/VBox/Runtime/testcase/tstRTMemEf.cpp index e47eb5b8..904c6ed1 100644 --- a/src/VBox/Runtime/testcase/tstRTMemEf.cpp +++ b/src/VBox/Runtime/testcase/tstRTMemEf.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTMemPool.cpp b/src/VBox/Runtime/testcase/tstRTMemPool.cpp index 2956eb0f..fc59a8bd 100644 --- a/src/VBox/Runtime/testcase/tstRTMemPool.cpp +++ b/src/VBox/Runtime/testcase/tstRTMemPool.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTMp-1.cpp b/src/VBox/Runtime/testcase/tstRTMp-1.cpp new file mode 100644 index 00000000..4a09ba52 --- /dev/null +++ b/src/VBox/Runtime/testcase/tstRTMp-1.cpp @@ -0,0 +1,241 @@ +/* $Id: tstRTMp-1.cpp $ */ +/** @file + * IPRT Testcase - RTMp. + */ + +/* + * Copyright (C) 2008-2011 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL) only, as it comes in the "COPYING.CDDL" file of the + * VirtualBox OSE distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + */ + +/******************************************************************************* +* Header Files * +*******************************************************************************/ +#include <iprt/mp.h> +#include <iprt/cpuset.h> +#include <iprt/err.h> +#include <iprt/string.h> +#include <iprt/test.h> + + + +int main() +{ + RTTEST hTest; + RTEXITCODE rcExit = RTTestInitAndCreate("tstRTMp-1", &hTest); + if (rcExit != RTEXITCODE_SUCCESS) + return rcExit; + RTTestBanner(hTest); + + /* + * Present and possible CPUs. + */ + RTCPUID cCpus = RTMpGetCount(); + if (cCpus > 0) + RTTestIPrintf(RTTESTLVL_ALWAYS, "RTMpGetCount -> %u\n", cCpus); + else + { + RTTestIFailed("RTMpGetCount returned zero"); + cCpus = 1; + } + + RTCPUID cCoreCpus = RTMpGetCoreCount(); + if (cCoreCpus > 0) + RTTestIPrintf(RTTESTLVL_ALWAYS, "RTMpGetCoreCount -> %d\n", (int)cCoreCpus); + else + { + RTTestIFailed("RTMpGetCoreCount returned zero"); + cCoreCpus = 1; + } + RTTESTI_CHECK(cCoreCpus <= cCpus); + + RTCPUSET Set; + PRTCPUSET pSet = RTMpGetSet(&Set); + RTTESTI_CHECK(pSet == &Set); + if (pSet == &Set) + { + RTTESTI_CHECK((RTCPUID)RTCpuSetCount(&Set) == cCpus); + + RTTestIPrintf(RTTESTLVL_ALWAYS, "Possible CPU mask:\n"); + for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++) + { + RTCPUID idCpu = RTMpCpuIdFromSetIndex(iCpu); + if (RTCpuSetIsMemberByIndex(&Set, iCpu)) + { + RTTestIPrintf(RTTESTLVL_ALWAYS, "%2d - id %d: %u/%u MHz", iCpu, (int)idCpu, + RTMpGetCurFrequency(idCpu), RTMpGetMaxFrequency(idCpu)); + if (RTMpIsCpuPresent(idCpu)) + RTTestIPrintf(RTTESTLVL_ALWAYS, RTMpIsCpuOnline(idCpu) ? " online\n" : " offline\n"); + else + { + if (!RTMpIsCpuOnline(idCpu)) + RTTestIPrintf(RTTESTLVL_ALWAYS, " absent\n"); + else + { + RTTestIPrintf(RTTESTLVL_ALWAYS, " online but absent!\n"); + RTTestIFailed("Cpu with index %d is report as !RTIsCpuPresent while RTIsCpuOnline returns true!\n", iCpu); + } + } + if (!RTMpIsCpuPossible(idCpu)) + RTTestIFailed("Cpu with index %d is returned by RTCpuSet but not RTMpIsCpuPossible!\n", iCpu); + } + else if (RTMpIsCpuPossible(idCpu)) + RTTestIFailed("Cpu with index %d is returned by RTMpIsCpuPossible but not RTCpuSet!\n", iCpu); + else if (RTMpGetCurFrequency(idCpu) != 0) + RTTestIFailed("RTMpGetCurFrequency(%d[idx=%d]) didn't return 0 as it should\n", (int)idCpu, iCpu); + else if (RTMpGetMaxFrequency(idCpu) != 0) + RTTestIFailed("RTMpGetMaxFrequency(%d[idx=%d]) didn't return 0 as it should\n", (int)idCpu, iCpu); + } + } + else + { + RTCpuSetEmpty(&Set); + RTCpuSetAdd(&Set, RTMpCpuIdFromSetIndex(0)); + } + + /* + * Online CPUs. + */ + RTCPUID cCpusOnline = RTMpGetOnlineCount(); + if (cCpusOnline > 0) + { + if (cCpusOnline <= cCpus) + RTTestIPrintf(RTTESTLVL_ALWAYS, "RTMpGetOnlineCount -> %d\n", (int)cCpusOnline); + else + { + RTTestIFailed("RTMpGetOnlineCount -> %d, expected <= %d\n", (int)cCpusOnline, (int)cCpus); + cCpusOnline = cCpus; + } + } + else + { + RTTestIFailed("RTMpGetOnlineCount -> %d\n", (int)cCpusOnline); + cCpusOnline = 1; + } + + RTCPUID cCoresOnline = RTMpGetOnlineCoreCount(); + if (cCoresOnline > 0) + RTTestIPrintf(RTTESTLVL_ALWAYS, "RTMpGetOnlineCoreCount -> %d\n", (int)cCoresOnline); + else + { + RTTestIFailed("RTMpGetOnlineCoreCount -> %d, expected <= %d\n", (int)cCoresOnline, (int)cCpusOnline); + cCoresOnline = 1; + } + RTTESTI_CHECK(cCoresOnline <= cCpusOnline); + + RTCPUSET SetOnline; + pSet = RTMpGetOnlineSet(&SetOnline); + if (pSet == &SetOnline) + { + if (RTCpuSetCount(&SetOnline) <= 0) + RTTestIFailed("RTMpGetOnlineSet returned an empty set!\n"); + else if ((RTCPUID)RTCpuSetCount(&SetOnline) > cCpus) + RTTestIFailed("RTMpGetOnlineSet returned a too high value; %d, expected <= %d\n", + RTCpuSetCount(&SetOnline), cCpus); + RTTestIPrintf(RTTESTLVL_ALWAYS, "Online CPU mask:\n"); + for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++) + if (RTCpuSetIsMemberByIndex(&SetOnline, iCpu)) + { + RTCPUID idCpu = RTMpCpuIdFromSetIndex(iCpu); + RTTestIPrintf(RTTESTLVL_ALWAYS, "%2d - id %d: %u/%u MHz %s\n", iCpu, (int)idCpu, RTMpGetCurFrequency(idCpu), + RTMpGetMaxFrequency(idCpu), RTMpIsCpuOnline(idCpu) ? "online" : "offline"); + if (!RTCpuSetIsMemberByIndex(&Set, iCpu)) + RTTestIFailed("online cpu with index %2d is not a member of the possible cpu set!\n", iCpu); + } + + /* There isn't any sane way of testing RTMpIsCpuOnline really... :-/ */ + } + else + RTTestIFailed("RTMpGetOnlineSet -> %p, expected %p\n", pSet, &Set); + + /* + * Present CPUs. + */ + RTCPUID cCpusPresent = RTMpGetPresentCount(); + if (cCpusPresent > 0) + { + if ( cCpusPresent <= cCpus + && cCpusPresent >= cCpusOnline) + RTTestIPrintf(RTTESTLVL_ALWAYS, "RTMpGetPresentCount -> %d\n", (int)cCpusPresent); + else + RTTestIFailed("RTMpGetPresentCount -> %d, expected <= %d and >= %d\n", + (int)cCpusPresent, (int)cCpus, (int)cCpusOnline); + } + else + { + RTTestIFailed("RTMpGetPresentCount -> %d\n", (int)cCpusPresent); + cCpusPresent = 1; + } + + RTCPUSET SetPresent; + pSet = RTMpGetPresentSet(&SetPresent); + if (pSet == &SetPresent) + { + if (RTCpuSetCount(&SetPresent) <= 0) + RTTestIFailed("RTMpGetPresentSet returned an empty set!\n"); + else if ((RTCPUID)RTCpuSetCount(&SetPresent) != cCpusPresent) + RTTestIFailed("RTMpGetPresentSet returned a bad value; %d, expected = %d\n", + RTCpuSetCount(&SetPresent), cCpusPresent); + RTTestIPrintf(RTTESTLVL_ALWAYS, "Present CPU mask:\n"); + for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++) + if (RTCpuSetIsMemberByIndex(&SetPresent, iCpu)) + { + RTCPUID idCpu = RTMpCpuIdFromSetIndex(iCpu); + RTTestIPrintf(RTTESTLVL_ALWAYS, "%2d - id %d: %u/%u MHz %s\n", iCpu, (int)idCpu, RTMpGetCurFrequency(idCpu), + RTMpGetMaxFrequency(idCpu), RTMpIsCpuPresent(idCpu) ? "present" : "absent"); + if (!RTCpuSetIsMemberByIndex(&Set, iCpu)) + RTTestIFailed("online cpu with index %2d is not a member of the possible cpu set!\n", iCpu); + } + + /* There isn't any sane way of testing RTMpIsCpuPresent really... :-/ */ + } + else + RTTestIFailed("RTMpGetPresentSet -> %p, expected %p\n", pSet, &Set); + + + /* Find an online cpu for the next test. */ + RTCPUID idCpuOnline; + for (idCpuOnline = 0; idCpuOnline < RTCPUSET_MAX_CPUS; idCpuOnline++) + if (RTMpIsCpuOnline(idCpuOnline)) + break; + + /* + * Quick test of RTMpGetDescription. + */ + char szBuf[64]; + int rc = RTMpGetDescription(idCpuOnline, &szBuf[0], sizeof(szBuf)); + if (RT_SUCCESS(rc)) + { + RTTestIPrintf(RTTESTLVL_ALWAYS, "RTMpGetDescription -> '%s'\n", szBuf); + + size_t cch = strlen(szBuf); + rc = RTMpGetDescription(idCpuOnline, &szBuf[0], cch); + if (rc != VERR_BUFFER_OVERFLOW) + RTTestIFailed("RTMpGetDescription -> %Rrc, expected VERR_BUFFER_OVERFLOW\n", rc); + + rc = RTMpGetDescription(idCpuOnline, &szBuf[0], cch + 1); + if (RT_FAILURE(rc)) + RTTestIFailed("RTMpGetDescription -> %Rrc, expected VINF_SUCCESS\n", rc); + } + else + RTTestIFailed("RTMpGetDescription -> %Rrc\n", rc); + + return RTTestSummaryAndDestroy(hTest); +} + diff --git a/src/VBox/Runtime/testcase/tstRTPath.cpp b/src/VBox/Runtime/testcase/tstRTPath.cpp index cd97f55f..131466a7 100644 --- a/src/VBox/Runtime/testcase/tstRTPath.cpp +++ b/src/VBox/Runtime/testcase/tstRTPath.cpp @@ -38,6 +38,160 @@ #include <iprt/test.h> +static void testParserAndSplitter(RTTEST hTest) +{ + static struct + { + uint16_t cComps; + uint16_t cchPath; + uint16_t offSuffix; + const char *pszPath; + uint16_t fProps; + uint32_t fFlags; + } const s_aTests[] = + { + { 2, 5, 5, "/bin/", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_DIR_SLASH, RTPATH_STR_F_STYLE_UNIX }, + { 2, 13, 9, "C:/Config.sys", RTPATH_PROP_VOLUME | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX, RTPATH_STR_F_STYLE_DOS }, + { 2, 13, 10, "C://Config.sys", RTPATH_PROP_VOLUME | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX | RTPATH_PROP_EXTRA_SLASHES, RTPATH_STR_F_STYLE_DOS }, + { 2, 12, 8, "C:Config.sys", RTPATH_PROP_VOLUME | RTPATH_PROP_RELATIVE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX, RTPATH_STR_F_STYLE_DOS }, + { 1, 10, 6, "Config.sys", RTPATH_PROP_RELATIVE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX, RTPATH_STR_F_STYLE_DOS }, + { 1, 4, 4, "//./", RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE, RTPATH_STR_F_STYLE_DOS }, + { 2, 5, 5, "//./f", RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_DOS }, + { 2, 5, 6, "//.//f", RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_EXTRA_SLASHES, RTPATH_STR_F_STYLE_DOS }, + { 3, 7, 7, "//././f", RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_DOT_REFS, RTPATH_STR_F_STYLE_DOS }, + { 3, 8, 8, "//.././f", RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_DOT_REFS, RTPATH_STR_F_STYLE_DOS }, + { 3, 9, 9, "//../../f", RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_RELATIVE | RTPATH_PROP_FILENAME | RTPATH_PROP_DOTDOT_REFS, RTPATH_STR_F_STYLE_DOS }, + { 1, 1, 1, "/", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE, RTPATH_STR_F_STYLE_UNIX }, + { 2, 4, 4, "/bin", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX }, + { 2, 5, 5, "/bin/", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_DIR_SLASH, RTPATH_STR_F_STYLE_UNIX }, + { 3, 7, 7, "/bin/ls", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX }, + { 3, 12, 7, "/etc/rc.conf", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX, RTPATH_STR_F_STYLE_UNIX }, + { 1, 1, 2, "//", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_EXTRA_SLASHES, RTPATH_STR_F_STYLE_UNIX }, + { 1, 1, 3, "///", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_EXTRA_SLASHES, RTPATH_STR_F_STYLE_UNIX }, + { 3, 6, 7, "/.//bin", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_EXTRA_SLASHES | RTPATH_PROP_DOT_REFS | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX }, + { 1, 3, 3, "bin", RTPATH_PROP_RELATIVE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX }, + { 1, 4, 4, "bin/", RTPATH_PROP_RELATIVE | RTPATH_PROP_DIR_SLASH, RTPATH_STR_F_STYLE_UNIX }, + { 1, 4, 7, "bin////", RTPATH_PROP_RELATIVE | RTPATH_PROP_DIR_SLASH | RTPATH_PROP_EXTRA_SLASHES, RTPATH_STR_F_STYLE_UNIX }, + { 3, 10, 10, "bin/../usr", RTPATH_PROP_RELATIVE | RTPATH_PROP_DOTDOT_REFS | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX }, + { 4, 11, 11, "/bin/../usr", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_RELATIVE | RTPATH_PROP_DOTDOT_REFS | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX }, + { 4, 8, 8, "/a/.../u", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX }, + { 4, 8, 8, "/a/.b./u", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX }, + { 4, 8, 8, "/a/..c/u", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX }, + { 4, 8, 8, "/a/d../u", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX }, + { 4, 8, 8, "/a/.e/.u", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX }, + { 4, 8, 8, "/a/.f/.u", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX }, + { 4, 8, 8, "/a/.g/u.", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX }, + { 3, 9, 10, "/a/h/u.ext", RTPATH_PROP_EXTRA_SLASHES | RTPATH_PROP_RELATIVE, RTPATH_STR_F_STYLE_UNIX | RTPATH_STR_F_MIDDLE }, + { 3, 9, 9, "a/h/u.ext", RTPATH_PROP_RELATIVE, RTPATH_STR_F_STYLE_UNIX | RTPATH_STR_F_MIDDLE }, + { 3, 9, 10, "a/h/u.ext/", RTPATH_PROP_EXTRA_SLASHES | RTPATH_PROP_RELATIVE, RTPATH_STR_F_STYLE_UNIX | RTPATH_STR_F_MIDDLE }, + }; + + char szPath1[RTPATH_MAX]; + union + { + RTPATHPARSED Parsed; + RTPATHSPLIT Split; + uint8_t ab[4096]; + } u; + + RTTestSub(hTest, "RTPathParse"); + for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++) + { + memset(&u, i & 1 ? 0xff : 0, sizeof(u)); + int rc = RTPathParse(s_aTests[i].pszPath, &u.Parsed, sizeof(u), s_aTests[i].fFlags); + if ( rc != VINF_SUCCESS + || s_aTests[i].cComps != u.Parsed.cComps + || s_aTests[i].fProps != u.Parsed.fProps + || s_aTests[i].offSuffix != u.Parsed.offSuffix + || s_aTests[i].cchPath != u.Parsed.cchPath) + { + RTTestFailed(hTest, "i=%d rc=%Rrc %s", i, rc, s_aTests[i].pszPath); + RTTestFailureDetails(hTest, + " cComps %u, got %u\n" + " fProps %#x, got %#x, xor=>%#x\n" + " offSuffix %u, got %u\n" + " cchPath %u, got %u\n" + , + s_aTests[i].cComps, u.Parsed.cComps, + s_aTests[i].fProps, u.Parsed.fProps, s_aTests[i].fProps ^ u.Parsed.fProps, + s_aTests[i].offSuffix, u.Parsed.offSuffix, + s_aTests[i].cchPath, u.Parsed.cchPath); + } + else + { + rc = RTPathParsedReassemble(s_aTests[i].pszPath, &u.Parsed, s_aTests[i].fFlags & ~RTPATH_STR_F_MIDDLE, + szPath1, sizeof(szPath1)); + if (rc == VINF_SUCCESS) + { + RTTESTI_CHECK_MSG(strlen(szPath1) == s_aTests[i].cchPath, ("%s\n", szPath1)); + if ( !(u.Parsed.fProps & RTPATH_PROP_EXTRA_SLASHES) + && (s_aTests[i].fFlags & RTPATH_STR_F_STYLE_MASK) != RTPATH_STR_F_STYLE_DOS) + RTTESTI_CHECK_MSG(strcmp(szPath1, s_aTests[i].pszPath) == 0, ("%s\n", szPath1)); + } + else + RTTestIFailed("RTPathParsedReassemble -> %Rrc", rc); + } + } + + RTTestSub(hTest, "RTPathSplit"); + for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++) + { + memset(&u, i & 1 ? 0xff : 0, sizeof(u)); + int rc = RTPathSplit(s_aTests[i].pszPath, &u.Split, sizeof(u), s_aTests[i].fFlags); + if ( rc != VINF_SUCCESS + || s_aTests[i].cComps != u.Split.cComps + || s_aTests[i].fProps != u.Split.fProps + || s_aTests[i].cchPath != u.Split.cchPath) + { + RTTestFailed(hTest, "i=%d rc=%Rrc %s", i, rc, s_aTests[i].pszPath); + RTTestFailureDetails(hTest, + " cComps %u, got %u\n" + " fProps %#x, got %#x, xor=>%#x\n" + " cchPath %u, got %u\n" + , + s_aTests[i].cComps, u.Split.cComps, + s_aTests[i].fProps, u.Split.fProps, s_aTests[i].fProps ^ u.Split.fProps, + s_aTests[i].cchPath, u.Split.cchPath); + } + else + { + RTTESTI_CHECK_MSG(*u.Split.pszSuffix == '\0' || *u.Split.pszSuffix == '.', ("%s", u.Split.pszSuffix)); + for (uint32_t idxComp = RTPATH_PROP_HAS_ROOT_SPEC(u.Split.fProps); idxComp < u.Split.cComps; idxComp++) + if ( (s_aTests[i].fFlags & RTPATH_STR_F_STYLE_MASK) == RTPATH_STR_F_STYLE_DOS + ? strpbrk(u.Split.apszComps[idxComp], "/\\") + : strchr(u.Split.apszComps[idxComp], RTPATH_SLASH) ) + RTTestFailed(hTest, "i=%d idxComp=%d '%s'", i, idxComp, u.Split.apszComps[idxComp]); + + PRTPATHSPLIT pSplit = NULL; + RTTESTI_CHECK_RC(rc = RTPathSplitA(s_aTests[i].pszPath, &pSplit, s_aTests[i].fFlags), VINF_SUCCESS); + if (RT_SUCCESS(rc)) + { + RTTESTI_CHECK(pSplit); + RTTESTI_CHECK(pSplit->cComps == u.Split.cComps); + RTTESTI_CHECK(pSplit->fProps == u.Split.fProps); + RTTESTI_CHECK(pSplit->cchPath == u.Split.cchPath); + RTTESTI_CHECK(pSplit->cbNeeded == u.Split.cbNeeded); + RTTESTI_CHECK(!strcmp(pSplit->pszSuffix, u.Split.pszSuffix)); + for (uint32_t idxComp = 0; idxComp < u.Split.cComps; idxComp++) + RTTESTI_CHECK(!strcmp(pSplit->apszComps[idxComp], pSplit->apszComps[idxComp])); + RTPathSplitFree(pSplit); + } + + rc = RTPathSplitReassemble(&u.Split, s_aTests[i].fFlags & ~RTPATH_STR_F_MIDDLE, szPath1, sizeof(szPath1)); + if (rc == VINF_SUCCESS) + { + RTTESTI_CHECK_MSG(strlen(szPath1) == s_aTests[i].cchPath, ("%s\n", szPath1)); + if ( !(u.Parsed.fProps & RTPATH_PROP_EXTRA_SLASHES) + && (s_aTests[i].fFlags & RTPATH_STR_F_STYLE_MASK) != RTPATH_STR_F_STYLE_DOS) + RTTESTI_CHECK_MSG(strcmp(szPath1, s_aTests[i].pszPath) == 0, ("%s\n", szPath1)); + } + else + RTTestIFailed("RTPathSplitReassemble -> %Rrc", rc); + } + } +} + + int main() { char szPath[RTPATH_MAX]; @@ -51,6 +205,32 @@ int main() return rc; RTTestBanner(hTest); + RTTestSub(hTest, "Environment"); +#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS) + RTTESTI_CHECK(RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS); +# if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS +# else + RTTestIFailed("#if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS"); +# endif + RTTESTI_CHECK(strcmp(RTPATH_SLASH_STR, "\\") == 0); + RTTESTI_CHECK(RTPATH_SLASH == '\\'); + RTTESTI_CHECK(RTPATH_IS_SEP('/')); + RTTESTI_CHECK(RTPATH_IS_SEP('\\')); + RTTESTI_CHECK(RTPATH_IS_SEP(':')); + +#else + RTTESTI_CHECK(RTPATH_STYLE == RTPATH_STR_F_STYLE_UNIX); +# if RTPATH_STYLE == RTPATH_STR_F_STYLE_UNIX +# else + RTTestIFailed("#if RTPATH_STYLE == RTPATH_STR_F_STYLE_UNIX"); +# endif + RTTESTI_CHECK(strcmp(RTPATH_SLASH_STR, "/") == 0); + RTTESTI_CHECK(RTPATH_SLASH == '/'); + RTTESTI_CHECK(RTPATH_IS_SEP('/')); + RTTESTI_CHECK(!RTPATH_IS_SEP('\\')); + RTTESTI_CHECK(!RTPATH_IS_SEP(':')); +#endif + /* * RTPathExecDir, RTPathUserHome and RTProcGetExecutablePath. */ @@ -553,6 +733,49 @@ int main() pszInput, szPath, pszResult); } + /* + * RTPathCalcRelative + */ + RTTestSub(hTest, "RTPathCalcRelative"); + struct + { + const char *pszFrom; + const char *pszTo; + int rc; + const char *pszExpected; + } s_aRelPath[] = + { + { "/home/test.ext", "/home/test2.ext", VINF_SUCCESS, "test2.ext"}, + { "/dir/test.ext", "/dir/dir2/test2.ext", VINF_SUCCESS, "dir2/test2.ext"}, + { "/dir/dir2/test.ext", "/dir/test2.ext", VINF_SUCCESS, "../test2.ext"}, + { "/dir/dir2/test.ext", "/dir/dir3/test2.ext", VINF_SUCCESS, "../dir3/test2.ext"}, +#if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS) + { "\\\\server\\share\\test.ext", "\\\\server\\share2\\test2.ext", VERR_NOT_SUPPORTED, ""}, + { "c:\\dir\\test.ext", "f:\\dir\\test.ext", VERR_NOT_SUPPORTED, ""} +#endif + }; + for (unsigned i = 0; i < RT_ELEMENTS(s_aRelPath); i++) + { + const char *pszFrom = s_aRelPath[i].pszFrom; + const char *pszTo = s_aRelPath[i].pszTo; + + rc = RTPathCalcRelative(szPath, sizeof(szPath), pszFrom, pszTo); + if (rc != s_aRelPath[i].rc) + RTTestIFailed("Unexpected return code\n" + " got: %Rrc\n" + "expected: %Rrc", + rc, s_aRelPath[i].rc); + else if ( RT_SUCCESS(rc) + && strcmp(szPath, s_aRelPath[i].pszExpected)) + RTTestIFailed("Unexpected result\n" + " from: '%s'\n" + " to: '%s'\n" + " output: '%s'\n" + "expected: '%s'", + pszFrom, pszTo, szPath, s_aRelPath[i].pszExpected); + } + + testParserAndSplitter(hTest); /* * Summary. diff --git a/src/VBox/Runtime/testcase/tstRTPipe.cpp b/src/VBox/Runtime/testcase/tstRTPipe.cpp index 6944aef3..f0348993 100644 --- a/src/VBox/Runtime/testcase/tstRTPipe.cpp +++ b/src/VBox/Runtime/testcase/tstRTPipe.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp b/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp index 7e36c64a..af837a86 100644 --- a/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp +++ b/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -170,8 +170,6 @@ static void tstRTCreateProcEx5(const char *pszUser, const char *pszPassword) if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0) RTTestIFailed("enmReason=%d iStatus=%d", ProcStatus.enmReason, ProcStatus.iStatus); - else - RTTestIPassed(NULL); } @@ -207,8 +205,6 @@ static void tstRTCreateProcEx4(const char *pszAsUser, const char *pszPassword) if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0) RTTestIFailed("enmReason=%d iStatus=%d", ProcStatus.enmReason, ProcStatus.iStatus); - else - RTTestIPassed(NULL); } @@ -277,8 +273,6 @@ static void tstRTCreateProcEx3(const char *pszAsUser, const char *pszPassword) else if ( offOutput != sizeof("works") - 1 || strcmp(szOutput, "works")) RTTestIFailed("wrong output: \"%s\" (len=%u)", szOutput, offOutput); - else - RTTestIPassed(NULL); } @@ -344,8 +338,6 @@ static void tstRTCreateProcEx2(const char *pszAsUser, const char *pszPassword) else if ( offOutput != sizeof("howdy") - 1 || strcmp(szOutput, "howdy")) RTTestIFailed("wrong output: \"%s\" (len=%u)", szOutput, offOutput); - else - RTTestIPassed(NULL); } @@ -411,8 +403,6 @@ static void tstRTCreateProcEx1(const char *pszAsUser, const char *pszPassword) else if ( offOutput != sizeof("it works") - 1 || strcmp(szOutput, "it works")) RTTestIFailed("wrong output: \"%s\" (len=%u)", szOutput, offOutput); - else - RTTestIPassed(NULL); } diff --git a/src/VBox/Runtime/testcase/tstRTProcCreatePrf.cpp b/src/VBox/Runtime/testcase/tstRTProcCreatePrf.cpp index f17d0985..b2eaa26a 100644 --- a/src/VBox/Runtime/testcase/tstRTProcCreatePrf.cpp +++ b/src/VBox/Runtime/testcase/tstRTProcCreatePrf.cpp @@ -56,7 +56,7 @@ int main(int argc, char **argv) uint64_t NsStart = RTTimeNanoTS(); uint32_t i; -#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) +#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) || defined(RT_OS_DARWIN) for (i = 0; i < 1000; i++) #else for (i = 0; i < 10000; i++) @@ -81,4 +81,3 @@ int main(int argc, char **argv) return RTTestSummaryAndDestroy(hTest); } - diff --git a/src/VBox/Runtime/testcase/tstRTProcIsRunningByName.cpp b/src/VBox/Runtime/testcase/tstRTProcIsRunningByName.cpp index c846f587..f784d949 100644 --- a/src/VBox/Runtime/testcase/tstRTProcIsRunningByName.cpp +++ b/src/VBox/Runtime/testcase/tstRTProcIsRunningByName.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTProcWait.cpp b/src/VBox/Runtime/testcase/tstRTProcWait.cpp index a4f45346..fb555678 100644 --- a/src/VBox/Runtime/testcase/tstRTProcWait.cpp +++ b/src/VBox/Runtime/testcase/tstRTProcWait.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTR0Common.h b/src/VBox/Runtime/testcase/tstRTR0Common.h index 196e5f9d..ed8a5a7e 100644 --- a/src/VBox/Runtime/testcase/tstRTR0Common.h +++ b/src/VBox/Runtime/testcase/tstRTR0Common.h @@ -176,6 +176,24 @@ static uint32_t volatile g_cErrors; } \ } while (0) +/** + * Macro for skipping a test in the ring-0 testcase. + */ +#define RTR0TESTR0_SKIP() \ + do { \ + RTR0TestR0Skip("line %u: SKIPPED", __LINE__); \ + } while (0) + +/** + * Same as RTR0TESTR0_SKIP + break. + */ +#define RTR0TESTR0_SKIP_BREAK() \ + if (1) \ + { \ + RTR0TestR0Skip("line %u: SKIPPED", __LINE__); \ + break; \ + } else do { } while (0) + /** * Report an error. @@ -244,6 +262,35 @@ void RTR0TestR0Info(const char *pszFormat, ...) } } + +/** + * Report an error. + */ +void RTR0TestR0Skip(const char *pszFormat, ...) +{ + size_t off = RTStrNLen(g_szErr, sizeof(g_szErr) - 1); + size_t cbLeft = sizeof(g_szErr) - off; + if (cbLeft > 10) + { + char *psz = &g_szErr[off]; + if (off) + { + *psz++ = '\n'; + *psz++ = '\n'; + cbLeft -= 2; + } + *psz++ = '$'; + cbLeft--; + + va_list va; + va_start(va, pszFormat); + RTStrPrintfV(psz, cbLeft, pszFormat, va); + va_end(va); + } + ASMAtomicIncU32(&g_cErrors); +} + + /** * Checks if we have any error reports. * diff --git a/src/VBox/Runtime/testcase/tstRTR0CommonDriver.h b/src/VBox/Runtime/testcase/tstRTR0CommonDriver.h index b381383c..17d55667 100644 --- a/src/VBox/Runtime/testcase/tstRTR0CommonDriver.h +++ b/src/VBox/Runtime/testcase/tstRTR0CommonDriver.h @@ -177,7 +177,8 @@ static bool rtR3TestR0ProcessMessages(PRTTSTR0REQ pReq) * * We can have multiple failures and info messages packed into szMsg. They * are separated by a double newline. The kind of message is indicated by - * the first character, '!' means error and '?' means info message. + * the first character, '!' means error and '?' means info message. '$' means + * the test was skipped because a feature is not supported on the host. */ bool fRc = true; if (pReq->szMsg[0]) @@ -189,7 +190,7 @@ static bool rtR3TestR0ProcessMessages(PRTTSTR0REQ pReq) { char *pszCur = pszNext; do - pszNext = strpbrk(pszNext + 1, "!?"); + pszNext = strpbrk(pszNext + 1, "!?$"); while (pszNext && (pszNext[-1] != '\n' || pszNext[-2] != '\n')); char *pszEnd = pszNext ? pszNext - 1 : strchr(pszCur, '\0'); @@ -202,6 +203,10 @@ static bool rtR3TestR0ProcessMessages(PRTTSTR0REQ pReq) RTTestFailed(g_hTest, "%s", pszCur + 1); fRc = false; } + else if (*pszCur == '$') + { + RTTestSkipped(g_hTest, "%s", pszCur + 1); + } else RTTestPrintfNl(g_hTest, RTTESTLVL_ALWAYS, "%s", pszCur + 1); } while (pszNext); diff --git a/src/VBox/Runtime/testcase/tstRTR0DbgKrnlInfoDriver.cpp b/src/VBox/Runtime/testcase/tstRTR0DbgKrnlInfoDriver.cpp index 2e3dff7e..2ffb761c 100644 --- a/src/VBox/Runtime/testcase/tstRTR0DbgKrnlInfoDriver.cpp +++ b/src/VBox/Runtime/testcase/tstRTR0DbgKrnlInfoDriver.cpp @@ -83,7 +83,7 @@ int main (int argc, char **argv) void *pvImageBase; rc = SUPR3LoadServiceModule(szPath, "tstRTR0DbgKrnlInfo", - "tstRTR0DbgKrnlInfoSrvReqHandler", + "TSTR0DbgKrnlInfoSrvReqHandler", &pvImageBase); if (RT_FAILURE(rc)) { @@ -120,8 +120,8 @@ int main (int argc, char **argv) TSTRTR0DBGKRNLINFO_SANITY_FAILURE, 0, &Req.Hdr), VINF_SUCCESS); if (RT_FAILURE(rc)) return RTTestSummaryAndDestroy(hTest); - RTTESTI_CHECK_MSG(!strncmp(Req.szMsg, "!42failure42", sizeof("!42failure42") - 1), ("%s", Req.szMsg)); - if (strncmp(Req.szMsg, "!42failure42", sizeof("!42failure42") - 1)) + RTTESTI_CHECK_MSG(!strncmp(Req.szMsg, RT_STR_TUPLE("!42failure42")), ("%s", Req.szMsg)); + if (strncmp(Req.szMsg, RT_STR_TUPLE("!42failure42"))) return RTTestSummaryAndDestroy(hTest); /* diff --git a/src/VBox/Runtime/testcase/tstRTR0MemUserKernel.cpp b/src/VBox/Runtime/testcase/tstRTR0MemUserKernel.cpp index 7b9a63f3..49c61d39 100644 --- a/src/VBox/Runtime/testcase/tstRTR0MemUserKernel.cpp +++ b/src/VBox/Runtime/testcase/tstRTR0MemUserKernel.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTR0MemUserKernel.h b/src/VBox/Runtime/testcase/tstRTR0MemUserKernel.h index 7efbeed5..c4795b1f 100644 --- a/src/VBox/Runtime/testcase/tstRTR0MemUserKernel.h +++ b/src/VBox/Runtime/testcase/tstRTR0MemUserKernel.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTR0MemUserKernelDriver.cpp b/src/VBox/Runtime/testcase/tstRTR0MemUserKernelDriver.cpp index dddcb775..e789dffc 100644 --- a/src/VBox/Runtime/testcase/tstRTR0MemUserKernelDriver.cpp +++ b/src/VBox/Runtime/testcase/tstRTR0MemUserKernelDriver.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -121,8 +121,8 @@ int main(int argc, char **argv) TSTRTR0MEMUSERKERNEL_SANITY_FAILURE, 0, &Req.Hdr), VINF_SUCCESS); if (RT_FAILURE(rc)) return RTTestSummaryAndDestroy(hTest); - RTTESTI_CHECK_MSG(!strncmp(Req.szMsg, "!42failure42", sizeof("!42failure42") - 1), ("%s", Req.szMsg)); - if (strncmp(Req.szMsg, "!42failure42", sizeof("!42failure42") - 1)) + RTTESTI_CHECK_MSG(!strncmp(Req.szMsg, RT_STR_TUPLE("!42failure42")), ("%s", Req.szMsg)); + if (strncmp(Req.szMsg, RT_STR_TUPLE("!42failure42"))) return RTTestSummaryAndDestroy(hTest); /* diff --git a/src/VBox/Runtime/testcase/tstRTR0SemMutex.cpp b/src/VBox/Runtime/testcase/tstRTR0SemMutex.cpp index 8c17a095..b33ba500 100644 --- a/src/VBox/Runtime/testcase/tstRTR0SemMutex.cpp +++ b/src/VBox/Runtime/testcase/tstRTR0SemMutex.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009-2010 Oracle Corporation + * Copyright (C) 2009-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTR0SemMutexDriver.cpp b/src/VBox/Runtime/testcase/tstRTR0SemMutexDriver.cpp index 62bfaabf..21ee35cd 100644 --- a/src/VBox/Runtime/testcase/tstRTR0SemMutexDriver.cpp +++ b/src/VBox/Runtime/testcase/tstRTR0SemMutexDriver.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009-2010 Oracle Corporation + * Copyright (C) 2009-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -237,8 +237,8 @@ int main(int argc, char **argv) TSTRTR0SEMMUTEX_SANITY_FAILURE, 0, &Req.Hdr), VINF_SUCCESS); if (RT_FAILURE(rc)) return RTTestSummaryAndDestroy(hTest); - RTTESTI_CHECK_MSG(!strncmp(Req.szMsg, "!42failure42", sizeof("!42failure42") - 1), ("%s", Req.szMsg)); - if (strncmp(Req.szMsg, "!42failure42", sizeof("!42failure42") - 1)) + RTTESTI_CHECK_MSG(!strncmp(Req.szMsg, RT_STR_TUPLE("!42failure42")), ("%s", Req.szMsg)); + if (strncmp(Req.szMsg, RT_STR_TUPLE("!42failure42"))) return RTTestSummaryAndDestroy(hTest); /* diff --git a/src/VBox/Runtime/testcase/tstRTR0Timer.cpp b/src/VBox/Runtime/testcase/tstRTR0Timer.cpp index 8e12602e..ad41354b 100644 --- a/src/VBox/Runtime/testcase/tstRTR0Timer.cpp +++ b/src/VBox/Runtime/testcase/tstRTR0Timer.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009-2010 Oracle Corporation + * Copyright (C) 2009-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -31,6 +31,7 @@ #include <iprt/timer.h> #include <iprt/asm.h> +#include <iprt/asm-amd64-x86.h> #include <iprt/cpuset.h> #include <iprt/err.h> #include <iprt/mem.h> @@ -107,6 +108,53 @@ typedef struct TSTRTR0TIMEROMNI1 typedef TSTRTR0TIMEROMNI1 *PTSTRTR0TIMEROMNI1; +/******************************************************************************* +* Global Variables * +*******************************************************************************/ +/** + * Latency data. + */ +static struct TSTRTR0TIMEROMNILATENCY +{ + /** The number of samples. */ + volatile uint32_t cSamples; + uint32_t auPadding[3]; + struct + { + uint64_t uTsc; + uint64_t uNanoTs; + } aSamples[4096]; +} g_aOmniLatency[16]; + + +/** + * Callback for the omni timer latency test, adds a sample to g_aOmniLatency. + * + * @param pTimer The timer. + * @param iTick The current tick. + * @param pvUser The user argument. + */ +static DECLCALLBACK(void) tstRTR0TimerCallbackLatencyOmni(PRTTIMER pTimer, void *pvUser, uint64_t iTick) +{ + RTCPUID idCpu = RTMpCpuId(); + uint32_t iCpu = RTMpCpuIdToSetIndex(idCpu); + NOREF(pTimer); NOREF(pvUser); NOREF(iTick); + + RTR0TESTR0_CHECK_MSG(iCpu < RT_ELEMENTS(g_aOmniLatency), ("iCpu=%d idCpu=%u\n", iCpu, idCpu)); + if (iCpu < RT_ELEMENTS(g_aOmniLatency)) + { + uint32_t iSample = g_aOmniLatency[iCpu].cSamples; + if (iSample < RT_ELEMENTS(g_aOmniLatency[iCpu].aSamples)) + { + g_aOmniLatency[iCpu].aSamples[iSample].uTsc = ASMReadTSC(); + g_aOmniLatency[iCpu].aSamples[iSample].uNanoTs = RTTimeSystemNanoTS(); + g_aOmniLatency[iCpu].cSamples = iSample + 1; + } + } +} + + + /** * Callback which increments a 32-bit counter. * @@ -394,33 +442,38 @@ DECLEXPORT(int) TSTRTR0TimerSrvReqHandler(PSUPDRVSESSION pSession, uint32_t uOpe /* Create a one-shot timer and take one shot. */ PRTTIMER pTimer; uint32_t fFlags = TSTRTR0TIMER_IS_HIRES(uOperation) ? RTTIMER_FLAGS_HIGH_RES : 0; - RTR0TESTR0_CHECK_RC_BREAK(RTTimerCreateEx(&pTimer, 0, fFlags, tstRTR0TimerCallbackU32Counter, &State), - VINF_SUCCESS); + int rc = RTTimerCreateEx(&pTimer, 0, fFlags, tstRTR0TimerCallbackU32Counter, &State); + if (rc == VERR_NOT_SUPPORTED) + { + RTR0TestR0Info("one-shot timer are not supported, skipping\n"); + break; + } + RTR0TESTR0_CHECK_RC_BREAK(rc, VINF_SUCCESS); do /* break loop */ { - RT_ZERO(State); + RT_ZERO(State); ASMAtomicWriteU32(&State.cShots, State.cShots); RTR0TESTR0_CHECK_RC_BREAK(RTTimerStart(pTimer, 0), VINF_SUCCESS); for (uint32_t i = 0; i < 1000 && !ASMAtomicUoReadU32(&State.cShots); i++) RTThreadSleep(5); RTR0TESTR0_CHECK_MSG_BREAK(ASMAtomicUoReadU32(&State.cShots) == 1, ("cShots=%u\n", State.cShots)); /* check that it is restartable. */ - RT_ZERO(State); + RT_ZERO(State); ASMAtomicWriteU32(&State.cShots, State.cShots); RTR0TESTR0_CHECK_RC_BREAK(RTTimerStart(pTimer, 0), VINF_SUCCESS); for (uint32_t i = 0; i < 1000 && !ASMAtomicUoReadU32(&State.cShots); i++) RTThreadSleep(5); RTR0TESTR0_CHECK_MSG_BREAK(ASMAtomicUoReadU32(&State.cShots) == 1, ("cShots=%u\n", State.cShots)); /* check that it respects the timeout value and can be cancelled. */ - RT_ZERO(State); + RT_ZERO(State); ASMAtomicWriteU32(&State.cShots, State.cShots); RTR0TESTR0_CHECK_RC(RTTimerStart(pTimer, 5*UINT64_C(1000000000)), VINF_SUCCESS); RTR0TESTR0_CHECK_RC(RTTimerStop(pTimer), VINF_SUCCESS); RTThreadSleep(1); RTR0TESTR0_CHECK_MSG_BREAK(ASMAtomicUoReadU32(&State.cShots) == 0, ("cShots=%u\n", State.cShots)); /* Check some double starts and stops (shall not assert). */ - RT_ZERO(State); + RT_ZERO(State); ASMAtomicWriteU32(&State.cShots, State.cShots); RTR0TESTR0_CHECK_RC(RTTimerStart(pTimer, 5*UINT64_C(1000000000)), VINF_SUCCESS); RTR0TESTR0_CHECK_RC(RTTimerStart(pTimer, 0), VERR_TIMER_ACTIVE); RTR0TESTR0_CHECK_RC(RTTimerStop(pTimer), VINF_SUCCESS); @@ -442,11 +495,17 @@ DECLEXPORT(int) TSTRTR0TimerSrvReqHandler(PSUPDRVSESSION pSession, uint32_t uOpe uint32_t fFlags = TSTRTR0TIMER_IS_HIRES(uOperation) ? RTTIMER_FLAGS_HIGH_RES : 0; for (uint32_t iTest = 0; iTest < 2; iTest++) { - RTR0TESTR0_CHECK_RC_BREAK(RTTimerCreateEx(&pTimer, 0, fFlags, tstRTR0TimerCallbackRestartOnce, &State), - VINF_SUCCESS); + int rc = RTTimerCreateEx(&pTimer, 0, fFlags, tstRTR0TimerCallbackRestartOnce, &State); + if (rc == VERR_NOT_SUPPORTED) + { + RTR0TestR0Info("one-shot timer are not supported, skipping\n"); + break; + } + RTR0TESTR0_CHECK_RC_BREAK(rc, VINF_SUCCESS); RT_ZERO(State); State.iActionShot = 0; + ASMAtomicWriteU32(&State.cShots, State.cShots); do /* break loop */ { RTR0TESTR0_CHECK_RC_BREAK(RTTimerStart(pTimer, cNsSysHz * iTest), VINF_SUCCESS); @@ -469,16 +528,22 @@ DECLEXPORT(int) TSTRTR0TimerSrvReqHandler(PSUPDRVSESSION pSession, uint32_t uOpe uint32_t fFlags = TSTRTR0TIMER_IS_HIRES(uOperation) ? RTTIMER_FLAGS_HIGH_RES : 0; for (uint32_t iTest = 0; iTest < 2; iTest++) { - RTR0TESTR0_CHECK_RC_BREAK(RTTimerCreateEx(&pTimer, 0, fFlags, tstRTR0TimerCallbackDestroyOnce, &State), - VINF_SUCCESS); + int rc = RTTimerCreateEx(&pTimer, 0, fFlags, tstRTR0TimerCallbackDestroyOnce, &State); + if (rc == VERR_NOT_SUPPORTED) + { + RTR0TestR0Info("one-shot timer are not supported, skipping\n"); + break; + } + RTR0TESTR0_CHECK_RC_BREAK(rc, VINF_SUCCESS); RT_ZERO(State); State.rc = VERR_IPE_UNINITIALIZED_STATUS; State.iActionShot = 0; + ASMAtomicWriteU32(&State.cShots, State.cShots); do /* break loop */ { RTR0TESTR0_CHECK_RC_BREAK(RTTimerStart(pTimer, cNsSysHz * iTest), VINF_SUCCESS); - for (uint32_t i = 0; i < 1000 && ASMAtomicUoReadU32(&State.cShots) < 1; i++) + for (uint32_t i = 0; i < 1000 && (ASMAtomicUoReadU32(&State.cShots) < 1 || State.rc == VERR_IPE_UNINITIALIZED_STATUS); i++) RTThreadSleep(5); RTR0TESTR0_CHECK_MSG_BREAK(ASMAtomicReadU32(&State.cShots) == 1, ("cShots=%u\n", State.cShots)); RTR0TESTR0_CHECK_MSG_BREAK(State.rc == VINF_SUCCESS, ("rc=%Rrc\n", State.rc)); @@ -503,13 +568,14 @@ DECLEXPORT(int) TSTRTR0TimerSrvReqHandler(PSUPDRVSESSION pSession, uint32_t uOpe State.iActionShot = 0; State.rc = VINF_SUCCESS; State.u.Specific.idCpu = RTMpCpuIdFromSetIndex(iCpu); + ASMAtomicWriteU32(&State.cShots, State.cShots); uint32_t fFlags = TSTRTR0TIMER_IS_HIRES(uOperation) ? RTTIMER_FLAGS_HIGH_RES : 0; fFlags |= RTTIMER_FLAGS_CPU(iCpu); int rc = RTTimerCreateEx(&pTimer, 0, fFlags, tstRTR0TimerCallbackSpecific, &State); if (rc == VERR_NOT_SUPPORTED) { - RTR0TestR0Info("specific timer are not supported, skipping\n"); + RTR0TestR0Info("one-shot specific timer are not supported, skipping\n"); break; } RTR0TESTR0_CHECK_RC_BREAK(rc, VINF_SUCCESS); @@ -556,6 +622,8 @@ DECLEXPORT(int) TSTRTR0TimerSrvReqHandler(PSUPDRVSESSION pSession, uint32_t uOpe { RT_ZERO(State); State.fPeriodic = true; + ASMAtomicWriteU32(&State.cShots, State.cShots); + uint64_t uStartNsTS = RTTimeSystemNanoTS(); RTR0TESTR0_CHECK_RC_BREAK(RTTimerStart(pTimer, u10HzAsNs), VINF_SUCCESS); for (uint32_t i = 0; i < 1000 && ASMAtomicUoReadU32(&State.cShots) < 10; i++) @@ -584,6 +652,8 @@ DECLEXPORT(int) TSTRTR0TimerSrvReqHandler(PSUPDRVSESSION pSession, uint32_t uOpe { RT_ZERO(State); State.fPeriodic = true; + ASMAtomicWriteU32(&State.cShots, State.cShots); /* ordered, necessary? */ + RTR0TESTR0_CHECK_RC_BREAK(RTTimerStart(pTimer, i < 20 ? 0 : cNsSysHz), VINF_SUCCESS); for (uint32_t k = 0; k < 1000 && ASMAtomicUoReadU32(&State.cShots) < 2; k++) RTThreadSleep(1); @@ -620,6 +690,7 @@ DECLEXPORT(int) TSTRTR0TimerSrvReqHandler(PSUPDRVSESSION pSession, uint32_t uOpe State.u.ChgInt.cStepsBetween = u64Arg & 4 ? 1 : 3; RTR0TESTR0_CHECK_MSG_BREAK(State.u.ChgInt.cNsMinInterval > 1000, ("%u\n", State.u.ChgInt.cNsMinInterval)); RTR0TESTR0_CHECK_MSG_BREAK(State.u.ChgInt.cNsMaxInterval > State.u.ChgInt.cNsMinInterval, ("max=%u min=%u\n", State.u.ChgInt.cNsMaxInterval, State.u.ChgInt.cNsMinInterval)); + ASMAtomicWriteU32(&State.cShots, State.cShots); /* create the timer and check if RTTimerChangeInterval is supported. */ PRTTIMER pTimer; @@ -663,6 +734,7 @@ DECLEXPORT(int) TSTRTR0TimerSrvReqHandler(PSUPDRVSESSION pSession, uint32_t uOpe State.rc = VINF_SUCCESS; State.fPeriodic = true; State.u.Specific.idCpu = RTMpCpuIdFromSetIndex(iCpu); + ASMAtomicWriteU32(&State.cShots, State.cShots); uint32_t fFlags = TSTRTR0TIMER_IS_HIRES(uOperation) ? RTTIMER_FLAGS_HIGH_RES : 0; fFlags |= RTTIMER_FLAGS_CPU(iCpu); @@ -714,8 +786,12 @@ DECLEXPORT(int) TSTRTR0TimerSrvReqHandler(PSUPDRVSESSION pSession, uint32_t uOpe PRTTIMER pTimer; uint32_t fFlags = (TSTRTR0TIMER_IS_HIRES(uOperation) ? RTTIMER_FLAGS_HIGH_RES : 0) | RTTIMER_FLAGS_CPU_ALL; - RTR0TESTR0_CHECK_RC_BREAK(RTTimerCreateEx(&pTimer, cNsInterval, fFlags, tstRTR0TimerCallbackOmni, paStates), - VINF_SUCCESS); + int rc = RTTimerCreateEx(&pTimer, cNsInterval, fFlags, tstRTR0TimerCallbackOmni, paStates); + if (rc == VERR_NOT_SUPPORTED) + { + RTR0TESTR0_SKIP_BREAK(); + } + RTR0TESTR0_CHECK_RC_BREAK(rc, VINF_SUCCESS); for (uint32_t iTest = 0; iTest < 3 && !RTR0TestR0HaveErrors(); iTest++) { @@ -778,6 +854,72 @@ DECLEXPORT(int) TSTRTR0TimerSrvReqHandler(PSUPDRVSESSION pSession, uint32_t uOpe RTMemFree(paStates); break; } + + case TSTRTR0TIMER_LATENCY_OMNI: + case TSTRTR0TIMER_LATENCY_OMNI_HIRES: + { + /* + * Create a periodic timer running at max host frequency, but no more than 1000 Hz. + */ + PRTTIMER pTimer; + uint32_t fFlags = (TSTRTR0TIMER_IS_HIRES(uOperation) ? RTTIMER_FLAGS_HIGH_RES : 0) + | RTTIMER_FLAGS_CPU_ALL; + uint32_t cNsInterval = cNsSysHz; + while (cNsInterval < UINT32_C(1000000)) + cNsInterval *= 2; + int rc = RTTimerCreateEx(&pTimer, cNsInterval, fFlags, tstRTR0TimerCallbackLatencyOmni, NULL); + if (rc == VERR_NOT_SUPPORTED) + { + RTR0TESTR0_SKIP_BREAK(); + } + RTR0TESTR0_CHECK_RC_BREAK(rc, VINF_SUCCESS); + + /* + * Reset the state and run the test for 4 seconds. + */ + RT_ZERO(g_aOmniLatency); + + RTCPUSET OnlineSet; + uint64_t uStartNsTS = RTTimeSystemNanoTS(); + RTR0TESTR0_CHECK_RC_BREAK(RTTimerStart(pTimer, 0), VINF_SUCCESS); + RTMpGetOnlineSet(&OnlineSet); + + for (uint32_t i = 0; i < 5000 && RTTimeSystemNanoTS() - uStartNsTS <= UINT64_C(4000000000); i++) + RTThreadSleep(2); + + RTR0TESTR0_CHECK_RC_BREAK(RTTimerStop(pTimer), VINF_SUCCESS); + uint64_t cNsElapsedX = RTTimeNanoTS() - uStartNsTS; + + /* + * Process the result. + */ + int32_t cNsLow = cNsInterval / 4 * 3; /* 75% */ + int32_t cNsHigh = cNsInterval / 4 * 5; /* 125% */ + uint32_t cTotal = 0; + uint32_t cLow = 0; + uint32_t cHigh = 0; + for (uint32_t iCpu = 0; iCpu < RT_ELEMENTS(g_aOmniLatency); iCpu++) + { + uint32_t cSamples = g_aOmniLatency[iCpu].cSamples; + if (cSamples > 1) + { + cTotal += cSamples - 1; + for (uint32_t iSample = 1; iSample < cSamples; iSample++) + { + int64_t cNsDelta = g_aOmniLatency[iCpu].aSamples[iSample - 1].uNanoTs + - g_aOmniLatency[iCpu].aSamples[iSample].uNanoTs; + if (cNsDelta < cNsLow) + cLow++; + else if (cNsDelta > cNsHigh) + cHigh++; + } + } + } + RTR0TestR0Info("125%%: %u; 75%%: %u; total: %u", cHigh, cLow, cTotal); + RTR0TESTR0_CHECK_RC(RTTimerDestroy(pTimer), VINF_SUCCESS); + break; + } + } RTR0TESTR0_SRV_REQ_EPILOG(pReqHdr); diff --git a/src/VBox/Runtime/testcase/tstRTR0Timer.h b/src/VBox/Runtime/testcase/tstRTR0Timer.h index 8699490f..8edf273e 100644 --- a/src/VBox/Runtime/testcase/tstRTR0Timer.h +++ b/src/VBox/Runtime/testcase/tstRTR0Timer.h @@ -54,6 +54,8 @@ typedef enum TSTRTR0TIMER TSTRTR0TIMER_PERIODIC_SPECIFIC_HIRES, TSTRTR0TIMER_PERIODIC_OMNI, TSTRTR0TIMER_PERIODIC_OMNI_HIRES, + TSTRTR0TIMER_LATENCY_OMNI, + TSTRTR0TIMER_LATENCY_OMNI_HIRES, TSTRTR0TIMER_END } TSTRTR0TIMER; @@ -68,5 +70,6 @@ typedef enum TSTRTR0TIMER || (uOperation) == TSTRTR0TIMER_PERIODIC_CHANGE_INTERVAL_HIRES \ || (uOperation) == TSTRTR0TIMER_PERIODIC_SPECIFIC_HIRES \ || (uOperation) == TSTRTR0TIMER_PERIODIC_OMNI_HIRES \ + || (uOperation) == TSTRTR0TIMER_LATENCY_OMNI_HIRES \ ) diff --git a/src/VBox/Runtime/testcase/tstRTR0TimerDriver.cpp b/src/VBox/Runtime/testcase/tstRTR0TimerDriver.cpp index 8b34cbd1..0fd6b3c8 100644 --- a/src/VBox/Runtime/testcase/tstRTR0TimerDriver.cpp +++ b/src/VBox/Runtime/testcase/tstRTR0TimerDriver.cpp @@ -56,47 +56,59 @@ int main(int argc, char **argv) if (rcExit != RTEXITCODE_SUCCESS) return rcExit; -# if 1 - /* - * Standard timers. - */ - RTR3TestR0SimpleTest(TSTRTR0TIMER_ONE_SHOT_BASIC, "Basic one shot"); - RTR3TestR0SimpleTest(TSTRTR0TIMER_PERIODIC_BASIC, "Basic periodic"); - if (RTTestErrorCount(g_hTest) == 0) + if (argc == 2 && !strcmp(argv[1], "latency")) { + RTR3TestR0SimpleTest(TSTRTR0TIMER_LATENCY_OMNI, "Latency omni timer"); + RTR3TestR0SimpleTest(TSTRTR0TIMER_LATENCY_OMNI_HIRES, "Latency omni hires timer"); + } + else + { +# if 1 + /* + * Standard timers. + */ + RTR3TestR0SimpleTest(TSTRTR0TIMER_ONE_SHOT_BASIC, "Basic one shot"); + RTR3TestR0SimpleTest(TSTRTR0TIMER_PERIODIC_BASIC, "Basic periodic"); + if (RTTestErrorCount(g_hTest) == 0) + { # if 1 - RTR3TestR0SimpleTest(TSTRTR0TIMER_ONE_SHOT_RESTART, "Restart one shot from callback"); - RTR3TestR0SimpleTest(TSTRTR0TIMER_ONE_SHOT_DESTROY, "Destroy one shot from callback"); - RTR3TestR0SimpleTest(TSTRTR0TIMER_PERIODIC_CSSD_LOOPS, "Create-start-stop-destroy loops"); - for (uint32_t i = 0; i <= 7; i++) - RTR3TestR0SimpleTestWithArg(TSTRTR0TIMER_PERIODIC_CHANGE_INTERVAL, i, "Change interval from callback, variation %u", i); +# ifndef RT_OS_SOLARIS /* Solaris cannot call back into cyclic subsystem from a cyclic callback. */ + RTR3TestR0SimpleTest(TSTRTR0TIMER_ONE_SHOT_RESTART, "Restart one shot from callback"); + RTR3TestR0SimpleTest(TSTRTR0TIMER_ONE_SHOT_DESTROY, "Destroy one shot from callback"); +# endif + RTR3TestR0SimpleTest(TSTRTR0TIMER_PERIODIC_CSSD_LOOPS, "Create-start-stop-destroy loops"); + for (uint32_t i = 0; i <= 7; i++) + RTR3TestR0SimpleTestWithArg(TSTRTR0TIMER_PERIODIC_CHANGE_INTERVAL, i, "Change interval from callback, variation %u", i); # endif - RTR3TestR0SimpleTest(TSTRTR0TIMER_ONE_SHOT_SPECIFIC, "One shot cpu specific"); - RTR3TestR0SimpleTest(TSTRTR0TIMER_PERIODIC_SPECIFIC, "Periodic cpu specific"); - RTR3TestR0SimpleTest(TSTRTR0TIMER_PERIODIC_OMNI, "Periodic omni timer"); - } + RTR3TestR0SimpleTest(TSTRTR0TIMER_ONE_SHOT_SPECIFIC, "One shot cpu specific"); + RTR3TestR0SimpleTest(TSTRTR0TIMER_PERIODIC_SPECIFIC, "Periodic cpu specific"); + RTR3TestR0SimpleTest(TSTRTR0TIMER_PERIODIC_OMNI, "Periodic omni timer"); + } # endif # if 1 - /* - * High resolution timers. - */ - RTR3TestR0SimpleTest(TSTRTR0TIMER_ONE_SHOT_BASIC_HIRES, "Basic hires one shot"); - RTR3TestR0SimpleTest(TSTRTR0TIMER_PERIODIC_BASIC_HIRES, "Basic hires periodic"); - if (RTTestErrorCount(g_hTest) == 0) - { + /* + * High resolution timers. + */ + RTR3TestR0SimpleTest(TSTRTR0TIMER_ONE_SHOT_BASIC_HIRES, "Basic hires one shot"); + RTR3TestR0SimpleTest(TSTRTR0TIMER_PERIODIC_BASIC_HIRES, "Basic hires periodic"); + if (RTTestErrorCount(g_hTest) == 0) + { # if 1 - RTR3TestR0SimpleTest(TSTRTR0TIMER_ONE_SHOT_RESTART_HIRES, "Restart hires one shot from callback"); - RTR3TestR0SimpleTest(TSTRTR0TIMER_ONE_SHOT_DESTROY_HIRES, "Destroy hires one shot from callback"); - RTR3TestR0SimpleTest(TSTRTR0TIMER_PERIODIC_CSSD_LOOPS_HIRES, "Create-start-stop-destroy loops, hires"); - for (uint32_t i = 0; i <= 7; i++) - RTR3TestR0SimpleTestWithArg(TSTRTR0TIMER_PERIODIC_CHANGE_INTERVAL, i, "Change interval from callback, hires, variation %u", i); +# ifndef RT_OS_SOLARIS /* Solaris cannot call back into cyclic subsystem from a cyclic callback. */ + RTR3TestR0SimpleTest(TSTRTR0TIMER_ONE_SHOT_RESTART_HIRES, "Restart hires one shot from callback"); + RTR3TestR0SimpleTest(TSTRTR0TIMER_ONE_SHOT_DESTROY_HIRES, "Destroy hires one shot from callback"); +# endif + RTR3TestR0SimpleTest(TSTRTR0TIMER_PERIODIC_CSSD_LOOPS_HIRES, "Create-start-stop-destroy loops, hires"); + for (uint32_t i = 0; i <= 7; i++) + RTR3TestR0SimpleTestWithArg(TSTRTR0TIMER_PERIODIC_CHANGE_INTERVAL, i, "Change interval from callback, hires, variation %u", i); # endif - RTR3TestR0SimpleTest(TSTRTR0TIMER_ONE_SHOT_SPECIFIC_HIRES, "One shot hires cpu specific"); - RTR3TestR0SimpleTest(TSTRTR0TIMER_PERIODIC_SPECIFIC_HIRES, "Periodic hires cpu specific"); - RTR3TestR0SimpleTest(TSTRTR0TIMER_PERIODIC_OMNI, "Periodic omni hires timer"); - } + RTR3TestR0SimpleTest(TSTRTR0TIMER_ONE_SHOT_SPECIFIC_HIRES, "One shot hires cpu specific"); + RTR3TestR0SimpleTest(TSTRTR0TIMER_PERIODIC_SPECIFIC_HIRES, "Periodic hires cpu specific"); + RTR3TestR0SimpleTest(TSTRTR0TIMER_PERIODIC_OMNI, "Periodic omni hires timer"); + } # endif + } /* * Done. diff --git a/src/VBox/Runtime/testcase/tstRTS3.cpp b/src/VBox/Runtime/testcase/tstRTS3.cpp index 6dda0054..3b5b0514 100644 --- a/src/VBox/Runtime/testcase/tstRTS3.cpp +++ b/src/VBox/Runtime/testcase/tstRTS3.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTSemRW.cpp b/src/VBox/Runtime/testcase/tstRTSemRW.cpp index 06575bce..ea2a7609 100644 --- a/src/VBox/Runtime/testcase/tstRTSemRW.cpp +++ b/src/VBox/Runtime/testcase/tstRTSemRW.cpp @@ -297,14 +297,17 @@ static void Test4(unsigned cThreads, unsigned cSeconds, unsigned uWritePercent, } - RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, - "Threads: %u Total: %llu Per Sec: %llu Avg: %llu ns Max dev: %llu%%\n", - cThreads, - cItrTotal, - cItrTotal / cSeconds, - ElapsedNS / cItrTotal, - cItrMaxDeviation * 100 / cItrNormal - ); + //RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, + // "Threads: %u Total: %llu Per Sec: %llu Avg: %llu ns Max dev: %llu%%\n", + // cThreads, + // cItrTotal, + // cItrTotal / cSeconds, + // ElapsedNS / cItrTotal, + // cItrMaxDeviation * 100 / cItrNormal + // ); + // + RTTestValue(g_hTest, "Thruput", cItrTotal * UINT32_C(1000000000) / ElapsedNS, RTTESTUNIT_CALLS_PER_SEC); + RTTestValue(g_hTest, "Max diviation", cItrMaxDeviation * 100 / cItrNormal, RTTESTUNIT_PCT); } diff --git a/src/VBox/Runtime/testcase/tstRTSemXRoads.cpp b/src/VBox/Runtime/testcase/tstRTSemXRoads.cpp index bd5f31a4..a6759a6f 100644 --- a/src/VBox/Runtime/testcase/tstRTSemXRoads.cpp +++ b/src/VBox/Runtime/testcase/tstRTSemXRoads.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTStrAlloc.cpp b/src/VBox/Runtime/testcase/tstRTStrAlloc.cpp index 6f49cb0e..b1240c2f 100644 --- a/src/VBox/Runtime/testcase/tstRTStrAlloc.cpp +++ b/src/VBox/Runtime/testcase/tstRTStrAlloc.cpp @@ -189,13 +189,13 @@ static void tst1(void) /* RTStrAAppendExN / RTStrAAppendExNV */ psz = NULL; - RTTESTI_CHECK_RC(RTStrAAppendExN(&psz, 5, "a", 1, "bc", 1, "cdefg", RTSTR_MAX, "hijkl", 2, "jklmnopqrstuvwxyz", RTSTR_MAX), VINF_SUCCESS); + RTTESTI_CHECK_RC(RTStrAAppendExN(&psz, 5, "a", (size_t)1, "bc", (size_t)1, "cdefg", RTSTR_MAX, "hijkl", (size_t)2, "jklmnopqrstuvwxyz", RTSTR_MAX), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "abcdefghijklmnopqrstuvwxyz")); RTTESTI_CHECK_RC(RTStrAAppendExN(&psz, 0), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "abcdefghijklmnopqrstuvwxyz")); - RTTESTI_CHECK_RC(RTStrAAppendExN(&psz, 2, NULL, 0, "", 0), VINF_SUCCESS); + RTTESTI_CHECK_RC(RTStrAAppendExN(&psz, 2, NULL, (size_t)0, "", (size_t)0), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "abcdefghijklmnopqrstuvwxyz")); - RTTESTI_CHECK_RC(RTStrAAppendExN(&psz, 1, "-", 1), VINF_SUCCESS); + RTTESTI_CHECK_RC(RTStrAAppendExN(&psz, 1, "-", (size_t)1), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "abcdefghijklmnopqrstuvwxyz-")); RTStrFree(psz); diff --git a/src/VBox/Runtime/testcase/tstRTStrCache.cpp b/src/VBox/Runtime/testcase/tstRTStrCache.cpp index ef466554..15d9da86 100644 --- a/src/VBox/Runtime/testcase/tstRTStrCache.cpp +++ b/src/VBox/Runtime/testcase/tstRTStrCache.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -30,12 +30,108 @@ #include <iprt/strcache.h> #include <iprt/asm.h> +#include <iprt/ctype.h> #include <iprt/err.h> #include <iprt/initterm.h> +#include <iprt/mem.h> +#include <iprt/rand.h> #include <iprt/string.h> #include <iprt/test.h> #include <iprt/thread.h> -#include <iprt/rand.h> +#include <iprt/time.h> + + +static void tstShowStats(RTSTRCACHE hStrCache) +{ + size_t cbStrings; + size_t cbChunks; + size_t cbBigEntries; + uint32_t cHashCollisions; + uint32_t cHashCollisions2; + uint32_t cHashInserts; + uint32_t cRehashes; + uint32_t cStrings = RTStrCacheGetStats(hStrCache, &cbStrings, &cbChunks, &cbBigEntries, + &cHashCollisions, &cHashCollisions2, &cHashInserts, &cRehashes); + if (cbStrings == UINT32_MAX) + { + RTTESTI_CHECK(!RTStrCacheIsRealImpl()); + return; + } + + RTTestIValue("Strings", cStrings, RTTESTUNIT_OCCURRENCES); + RTTestIValue("Memory overhead", (uint64_t)(cbChunks + cbBigEntries - cbStrings) * 100 / cbStrings, RTTESTUNIT_PCT); + if (cHashInserts > 0) + { + RTTestIValue("Collisions", (uint64_t)cHashCollisions * 100 / cHashInserts, RTTESTUNIT_PCT); + RTTestIValue("Collisions2", (uint64_t)cHashCollisions2 * 100 / cHashInserts, RTTESTUNIT_PCT); + } + RTTestIPrintf(RTTESTLVL_ALWAYS, "cHashInserts=%u cHashCollisions=%u cHashCollisions2=%u cRehashes=%u\n", + cHashInserts, cHashCollisions, cHashCollisions2, cRehashes); + RTTestIPrintf(RTTESTLVL_ALWAYS, "cbChunks=%zu cbBigEntries=%zu cbStrings=%zu\n", cbChunks, cbBigEntries, cbStrings); +} + + +/** + * Check hash and memory performance. + */ +static void tst2(void) +{ + RTTestISub("Hash performance"); + + /* + * Generate test strings using a specific pseudo random generator. + */ + size_t cbStrings = 0; + char *apszTests[8192]; + RTRAND hRand; + RTTESTI_CHECK_RC_RETV(RTRandAdvCreateParkMiller(&hRand), VINF_SUCCESS); + for (uint32_t i = 0; i < 8192; i++) + { + char szBuf[8192]; + uint32_t cch = RTRandAdvU32Ex(hRand, 3, sizeof(szBuf) - 1); + RTRandAdvBytes(hRand, szBuf, cch); + szBuf[cch] = '\0'; + for (uint32_t off = 0; off < cch; off++) + { + uint8_t b = szBuf[off]; + b &= 0x7f; + if (!b || b == 0x7f) + b = ' '; + else if (RTLocCIsCntrl(b) && b != '\n' && b != '\r' && b != '\t') + b += 0x30; + szBuf[off] = b; + } + apszTests[i] = (char *)RTMemDup(szBuf, cch + 1); + RTTESTI_CHECK_RETV(apszTests[i] != NULL); + cbStrings += cch + 1; + } + RTRandAdvDestroy(hRand); + RTTestIValue("Average string", cbStrings / RT_ELEMENTS(apszTests), RTTESTUNIT_BYTES); + + /* + * Test new insertion first time around. + */ + RTSTRCACHE hStrCache; + RTTESTI_CHECK_RC_RETV(RTStrCacheCreate(&hStrCache, "hash performance"), VINF_SUCCESS); + + uint64_t nsTsStart = RTTimeNanoTS(); + for (uint32_t i = 0; i < RT_ELEMENTS(apszTests); i++) + RTTESTI_CHECK_RETV(RTStrCacheEnter(hStrCache, apszTests[i]) != NULL); + uint64_t cNsElapsed = RTTimeNanoTS() - nsTsStart; + RTTestIValue("First insert", cNsElapsed / RT_ELEMENTS(apszTests), RTTESTUNIT_NS_PER_CALL); + + /* + * Insert existing strings. + */ + nsTsStart = RTTimeNanoTS(); + for (uint32_t i = 0; i < 8192; i++) + RTTESTI_CHECK(RTStrCacheEnter(hStrCache, apszTests[i]) != NULL); + cNsElapsed = RTTimeNanoTS() - nsTsStart; + RTTestIValue("Duplicate insert", cNsElapsed / RT_ELEMENTS(apszTests), RTTESTUNIT_NS_PER_CALL); + + tstShowStats(hStrCache); + RTTESTI_CHECK_RC(RTStrCacheDestroy(hStrCache), VINF_SUCCESS); +} /** @@ -87,8 +183,8 @@ static void tst1(RTSTRCACHE hStrCache) RTTESTI_CHECK(RTStrCacheRetain(psz) == 4); RTTESTI_CHECK(RTStrCacheRetain(psz) == 5); RTTESTI_CHECK(RTStrCacheRetain(psz) == 6); - RTTESTI_CHECK(RTStrCacheRelease(NIL_RTSTRCACHE, psz) == 5); - RTTESTI_CHECK(RTStrCacheRelease(NIL_RTSTRCACHE, psz) == 4); + RTTESTI_CHECK(RTStrCacheRelease(hStrCache, psz) == 5); + RTTESTI_CHECK(RTStrCacheRelease(hStrCache, psz) == 4); RTTESTI_CHECK_MSG_RETV((pv2 = ASMMemIsAll8(psz, i, 'a')) == NULL && !psz[i], ("i=%#x psz=%p off=%#x\n", i, psz, (uintptr_t)pv2 - (uintptr_t)psz)); for (uint32_t cRefs = 3;; cRefs--) @@ -107,6 +203,41 @@ static void tst1(RTSTRCACHE hStrCache) } } } + + /* Lots of allocations. */ + memset(szTest, 'b', sizeof(szTest)); + memset(szTest2, 'e', sizeof(szTest)); + const char *pszTest1Rets[4096 + 16]; + const char *pszTest2Rets[4096 + 16]; + for (uint32_t i = 1; i < RT_ELEMENTS(pszTest1Rets); i++) + { + RTTESTI_CHECK(pszTest1Rets[i] = RTStrCacheEnterN(hStrCache, szTest, i)); + RTTESTI_CHECK(strlen(pszTest1Rets[i]) == i); + RTTESTI_CHECK(pszTest2Rets[i] = RTStrCacheEnterN(hStrCache, szTest2, i)); + RTTESTI_CHECK(strlen(pszTest2Rets[i]) == i); + } + + if (RTStrCacheIsRealImpl()) + { + for (uint32_t i = 1; i < RT_ELEMENTS(pszTest1Rets); i++) + { + uint32_t cRefs; + const char *psz1, *psz2; + RTTESTI_CHECK((psz1 = RTStrCacheEnterN(hStrCache, szTest, i)) == pszTest1Rets[i]); + RTTESTI_CHECK((psz2 = RTStrCacheEnterN(hStrCache, szTest2, i)) == pszTest2Rets[i]); + RTTESTI_CHECK_MSG((cRefs = RTStrCacheRelease(hStrCache, psz1)) == 1, ("cRefs=%#x i=%#x\n", cRefs, i)); + RTTESTI_CHECK_MSG((cRefs = RTStrCacheRelease(hStrCache, psz2)) == 1, ("cRefs=%#x i=%#x\n", cRefs, i)); + } + } + + for (uint32_t i = 1; i < RT_ELEMENTS(pszTest1Rets); i++) + { + uint32_t cRefs; + RTTESTI_CHECK(strlen(pszTest1Rets[i]) == i); + RTTESTI_CHECK_MSG((cRefs = RTStrCacheRelease(hStrCache, pszTest1Rets[i])) == 0, ("cRefs=%#x i=%#x\n", cRefs, i)); + RTTESTI_CHECK(strlen(pszTest2Rets[i]) == i); + RTTESTI_CHECK_MSG((cRefs = RTStrCacheRelease(hStrCache, pszTest2Rets[i])) == 0, ("cRefs=%#x i=%#x\n", cRefs, i)); + } } @@ -141,6 +272,11 @@ int main() } /* + * Cache performance on relatively real world examples. + */ + tst2(); + + /* * Summary. */ return RTTestSummaryAndDestroy(hTest); diff --git a/src/VBox/Runtime/testcase/tstRTStrFormat.cpp b/src/VBox/Runtime/testcase/tstRTStrFormat.cpp index 7af97859..e0504e5f 100644 --- a/src/VBox/Runtime/testcase/tstRTStrFormat.cpp +++ b/src/VBox/Runtime/testcase/tstRTStrFormat.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -336,6 +336,97 @@ int main() CHECK42("%RTnaipv4", Ipv4Addr.u, "255.255.255.255"); RTNETADDRIPV6 Ipv6Addr; + + /* any */ + memset(&Ipv6Addr, 0, sizeof(Ipv6Addr)); + CHECK42("%RTnaipv6", &Ipv6Addr, "::"); + + /* loopback */ + Ipv6Addr.au8[15] = 1; + CHECK42("%RTnaipv6", &Ipv6Addr, "::1"); + + /* IPv4-compatible */ + Ipv6Addr.au8[12] = 1; + Ipv6Addr.au8[13] = 1; + Ipv6Addr.au8[14] = 1; + Ipv6Addr.au8[15] = 1; + CHECK42("%RTnaipv6", &Ipv6Addr, "::1.1.1.1"); + + /* IPv4-mapped */ + Ipv6Addr.au16[5] = RT_H2N_U16_C(0xffff); + CHECK42("%RTnaipv6", &Ipv6Addr, "::ffff:1.1.1.1"); + + /* IPv4-translated */ + Ipv6Addr.au16[4] = RT_H2N_U16_C(0xffff); + Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0000); + CHECK42("%RTnaipv6", &Ipv6Addr, "::ffff:0:1.1.1.1"); + + /* single zero word is not abbreviated, leading zeroes are not printed */ + Ipv6Addr.au16[0] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0001); + Ipv6Addr.au16[2] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[3] = RT_H2N_U16_C(0x0001); + Ipv6Addr.au16[4] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0001); + Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[7] = RT_H2N_U16_C(0x0001); + CHECK42("%RTnaipv6", &Ipv6Addr, "0:1:0:1:0:1:0:1"); + + /* longest run is abbreviated (here: at the beginning) */ + Ipv6Addr.au16[0] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[2] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[3] = RT_H2N_U16_C(0x0001); + Ipv6Addr.au16[4] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0001); + Ipv6Addr.au16[7] = RT_H2N_U16_C(0x0000); + CHECK42("%RTnaipv6", &Ipv6Addr, "::1:0:0:1:0"); + + /* longest run is abbreviated (here: first) */ + Ipv6Addr.au16[0] = RT_H2N_U16_C(0x0001); + Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[2] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[3] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[4] = RT_H2N_U16_C(0x0001); + Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[7] = RT_H2N_U16_C(0x0001); + CHECK42("%RTnaipv6", &Ipv6Addr, "1::1:0:0:1"); + + /* longest run is abbreviated (here: second) */ + Ipv6Addr.au16[0] = RT_H2N_U16_C(0x0001); + Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[2] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[3] = RT_H2N_U16_C(0x0001); + Ipv6Addr.au16[4] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[7] = RT_H2N_U16_C(0x0001); + CHECK42("%RTnaipv6", &Ipv6Addr, "1:0:0:1::1"); + + /* longest run is abbreviated (here: at the end) */ + Ipv6Addr.au16[0] = RT_H2N_U16_C(0x0001); + Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[2] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[3] = RT_H2N_U16_C(0x0001); + Ipv6Addr.au16[4] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[7] = RT_H2N_U16_C(0x0000); + CHECK42("%RTnaipv6", &Ipv6Addr, "1:0:0:1::"); + + /* first of the two runs of equal length is abbreviated */ + Ipv6Addr.au16[0] = RT_H2N_U16_C(0x2001); + Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0db8); + Ipv6Addr.au16[2] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[3] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[4] = RT_H2N_U16_C(0x0001); + Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0000); + Ipv6Addr.au16[7] = RT_H2N_U16_C(0x0001); + CHECK42("%RTnaipv6", &Ipv6Addr, "2001:db8::1:0:0:1"); + Ipv6Addr.au16[0] = RT_H2N_U16_C(0x2001); Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0db8); Ipv6Addr.au16[2] = RT_H2N_U16_C(0x85a3); @@ -344,11 +435,26 @@ int main() Ipv6Addr.au16[5] = RT_H2N_U16_C(0x8a2e); Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0370); Ipv6Addr.au16[7] = RT_H2N_U16_C(0x7334); - CHECK42("%RTnaipv6", &Ipv6Addr, "2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + CHECK42("%RTnaipv6", &Ipv6Addr, "2001:db8:85a3::8a2e:370:7334"); + Ipv6Addr.au64[0] = UINT64_MAX; Ipv6Addr.au64[1] = UINT64_MAX; CHECK42("%RTnaipv6", &Ipv6Addr, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); + RTNETADDR NetAddr; + memset(&NetAddr, 0, sizeof(NetAddr)); + + /* plain IPv6 address if port is not specified */ + NetAddr.enmType = RTNETADDRTYPE_IPV6; + NetAddr.uAddr.au16[0] = RT_H2N_U16_C(0x0001); + NetAddr.uAddr.au16[7] = RT_H2N_U16_C(0x0001); + NetAddr.uPort = RTNETADDR_PORT_NA; + CHECK42("%RTnaddr", &NetAddr, "1::1"); + + /* square brackets around IPv6 address if port is specified */ + NetAddr.uPort = 1; + CHECK42("%RTnaddr", &NetAddr, "[1::1]:1"); + CHECK42("%RTproc", (RTPROCESS)0xffffff, "00ffffff"); CHECK42("%RTproc", (RTPROCESS)0x43455443, "43455443"); diff --git a/src/VBox/Runtime/testcase/tstRTSymlink.cpp b/src/VBox/Runtime/testcase/tstRTSymlink.cpp index 259d522f..46188eca 100644 --- a/src/VBox/Runtime/testcase/tstRTSymlink.cpp +++ b/src/VBox/Runtime/testcase/tstRTSymlink.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -121,7 +121,7 @@ static void test1(RTTEST hTest, const char *pszBaseDir) /* * Making some assumptions about how we are executed from to start with... */ - RTTestISub("Negative RTSymlinkRead, RTSymlinkExists and RTSymlinkIsDangling"); + RTTestISub("Negative RTSymlinkRead, Exists & IsDangling"); char szExecDir[RTPATH_MAX]; RTTESTI_CHECK_RC_OK_RETV(RTPathExecDir(szExecDir, sizeof(szExecDir))); size_t cchExecDir = strlen(szExecDir); diff --git a/src/VBox/Runtime/testcase/tstRTSystemQueryOsInfo.cpp b/src/VBox/Runtime/testcase/tstRTSystemQueryOsInfo.cpp index d2febda3..338e59f4 100644 --- a/src/VBox/Runtime/testcase/tstRTSystemQueryOsInfo.cpp +++ b/src/VBox/Runtime/testcase/tstRTSystemQueryOsInfo.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -65,6 +65,16 @@ int main() rc = RTSystemQueryOSInfo(RTSYSOSINFO_SERVICE_PACK, szInfo, sizeof(szInfo)); RTTestIPrintf(RTTESTLVL_ALWAYS, "SERVICE_PACK: \"%s\", rc=%Rrc\n", szInfo, rc); + uint64_t cbTotal; + rc = RTSystemQueryTotalRam(&cbTotal); + RTTestIPrintf(RTTESTLVL_ALWAYS, "Total RAM: %'RU64 Bytes (%RU64 KB, %RU64 MB)\n", + cbTotal, cbTotal / _1K, cbTotal / _1M); + + uint64_t cbAvailable; + rc = RTSystemQueryAvailableRam(&cbAvailable); + RTTestIPrintf(RTTESTLVL_ALWAYS, "Available RAM: %'RU64 Bytes (%RU64 KB, %RU64 MB)\n", + cbAvailable, cbAvailable / _1K, cbAvailable / _1M); + /* * Check that unsupported stuff is terminated correctly. */ diff --git a/src/VBox/Runtime/testcase/tstRTTcp-1.cpp b/src/VBox/Runtime/testcase/tstRTTcp-1.cpp index 94f60973..1ee7c15c 100644 --- a/src/VBox/Runtime/testcase/tstRTTcp-1.cpp +++ b/src/VBox/Runtime/testcase/tstRTTcp-1.cpp @@ -45,10 +45,22 @@ void test3() for (unsigned i = 0; i < 100 && cStartErrors == RTTestErrorCount(g_hTest); i++) { PRTTCPSERVER pServer; - RTTESTI_CHECK_RC_RETV(RTTcpServerCreate("localhost", 9999, RTTHREADTYPE_DEFAULT, "server-2", - test3Server, NULL, &pServer), VINF_SUCCESS); + int rc = RTTcpServerCreate("localhost", 9999, RTTHREADTYPE_DEFAULT, "server-2", test3Server, NULL, &pServer); +#ifdef RT_OS_SOLARIS + /** @todo testboxsh1 occationally hits this for some stupid reason. i=21 in + * one occurrence. Fudge a bit for now and see if it helps. */ + if (rc == VERR_NET_ADDRESS_IN_USE) + { + RTThreadSleep(500); + rc = RTTcpServerCreate("localhost", 9999, RTTHREADTYPE_DEFAULT, "server-2", test3Server, NULL, &pServer); + } +#endif + if (rc != VINF_SUCCESS) + { + RTTestIFailed("RTTcpServerCreate -> %Rrc, i=%d", rc, i); + return; + } - int rc; RTSOCKET hSocket; RTTESTI_CHECK_RC(rc = RTTcpClientConnect("localhost", 9999, &hSocket), VINF_SUCCESS); if (RT_SUCCESS(rc)) diff --git a/src/VBox/Runtime/testcase/tstRTTemp.cpp b/src/VBox/Runtime/testcase/tstRTTemp.cpp index 8eb66206..758f5387 100644 --- a/src/VBox/Runtime/testcase/tstRTTemp.cpp +++ b/src/VBox/Runtime/testcase/tstRTTemp.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -130,7 +130,7 @@ static void tstDirCreateTemp(const char *pszSubTest, const char *pszTemplate, RT static void tstBothCreateTemp(const char *pszSubTest, const char *pszTemplate, RTFMODE fMode, unsigned cTimes, bool fSkipXCheck) { char pszSubTestLong[128]; - + RTStrPrintf(pszSubTestLong, sizeof(pszSubTestLong), "RTFileCreateTemp %s", pszSubTest); tstFileCreateTemp(pszSubTestLong, pszTemplate, fMode, cTimes, diff --git a/src/VBox/Runtime/testcase/tstTime.cpp b/src/VBox/Runtime/testcase/tstRTTime.cpp index 63841e99..302acc7f 100644 --- a/src/VBox/Runtime/testcase/tstTime.cpp +++ b/src/VBox/Runtime/testcase/tstRTTime.cpp @@ -1,10 +1,10 @@ -/* $Id: tstTime.cpp $ */ +/* $Id: tstRTTime.cpp $ */ /** @file - * IPRT Testcase - Simple RTTime tests. + * IPRT Testcase - Simple RTTime tests (requires GIP). */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -28,19 +28,23 @@ * Header Files * *******************************************************************************/ #include <iprt/time.h> -#include <iprt/stream.h> + +#include <iprt/err.h> #include <iprt/initterm.h> +#include <iprt/message.h> +#include <iprt/test.h> #include <iprt/thread.h> -#include <VBox/sup.h> - int main() { - unsigned cErrors = 0; - int i; - - RTR3InitExeNoArguments(RTR3INIT_FLAGS_SUPLIB); - RTPrintf("tstTime: TESTING...\n"); + /* + * Init. + */ + RTTEST hTest; + RTEXITCODE rcExit = RTTestInitExAndCreate(0, NULL, RTR3INIT_FLAGS_SUPLIB, "tstRTTime", &hTest); + if (rcExit != RTEXITCODE_SUCCESS) + return rcExit; + RTTestBanner(hTest); /* * RTNanoTimeTS() shall never return something which @@ -51,6 +55,7 @@ int main() uint64_t u64RTStartTS = RTTimeNanoTS(); uint64_t u64OSStartTS = RTTimeSystemNanoTS(); + uint32_t i; uint64_t u64Prev = RTTimeNanoTS(); for (i = 0; i < 100*_1M; i++) { @@ -58,21 +63,23 @@ int main() if (u64 <= u64Prev) { /** @todo wrapping detection. */ - RTPrintf("tstTime: error: i=%#010x u64=%#llx u64Prev=%#llx (1)\n", i, u64, u64Prev); - cErrors++; + RTTestFailed(hTest, "i=%#010x u64=%#llx u64Prev=%#llx (1)\n", i, u64, u64Prev); + if (RTTestErrorCount(hTest) >= 256) + break; RTThreadYield(); u64 = RTTimeNanoTS(); } else if (u64 - u64Prev > 1000000000 /* 1sec */) { - RTPrintf("tstTime: error: i=%#010x u64=%#llx u64Prev=%#llx delta=%lld\n", i, u64, u64Prev, u64 - u64Prev); - cErrors++; + RTTestFailed(hTest, "i=%#010x u64=%#llx u64Prev=%#llx delta=%lld\n", i, u64, u64Prev, u64 - u64Prev); + if (RTTestErrorCount(hTest) >= 256) + break; RTThreadYield(); u64 = RTTimeNanoTS(); } if (!(i & (_1M*2 - 1))) { - RTPrintf("tstTime: i=%#010x u64=%#llx u64Prev=%#llx delta=%lld\n", i, u64, u64Prev, u64 - u64Prev); + RTTestPrintf(hTest, RTTESTLVL_INFO, "i=%#010x u64=%#llx u64Prev=%#llx delta=%lld\n", i, u64, u64Prev, u64 - u64Prev); RTThreadYield(); u64 = RTTimeNanoTS(); } @@ -86,24 +93,25 @@ int main() u64OSElapsedTS -= u64OSStartTS; int64_t i64Diff = u64OSElapsedTS >= u64RTElapsedTS ? u64OSElapsedTS - u64RTElapsedTS : u64RTElapsedTS - u64OSElapsedTS; if (i64Diff > (int64_t)(u64OSElapsedTS / 1000)) + RTTestFailed(hTest, "total time differs too much! u64OSElapsedTS=%#llx u64RTElapsedTS=%#llx delta=%lld\n", + u64OSElapsedTS, u64RTElapsedTS, u64OSElapsedTS - u64RTElapsedTS); + else { - RTPrintf("tstTime: error: total time differs too much! u64OSElapsedTS=%#llx u64RTElapsedTS=%#llx delta=%lld\n", - u64OSElapsedTS, u64RTElapsedTS, u64OSElapsedTS - u64RTElapsedTS); - cErrors++; + RTTestValue(hTest, "Total time delta", u64OSElapsedTS - u64RTElapsedTS, RTTESTUNIT_NS); + RTTestPrintf(hTest, RTTESTLVL_INFO, "total time difference: u64OSElapsedTS=%#llx u64RTElapsedTS=%#llx delta=%lld\n", + u64OSElapsedTS, u64RTElapsedTS, u64OSElapsedTS - u64RTElapsedTS); } - else - RTPrintf("tstTime: total time difference: u64OSElapsedTS=%#llx u64RTElapsedTS=%#llx delta=%lld\n", - u64OSElapsedTS, u64RTElapsedTS, u64OSElapsedTS - u64RTElapsedTS); #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) /** @todo This isn't really x86 or AMD64 specific... */ - RTPrintf("RTTimeDbgSteps -> %u (%d ppt)\n", RTTimeDbgSteps(), ((uint64_t)RTTimeDbgSteps() * 1000) / i); - RTPrintf("RTTimeDbgExpired -> %u (%d ppt)\n", RTTimeDbgExpired(), ((uint64_t)RTTimeDbgExpired() * 1000) / i); - RTPrintf("RTTimeDbgBad -> %u (%d ppt)\n", RTTimeDbgBad(), ((uint64_t)RTTimeDbgBad() * 1000) / i); - RTPrintf("RTTimeDbgRaces -> %u (%d ppt)\n", RTTimeDbgRaces(), ((uint64_t)RTTimeDbgRaces() * 1000) / i); + RTTestValue(hTest, "RTTimeDbgSteps", RTTimeDbgSteps(), RTTESTUNIT_OCCURRENCES); + RTTestValue(hTest, "RTTimeDbgSteps pp", ((uint64_t)RTTimeDbgSteps() * 1000) / i, RTTESTUNIT_PP1K); + RTTestValue(hTest, "RTTimeDbgExpired", RTTimeDbgExpired(), RTTESTUNIT_OCCURRENCES); + RTTestValue(hTest, "RTTimeDbgExpired pp", ((uint64_t)RTTimeDbgExpired() * 1000) / i, RTTESTUNIT_PP1K); + RTTestValue(hTest, "RTTimeDbgBad", RTTimeDbgBad(), RTTESTUNIT_OCCURRENCES); + RTTestValue(hTest, "RTTimeDbgBad pp", ((uint64_t)RTTimeDbgBad() * 1000) / i, RTTESTUNIT_PP1K); + RTTestValue(hTest, "RTTimeDbgRaces", RTTimeDbgRaces(), RTTESTUNIT_OCCURRENCES); + RTTestValue(hTest, "RTTimeDbgRaces pp", ((uint64_t)RTTimeDbgRaces() * 1000) / i, RTTESTUNIT_PP1K); #endif - if (!cErrors) - RTPrintf("tstTime: SUCCESS\n"); - else - RTPrintf("tstTime: FAILURE - %d errors\n", cErrors); - return !!cErrors; + + return RTTestSummaryAndDestroy(hTest); } diff --git a/src/VBox/Runtime/testcase/tstRTTimeSpec.cpp b/src/VBox/Runtime/testcase/tstRTTimeSpec.cpp index 08f5cc90..450041f6 100644 --- a/src/VBox/Runtime/testcase/tstRTTimeSpec.cpp +++ b/src/VBox/Runtime/testcase/tstRTTimeSpec.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRTUri.cpp b/src/VBox/Runtime/testcase/tstRTUri.cpp index 5a2c39ba..e94ade2a 100644 --- a/src/VBox/Runtime/testcase/tstRTUri.cpp +++ b/src/VBox/Runtime/testcase/tstRTUri.cpp @@ -38,7 +38,7 @@ * Test data * *******************************************************************************/ -static const char *gs_apcszTestURIs[] = +static const char *g_apcszTestURIs[] = { "foo://tt:tt@example.com:8042/over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret#nose%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60", "foo://tt:tt@example.com:8042/over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there?name=%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60ferret", @@ -58,7 +58,7 @@ static const char *gs_apcszTestURIs[] = "foo://" }; -static const char *gs_apcszSchemeResult[] = +static const char *g_apcszSchemeResult[] = { "foo", "foo", @@ -78,7 +78,7 @@ static const char *gs_apcszSchemeResult[] = "foo" }; -static const char *gs_apcszAuthorityResult[] = +static const char *g_apcszAuthorityResult[] = { "tt:tt@example.com:8042", "tt:tt@example.com:8042", @@ -98,7 +98,7 @@ static const char *gs_apcszAuthorityResult[] = NULL }; -static const char *gs_apcszPathResult[] = +static const char *g_apcszPathResult[] = { "/over/ <>#%\"{}|^[]`/there", "/over/ <>#%\"{}|^[]`/there", @@ -118,7 +118,7 @@ static const char *gs_apcszPathResult[] = NULL }; -static const char *gs_apcszQueryResult[] = +static const char *g_apcszQueryResult[] = { "name= <>#%\"{}|^[]`ferret", "name= <>#%\"{}|^[]`ferret", @@ -138,7 +138,7 @@ static const char *gs_apcszQueryResult[] = NULL }; -static const char *gs_apcszFragmentResult[] = +static const char *g_apcszFragmentResult[] = { "nose <>#%\"{}|^[]`", NULL, @@ -158,7 +158,7 @@ static const char *gs_apcszFragmentResult[] = NULL }; -static const char *gs_apcszCreateURIs[][5] = +static const char *g_apcszCreateURIs[][5] = { { "foo", "tt:tt@example.com:8042", "/over/ <>#%\"{}|^[]`/there", "name= <>#%\"{}|^[]`ferret", "nose <>#%\"{}|^[]`" }, { "foo", "tt:tt@example.com:8042", "/over/ <>#%\"{}|^[]`/there", "name= <>#%\"{}|^[]`ferret", NULL }, @@ -184,7 +184,7 @@ struct URIFILETEST const char *pcszUri; uint32_t uFormat; } -gs_apCreateFileURIs[] = +g_apCreateFileURIs[] = { { "C:\\over\\ <>#%\"{}|^[]`\\there", "file:///C:%5Cover%5C%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60%5Cthere", URI_FILE_FORMAT_WIN }, { "/over/ <>#%\"{}|^[]`/there", "file:///over/%20%3C%3E%23%25%22%7B%7D%7C%5E%5B%5D%60/there", URI_FILE_FORMAT_UNIX }, @@ -198,8 +198,6 @@ gs_apCreateFileURIs[] = */ static void tstScheme(size_t iCount, const char *pszUri, const char *pszTest) { - RTTestISubF("Uri scheme parsing %2u: '%s' -> '%s'", iCount, pszUri, pszTest); - char *pszResult = RTUriScheme(pszUri); if (pszTest) { @@ -215,8 +213,6 @@ static void tstScheme(size_t iCount, const char *pszUri, const char *pszTest) static void tstAuthority(size_t iCount, const char *pszUri, const char *pszTest) { - RTTestISubF("Uri authority parsing %2u: '%s' -> '%s'", iCount, pszUri, pszTest); - char *pszResult = RTUriAuthority(pszUri); if (pszTest) { @@ -232,8 +228,6 @@ static void tstAuthority(size_t iCount, const char *pszUri, const char *pszTest) static void tstPath(size_t iCount, const char *pszUri, const char *pszTest) { - RTTestISubF("Uri path parsing %2u: '%s' -> '%s'", iCount, pszUri, pszTest); - char *pszResult = RTUriPath(pszUri); if (pszTest) { @@ -249,8 +243,6 @@ static void tstPath(size_t iCount, const char *pszUri, const char *pszTest) static void tstQuery(size_t iCount, const char *pszUri, const char *pszTest) { - RTTestISubF("Uri query parsing %2u: '%s' -> '%s'", iCount, pszUri, pszTest); - char *pszResult = RTUriQuery(pszUri); if (pszTest) { @@ -266,8 +258,6 @@ static void tstQuery(size_t iCount, const char *pszUri, const char *pszTest) static void tstFragment(size_t iCount, const char *pszUri, const char *pszTest) { - RTTestISubF("Uri fragment parsing %2u: '%s' -> '%s'", iCount, pszUri, pszTest); - char *pszResult = RTUriFragment(pszUri); if (pszTest) { @@ -283,8 +273,6 @@ static void tstFragment(size_t iCount, const char *pszUri, const char *pszTest) static void tstCreate(size_t iCount, const char *pszScheme, const char *pszAuthority, const char *pszPath, const char *pszQuery, const char *pszFragment, const char *pszTest) { - RTTestISubF("Uri creating %2u: Scheme: '%s', Authority: '%s', Path: '%s', Query: '%s', Fragment: '%s'", iCount, pszScheme, pszAuthority, pszPath, pszQuery, pszFragment); - char *pszResult = RTUriCreate(pszScheme, pszAuthority, pszPath, pszQuery, pszFragment); if (pszTest) { @@ -301,8 +289,6 @@ static void tstCreate(size_t iCount, const char *pszScheme, const char *pszAutho static void tstFileCreate(size_t iCount, const char *pszPath, const char *pszTest) { - RTTestISubF("Uri file creating %2u: Path: '%s'", iCount, pszPath); - char *pszResult = RTUriFileCreate(pszPath); if (pszTest) { @@ -319,8 +305,6 @@ static void tstFileCreate(size_t iCount, const char *pszPath, const char *pszTes static void tstFilePath(size_t iCount, const char *pszUri, const char *pszTest, uint32_t uFormat) { - RTTestISubF("Uri file path parsing %2u: '%s' -> '%s'", iCount, pszUri, pszTest); - char *pszResult = RTUriFilePath(pszUri, uFormat); if (pszTest) { @@ -344,42 +328,51 @@ int main() RTTestBanner(hTest); /* Scheme */ - Assert(RT_ELEMENTS(gs_apcszTestURIs) == RT_ELEMENTS(gs_apcszSchemeResult)); - for (size_t i = 0; i < RT_ELEMENTS(gs_apcszTestURIs); ++i) - tstScheme(i+1, gs_apcszTestURIs[i], gs_apcszSchemeResult[i]); + RTTestISubF("RTUriScheme"); + Assert(RT_ELEMENTS(g_apcszTestURIs) == RT_ELEMENTS(g_apcszSchemeResult)); + for (size_t i = 0; i < RT_ELEMENTS(g_apcszTestURIs); ++i) + tstScheme(i+1, g_apcszTestURIs[i], g_apcszSchemeResult[i]); /* Authority */ - Assert(RT_ELEMENTS(gs_apcszTestURIs) == RT_ELEMENTS(gs_apcszAuthorityResult)); - for (size_t i = 0; i < RT_ELEMENTS(gs_apcszTestURIs); ++i) - tstAuthority(i+1, gs_apcszTestURIs[i], gs_apcszAuthorityResult[i]); + RTTestISubF("RTUriAuthority"); + Assert(RT_ELEMENTS(g_apcszTestURIs) == RT_ELEMENTS(g_apcszAuthorityResult)); + for (size_t i = 0; i < RT_ELEMENTS(g_apcszTestURIs); ++i) + tstAuthority(i+1, g_apcszTestURIs[i], g_apcszAuthorityResult[i]); /* Path */ - Assert(RT_ELEMENTS(gs_apcszTestURIs) == RT_ELEMENTS(gs_apcszPathResult)); - for (size_t i = 0; i < RT_ELEMENTS(gs_apcszTestURIs); ++i) - tstPath(i+1, gs_apcszTestURIs[i], gs_apcszPathResult[i]); + RTTestISubF("RTUriPath"); + Assert(RT_ELEMENTS(g_apcszTestURIs) == RT_ELEMENTS(g_apcszPathResult)); + for (size_t i = 0; i < RT_ELEMENTS(g_apcszTestURIs); ++i) + tstPath(i+1, g_apcszTestURIs[i], g_apcszPathResult[i]); /* Query */ - Assert(RT_ELEMENTS(gs_apcszTestURIs) == RT_ELEMENTS(gs_apcszQueryResult)); - for (size_t i = 0; i < RT_ELEMENTS(gs_apcszTestURIs); ++i) - tstQuery(i+1, gs_apcszTestURIs[i], gs_apcszQueryResult[i]); + RTTestISubF("RTUriQuery"); + Assert(RT_ELEMENTS(g_apcszTestURIs) == RT_ELEMENTS(g_apcszQueryResult)); + for (size_t i = 0; i < RT_ELEMENTS(g_apcszTestURIs); ++i) + tstQuery(i+1, g_apcszTestURIs[i], g_apcszQueryResult[i]); /* Fragment */ - Assert(RT_ELEMENTS(gs_apcszTestURIs) == RT_ELEMENTS(gs_apcszFragmentResult)); - for (size_t i = 0; i < RT_ELEMENTS(gs_apcszTestURIs); ++i) - tstFragment(i+1, gs_apcszTestURIs[i], gs_apcszFragmentResult[i]); + RTTestISubF("RTUriFragment"); + Assert(RT_ELEMENTS(g_apcszTestURIs) == RT_ELEMENTS(g_apcszFragmentResult)); + for (size_t i = 0; i < RT_ELEMENTS(g_apcszTestURIs); ++i) + tstFragment(i+1, g_apcszTestURIs[i], g_apcszFragmentResult[i]); /* Creation */ - Assert(RT_ELEMENTS(gs_apcszTestURIs) == RT_ELEMENTS(gs_apcszCreateURIs)); - for (size_t i = 0; i < RT_ELEMENTS(gs_apcszTestURIs); ++i) - tstCreate(i+1, gs_apcszCreateURIs[i][0], gs_apcszCreateURIs[i][1], gs_apcszCreateURIs[i][2], gs_apcszCreateURIs[i][3], gs_apcszCreateURIs[i][4], gs_apcszTestURIs[i]); + RTTestISubF("RTUriCreate"); + Assert(RT_ELEMENTS(g_apcszTestURIs) == RT_ELEMENTS(g_apcszCreateURIs)); + for (size_t i = 0; i < RT_ELEMENTS(g_apcszTestURIs); ++i) + tstCreate(i+1, g_apcszCreateURIs[i][0], g_apcszCreateURIs[i][1], g_apcszCreateURIs[i][2], + g_apcszCreateURIs[i][3], g_apcszCreateURIs[i][4], g_apcszTestURIs[i]); /* File Uri path */ - for (size_t i = 0; i < RT_ELEMENTS(gs_apCreateFileURIs); ++i) - tstFilePath(i+1, gs_apCreateFileURIs[i].pcszUri, gs_apCreateFileURIs[i].pcszPath, gs_apCreateFileURIs[i].uFormat); + RTTestISubF("RTUriFilePath"); + for (size_t i = 0; i < RT_ELEMENTS(g_apCreateFileURIs); ++i) + tstFilePath(i+1, g_apCreateFileURIs[i].pcszUri, g_apCreateFileURIs[i].pcszPath, g_apCreateFileURIs[i].uFormat); /* File Uri creation */ + RTTestISubF("RTUriFileCreate"); for (size_t i = 0; i < 3; ++i) - tstFileCreate(i+1, gs_apCreateFileURIs[i].pcszPath, gs_apCreateFileURIs[i].pcszUri); + tstFileCreate(i+1, g_apCreateFileURIs[i].pcszPath, g_apCreateFileURIs[i].pcszUri); return RTTestSummaryAndDestroy(hTest); } diff --git a/src/VBox/Runtime/testcase/tstRTUuid.cpp b/src/VBox/Runtime/testcase/tstRTUuid.cpp index 692bcb94..a2fd7e08 100644 --- a/src/VBox/Runtime/testcase/tstRTUuid.cpp +++ b/src/VBox/Runtime/testcase/tstRTUuid.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstRand.cpp b/src/VBox/Runtime/testcase/tstRand.cpp index 5205ceae..88edf856 100644 --- a/src/VBox/Runtime/testcase/tstRand.cpp +++ b/src/VBox/Runtime/testcase/tstRand.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2008 Oracle Corporation + * Copyright (C) 2008-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstSemMutex.cpp b/src/VBox/Runtime/testcase/tstSemMutex.cpp index 373c2b61..1bdb4a91 100644 --- a/src/VBox/Runtime/testcase/tstSemMutex.cpp +++ b/src/VBox/Runtime/testcase/tstSemMutex.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstSemPingPong.cpp b/src/VBox/Runtime/testcase/tstSemPingPong.cpp index 37db163b..0be9f7ef 100644 --- a/src/VBox/Runtime/testcase/tstSemPingPong.cpp +++ b/src/VBox/Runtime/testcase/tstSemPingPong.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstStrSimplePattern.cpp b/src/VBox/Runtime/testcase/tstStrSimplePattern.cpp index f9f11cc6..756b8431 100644 --- a/src/VBox/Runtime/testcase/tstStrSimplePattern.cpp +++ b/src/VBox/Runtime/testcase/tstStrSimplePattern.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2008 Oracle Corporation + * Copyright (C) 2008-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstStrToNum.cpp b/src/VBox/Runtime/testcase/tstStrToNum.cpp index 43f89923..53b92275 100644 --- a/src/VBox/Runtime/testcase/tstStrToNum.cpp +++ b/src/VBox/Runtime/testcase/tstStrToNum.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstTSC.cpp b/src/VBox/Runtime/testcase/tstTSC.cpp index 2ebed4fe..b18d8432 100644 --- a/src/VBox/Runtime/testcase/tstTSC.cpp +++ b/src/VBox/Runtime/testcase/tstTSC.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -437,7 +437,7 @@ int main(int argc, char **argv) return 1; case 'V': - RTPrintf("$Revision: $\n"); + RTPrintf("$Revision: 89632 $\n"); return 0; default: diff --git a/src/VBox/Runtime/testcase/tstTermCallbacks.cpp b/src/VBox/Runtime/testcase/tstTermCallbacks.cpp index e72e16b5..ea33f889 100644 --- a/src/VBox/Runtime/testcase/tstTermCallbacks.cpp +++ b/src/VBox/Runtime/testcase/tstTermCallbacks.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstThread-1.cpp b/src/VBox/Runtime/testcase/tstThread-1.cpp index 715fa491..e4cfebe8 100644 --- a/src/VBox/Runtime/testcase/tstThread-1.cpp +++ b/src/VBox/Runtime/testcase/tstThread-1.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstTime-2.cpp b/src/VBox/Runtime/testcase/tstTime-2.cpp index aa8288e4..8d2405d9 100644 --- a/src/VBox/Runtime/testcase/tstTime-2.cpp +++ b/src/VBox/Runtime/testcase/tstTime-2.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstTime-3.cpp b/src/VBox/Runtime/testcase/tstTime-3.cpp index 45985c0f..436b0955 100644 --- a/src/VBox/Runtime/testcase/tstTime-3.cpp +++ b/src/VBox/Runtime/testcase/tstTime-3.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -30,8 +30,6 @@ #ifdef RT_OS_WINDOWS # include <Windows.h> -#elif defined RT_OS_L4 - #else /* posix */ # include <sys/time.h> #endif @@ -51,10 +49,6 @@ DECLINLINE(uint64_t) OSNanoTS(void) GetSystemTimeAsFileTime((LPFILETIME)&u64); return u64 * 100; -#elif defined RT_OS_L4 - /** @todo fix a different timesource on l4. */ - return RTTimeNanoTS(); - #else /* posix */ struct timeval tv; diff --git a/src/VBox/Runtime/testcase/tstTime-4.cpp b/src/VBox/Runtime/testcase/tstTime-4.cpp index 305ce7ce..c9d1cf65 100644 --- a/src/VBox/Runtime/testcase/tstTime-4.cpp +++ b/src/VBox/Runtime/testcase/tstTime-4.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -64,11 +64,12 @@ int main() cErrors++; RTPrintf("tstTime-4: Bad Gip time!\n"); } - int64_t Delta = GipPrevTS - SysPrevTS; - if (Delta > 0 ? Delta > 100000000 /* 100 ms */ : Delta < -100000000 /* -100 ms */) + uint64_t Delta = GipPrevTS > SysPrevTS ? GipPrevTS - SysPrevTS : + SysPrevTS - GipPrevTS; + if (Delta > 100000000ULL /* 100 ms */ ) { cErrors++; - RTPrintf("tstTime-4: Delta=%lld!\n", Delta); + RTPrintf("tstTime-4: Delta=%llu (GipPrevTS=%llu, SysPrevTS=%llu)!\n", Delta, GipPrevTS, SysPrevTS); } } while (SysPrevTS - SysStartTS < 2000000000 /* 2s */); diff --git a/src/VBox/Runtime/testcase/tstTimer.cpp b/src/VBox/Runtime/testcase/tstTimer.cpp index 2ac2c159..6fdee70b 100644 --- a/src/VBox/Runtime/testcase/tstTimer.cpp +++ b/src/VBox/Runtime/testcase/tstTimer.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstTimerLR.cpp b/src/VBox/Runtime/testcase/tstTimerLR.cpp index 8bba2339..b179ed79 100644 --- a/src/VBox/Runtime/testcase/tstTimerLR.cpp +++ b/src/VBox/Runtime/testcase/tstTimerLR.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2008 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/testcase/tstUtf8.cpp b/src/VBox/Runtime/testcase/tstUtf8.cpp index 890c644b..7f81f103 100644 --- a/src/VBox/Runtime/testcase/tstUtf8.cpp +++ b/src/VBox/Runtime/testcase/tstUtf8.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -29,15 +29,16 @@ *******************************************************************************/ #include <iprt/string.h> -#include <iprt/uni.h> -#include <iprt/uuid.h> -#include <iprt/time.h> -#include <iprt/stream.h> #include <iprt/alloc.h> #include <iprt/assert.h> +#include <iprt/env.h> #include <iprt/err.h> #include <iprt/rand.h> +#include <iprt/stream.h> #include <iprt/test.h> +#include <iprt/time.h> +#include <iprt/uni.h> +#include <iprt/uuid.h> @@ -49,7 +50,7 @@ static RTUTF16 GetRandUtf16(void) RTUTF16 wc; do { - wc = (RTUTF16)RTRandU32Ex(1, 0xffff); + wc = (RTUTF16)RTRandU32Ex(1, 0xfffd); } while (wc >= 0xd800 && wc <= 0xdfff); return wc; } @@ -103,6 +104,8 @@ static void test1(RTTEST hTest) } else if (rc == VERR_NO_TRANSLATION) RTTestPassed(hTest, "The second part of random UTF-16 -> UTF-8 -> Current -> UTF-8 returned VERR_NO_TRANSLATION. This is probably as it should be.\n"); + else if (rc == VWRN_NO_TRANSLATION) + RTTestPassed(hTest, "The second part of random UTF-16 -> UTF-8 -> Current -> UTF-8 returned VWRN_NO_TRANSLATION. This is probably as it should be.\n"); else RTTestFailed(hTest, "%d: The second part of random UTF-16 -> UTF-8 -> Current -> UTF-8 failed with return value %Rrc.", __LINE__, rc); @@ -1395,14 +1398,15 @@ static void testNoTransation(RTTEST hTest) RTTestSub(hTest, "VERR_NO_TRANSLATION/RTStrUtf8ToCurrentCP"); char *pszOut; rc = RTStrUtf8ToCurrentCP(&pszOut, pszTest1); - if (RT_SUCCESS(rc)) + if (rc == VINF_SUCCESS) { RTTESTI_CHECK(!strcmp(pszOut, pszTest1)); - RTTestIPrintf(RTTESTLVL_ALWAYS, "CurrentCP is UTF-8 or similar\n"); + RTTestIPrintf(RTTESTLVL_ALWAYS, "CurrentCP is UTF-8 or similar (LC_ALL=%s LANG=%s LC_CTYPE=%s)\n", + RTEnvGet("LC_ALL"), RTEnvGet("LANG"), RTEnvGet("LC_CTYPE")); RTStrFree(pszOut); } else - RTTESTI_CHECK_RC(rc, VERR_NO_TRANSLATION); + RTTESTI_CHECK_MSG(rc == VWRN_NO_TRANSLATION || rc == VERR_NO_TRANSLATION, ("rc=%Rrc\n", rc)); RTTestSub(hTest, "VERR_NO_TRANSLATION/RTUtf16ToLatin1"); rc = RTUtf16ToLatin1(s_swzTest1, &pszOut); |