device/rockchip:add aispeech 2mic with support rkecho softap send ssid and password
Change-Id: Iba2f010146b2e64b36c09797bcfe70efce73291c Signed-off-by: aaron.sun <aaron.sun@rock-chips.com>
This commit is contained in:
41
rk3308/BoardConfig_voice_moudle_64bit.mk
Executable file
41
rk3308/BoardConfig_voice_moudle_64bit.mk
Executable file
@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
|
||||
#=========================
|
||||
# Compile Config
|
||||
#=========================
|
||||
# Target arch
|
||||
ARCH=arm64
|
||||
# Uboot defconfig
|
||||
UBOOT_DEFCONFIG=evb-rk3308
|
||||
# Kernel defconfig
|
||||
KERNEL_DEFCONFIG=rk3308_linux_defconfig
|
||||
# Kernel dts
|
||||
KERNEL_DTS=rk3308-voice-module-board-v10
|
||||
# Buildroot config
|
||||
CFG_BUILDROOT=rockchip_rk3308_release
|
||||
# Recovery config
|
||||
CFG_RECOVERY=rockchip_rk3308_recovery
|
||||
# Pcba config
|
||||
CFG_PCBA=rockchip_rk3308_pcba
|
||||
# Build jobs
|
||||
JOBS=12
|
||||
|
||||
#=========================
|
||||
# Platform Target
|
||||
#=========================
|
||||
TARGET_PRODUCT=rk3308
|
||||
|
||||
# Set rootfs type, see buildroot.
|
||||
# ext4 squashfs
|
||||
ROOTFS_TYPE=squashfs
|
||||
|
||||
# Set data partition type.
|
||||
# ext2 squashfs
|
||||
OEM_PARTITION_TYPE=ext2
|
||||
|
||||
# Set flash type.
|
||||
# support <emmc, nand, spi_nand, spi_nor>
|
||||
FLASH_TYPE=nand
|
||||
|
||||
#OEM config: /oem/dueros/aispeech/iflytekSDK/CaeDemo_VAD
|
||||
OEM_PATH=oem
|
||||
61
rk3308/aispeech-2mic/RkLunch.sh
Executable file
61
rk3308/aispeech-2mic/RkLunch.sh
Executable file
@ -0,0 +1,61 @@
|
||||
tinymix set "ADC MIC Group 1 Left Volume" 3
|
||||
tinymix set "ADC MIC Group 2 Left Volume" 3
|
||||
tinymix set "ADC MIC Group 2 Right Volume" 3
|
||||
tinymix set "ADC ALC Group 2 Left Volume" 18
|
||||
tinymix set "ADC ALC Group 2 Right Volume" 18
|
||||
arecord -c 4 -r 16000 -f S16_LE -d 1 -t raw /tmp/test.pcm
|
||||
rm /tmp/test.pcm
|
||||
#echo 0x60 0x40ff0050 > /sys/kernel/debug/vad/reg
|
||||
echo 0x60 0x40ff04b0 > /sys/kernel/debug/vad/reg
|
||||
echo 0x5c 0x000e2080 > /sys/kernel/debug/vad/reg
|
||||
|
||||
ln -s /oem/aispeech_softap_lite /data/aispeech_softap_lite
|
||||
ln -s /oem/wifi_monitor.sh /data/
|
||||
ln -s /oem/dds_client /data/dds_client
|
||||
ln -s /oem/dds_service.sh /data/
|
||||
|
||||
export AISPEECH_WIFI_CFG="/data/wpa_supplicant.conf"
|
||||
|
||||
#aispeech dui app information file
|
||||
export AISPEECH_DUIKIT_APP="/data/aispeech_softap_lite/device/app.json"
|
||||
|
||||
#aispeech dui device file
|
||||
export AISPEECH_DUIKIT_DEVICE="/data/aispeech_softap_lite/device/device.json"
|
||||
|
||||
#aispeech dui softap web server address
|
||||
export AISPEECH_SOFTAP_SERVER_PORT="8000"
|
||||
|
||||
#aispeech dui softap configuration folder
|
||||
export AISPEECH_SOFTAP_DIR="/data/cfg"
|
||||
|
||||
export AISPEECH_DO_CONNECT_MP3="/data/aispeech_softap_lite/audio/do_connect.mp3"
|
||||
|
||||
export AISPEECH_WIFI_OK_MP3="/data/aispeech_softap_lite/audio/wifi_ok.mp3"
|
||||
|
||||
export AISPEECH_NEED_CONNECT_MP3="/data/aispeech_softap_lite/audio/need_connect.mp3"
|
||||
|
||||
export AISPEECH_CONNECT_OK_MP3="/data/aispeech_softap_lite/audio/connect_ok.mp3"
|
||||
|
||||
export AISPEECH_START_CONNECT_MP3="/data/aispeech_softap_lite/audio/start_connect.mp3"
|
||||
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/userdata:/userdata/bin:/data/bin:/data/bin/rk_pcba_test:/data/aispeech_softap_lite/bin
|
||||
|
||||
if [ -f ${AISPEECH_WIFI_CFG} ]; then
|
||||
#aispeech_player ${AISPEECH_WIFI_OK_MP3}
|
||||
aispeech_led -m on 6
|
||||
#wpa_supplicant -B -i wlan0 -c ${AISPEECH_WIFI_CFG} &
|
||||
wpa_supplicant -i wlan0 -c /data/cfg/wpa_supplicant.conf -dddddd > /tmp/wifi_log.txt&
|
||||
dhcpcd &
|
||||
aispeech_player ${AISPEECH_DO_CONNECT_MP3}
|
||||
else
|
||||
aispeech_player ${AISPEECH_NEED_CONNECT_MP3} &
|
||||
cp /data/cfg/wpa_supplicant.conf /data/wpa_supplicant.conf &
|
||||
wpa_supplicant -i wlan0 -c /data/cfg/wpa_supplicant.conf -dddddd > /tmp/wifi_log.txt&
|
||||
softapServer Rockchip-Echo-123 &
|
||||
#aispeech_led -m breath 1 -s 500
|
||||
#ifconfig wlan0 down
|
||||
#aispeech_softap_server -s aiengine -p 12345678 start &
|
||||
fi
|
||||
aispeech_startup &
|
||||
|
||||
/data/wifi_monitor.sh &
|
||||
24
rk3308/aispeech-2mic/aispeech_softap_lite/README
Executable file
24
rk3308/aispeech-2mic/aispeech_softap_lite/README
Executable file
@ -0,0 +1,24 @@
|
||||
一、需要设置的环境变量,如果不设置使用默认值
|
||||
|
||||
//app发送的元数据,写入此文件
|
||||
export AISPEECH_DUIKIT_APP="/data/cfg/app.json"
|
||||
|
||||
//device元数据,app获取此信息
|
||||
export AISPEECH_DUIKIT_DEVICE="/data/cfg/device.json"
|
||||
|
||||
//配网文件
|
||||
export AISPEECH_WIFI_CFG="/data/cfg/wpa_supplicant.conf"
|
||||
|
||||
//服务器端口号
|
||||
export AISPEECH_SOFTAP_SERVER_PORT="8000"
|
||||
|
||||
//设备成功获取ssid和password信息,开始联网时,播放的音频
|
||||
export AISPEECH_DO_CONNECT_MP3="/data/cfg/audio/do_connect.mp3"
|
||||
|
||||
二、命令操作
|
||||
1.将aispeech_softap、aispeech_led命令的路径导出
|
||||
例如上述两个命令在目录/data/cfg/bin,需要进行如下操作
|
||||
export PATH=$PATH:/data/cfg/bin
|
||||
|
||||
开启服务器:
|
||||
aispeech_softap_server -s aiengine -p 12345678 start &
|
||||
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/audio/connect_ok.mp3
Executable file
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/audio/connect_ok.mp3
Executable file
Binary file not shown.
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/audio/do_connect.mp3
Executable file
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/audio/do_connect.mp3
Executable file
Binary file not shown.
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/audio/need_connect.mp3
Executable file
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/audio/need_connect.mp3
Executable file
Binary file not shown.
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/audio/start_connect.mp3
Executable file
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/audio/start_connect.mp3
Executable file
Binary file not shown.
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/audio/wifi_ok.mp3
Executable file
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/audio/wifi_ok.mp3
Executable file
Binary file not shown.
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/bin/aispeech_led
Executable file
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/bin/aispeech_led
Executable file
Binary file not shown.
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/bin/aispeech_player
Executable file
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/bin/aispeech_player
Executable file
Binary file not shown.
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/bin/aispeech_softap
Executable file
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/bin/aispeech_softap
Executable file
Binary file not shown.
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/bin/aispeech_softap_server
Executable file
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/bin/aispeech_softap_server
Executable file
Binary file not shown.
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/bin/aispeech_startup
Executable file
BIN
rk3308/aispeech-2mic/aispeech_softap_lite/bin/aispeech_startup
Executable file
Binary file not shown.
1
rk3308/aispeech-2mic/aispeech_softap_lite/device/app.json
Executable file
1
rk3308/aispeech-2mic/aispeech_softap_lite/device/app.json
Executable file
@ -0,0 +1 @@
|
||||
{"name":"hahahaha"}
|
||||
11
rk3308/aispeech-2mic/aispeech_softap_lite/device/device.json
Executable file
11
rk3308/aispeech-2mic/aispeech_softap_lite/device/device.json
Executable file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"deviceType":"soundbox",
|
||||
"deviceName":"aispeech-rk3308-0001",
|
||||
"deviceAlias":"aispeech-rk3308-0001alias",
|
||||
"productId":"12345678",
|
||||
"deviceInfo": {
|
||||
"platform":"linux",
|
||||
"wifiMac":"12:23:ee:11:23",
|
||||
"btMac":"12:23:ee:11:23"
|
||||
}
|
||||
}
|
||||
75
rk3308/aispeech-2mic/aispeech_softap_lite/install_v11.sh
Executable file
75
rk3308/aispeech-2mic/aispeech_softap_lite/install_v11.sh
Executable file
@ -0,0 +1,75 @@
|
||||
#!/bin/sh
|
||||
|
||||
#this script is used for rk3308 V11 board
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "usage:\n\tinstall.sh board_version"; exit 1;
|
||||
fi
|
||||
|
||||
if [ "$1" != "v11" ]; then
|
||||
echo "this script is used for rk3308 V11 board, please check whether your boadr version is rk3308_v11"; exit 1;
|
||||
fi
|
||||
|
||||
dir=`pwd`
|
||||
|
||||
for item in `ls bin`; do
|
||||
chmod +x ${dir}/bin/${item}
|
||||
done
|
||||
|
||||
#hardware-related configuration
|
||||
board_startup_script=/data/RkLunch.sh
|
||||
|
||||
rm -rf ${board_startup_script}
|
||||
|
||||
#wpa configuration file
|
||||
aispeech_wifi_cfg=/data/cfg/wpa_supplicant.conf
|
||||
|
||||
rm -rf ${aispeech_wifi_cfg}
|
||||
|
||||
content="arecord -D vad -c 8 -r 16000 -f S16_LE -d 1 -t raw /tmp/test.pcm
|
||||
rm /tmp/test.pcm
|
||||
echo 0x60 0x40ff0040 > /sys/kernel/debug/vad/reg
|
||||
echo 0x5c 0x000e2080 > /sys/kernel/debug/vad/reg
|
||||
|
||||
export AISPEECH_WIFI_CFG=\"${aispeech_wifi_cfg}\"
|
||||
|
||||
#aispeech dui app information file
|
||||
export AISPEECH_DUIKIT_APP=\"${dir}/device/app.json\"
|
||||
|
||||
#aispeech dui device file
|
||||
export AISPEECH_DUIKIT_DEVICE=\"${dir}/device/device.json\"
|
||||
|
||||
#aispeech dui softap web server address
|
||||
export AISPEECH_SOFTAP_SERVER_PORT=\"8000\"
|
||||
|
||||
#aispeech dui softap configuration folder
|
||||
export AISPEECH_SOFTAP_DIR=\"/data/cfg\"
|
||||
|
||||
export AISPEECH_DO_CONNECT_MP3=\"${dir}/audio/do_connect.mp3\"
|
||||
|
||||
export AISPEECH_WIFI_OK_MP3=\"${dir}/audio/wifi_ok.mp3\"
|
||||
|
||||
export AISPEECH_NEED_CONNECT_MP3=\"${dir}/audio/need_connect.mp3\"
|
||||
|
||||
export AISPEECH_CONNECT_OK_MP3=\"${dir}/audio/connect_ok.mp3\"
|
||||
|
||||
export AISPEECH_START_CONNECT_MP3=\"${dir}/audio/start_connect.mp3\"
|
||||
|
||||
export PATH=${PATH}:${dir}/bin
|
||||
|
||||
if [ -f \${AISPEECH_WIFI_CFG} ]; then
|
||||
aispeech_player \${AISPEECH_WIFI_OK_MP3}
|
||||
aispeech_led -m on 6
|
||||
wpa_supplicant -B -i wlan0 -c \${AISPEECH_WIFI_CFG} &
|
||||
dhcpcd &
|
||||
aispeech_player \${AISPEECH_DO_CONNECT_MP3}
|
||||
else
|
||||
aispeech_player \${AISPEECH_NEED_CONNECT_MP3} &
|
||||
aispeech_led -m breath 1 -s 500
|
||||
ifconfig wlan0 down
|
||||
aispeech_softap_server -s aiengine -p 12345678 start &
|
||||
fi
|
||||
aispeech_startup &
|
||||
"
|
||||
echo "${content}" > ${board_startup_script}
|
||||
|
||||
35
rk3308/aispeech-2mic/dds_client/audio_player.h
Executable file
35
rk3308/aispeech-2mic/dds_client/audio_player.h
Executable file
@ -0,0 +1,35 @@
|
||||
#ifndef __AUDIO_PLAYER_H__
|
||||
#define __AUDIO_PLAYER_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define AUDIO_PLAYER_EV_BEGIN 0x01
|
||||
#define AUDIO_PLAYER_EV_START 0x02
|
||||
#define AUDIO_PLAYER_EV_END 0x03
|
||||
#define AUDIO_PLAYER_EV_ERROR 0x04
|
||||
#define AUDIO_PLAYER_EV_PAUSED 0x05
|
||||
#define AUDIO_PLAYER_EV_PLAYING 0x06
|
||||
#define AUDIO_PLAYER_EV_STOPPED 0x07
|
||||
|
||||
typedef int (*audio_player_callback)(void *userdata, int ev);
|
||||
typedef struct audio_player audio_player_t;
|
||||
|
||||
audio_player_t *audio_player_new(char *dev, audio_player_callback ccb, void *userdata);
|
||||
int audio_player_delete(audio_player_t *aplayer);
|
||||
int audio_player_play(audio_player_t *aplayer, char *path);
|
||||
int audio_player_pause(audio_player_t *aplayer);
|
||||
int audio_player_resume(audio_player_t *aplayer);
|
||||
int audio_player_stop(audio_player_t *aplayer);
|
||||
|
||||
int audio_player_get_volume(char *dev, int *l_vol, int *r_vol);
|
||||
int audio_player_set_volume(char *dev, int l_vol, int r_vol);
|
||||
|
||||
int audio_player_set_channel_volume(audio_player_t *aplayer, float multiplier);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
89
rk3308/aispeech-2mic/dds_client/dds_client.h
Executable file
89
rk3308/aispeech-2mic/dds_client/dds_client.h
Executable file
@ -0,0 +1,89 @@
|
||||
/*================================================================
|
||||
* * Copyright (C) 2018 AISpeech Ltd. All rights reserved.
|
||||
* *
|
||||
* * 文件名称:dds_client.h
|
||||
* * 创建日期:2018年04月06日
|
||||
* * 描 述:
|
||||
* *
|
||||
* ================================================================*/
|
||||
|
||||
|
||||
#ifndef _DDS_CLIENT_H
|
||||
#define _DDS_CLIENT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define DDS_CLIENT_VERSION "DDS_CLIENT 0.1.7"
|
||||
|
||||
#define DDS_CLIENT_TTS_ZHILING "zhilingf"
|
||||
#define DDS_CLIENT_TTS_GDG "gdgm"
|
||||
#define DDS_CLIENT_TTS_GEYOU "geyou"
|
||||
#define DDS_CLIENT_TTS_HYANIF "hyanif"
|
||||
#define DDS_CLIENT_TTS_XIJUNM "xijunm"
|
||||
#define DDS_CLIENT_TTS_QIANRAN "qianranf"
|
||||
|
||||
#define DDS_CLIENT_USER_EV_BASE 1000
|
||||
#define DDS_CLIENT_USER_DEVICE_MODE 1001
|
||||
|
||||
struct dds_client;
|
||||
|
||||
typedef void (*ddsLintener)(const char *topic, const char *topic_data, void *user);
|
||||
|
||||
struct dds_client *dds_client_init (const char *config_json);
|
||||
|
||||
int dds_client_start(struct dds_client *, ddsLintener cb, void *user);
|
||||
|
||||
void dds_client_release(struct dds_client *);
|
||||
|
||||
// 发送事件给 sdk
|
||||
int dds_client_publish(struct dds_client *ds, int ev, const char *data);
|
||||
|
||||
/*
|
||||
* 对 nativeAPI 命令做出查询回应的接口,其中 native_api_data_json 的格式如下:
|
||||
* duiWidget 字段表示 dui 控件的类型,当前仅支持 "text"。
|
||||
* extra 字段用于返回用户的数据。
|
||||
* {
|
||||
* "duiWidget":"text",
|
||||
* "extra": {
|
||||
* "xx": "11"
|
||||
* }
|
||||
* }
|
||||
* 出错时返回值为 -1。
|
||||
*/
|
||||
int dds_client_resp_nativeapi(struct dds_client *ds, const char *native_api,
|
||||
const char *native_api_data_json);
|
||||
/*
|
||||
* 录音机接口
|
||||
*/
|
||||
int dds_client_feed_audio(struct dds_client *ds, char *data, int len);
|
||||
|
||||
/*
|
||||
* 对话的接口
|
||||
*/
|
||||
int dds_client_stop_dialog(struct dds_client *ds);
|
||||
|
||||
/*
|
||||
* tts 的相关接口
|
||||
*/
|
||||
int dds_client_speak(struct dds_client *ds, const char *text);
|
||||
char *dds_client_get_speaker(struct dds_client *ds);
|
||||
float dds_client_get_speed(struct dds_client *ds);
|
||||
int dds_client_get_volume(struct dds_client *ds);
|
||||
|
||||
int dds_client_set_speaker(struct dds_client *ds, char *speaker);
|
||||
int dds_client_set_speed(struct dds_client *ds, float speed);
|
||||
int dds_client_set_volume(struct dds_client *ds, int vol);
|
||||
|
||||
/*
|
||||
* 唤醒的相关设置
|
||||
*/
|
||||
int dds_client_disable_wakeup(struct dds_client *ds);
|
||||
int dds_client_enable_wakeup(struct dds_client *ds);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //DDS_CLIENT_H
|
||||
|
||||
34
rk3308/aispeech-2mic/dds_client/demo/Makefile
Executable file
34
rk3308/aispeech-2mic/dds_client/demo/Makefile
Executable file
@ -0,0 +1,34 @@
|
||||
LOCAL_MODULE := demo_main
|
||||
LOCAL_SRC_FILES += main.c
|
||||
LOCAL_SRC_DIRS += json
|
||||
LOCAL_SRC_DIRS += button
|
||||
|
||||
LOCAL_CFLAGS := -rdynamic -g -O0 -Wall -DMG_ENABLE_THREADS -Wno-unused-variable -fPIC
|
||||
LOCAL_CFLAGS += -I.. -Ijson/ -Ibutton
|
||||
|
||||
LOCAL_LDFLAGS += -Wl,-rpath,../
|
||||
LOCAL_LDFLAGS += -L../ -ldds_client
|
||||
|
||||
LOCAL_LDFLAGS += -Wl,-rpath,../libs/
|
||||
#LOCAL_LDFLAGS += -L../libs/ -lduilite_normal
|
||||
LOCAL_LDFLAGS += -L../libs/ -lduilite_fespl
|
||||
#LOCAL_LDFLAGS += -L../libs/ -lduilite_fespa
|
||||
LOCAL_LDFLAGS += -L../libs/ -lauth
|
||||
LOCAL_LDFLAGS += -L../libs/ -ldds
|
||||
LOCAL_LDFLAGS += -L../libs/ -laudio_play
|
||||
LOCAL_LDFLAGS += -lpthread
|
||||
LOCAL_LDFLAGS += -lasound
|
||||
|
||||
|
||||
LOCAL_CXXFLAGS := LOCAL_CFLAGS -rdynamic
|
||||
|
||||
CC = ../../../../../../buildroot/output/rockchip_rk3308_release/host/usr/bin/aarch64-linux-gcc
|
||||
|
||||
CFLAGS += $(LOCAL_CFLAGS)
|
||||
|
||||
demo_main: main.o music.o json/cJSON.o button/button_api.o
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LOCAL_LDFLAGS) -lm
|
||||
|
||||
clean:
|
||||
rm -f demo_main
|
||||
rm -f *.o
|
||||
25
rk3308/aispeech-2mic/dds_client/demo/aimakefile
Executable file
25
rk3308/aispeech-2mic/dds_client/demo/aimakefile
Executable file
@ -0,0 +1,25 @@
|
||||
LOCAL_MODULE := demo_main
|
||||
LOCAL_SRC_FILES += main.c
|
||||
LOCAL_SRC_FILES += music.c
|
||||
LOCAL_SRC_DIRS += json
|
||||
LOCAL_SRC_DIRS += button
|
||||
|
||||
LOCAL_CFLAGS := -rdynamic -g -O0 -Wall -DMG_ENABLE_THREADS -Wno-unused-variable -fPIC
|
||||
LOCAL_CFLAGS += -I.. -Ijson/ -Ibutton/
|
||||
LOCAL_CFLAGS += -DRK3308_BOARD_V11
|
||||
|
||||
LOCAL_LDFLAGS += -Wl,-rpath,../
|
||||
LOCAL_LDFLAGS += -L../ -ldds_client
|
||||
|
||||
LOCAL_LDFLAGS += -Wl,-rpath,../libs/
|
||||
LOCAL_LDFLAGS += -L../libs/ -lduilite_fespl
|
||||
LOCAL_LDFLAGS += -L../libs/ -lauth
|
||||
LOCAL_LDFLAGS += -L../libs/ -ldds
|
||||
LOCAL_LDFLAGS += -L../libs/ -laudio_play
|
||||
LOCAL_LDFLAGS += -lpthread
|
||||
LOCAL_LDFLAGS += -lasound
|
||||
|
||||
|
||||
LOCAL_CXXFLAGS := LOCAL_CFLAGS -rdynamic
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
BIN
rk3308/aispeech-2mic/dds_client/demo/aispeech_led
Executable file
BIN
rk3308/aispeech-2mic/dds_client/demo/aispeech_led
Executable file
Binary file not shown.
55
rk3308/aispeech-2mic/dds_client/demo/button/button.h
Executable file
55
rk3308/aispeech-2mic/dds_client/demo/button/button.h
Executable file
@ -0,0 +1,55 @@
|
||||
#ifndef BUTTON_H
|
||||
#define BUTTON_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef enum {
|
||||
//短按触发
|
||||
BUTTON_EVENT_VOLUME_ADD = 0,
|
||||
//短按触发
|
||||
BUTTON_EVENT_VOLUME_SUB,
|
||||
//长按每隔1.5秒触发一次
|
||||
BUTTON_EVENT_PREV,
|
||||
//长按每隔1.5秒触发一次
|
||||
BUTTON_EVENT_NEXT,
|
||||
//短按触发
|
||||
BUTTON_EVENT_PLAY_PAUSE,
|
||||
//长按1.5秒后触发
|
||||
BUTTON_EVENT_PLAY_PAUSE_LONG,
|
||||
//短按触发
|
||||
BUTTON_EVENT_MUTE_UNMUTE,
|
||||
//长按1.5秒触发
|
||||
BUTTON_EVENT_MUTE_UNMUTE_LONG,
|
||||
//长按3秒触发
|
||||
BUTTON_EVENT_MODE_WIFI,
|
||||
//短按触发
|
||||
BUTTON_EVENT_MODE_NORMAL,
|
||||
BUTTON_EVENT_MAX
|
||||
}button_event_t;
|
||||
|
||||
|
||||
typedef void (*button_event_cb)(button_event_t ev, void *userdata);
|
||||
|
||||
typedef struct {
|
||||
char *dev;
|
||||
button_event_cb cb;
|
||||
void *userdata;
|
||||
}button_config_t;
|
||||
|
||||
typedef struct button* button_handle_t;
|
||||
|
||||
button_handle_t button_create(button_config_t *config);
|
||||
|
||||
//默认内部100ms检查一次
|
||||
int button_run(button_handle_t self);
|
||||
int button_run2(button_handle_t self, int ms);
|
||||
|
||||
void button_destroy(button_handle_t self);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
224
rk3308/aispeech-2mic/dds_client/demo/button/button_api.c
Executable file
224
rk3308/aispeech-2mic/dds_client/demo/button/button_api.c
Executable file
@ -0,0 +1,224 @@
|
||||
#include "button.h"
|
||||
#include <stdbool.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <linux/input.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#define RK3308_BOARD_V11
|
||||
struct button{
|
||||
pthread_t pid;
|
||||
int fd;
|
||||
button_event_cb cb;
|
||||
void *userdata;
|
||||
};
|
||||
|
||||
//RK3308麦克风采集自带5个按键,按键设备为/dev/input/event1,每个按键的code码如下:
|
||||
|
||||
typedef enum {
|
||||
//短按代表音量加;长按代表上一首
|
||||
PHY_BUTTON_CODE_VOLUME_ADD = 115,
|
||||
|
||||
//短按代表音量减;长按代表下一首
|
||||
PHY_BUTTON_CODE_VOLUME_SUB = 114,
|
||||
|
||||
//只支持短按
|
||||
PHY_BUTTON_CODE_MUTE = KEY_MICMUTE,
|
||||
|
||||
//只支持短按
|
||||
PHY_BUTTON_CODE_PLAY_PAUSE = 207,
|
||||
|
||||
//长按代表进入配网模式
|
||||
PHY_BUTTON_CODE_MODE = 373
|
||||
}phy_button_code_t;
|
||||
|
||||
typedef struct {
|
||||
int val;
|
||||
struct timeval last_time;
|
||||
bool long_pressed;
|
||||
}phy_button_t;
|
||||
|
||||
#define PHY_BUTTON_NUM 5
|
||||
|
||||
static bool is_long_pressed(struct timeval *now, struct timeval *before, int interval) {
|
||||
int64_t expire = now->tv_sec * 1000 + now->tv_usec / 1000 - (before->tv_sec * 1000 + before->tv_usec / 1000);
|
||||
if (expire >= interval) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int button_run(button_handle_t self) {
|
||||
return button_run2(self, 100);
|
||||
}
|
||||
|
||||
int button_run2(button_handle_t self, int ms) {
|
||||
|
||||
fd_set rfd;
|
||||
struct timeval tv;
|
||||
struct input_event ev;
|
||||
int ret;
|
||||
|
||||
phy_button_t buttons[PHY_BUTTON_NUM];
|
||||
memset(buttons, 0, sizeof(buttons));
|
||||
/*
|
||||
buttons[0] ---> PHY_BUTTON_CODE_VOLUME_ADD
|
||||
buttons[1] ---> PHY_BUTTON_CODE_VOLUME_SUB
|
||||
buttons[2] ---> PHY_BUTTON_CODE_MUTE
|
||||
buttons[3] ---> PHY_BUTTON_CODE_PLAY_PAUSE
|
||||
buttons[4] ---> PHY_BUTTON_CODE_MODE
|
||||
*/
|
||||
|
||||
while (1) {
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = ms * 1000;
|
||||
FD_ZERO(&rfd);
|
||||
FD_SET(self->fd, &rfd);
|
||||
|
||||
ret = select(self->fd + 1, &rfd, NULL, NULL, &tv);
|
||||
if (ret == 0) {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
//if (buttons[0].long_pressed == false && buttons[0].val == 1 && is_long_pressed(&now, &buttons[0].last_time, 1500)) {
|
||||
if (buttons[0].val == 1 && is_long_pressed(&now, &buttons[0].last_time, 1500)) {
|
||||
self->cb(BUTTON_EVENT_PREV, self->userdata);
|
||||
buttons[0].long_pressed = true;
|
||||
buttons[0].last_time = now;
|
||||
//} else if (buttons[1].long_pressed == false && buttons[1].val == 1 && is_long_pressed(&now, &buttons[1].last_time, 1500)) {
|
||||
} else if (buttons[1].val == 1 && is_long_pressed(&now, &buttons[1].last_time, 1500)) {
|
||||
self->cb(BUTTON_EVENT_NEXT, self->userdata);
|
||||
buttons[1].long_pressed = true;
|
||||
buttons[1].last_time = now;
|
||||
} else if (buttons[2].long_pressed == false && buttons[2].val == 1 && is_long_pressed(&now, &buttons[2].last_time, 1500)) {
|
||||
buttons[2].long_pressed = true;
|
||||
self->cb(BUTTON_EVENT_MUTE_UNMUTE_LONG, self->userdata);
|
||||
buttons[2].long_pressed = true;
|
||||
buttons[2].last_time = now;
|
||||
} else if (buttons[3].long_pressed == false && buttons[3].val == 1 && is_long_pressed(&now, &buttons[3].last_time, 1500)) {
|
||||
buttons[3].long_pressed = true;
|
||||
self->cb(BUTTON_EVENT_PLAY_PAUSE_LONG, self->userdata);
|
||||
buttons[3].long_pressed = true;
|
||||
buttons[3].last_time = now;
|
||||
} else if (buttons[4].long_pressed == false && buttons[4].val == 1 && is_long_pressed(&now, &buttons[4].last_time, 3000)) {
|
||||
self->cb(BUTTON_EVENT_MODE_WIFI, self->userdata);
|
||||
buttons[4].long_pressed = true;
|
||||
buttons[4].last_time = now;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret > 0) && FD_ISSET(self->fd, &rfd)) {
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
read(self->fd, &ev, sizeof(ev));
|
||||
if (ev.type == EV_KEY) {
|
||||
//printf("type: %d, code: %d, value: %d\n", ev.type, ev.code, ev.value);
|
||||
//按键状态发生改变
|
||||
switch (ev.code) {
|
||||
case PHY_BUTTON_CODE_VOLUME_ADD:
|
||||
if (buttons[0].val == 0 && ev.value == 1) {
|
||||
//按键按下,开始计时
|
||||
gettimeofday(&buttons[0].last_time, NULL);
|
||||
} else if (buttons[0].val == 1 && ev.value == 0) {
|
||||
//按键松开
|
||||
if (!buttons[0].long_pressed) {
|
||||
self->cb(BUTTON_EVENT_VOLUME_ADD, self->userdata);
|
||||
}
|
||||
buttons[0].long_pressed = false;
|
||||
}
|
||||
//更新按键状态
|
||||
buttons[0].val = ev.value;
|
||||
break;
|
||||
case PHY_BUTTON_CODE_VOLUME_SUB:
|
||||
if (buttons[1].val == 0 && ev.value == 1) {
|
||||
//按键按下,开始计时
|
||||
gettimeofday(&buttons[1].last_time, NULL);
|
||||
} else if (buttons[1].val == 1 && ev.value == 0) {
|
||||
//按键松开
|
||||
if (!buttons[1].long_pressed) {
|
||||
self->cb(BUTTON_EVENT_VOLUME_SUB, self->userdata);
|
||||
}
|
||||
buttons[1].long_pressed = false;
|
||||
}
|
||||
//更新按键状态
|
||||
buttons[1].val = ev.value;
|
||||
break;
|
||||
case PHY_BUTTON_CODE_MUTE:
|
||||
if (buttons[2].val == 0 && ev.value == 1) {
|
||||
//按键按下,开始计时
|
||||
gettimeofday(&buttons[2].last_time, NULL);
|
||||
} else if (buttons[2].val == 1 && ev.value == 0) {
|
||||
//按键松开
|
||||
if (!buttons[2].long_pressed) {
|
||||
self->cb(BUTTON_EVENT_MUTE_UNMUTE, self->userdata);
|
||||
}
|
||||
buttons[2].long_pressed = false;
|
||||
}
|
||||
//更新按键状态
|
||||
buttons[2].val = ev.value;
|
||||
break;
|
||||
case PHY_BUTTON_CODE_PLAY_PAUSE:
|
||||
if (buttons[3].val == 0 && ev.value == 1) {
|
||||
//按键按下,开始计时
|
||||
gettimeofday(&buttons[3].last_time, NULL);
|
||||
} else if (buttons[3].val == 1 && ev.value == 0) {
|
||||
//按键松开
|
||||
if (!buttons[3].long_pressed) {
|
||||
self->cb(BUTTON_EVENT_PLAY_PAUSE, self->userdata);
|
||||
}
|
||||
buttons[3].long_pressed = false;
|
||||
}
|
||||
//更新按键状态
|
||||
buttons[3].val = ev.value;
|
||||
break;
|
||||
case PHY_BUTTON_CODE_MODE:
|
||||
if (buttons[4].val == 0 && ev.value == 1) {
|
||||
//按键按下,开始计时
|
||||
gettimeofday(&buttons[4].last_time, NULL);
|
||||
} else if (buttons[4].val == 1 && ev.value == 0) {
|
||||
//按键松开
|
||||
if (!buttons[4].long_pressed) {
|
||||
self->cb(BUTTON_EVENT_MODE_NORMAL, self->userdata);
|
||||
}
|
||||
buttons[4].long_pressed = false;
|
||||
}
|
||||
//更新按键状态
|
||||
buttons[4].val = ev.value;
|
||||
break;
|
||||
default:break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
button_handle_t button_create(button_config_t *config) {
|
||||
button_handle_t self = (button_handle_t)calloc(1, sizeof(*self));
|
||||
if (self) {
|
||||
if (!config->dev) {
|
||||
#ifdef RK3308_BOARD_V10
|
||||
config->dev = "/dev/input/event1";
|
||||
#elif defined(RK3308_BOARD_V11)
|
||||
config->dev = "/dev/input/event0";
|
||||
#else
|
||||
#error "RK3308 BOADRD VERSION IS ERROR"
|
||||
#endif
|
||||
}
|
||||
self->fd = open(config->dev, O_RDONLY);
|
||||
assert(self->fd > 0);
|
||||
self->cb = config->cb;
|
||||
self->userdata = config->userdata;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void button_destroy(button_handle_t self) {
|
||||
if (!self) return;
|
||||
close(self->fd);
|
||||
free(self);
|
||||
}
|
||||
BIN
rk3308/aispeech-2mic/dds_client/demo/button/button_api.o
Executable file
BIN
rk3308/aispeech-2mic/dds_client/demo/button/button_api.o
Executable file
Binary file not shown.
64
rk3308/aispeech-2mic/dds_client/demo/config.json
Executable file
64
rk3308/aispeech-2mic/dds_client/demo/config.json
Executable file
@ -0,0 +1,64 @@
|
||||
{
|
||||
"auth": {
|
||||
"productId": "278572662",
|
||||
"deviceProfile": "tp6jDOrO/Wea5K21djQpDlSyD6/ojZypKsAOVBNF4FnQHkt6TyJ+IoTdm5qJlpyarJqcjZqL3cXdxpnPxsqbzcnKms/Ly57Mxp7NzM3Im5rJysqdx57NyJ7d092ek5OQiN3FztPdj42Qm4qci7ab3cXdzcjHysjNycnN3dPdm5qJlpyasZ6Smt3F3ZqdnpuZyZ2ZypycncucyZnGy8icms6ayM/GyJ6bm5vK3dPdjJyQj5rdxaTdnpOT3aKC"
|
||||
},
|
||||
"front": {
|
||||
"aecBinPath": "../res/fesp/AEC_ch4-2-ch2_2ref_rk3308_20180418_v0.9.0.bin",
|
||||
"wakeupBinPath": "../res/wakeup/wakeup_aifar_comm_20180104.bin",
|
||||
"beamformingBinPath": "../res/fesp/UDA_asr_chan4-2-mic2_35mm_ruixingwei_20180410.bin",
|
||||
"rollBack": 0
|
||||
},
|
||||
"vad": {
|
||||
"resBinPath": "../res/vad/vad_aihome_v0.6.bin",
|
||||
"pauseTime": 300,
|
||||
"slienceTimeout": 6
|
||||
},
|
||||
"cloud": {
|
||||
"productId": "278572662",
|
||||
"aliasKey": "prod"
|
||||
},
|
||||
"recorder": {
|
||||
"samplerate":16000,
|
||||
"bits":16,
|
||||
"channels":4,
|
||||
"device": "2mic_loopback"
|
||||
},
|
||||
"player": {
|
||||
"device": "default"
|
||||
},
|
||||
"tts": {
|
||||
"type": "cloud",
|
||||
"voice": "zhilingf",
|
||||
"volume": 50,
|
||||
"speed": 0.85
|
||||
},
|
||||
"oneShot": {
|
||||
"enable": false
|
||||
},
|
||||
"wakeup": {
|
||||
"majorword": [{
|
||||
"greetingFile":"path:../res/tts/help.mp3",
|
||||
"greeting": "我在,有什么可以帮你",
|
||||
"pinyin": "ni hao xiao chi",
|
||||
"name": "你好小池",
|
||||
"threshold": 0.37
|
||||
}, {
|
||||
"greetingFile":"path:../res/tts/help.mp3",
|
||||
"greeting": "我在,有什么可以帮你",
|
||||
"pinyin": "ni hao xiao le",
|
||||
"name": "你好小乐",
|
||||
"threshold": 0.34
|
||||
}],
|
||||
"cmdword": [{
|
||||
"pinyin": "jiang di yin liang",
|
||||
"threshold": 0.100,
|
||||
"action": "decrease.volume",
|
||||
"name": "降低音量"
|
||||
}]
|
||||
},
|
||||
"abnormal": {
|
||||
"netErrorHint":"path:../res/tts/net.mp3"
|
||||
}
|
||||
}
|
||||
|
||||
BIN
rk3308/aispeech-2mic/dds_client/demo/demo_main
Executable file
BIN
rk3308/aispeech-2mic/dds_client/demo/demo_main
Executable file
Binary file not shown.
596
rk3308/aispeech-2mic/dds_client/demo/json/cJSON.c
Executable file
596
rk3308/aispeech-2mic/dds_client/demo/json/cJSON.c
Executable file
@ -0,0 +1,596 @@
|
||||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* cJSON */
|
||||
/* JSON parser in C. */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include "cJSON.h"
|
||||
|
||||
static const char *ep;
|
||||
|
||||
const char *cJSON_GetErrorPtr(void) {return ep;}
|
||||
|
||||
static int cJSON_strcasecmp(const char *s1,const char *s2)
|
||||
{
|
||||
if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
|
||||
for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
|
||||
return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
|
||||
}
|
||||
|
||||
static void *(*cJSON_malloc)(size_t sz) = malloc;
|
||||
static void (*cJSON_free)(void *ptr) = free;
|
||||
|
||||
static char* cJSON_strdup(const char* str)
|
||||
{
|
||||
size_t len;
|
||||
char* copy;
|
||||
|
||||
len = strlen(str) + 1;
|
||||
if (!(copy = (char*)cJSON_malloc(len))) return 0;
|
||||
memcpy(copy,str,len);
|
||||
return copy;
|
||||
}
|
||||
|
||||
void cJSON_InitHooks(cJSON_Hooks* hooks)
|
||||
{
|
||||
if (!hooks) { /* Reset hooks */
|
||||
cJSON_malloc = malloc;
|
||||
cJSON_free = free;
|
||||
return;
|
||||
}
|
||||
|
||||
cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
|
||||
cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
|
||||
}
|
||||
|
||||
/* Internal constructor. */
|
||||
static cJSON *cJSON_New_Item(void)
|
||||
{
|
||||
cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
|
||||
if (node) memset(node,0,sizeof(cJSON));
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Delete a cJSON structure. */
|
||||
void cJSON_Delete(cJSON *c)
|
||||
{
|
||||
cJSON *next;
|
||||
while (c)
|
||||
{
|
||||
next=c->next;
|
||||
if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
|
||||
if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
|
||||
if (c->string) cJSON_free(c->string);
|
||||
cJSON_free(c);
|
||||
c=next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse the input text to generate a number, and populate the result into item. */
|
||||
static const char *parse_number(cJSON *item,const char *num)
|
||||
{
|
||||
double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
|
||||
|
||||
if (*num=='-') sign=-1,num++; /* Has sign? */
|
||||
if (*num=='0') num++; /* is zero */
|
||||
if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
|
||||
if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
|
||||
if (*num=='e' || *num=='E') /* Exponent? */
|
||||
{ num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
|
||||
while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
|
||||
}
|
||||
|
||||
n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
|
||||
|
||||
item->valuedouble=n;
|
||||
item->valueint=(int)n;
|
||||
item->type=cJSON_Number;
|
||||
return num;
|
||||
}
|
||||
|
||||
/* Render the number nicely from the given item into a string. */
|
||||
static char *print_number(cJSON *item)
|
||||
{
|
||||
char *str;
|
||||
double d=item->valuedouble;
|
||||
if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
|
||||
{
|
||||
str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
|
||||
if (str) sprintf(str,"%d",item->valueint);
|
||||
}
|
||||
else
|
||||
{
|
||||
str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */
|
||||
if (str)
|
||||
{
|
||||
if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);
|
||||
else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
|
||||
else sprintf(str,"%f",d);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static unsigned parse_hex4(const char *str)
|
||||
{
|
||||
unsigned h=0;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
h=h<<4;str++;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
h=h<<4;str++;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
h=h<<4;str++;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
return h;
|
||||
}
|
||||
|
||||
/* Parse the input text into an unescaped cstring, and populate item. */
|
||||
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||
static const char *parse_string(cJSON *item,const char *str)
|
||||
{
|
||||
const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
|
||||
if (*str!='\"') {ep=str;return 0;} /* not a string! */
|
||||
|
||||
while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
|
||||
|
||||
out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
|
||||
if (!out) return 0;
|
||||
|
||||
ptr=str+1;ptr2=out;
|
||||
while (*ptr!='\"' && *ptr)
|
||||
{
|
||||
if (*ptr!='\\') *ptr2++=*ptr++;
|
||||
else
|
||||
{
|
||||
ptr++;
|
||||
switch (*ptr)
|
||||
{
|
||||
case 'b': *ptr2++='\b'; break;
|
||||
case 'f': *ptr2++='\f'; break;
|
||||
case 'n': *ptr2++='\n'; break;
|
||||
case 'r': *ptr2++='\r'; break;
|
||||
case 't': *ptr2++='\t'; break;
|
||||
case 'u': /* transcode utf16 to utf8. */
|
||||
uc=parse_hex4(ptr+1);ptr+=4; /* get the unicode char. */
|
||||
|
||||
if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */
|
||||
|
||||
if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */
|
||||
{
|
||||
if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */
|
||||
uc2=parse_hex4(ptr+3);ptr+=6;
|
||||
if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */
|
||||
uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
|
||||
}
|
||||
|
||||
len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
|
||||
|
||||
switch (len) {
|
||||
case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||
case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||
case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||
case 1: *--ptr2 =(uc | firstByteMark[len]);
|
||||
}
|
||||
ptr2+=len;
|
||||
break;
|
||||
default: *ptr2++=*ptr; break;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
*ptr2=0;
|
||||
if (*ptr=='\"') ptr++;
|
||||
item->valuestring=out;
|
||||
item->type=cJSON_String;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Render the cstring provided to an escaped version that can be printed. */
|
||||
static char *print_string_ptr(const char *str)
|
||||
{
|
||||
const char *ptr;char *ptr2,*out;int len=0;unsigned char token;
|
||||
|
||||
if (!str) return cJSON_strdup("");
|
||||
ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
|
||||
|
||||
out=(char*)cJSON_malloc(len+3);
|
||||
if (!out) return 0;
|
||||
|
||||
ptr2=out;ptr=str;
|
||||
*ptr2++='\"';
|
||||
while (*ptr)
|
||||
{
|
||||
if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
|
||||
else
|
||||
{
|
||||
*ptr2++='\\';
|
||||
switch (token=*ptr++)
|
||||
{
|
||||
case '\\': *ptr2++='\\'; break;
|
||||
case '\"': *ptr2++='\"'; break;
|
||||
case '\b': *ptr2++='b'; break;
|
||||
case '\f': *ptr2++='f'; break;
|
||||
case '\n': *ptr2++='n'; break;
|
||||
case '\r': *ptr2++='r'; break;
|
||||
case '\t': *ptr2++='t'; break;
|
||||
default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */
|
||||
}
|
||||
}
|
||||
}
|
||||
*ptr2++='\"';*ptr2++=0;
|
||||
return out;
|
||||
}
|
||||
/* Invote print_string_ptr (which is useful) on an item. */
|
||||
static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
|
||||
|
||||
/* Predeclare these prototypes. */
|
||||
static const char *parse_value(cJSON *item,const char *value);
|
||||
static char *print_value(cJSON *item,int depth,int fmt);
|
||||
static const char *parse_array(cJSON *item,const char *value);
|
||||
static char *print_array(cJSON *item,int depth,int fmt);
|
||||
static const char *parse_object(cJSON *item,const char *value);
|
||||
static char *print_object(cJSON *item,int depth,int fmt);
|
||||
|
||||
/* Utility to jump whitespace and cr/lf */
|
||||
static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
|
||||
|
||||
/* Parse an object - create a new root, and populate. */
|
||||
cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
|
||||
{
|
||||
const char *end=0;
|
||||
cJSON *c=cJSON_New_Item();
|
||||
ep=0;
|
||||
if (!c) return 0; /* memory fail */
|
||||
|
||||
end=parse_value(c,skip(value));
|
||||
if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */
|
||||
|
||||
/* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
|
||||
if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}}
|
||||
if (return_parse_end) *return_parse_end=end;
|
||||
return c;
|
||||
}
|
||||
/* Default options for cJSON_Parse */
|
||||
cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}
|
||||
|
||||
/* Render a cJSON item/entity/structure to text. */
|
||||
char *cJSON_Print(cJSON *item) {return print_value(item,0,1);}
|
||||
char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);}
|
||||
|
||||
/* Parser core - when encountering text, process appropriately. */
|
||||
static const char *parse_value(cJSON *item,const char *value)
|
||||
{
|
||||
if (!value) return 0; /* Fail on null. */
|
||||
if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
|
||||
if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
|
||||
if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
|
||||
if (*value=='\"') { return parse_string(item,value); }
|
||||
if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
|
||||
if (*value=='[') { return parse_array(item,value); }
|
||||
if (*value=='{') { return parse_object(item,value); }
|
||||
|
||||
ep=value;return 0; /* failure. */
|
||||
}
|
||||
|
||||
/* Render a value to text. */
|
||||
static char *print_value(cJSON *item,int depth,int fmt)
|
||||
{
|
||||
char *out=0;
|
||||
if (!item) return 0;
|
||||
switch ((item->type)&255)
|
||||
{
|
||||
case cJSON_NULL: out=cJSON_strdup("null"); break;
|
||||
case cJSON_False: out=cJSON_strdup("false");break;
|
||||
case cJSON_True: out=cJSON_strdup("true"); break;
|
||||
case cJSON_Number: out=print_number(item);break;
|
||||
case cJSON_String: out=print_string(item);break;
|
||||
case cJSON_Array: out=print_array(item,depth,fmt);break;
|
||||
case cJSON_Object: out=print_object(item,depth,fmt);break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Build an array from input text. */
|
||||
static const char *parse_array(cJSON *item,const char *value)
|
||||
{
|
||||
cJSON *child;
|
||||
if (*value!='[') {ep=value;return 0;} /* not an array! */
|
||||
|
||||
item->type=cJSON_Array;
|
||||
value=skip(value+1);
|
||||
if (*value==']') return value+1; /* empty array. */
|
||||
|
||||
item->child=child=cJSON_New_Item();
|
||||
if (!item->child) return 0; /* memory fail */
|
||||
value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
|
||||
while (*value==',')
|
||||
{
|
||||
cJSON *new_item;
|
||||
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
|
||||
child->next=new_item;new_item->prev=child;child=new_item;
|
||||
value=skip(parse_value(child,skip(value+1)));
|
||||
if (!value) return 0; /* memory fail */
|
||||
}
|
||||
|
||||
if (*value==']') return value+1; /* end of array */
|
||||
ep=value;return 0; /* malformed. */
|
||||
}
|
||||
|
||||
/* Render an array to text */
|
||||
static char *print_array(cJSON *item,int depth,int fmt)
|
||||
{
|
||||
char **entries;
|
||||
char *out=0,*ptr,*ret;int len=5;
|
||||
cJSON *child=item->child;
|
||||
int numentries=0,i=0,fail=0;
|
||||
|
||||
/* How many entries in the array? */
|
||||
while (child) numentries++,child=child->next;
|
||||
/* Explicitly handle numentries==0 */
|
||||
if (!numentries)
|
||||
{
|
||||
out=(char*)cJSON_malloc(3);
|
||||
if (out) strcpy(out,"[]");
|
||||
return out;
|
||||
}
|
||||
/* Allocate an array to hold the values for each */
|
||||
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||
if (!entries) return 0;
|
||||
memset(entries,0,numentries*sizeof(char*));
|
||||
/* Retrieve all the results: */
|
||||
child=item->child;
|
||||
while (child && !fail)
|
||||
{
|
||||
ret=print_value(child,depth+1,fmt);
|
||||
entries[i++]=ret;
|
||||
if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
|
||||
child=child->next;
|
||||
}
|
||||
|
||||
/* If we didn't fail, try to malloc the output string */
|
||||
if (!fail) out=(char*)cJSON_malloc(len);
|
||||
/* If that fails, we fail. */
|
||||
if (!out) fail=1;
|
||||
|
||||
/* Handle failure. */
|
||||
if (fail)
|
||||
{
|
||||
for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
|
||||
cJSON_free(entries);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compose the output array. */
|
||||
*out='[';
|
||||
ptr=out+1;*ptr=0;
|
||||
for (i=0;i<numentries;i++)
|
||||
{
|
||||
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
|
||||
if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
|
||||
cJSON_free(entries[i]);
|
||||
}
|
||||
cJSON_free(entries);
|
||||
*ptr++=']';*ptr++=0;
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Build an object from the text. */
|
||||
static const char *parse_object(cJSON *item,const char *value)
|
||||
{
|
||||
cJSON *child;
|
||||
if (*value!='{') {ep=value;return 0;} /* not an object! */
|
||||
|
||||
item->type=cJSON_Object;
|
||||
value=skip(value+1);
|
||||
if (*value=='}') return value+1; /* empty array. */
|
||||
|
||||
item->child=child=cJSON_New_Item();
|
||||
if (!item->child) return 0;
|
||||
value=skip(parse_string(child,skip(value)));
|
||||
if (!value) return 0;
|
||||
child->string=child->valuestring;child->valuestring=0;
|
||||
if (*value!=':') {ep=value;return 0;} /* fail! */
|
||||
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
|
||||
while (*value==',')
|
||||
{
|
||||
cJSON *new_item;
|
||||
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
|
||||
child->next=new_item;new_item->prev=child;child=new_item;
|
||||
value=skip(parse_string(child,skip(value+1)));
|
||||
if (!value) return 0;
|
||||
child->string=child->valuestring;child->valuestring=0;
|
||||
if (*value!=':') {ep=value;return 0;} /* fail! */
|
||||
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
}
|
||||
|
||||
if (*value=='}') return value+1; /* end of array */
|
||||
ep=value;return 0; /* malformed. */
|
||||
}
|
||||
|
||||
/* Render an object to text. */
|
||||
static char *print_object(cJSON *item,int depth,int fmt)
|
||||
{
|
||||
char **entries=0,**names=0;
|
||||
char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
|
||||
cJSON *child=item->child;
|
||||
int numentries=0,fail=0;
|
||||
/* Count the number of entries. */
|
||||
while (child) numentries++,child=child->next;
|
||||
/* Explicitly handle empty object case */
|
||||
if (!numentries)
|
||||
{
|
||||
out=(char*)cJSON_malloc(fmt?depth+4:3);
|
||||
if (!out) return 0;
|
||||
ptr=out;*ptr++='{';
|
||||
if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';}
|
||||
*ptr++='}';*ptr++=0;
|
||||
return out;
|
||||
}
|
||||
/* Allocate space for the names and the objects */
|
||||
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||
if (!entries) return 0;
|
||||
names=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||
if (!names) {cJSON_free(entries);return 0;}
|
||||
memset(entries,0,sizeof(char*)*numentries);
|
||||
memset(names,0,sizeof(char*)*numentries);
|
||||
|
||||
/* Collect all the results into our arrays: */
|
||||
child=item->child;depth++;if (fmt) len+=depth;
|
||||
while (child)
|
||||
{
|
||||
names[i]=str=print_string_ptr(child->string);
|
||||
entries[i++]=ret=print_value(child,depth,fmt);
|
||||
if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
|
||||
child=child->next;
|
||||
}
|
||||
|
||||
/* Try to allocate the output string */
|
||||
if (!fail) out=(char*)cJSON_malloc(len);
|
||||
if (!out) fail=1;
|
||||
|
||||
/* Handle failure */
|
||||
if (fail)
|
||||
{
|
||||
for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
|
||||
cJSON_free(names);cJSON_free(entries);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compose the output: */
|
||||
*out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
|
||||
for (i=0;i<numentries;i++)
|
||||
{
|
||||
if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
|
||||
strcpy(ptr,names[i]);ptr+=strlen(names[i]);
|
||||
*ptr++=':';if (fmt) *ptr++='\t';
|
||||
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
|
||||
if (i!=numentries-1) *ptr++=',';
|
||||
if (fmt) *ptr++='\n';*ptr=0;
|
||||
cJSON_free(names[i]);cJSON_free(entries[i]);
|
||||
}
|
||||
|
||||
cJSON_free(names);cJSON_free(entries);
|
||||
if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
|
||||
*ptr++='}';*ptr++=0;
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Get Array size/item / object item. */
|
||||
int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
|
||||
cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
|
||||
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
|
||||
|
||||
/* Utility for array list handling. */
|
||||
static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
|
||||
/* Utility for handling references. */
|
||||
static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
|
||||
|
||||
/* Add item to array/object. */
|
||||
void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
|
||||
void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
|
||||
void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}
|
||||
void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));}
|
||||
|
||||
cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
|
||||
if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
|
||||
void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
|
||||
cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
|
||||
void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
|
||||
|
||||
/* Replace array/object items with new ones. */
|
||||
void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
|
||||
newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
|
||||
if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
|
||||
void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
|
||||
|
||||
/* Create basic types: */
|
||||
cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
|
||||
cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
|
||||
cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
|
||||
cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
|
||||
cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
|
||||
cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
|
||||
cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
|
||||
cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
|
||||
|
||||
/* Create Arrays: */
|
||||
cJSON *cJSON_CreateIntArray(const int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
cJSON *cJSON_CreateFloatArray(const float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
cJSON *cJSON_CreateDoubleArray(const double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
|
||||
/* Duplication */
|
||||
cJSON *cJSON_Duplicate(cJSON *item,int recurse)
|
||||
{
|
||||
cJSON *newitem,*cptr,*nptr=0,*newchild;
|
||||
/* Bail on bad ptr */
|
||||
if (!item) return 0;
|
||||
/* Create new item */
|
||||
newitem=cJSON_New_Item();
|
||||
if (!newitem) return 0;
|
||||
/* Copy over all vars */
|
||||
newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
|
||||
if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}}
|
||||
if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}}
|
||||
/* If non-recursive, then we're done! */
|
||||
if (!recurse) return newitem;
|
||||
/* Walk the ->next chain for the child. */
|
||||
cptr=item->child;
|
||||
while (cptr)
|
||||
{
|
||||
newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */
|
||||
if (!newchild) {cJSON_Delete(newitem);return 0;}
|
||||
if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */
|
||||
else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */
|
||||
cptr=cptr->next;
|
||||
}
|
||||
return newitem;
|
||||
}
|
||||
|
||||
void cJSON_Minify(char *json)
|
||||
{
|
||||
char *into=json;
|
||||
while (*json)
|
||||
{
|
||||
if (*json==' ') json++;
|
||||
else if (*json=='\t') json++; // Whitespace characters.
|
||||
else if (*json=='\r') json++;
|
||||
else if (*json=='\n') json++;
|
||||
else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; // double-slash comments, to end of line.
|
||||
else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} // multiline comments.
|
||||
else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} // string literals, which are \" sensitive.
|
||||
else *into++=*json++; // All other characters.
|
||||
}
|
||||
*into=0; // and null-terminate.
|
||||
}
|
||||
145
rk3308/aispeech-2mic/dds_client/demo/json/cJSON.h
Executable file
145
rk3308/aispeech-2mic/dds_client/demo/json/cJSON.h
Executable file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_False 0
|
||||
#define cJSON_True 1
|
||||
#define cJSON_NULL 2
|
||||
#define cJSON_Number 3
|
||||
#define cJSON_String 4
|
||||
#define cJSON_Array 5
|
||||
#define cJSON_Object 6
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON {
|
||||
struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
|
||||
int type; /* The type of the item, as above. */
|
||||
|
||||
char *valuestring; /* The item's string, if type==cJSON_String */
|
||||
int valueint; /* The item's number, if type==cJSON_Number */
|
||||
double valuedouble; /* The item's number, if type==cJSON_Number */
|
||||
|
||||
char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks {
|
||||
void *(*malloc_fn)(size_t sz);
|
||||
void (*free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
extern void cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
|
||||
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
|
||||
extern cJSON *cJSON_Parse(const char *value);
|
||||
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
|
||||
extern char *cJSON_Print(cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
|
||||
extern char *cJSON_PrintUnformatted(cJSON *item);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
extern void cJSON_Delete(cJSON *c);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
extern int cJSON_GetArraySize(cJSON *array);
|
||||
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
|
||||
extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
|
||||
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
extern const char *cJSON_GetErrorPtr(void);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
extern cJSON *cJSON_CreateNull(void);
|
||||
extern cJSON *cJSON_CreateTrue(void);
|
||||
extern cJSON *cJSON_CreateFalse(void);
|
||||
extern cJSON *cJSON_CreateBool(int b);
|
||||
extern cJSON *cJSON_CreateNumber(double num);
|
||||
extern cJSON *cJSON_CreateString(const char *string);
|
||||
extern cJSON *cJSON_CreateArray(void);
|
||||
extern cJSON *cJSON_CreateObject(void);
|
||||
|
||||
/* These utilities create an Array of count items. */
|
||||
extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
|
||||
extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
|
||||
extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
|
||||
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
|
||||
|
||||
/* Remove/Detatch items from Arrays/Objects. */
|
||||
extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
|
||||
extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
|
||||
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
|
||||
extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
|
||||
extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||
need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||
The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);
|
||||
|
||||
extern void cJSON_Minify(char *json);
|
||||
|
||||
/* Macros for creating things quickly. */
|
||||
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
|
||||
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
|
||||
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
|
||||
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
|
||||
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
|
||||
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
|
||||
|
||||
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||
#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
BIN
rk3308/aispeech-2mic/dds_client/demo/json/cJSON.o
Executable file
BIN
rk3308/aispeech-2mic/dds_client/demo/json/cJSON.o
Executable file
Binary file not shown.
461
rk3308/aispeech-2mic/dds_client/demo/main.c
Executable file
461
rk3308/aispeech-2mic/dds_client/demo/main.c
Executable file
@ -0,0 +1,461 @@
|
||||
/*================================================================
|
||||
* Copyright (C) 2018 AISPEECH Ltd. All rights reserved.
|
||||
*
|
||||
* 文件名称:main.c
|
||||
* 创 建 者:chenjie.gu
|
||||
* 创建日期:2018年05月16日
|
||||
* 描 述:
|
||||
*
|
||||
================================================================*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <sys/select.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include "dds_client.h"
|
||||
#include "button.h"
|
||||
#include "cJSON.h"
|
||||
#include <stdbool.h>
|
||||
int is_enable_wakeup = 1;
|
||||
struct dds_client *dc = NULL;
|
||||
bool m_is_dialog = false;
|
||||
bool m_is_tts_playing = false;
|
||||
pthread_mutex_t mylock=PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_cond_t mycond=PTHREAD_COND_INITIALIZER;
|
||||
extern int music_player_init(char *dev);
|
||||
extern int music_player_start();
|
||||
extern bool music_is_playing(void);
|
||||
extern void play_manager_f(const char *cmd, const char *data);
|
||||
void handle_doa_result(int doa);
|
||||
|
||||
#define WAIT_WAKEUP_SYSTEM_CMD "./aispeech_led -m on 4"
|
||||
#define RUNNING_ASR_SYSTEM_CMD "./aispeech_led -m scroll -b 4 2 -s 100"
|
||||
#define WAIT_DM_OUT_SYSTEM_CMD "./aispeech_led -m scroll -b 4 2 -s 100"
|
||||
#define RUNNING_TTS_SYSTEM_CMD "./aispeech_led -m on -b 2 2"
|
||||
#define DISABLE_WAKEUP_SYSTEM_CMD "./aispeech_led -m on -b 2 1"
|
||||
|
||||
void led_off() {
|
||||
printf("%s\n", __func__);
|
||||
system("./aispeech_led -m on 4");
|
||||
}
|
||||
void clean_silence_frame() {
|
||||
system("echo 0 > /sys/module/snd_soc_rockchip_vad/parameters/voice_inactive_frames");
|
||||
}
|
||||
void do_system_sleep() {
|
||||
system("echo mem > /sys/power/state");
|
||||
}
|
||||
/*
|
||||
* 1. volume.set
|
||||
* 2. play.list.update
|
||||
* 3. play.list.clear
|
||||
* 4. play.list.get
|
||||
* 5. status.set
|
||||
* 6. change.set
|
||||
* 7. mode.set
|
||||
* 8. play.choose.update
|
||||
* 9. play.collect.choose
|
||||
* 10. play.uncollect.choose
|
||||
* 11. player.end
|
||||
*/
|
||||
|
||||
void dds_cb(const char *topic, const char *topic_data, void *user) {
|
||||
static int end_dialog = 0;
|
||||
|
||||
printf("####### dds cb receive topic: %s\n", topic);
|
||||
printf("####### dds cb receive topic_data: %s\n", topic_data);
|
||||
|
||||
if (!strcmp(topic, "dm.output")) {
|
||||
cJSON *root = cJSON_Parse(topic_data);
|
||||
assert(root != NULL);
|
||||
|
||||
cJSON *dm = cJSON_GetObjectItem(root, "dm");
|
||||
cJSON *widget = cJSON_GetObjectItem(dm, "widget");
|
||||
if (widget) {
|
||||
cJSON *count = cJSON_GetObjectItem(widget, "count");
|
||||
if (count && count->valueint > 0) {
|
||||
char *out = cJSON_PrintUnformatted(widget);
|
||||
play_manager_f("play.list.update", out);
|
||||
free(out);
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *end_session = cJSON_GetObjectItem(dm, "shouldEndSession");
|
||||
if (end_session->valueint) {
|
||||
end_dialog = 1;
|
||||
}
|
||||
else end_dialog = 0;
|
||||
|
||||
system(WAIT_WAKEUP_SYSTEM_CMD);
|
||||
clean_silence_frame();
|
||||
m_is_dialog = false;
|
||||
printf("dm.output close dialog\n");
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
else if (!strcmp(topic, "doa.result")) {
|
||||
// doa 结果
|
||||
cJSON *root = cJSON_Parse(topic_data);
|
||||
assert(root != NULL);
|
||||
cJSON *doa = cJSON_GetObjectItem(root, "doa");
|
||||
handle_doa_result(doa->valueint);
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
|
||||
else if (!strcmp(topic, "command://spk.speaker.close")) {
|
||||
play_manager_f("play.list.clear", NULL);
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"APICommandResult\":\"success\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.single")) {
|
||||
play_manager_f("mode.set", "single");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"APICommandResult\":\"success\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.sequence")) {
|
||||
play_manager_f("mode.set", "sequence");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"APICommandResult\":\"success\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.random")) {
|
||||
play_manager_f("mode.set", "random");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"APICommandResult\":\"success\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.loop")) {
|
||||
play_manager_f("mode.set", "loop");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"APICommandResult\":\"success\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.pause")) {
|
||||
play_manager_f("status.set", "pause");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"APICommandResult\":\"success\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.continue")) {
|
||||
play_manager_f("status.set", "resume");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"APICommandResult\":\"success\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.stop")) {
|
||||
play_manager_f("play.list.clear", NULL);
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"APICommandResult\":\"success\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.replay")) {
|
||||
play_manager_f("status.set", "replay");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"APICommandResult\":\"success\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.prev")) {
|
||||
play_manager_f("change.set", "prev");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"count\":\"more\", \"skillName\":\"speakerChinaPlay\", \"title\":\"\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.next")) {
|
||||
play_manager_f("change.set", "next");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"count\":\"more\", \"skillName\":\"speakerChinaPlay\", \"title\":\"\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.change")) {
|
||||
play_manager_f("change.set", "change");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"count\":\"more\", \"skillName\":\"speakerChinaPlay\", \"title\":\"\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "command://spk.speaker.voice")) {
|
||||
cJSON *root = cJSON_Parse(topic_data);
|
||||
cJSON *voice = cJSON_GetObjectItem(root, "voice");
|
||||
if (voice) {
|
||||
play_manager_f("volume.set", voice->valuestring);
|
||||
}
|
||||
play_manager_f("status.set", "resume");
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
else if (!strcmp(topic, "native://alarm.set")) {
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"text\":\"已为您设置闹钟\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://alarm.list")) {
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"text\":\"您要查的闹钟不存在哦\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://alarm.delete")) {
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"text\":\"已为您删除闹钟\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://alarm.close")) {
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"text\":\"已为您关闭闹钟\"}}");
|
||||
}
|
||||
|
||||
else if (!strcmp(topic, "native://remind.set")) {
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"text\":\"已为您设置提醒\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://remind.list")) {
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"text\":\"暂时抄不到提醒哦\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://remind.delete")) {
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"text\":\"已为您删除提醒\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://remind.close")) {
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"text\":\"已为您关闭提醒\"}}");
|
||||
}
|
||||
|
||||
else if (!strcmp(topic, "local_wakeup.result")) {
|
||||
end_dialog = 0;
|
||||
play_manager_f("status.set", "pause");
|
||||
}
|
||||
else if (!strcmp(topic, "sys.dm.end")) {
|
||||
// 对话退出
|
||||
play_manager_f("play.list.check", NULL);
|
||||
system(WAIT_WAKEUP_SYSTEM_CMD);
|
||||
clean_silence_frame();
|
||||
m_is_dialog = false;
|
||||
if (!is_enable_wakeup) {
|
||||
system(DISABLE_WAKEUP_SYSTEM_CMD);
|
||||
}
|
||||
printf("sys.dm.end out \n");
|
||||
}
|
||||
else if (!strcmp(topic, "sys.tts.begin")) {
|
||||
clean_silence_frame();
|
||||
}
|
||||
else if (!strcmp(topic, "sys.tts.end")) {
|
||||
}
|
||||
else if (!strcmp(topic, "sys.vad.end")) {
|
||||
}
|
||||
else if (!strcmp(topic, "sys.asr.begin")) {
|
||||
//system(RUNNING_ASR_SYSTEM_CMD);
|
||||
clean_silence_frame();
|
||||
m_is_dialog = true;
|
||||
}
|
||||
else if (!strcmp(topic, "device.mode.return")) {
|
||||
pthread_cond_signal(&mycond);
|
||||
}
|
||||
}
|
||||
|
||||
void handle_doa_result(int doa) {
|
||||
printf("handle_doa_result doa is %d\n", doa);
|
||||
static char *doa_led_table[12] = {
|
||||
"./aispeech_led -m single -i 2 0",
|
||||
"./aispeech_led -m single -i 3 0",
|
||||
"./aispeech_led -m single -i 4 0",
|
||||
"./aispeech_led -m single -i 5 0",
|
||||
"./aispeech_led -m single -i 6 0",
|
||||
"./aispeech_led -m single -i 7 0",
|
||||
"./aispeech_led -m single -i 8 0",
|
||||
"./aispeech_led -m single -i 9 0",
|
||||
"./aispeech_led -m single -i 10 0",
|
||||
"./aispeech_led -m single -i 11 0",
|
||||
"./aispeech_led -m single -i 0 0",
|
||||
"./aispeech_led -m single -i 1 0"
|
||||
};
|
||||
|
||||
if (doa >= 0) {
|
||||
if (doa >=345 || doa < 15) {
|
||||
system(doa_led_table[0]);
|
||||
} else if (doa >= 15 && doa < 45) {
|
||||
system(doa_led_table[1]);
|
||||
} else if (doa >= 45 && doa < 75) {
|
||||
system(doa_led_table[2]);
|
||||
} else if (doa >= 75 && doa < 105) {
|
||||
system(doa_led_table[3]);
|
||||
} else if (doa >= 105 && doa < 135) {
|
||||
system(doa_led_table[4]);
|
||||
} else if (doa >= 135 && doa < 165) {
|
||||
system(doa_led_table[5]);
|
||||
} else if (doa >= 165 && doa < 195) {
|
||||
system(doa_led_table[6]);
|
||||
} else if (doa >= 195 && doa < 225) {
|
||||
system(doa_led_table[7]);
|
||||
} else if (doa >= 225 && doa < 255) {
|
||||
system(doa_led_table[8]);
|
||||
} else if (doa >= 255 && doa < 285) {
|
||||
system(doa_led_table[9]);
|
||||
} else if (doa >= 285 && doa < 315) {
|
||||
system(doa_led_table[10]);
|
||||
} else if (doa >= 315 && doa < 345) {
|
||||
system(doa_led_table[11]);
|
||||
}
|
||||
}
|
||||
else printf("=== doa result is wrong\n");
|
||||
}
|
||||
|
||||
|
||||
void button_cb(button_event_t ev, void *userdata) {
|
||||
const char *info[] = {
|
||||
"BUTTON_EVENT_VOLUME_ADD",
|
||||
"BUTTON_EVENT_VOLUME_SUB",
|
||||
"BUTTON_EVENT_PREV",
|
||||
"BUTTON_EVENT_NEXT",
|
||||
"BUTTON_EVENT_PLAY_PAUSE",
|
||||
"BUTTON_EVENT_PLAY_PAUSE_LONG",
|
||||
"BUTTON_EVENT_MUTE_UNMUTE",
|
||||
"BUTTON_EVENT_MUTE_UNMUTE_LONG",
|
||||
"BUTTON_EVENT_MODE_WIFI",
|
||||
"BUTTON_EVENT_MODE_NORMAL"
|
||||
};
|
||||
|
||||
printf("%s\n", info[ev]);
|
||||
|
||||
if (ev == BUTTON_EVENT_VOLUME_ADD) {
|
||||
//短按触发
|
||||
play_manager_f("volume.set", "+");
|
||||
}
|
||||
else if (ev == BUTTON_EVENT_VOLUME_SUB) {
|
||||
//短按触发
|
||||
play_manager_f("volume.set", "-");
|
||||
}
|
||||
else if (ev == BUTTON_EVENT_PREV) {
|
||||
//长按每隔1.5秒触发一次
|
||||
play_manager_f("change.set", "prev");
|
||||
play_manager_f("play.list.check", NULL);
|
||||
}
|
||||
else if (ev == BUTTON_EVENT_NEXT) {
|
||||
//长按每隔1.5秒触发一次
|
||||
play_manager_f("change.set", "next");
|
||||
play_manager_f("play.list.check", NULL);
|
||||
}
|
||||
else if (ev == BUTTON_EVENT_PLAY_PAUSE) {
|
||||
//短按触发
|
||||
play_manager_f("status.set", "step");
|
||||
} else if (ev == BUTTON_EVENT_MUTE_UNMUTE) {
|
||||
// mute
|
||||
if (is_enable_wakeup) {
|
||||
is_enable_wakeup = 0;
|
||||
dds_client_stop_dialog(dc);
|
||||
dds_client_disable_wakeup(dc);
|
||||
system(DISABLE_WAKEUP_SYSTEM_CMD);
|
||||
}
|
||||
else {
|
||||
is_enable_wakeup = 1;
|
||||
dds_client_enable_wakeup(dc);
|
||||
system(WAIT_WAKEUP_SYSTEM_CMD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void *button_routine(void *user) {
|
||||
button_config_t config = {
|
||||
.dev = "/dev/input/event0", // v11: event0 | v10: event1
|
||||
.cb = button_cb
|
||||
};
|
||||
button_handle_t button = button_create(&config);
|
||||
while (1) {
|
||||
button_run(button);
|
||||
}
|
||||
button_destroy(button);
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
const unsigned int voice_inactive_max_count = 16000 * 5; //16k, 3 seconds
|
||||
unsigned int read_voice_inactive_frames(void)
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[100];
|
||||
unsigned int frames = 0;
|
||||
|
||||
fp = popen("cat /sys/module/snd_soc_rockchip_vad/parameters/voice_inactive_frames", "r");
|
||||
if(!fp) {
|
||||
perror("popen");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
memset(buf, 0, sizeof(buf));
|
||||
if (fgets(buf, sizeof(buf) - 1, fp) != 0 ) {
|
||||
sscanf(buf, "%ul", &frames);
|
||||
//printf("%s frames %lu\n", buf, frames);
|
||||
}
|
||||
pclose(fp);
|
||||
return frames;
|
||||
}
|
||||
|
||||
bool sleep_check(void) {
|
||||
unsigned int inactive_frames = read_voice_inactive_frames();
|
||||
bool music_playing = music_is_playing();
|
||||
|
||||
printf("inactive frames %d, max %d, dialog %d, tts %d, music %d\n",
|
||||
inactive_frames, voice_inactive_max_count, m_is_dialog,
|
||||
m_is_tts_playing, music_playing);
|
||||
if (music_playing) {
|
||||
clean_silence_frame();
|
||||
}
|
||||
if ((inactive_frames > voice_inactive_max_count) \
|
||||
&& !m_is_dialog && !music_playing)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void wait_device_mode_timeout_ms(int microseconds)
|
||||
{
|
||||
struct timeval tv;
|
||||
long long absmsec;
|
||||
struct timespec abstime;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
absmsec = tv.tv_sec * 1000ll + tv.tv_usec / 1000ll;
|
||||
absmsec += microseconds;
|
||||
|
||||
abstime.tv_sec = absmsec / 1000ll;
|
||||
abstime.tv_nsec = absmsec % 1000ll * 1000000ll;
|
||||
|
||||
printf("#### public sleep mode ####");
|
||||
pthread_mutex_lock(&mylock);
|
||||
pthread_cond_timedwait(&mycond, &mylock, &abstime);
|
||||
pthread_mutex_unlock(&mylock);
|
||||
printf("#### return sleep mode succeed ####");
|
||||
}
|
||||
|
||||
void *vad_detect_func(void* arg) {
|
||||
clean_silence_frame();
|
||||
while(true) {
|
||||
if (sleep_check()) {
|
||||
fprintf(stderr,"voice inactive timeout,go to sleep\n");
|
||||
dds_client_publish(dc, DDS_CLIENT_USER_DEVICE_MODE, "{\"mode\":\"sleep\"}");
|
||||
wait_device_mode_timeout_ms(30);
|
||||
printf("pause >>>>\n");
|
||||
clean_silence_frame();
|
||||
do_system_sleep();
|
||||
printf("resume >>>>\n");
|
||||
dds_client_publish(dc, DDS_CLIENT_USER_DEVICE_MODE, "{\"mode\":\"normal\"}");
|
||||
}
|
||||
usleep(1000*1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main () {
|
||||
int ret;
|
||||
char config[1024 * 5];
|
||||
FILE *fp = NULL;
|
||||
fp = fopen("./config.json", "r");
|
||||
if (fp) {
|
||||
fread(config, 1, 1024 * 5, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
else return -1;
|
||||
|
||||
// 1. init music player
|
||||
cJSON *root = cJSON_Parse(config);
|
||||
cJSON *player = cJSON_GetObjectItem(root, "player");
|
||||
if (player) {
|
||||
player = cJSON_GetObjectItem(player, "device");
|
||||
if (player) music_player_init(player->valuestring);
|
||||
else music_player_init("default");
|
||||
}
|
||||
else music_player_init("default");
|
||||
|
||||
// 2. start the music player
|
||||
music_player_start();
|
||||
|
||||
// 3. run the dds client
|
||||
dc = dds_client_init(config);
|
||||
assert(dc != NULL);
|
||||
|
||||
ret = dds_client_start(dc, dds_cb, NULL);
|
||||
assert(ret != -1);
|
||||
|
||||
// 4. button thread
|
||||
pthread_t tid2;
|
||||
pthread_create(&tid2, NULL, button_routine, NULL);
|
||||
|
||||
// 5. system init
|
||||
system("amixer cset name='Master Playback Volume' 70");
|
||||
system("chmod +x aispeech_led");
|
||||
|
||||
|
||||
pthread_t softvad_detect;
|
||||
pthread_create(&softvad_detect,NULL,vad_detect_func,NULL);
|
||||
|
||||
led_off();//led init
|
||||
|
||||
select(0, 0, 0, 0, 0);
|
||||
|
||||
dds_client_release(dc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIN
rk3308/aispeech-2mic/dds_client/demo/main.o
Executable file
BIN
rk3308/aispeech-2mic/dds_client/demo/main.o
Executable file
Binary file not shown.
360
rk3308/aispeech-2mic/dds_client/demo/music.c
Executable file
360
rk3308/aispeech-2mic/dds_client/demo/music.c
Executable file
@ -0,0 +1,360 @@
|
||||
/*================================================================
|
||||
* Copyright (C) 2018 FREEDOM Ltd. All rights reserved.
|
||||
*
|
||||
* 文件名称:music.c
|
||||
* 创 建 者:chenjie.gu
|
||||
* 创建日期:2018年05月24日
|
||||
* 描 述:
|
||||
*
|
||||
================================================================*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "audio_player.h"
|
||||
#include <time.h>
|
||||
#include "cJSON.h"
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
audio_player_t *aplayer = NULL;
|
||||
float vol_multiplier = 0.4;
|
||||
int player_is_end = 0;
|
||||
pthread_mutex_t music_mutex;
|
||||
|
||||
int play_judge_f(int index, int count, int mode);
|
||||
void play_manager_f(const char *cmd, const char *data);
|
||||
|
||||
static int g_player_ev = AUDIO_PLAYER_EV_END;
|
||||
|
||||
bool music_is_playing(void) {
|
||||
if (g_player_ev == AUDIO_PLAYER_EV_END ||
|
||||
g_player_ev == AUDIO_PLAYER_EV_ERROR ||
|
||||
g_player_ev == AUDIO_PLAYER_EV_STOPPED)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
static int play_callback(void *userdata, int ev) {
|
||||
printf("++++++%s: ev %d\n", __func__, ev);
|
||||
if (ev == AUDIO_PLAYER_EV_END) {
|
||||
player_is_end = 1;
|
||||
}
|
||||
|
||||
g_player_ev = ev;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *player_routine(void *user) {
|
||||
while (1) {
|
||||
if (player_is_end) {
|
||||
player_is_end = 0;
|
||||
play_manager_f("player.end", NULL);
|
||||
}
|
||||
usleep(100 * 1000);
|
||||
}
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
int music_player_init(char *dev) {
|
||||
aplayer = audio_player_new(dev, play_callback, NULL);
|
||||
audio_player_set_channel_volume(aplayer, vol_multiplier);
|
||||
pthread_mutex_init(&music_mutex, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int music_player_play(char *path) {
|
||||
audio_player_play(aplayer, path);
|
||||
}
|
||||
|
||||
int music_player_start() {
|
||||
int ret;
|
||||
pthread_t tid;
|
||||
pthread_create(&tid, NULL, player_routine, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void play_manager_f(const char *cmd, const char *data) {
|
||||
|
||||
/*
|
||||
* 1. volume.set
|
||||
* 2. play.list.update
|
||||
* 3. play.list.clear
|
||||
* 4. play.list.get
|
||||
* 5. status.set
|
||||
* 6. change.set
|
||||
* 7. mode.set
|
||||
* 8. play.choose.update
|
||||
* 9. play.collect.choose
|
||||
* 10. play.uncollect.choose
|
||||
* 11. player.end
|
||||
*/
|
||||
|
||||
enum PLAY_MODE {
|
||||
sequence, random, single, loop
|
||||
};
|
||||
|
||||
enum PLAY_STATUS {
|
||||
idle, pause, playing
|
||||
};
|
||||
|
||||
static enum PLAY_MODE mode = sequence;
|
||||
static enum PLAY_STATUS status = idle;
|
||||
static int count = 0;
|
||||
static int index = 0;
|
||||
static int old_index = 0;
|
||||
static cJSON *root = NULL;
|
||||
|
||||
printf("play_manager_f cmd: %s\tdata: %s\n", cmd, data);
|
||||
|
||||
pthread_mutex_lock(&music_mutex);
|
||||
|
||||
if (!strcmp(cmd, "volume.set")) {
|
||||
// 设置音量
|
||||
if (!strcmp(data, "+")) {
|
||||
vol_multiplier += 0.05;
|
||||
if (vol_multiplier > 1.0) vol_multiplier = 0.99;
|
||||
audio_player_set_channel_volume(aplayer, vol_multiplier);
|
||||
|
||||
printf("set vol_multiplier to %f\n", vol_multiplier);
|
||||
printf("set vol to %d\n", (int)(vol_multiplier * 100.0));
|
||||
}
|
||||
|
||||
else if (!strcmp(data, "-")) {
|
||||
vol_multiplier -= 0.05;
|
||||
if (vol_multiplier < 0.01) vol_multiplier = 0.01;
|
||||
|
||||
audio_player_set_channel_volume(aplayer, vol_multiplier);
|
||||
printf("set vol_multiplier to %f\n", vol_multiplier);
|
||||
printf("set vol to %d\n", (int)(vol_multiplier * 100.0));
|
||||
}
|
||||
else {
|
||||
int vol = atoi(data);
|
||||
vol_multiplier = vol / 100.0;
|
||||
|
||||
audio_player_set_channel_volume(aplayer, vol_multiplier);
|
||||
printf("set vol_multiplier to %f\n", vol_multiplier);
|
||||
printf("set vol to %d\n", (int)(vol_multiplier * 100.0));
|
||||
}
|
||||
}
|
||||
|
||||
else if (!strcmp(cmd, "play.list.clear")) {
|
||||
// 清空播放列表
|
||||
printf("clear the play list info\n");
|
||||
audio_player_stop(aplayer);
|
||||
cJSON_Delete(root);
|
||||
root = NULL;
|
||||
index = 0;
|
||||
old_index = 0;
|
||||
count = 0;
|
||||
status = idle;
|
||||
}
|
||||
|
||||
else if (!strcmp(cmd, "play.list.get")) {
|
||||
}
|
||||
else if (!strcmp(cmd, "play.list.check")) {
|
||||
// 开始真正播放
|
||||
cJSON *temp, *music;
|
||||
if (root) {
|
||||
if (status == idle) {
|
||||
temp = cJSON_GetObjectItem(root, "count");
|
||||
count = temp->valueint;
|
||||
if (count > 0) {
|
||||
status = playing;
|
||||
music = cJSON_GetObjectItem(root, "content");
|
||||
temp = cJSON_GetArrayItem(music, index);
|
||||
temp = cJSON_GetObjectItem(temp, "linkUrl");
|
||||
printf("ready to play url is %s\n", temp->valuestring);
|
||||
audio_player_play(aplayer, temp->valuestring);
|
||||
}
|
||||
}
|
||||
else if (status == pause) {
|
||||
status = playing;
|
||||
audio_player_resume(aplayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(cmd, "play.list.update")) {
|
||||
// 更新播放列表
|
||||
// TODO: update
|
||||
printf("update the play list info\n");
|
||||
audio_player_stop(aplayer);
|
||||
if (root) cJSON_Delete(root);
|
||||
root = NULL;
|
||||
index = 0;
|
||||
old_index = 0;
|
||||
count = 0;
|
||||
status = idle;
|
||||
root = cJSON_Parse(data);
|
||||
}
|
||||
else if (!strcmp(cmd, "status.set")) {
|
||||
// 设置播放状态
|
||||
printf("status.set data is %s status is %d\n", data, status);
|
||||
if (!strcmp(data, "pause") && status == playing) {
|
||||
status = pause;
|
||||
audio_player_pause(aplayer);
|
||||
}
|
||||
else if (!strcmp(data, "resume") && status == pause) {
|
||||
status = playing;
|
||||
audio_player_resume(aplayer);
|
||||
}
|
||||
else if (!strcmp(data, "replay") && status == pause) {
|
||||
status = playing;
|
||||
|
||||
cJSON *temp, *music;
|
||||
music = cJSON_GetObjectItem(root, "content");
|
||||
temp = cJSON_GetArrayItem(music, index);
|
||||
temp = cJSON_GetObjectItem(temp, "linkUrl");
|
||||
printf("ready to play url is %s\n", temp->valuestring);
|
||||
audio_player_stop(aplayer);
|
||||
audio_player_play(aplayer, temp->valuestring);
|
||||
}
|
||||
else if (!strcmp(data, "step")) {
|
||||
if (status == playing) {
|
||||
status = pause;
|
||||
audio_player_pause(aplayer);
|
||||
}
|
||||
else if (status == pause) {
|
||||
status = playing;
|
||||
audio_player_resume(aplayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(cmd, "mode.set")) {
|
||||
// 播放模式
|
||||
if (!strcmp(data, "sequence")) mode = sequence;
|
||||
else if (!strcmp(data, "random")) mode = random;
|
||||
else if (!strcmp(data, "single")) mode = single;
|
||||
else if (!strcmp(data, "loop")) mode = loop;
|
||||
}
|
||||
else if (!strcmp(cmd, "change.set")) {
|
||||
// 歌曲切换
|
||||
// TODO: update
|
||||
if (!strcmp(data, "prev")) {
|
||||
// 上一首
|
||||
index = old_index;
|
||||
}
|
||||
else if (!strcmp(data, "next")) {
|
||||
// 下一首
|
||||
old_index = index;
|
||||
index = play_judge_f(index, count, mode);
|
||||
}
|
||||
else if (!strcmp(data, "change")) {
|
||||
// 换一首
|
||||
old_index = index;
|
||||
index = play_judge_f(index, count, mode);
|
||||
}
|
||||
|
||||
if (index == -1) {
|
||||
// 播放结束
|
||||
cJSON_Delete(root);
|
||||
audio_player_stop(aplayer);
|
||||
root = NULL;
|
||||
index = 0;
|
||||
old_index = 0;
|
||||
count = 0;
|
||||
status = idle;
|
||||
}
|
||||
else {
|
||||
// 待播放指定的音频
|
||||
status = idle;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(cmd, "play.choose.update")) {
|
||||
// 播放特定歌曲
|
||||
// TODO: update
|
||||
int find = 0;
|
||||
int i = 0;
|
||||
cJSON *temp = cJSON_Parse(data);
|
||||
temp = cJSON_GetObjectItem(temp, "linkUrl");
|
||||
|
||||
cJSON *music = cJSON_GetObjectItem(root, "content");
|
||||
cJSON *xx;
|
||||
for (i = 0; i < count; i++) {
|
||||
xx = cJSON_GetArrayItem(music, i);
|
||||
xx = cJSON_GetObjectItem(xx, "linkUrl");
|
||||
if (!strcmp(xx->valuestring, temp->valuestring)) {
|
||||
find = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (find) {
|
||||
old_index = index;
|
||||
index = i;
|
||||
printf("ready to play url is %s\n", temp->valuestring);
|
||||
audio_player_stop(aplayer);
|
||||
audio_player_play(aplayer, temp->valuestring);
|
||||
}
|
||||
else {
|
||||
// 播放歌曲不在播放列表里面
|
||||
printf("wwwwwwwwwwwwwwwwwwwwwwwwwww\n");
|
||||
}
|
||||
}
|
||||
else if (!strcmp(cmd, "play.collect.choose")) {
|
||||
// 收藏歌曲
|
||||
}
|
||||
|
||||
else if (!strcmp(cmd, "play.uncollect.choose")) {
|
||||
// 取消收藏
|
||||
}
|
||||
|
||||
else if (!strcmp(cmd, "player.end") && root) {
|
||||
// 播放器播放结束
|
||||
// TODO: update
|
||||
old_index = index;
|
||||
index = play_judge_f(index, count, mode);
|
||||
printf("play_judge_f index is %d\n", index);
|
||||
if (index == -1) {
|
||||
// 播放结束
|
||||
audio_player_stop(aplayer);
|
||||
cJSON_Delete(root);
|
||||
root = NULL;
|
||||
index = 0;
|
||||
old_index = 0;
|
||||
count = 0;
|
||||
status = idle;
|
||||
}
|
||||
else {
|
||||
// 播放指定的音频
|
||||
cJSON *temp, *music;
|
||||
music = cJSON_GetObjectItem(root, "content");
|
||||
temp = cJSON_GetArrayItem(music, index);
|
||||
temp = cJSON_GetObjectItem(temp, "linkUrl");
|
||||
printf("ready to play url is %s\n", temp->valuestring);
|
||||
audio_player_stop(aplayer);
|
||||
audio_player_play(aplayer, temp->valuestring);
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&music_mutex);
|
||||
}
|
||||
|
||||
int play_judge_f(int index, int count, int mode) {
|
||||
// sequence, random, single, loop
|
||||
if (mode == 0) {
|
||||
// 顺序播放
|
||||
if (index + 1 == count) return -1;
|
||||
else return index + 1;
|
||||
}
|
||||
else if (mode == 1) {
|
||||
// 随机播放
|
||||
srand(time(0));
|
||||
return rand() % count;
|
||||
}
|
||||
else if (mode == 2) {
|
||||
// 单曲循环
|
||||
return index;
|
||||
}
|
||||
else if (mode == 3) {
|
||||
// 循环播放
|
||||
return (index + 1) % count;
|
||||
}
|
||||
|
||||
else return -1;
|
||||
}
|
||||
|
||||
|
||||
BIN
rk3308/aispeech-2mic/dds_client/demo/music.o
Executable file
BIN
rk3308/aispeech-2mic/dds_client/demo/music.o
Executable file
Binary file not shown.
663
rk3308/aispeech-2mic/dds_client/doc/sdk帮助文档.md
Executable file
663
rk3308/aispeech-2mic/dds_client/doc/sdk帮助文档.md
Executable file
@ -0,0 +1,663 @@
|
||||
## linux-sdk 使用说明
|
||||
|
||||
### 接口说明
|
||||
|
||||
**sdk语音相关的接口**
|
||||
|
||||
```
|
||||
sdk 初始化函数,主要包括sdk参数初始化和授权两个过程,这个函数是阻塞的,
|
||||
授权的超时时间为 15 秒。
|
||||
|
||||
struct dds_client *dds_client_init (const char *config_json);
|
||||
|
||||
参数说明:
|
||||
|
||||
@ config_json: 配置选项,json 格式的字符串;
|
||||
|
||||
返回值:
|
||||
|
||||
错误情况下返回NULL, 否则返回 struct dds_client 实例指针;
|
||||
```
|
||||
```
|
||||
运行 sdk 函数,调用此函数之后就可以语音交互了。
|
||||
|
||||
int dds_client_start(struct dds_client *ds, ddsLintener cb,
|
||||
void *user);
|
||||
|
||||
参数说明:
|
||||
|
||||
@ ds: 由 dds_client_init 返回的 struct dds_client 实例指针;
|
||||
@ cb: 监听 sdk 事件的回调函数;
|
||||
@ user: 用户参数;
|
||||
|
||||
返回值:
|
||||
|
||||
出错返回 -1
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
释放 sdk 实例的函数:
|
||||
|
||||
void dds_client_release(struct dds_client *ds);
|
||||
|
||||
参数说明:
|
||||
|
||||
@ ds: 由 dds_client_init 返回的 struct dds_client 实例指针;
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
向 sdk 内部发送消息:
|
||||
|
||||
int dds_client_publish(struct dds_client *ds, int ev,
|
||||
const char *data);
|
||||
|
||||
参数说明:
|
||||
@ ds: 由 dds_client_init 返回的 struct dds_client 实例指针;
|
||||
@ ev: 发送的消息事件;
|
||||
@ data: 此消息附带的数据, json 格式;
|
||||
|
||||
|
||||
返回值:
|
||||
|
||||
只有当 sdk 完成初始化并且授权成功之后才能正确返回,否则返回 -1
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
返回 nativeAPI 查询结果的接口
|
||||
|
||||
int dds_client_resp_nativeapi(struct dds_client *ds,
|
||||
const char *native_api, const char *native_api_data_json);
|
||||
|
||||
参数说明:
|
||||
|
||||
ds: sdk 实例指针;
|
||||
|
||||
native_api: 这个 nativeAPI topic 名;
|
||||
|
||||
native_api_data_json: 查询数据结果,json string,格式如下,
|
||||
"duiWidget" 字段必须包含, 且目前取值为 "text"。 用户自定义的数据必须放在
|
||||
extra 字段中。
|
||||
|
||||
{
|
||||
"duiWidget": "text",
|
||||
"extra": {
|
||||
"xx": "11"
|
||||
}
|
||||
}
|
||||
|
||||
返回值: 如果 sdk 没有初始化完成或者授权成功则返回-1
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
内部合成的接口:
|
||||
|
||||
int dds_client_speak(struct dds_client *ds, const char *text);
|
||||
|
||||
参数说明:
|
||||
|
||||
ds: sdk 实例指针
|
||||
|
||||
text: 需要合成的文本
|
||||
|
||||
返回值: 如果 sdk 没有初始化完成或者授权成功则返回-1
|
||||
```
|
||||
|
||||
```
|
||||
外部 feed 音频接口:
|
||||
|
||||
int dds_client_feed_audio(struct dds_client *ds, char *data, int len);
|
||||
|
||||
参数说明:
|
||||
|
||||
ds: sdk 实例指针
|
||||
|
||||
data: 录音机数据
|
||||
|
||||
len: 数据长度
|
||||
|
||||
返回值: 出错返回 -1 ,此接口只有在 recorder 配置为外部方式才会生效。
|
||||
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
停止当前对话,包括停止合成,取消识别等。
|
||||
|
||||
int dds_client_stop_dialog(struct dds_client *ds);
|
||||
|
||||
参数说明:
|
||||
|
||||
ds: sdk 实例指针
|
||||
|
||||
text: 需要合成的文本
|
||||
|
||||
返回值: 如果 sdk 没有初始化完成或者授权成功则返回-1
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
关闭唤醒,此接口会终止当前的对话。
|
||||
|
||||
int dds_client_disable_wakeup(struct dds_client *ds);
|
||||
|
||||
参数说明:
|
||||
|
||||
ds: sdk 实例指针
|
||||
|
||||
返回值: 如果 sdk 没有初始化完成或者授权成功则返回-1
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
打开唤醒
|
||||
|
||||
int dds_client_enable_wakeup(struct dds_client *ds);
|
||||
|
||||
参数说明:
|
||||
|
||||
ds: sdk 实例指针
|
||||
|
||||
返回值: 如果 sdk 没有初始化完成或者授权成功则返回-1
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
// 获取当前的 tts 发音人,出错返回 NULL
|
||||
char *dds_client_get_speaker(struct dds_client *ds);
|
||||
|
||||
// 获取当前的 tts 播报速度,为 float 型, 在 0 ~ 1 之间,越大表示速度越慢。
|
||||
float dds_clent_get_speed(struct dds_client *ds);
|
||||
|
||||
// 获取当前的 tts 的播报音量大小, 为 int 型, 在 0 ~ 100 之间。
|
||||
int dds_client_get_volume(struct dds_client *ds);
|
||||
|
||||
// 设置当前的 tts 的播报音色人,出错返回 -1
|
||||
int dds_client_set_speaker(struct dds_client *ds, char *speaker);
|
||||
|
||||
// 设置当前的 tts 的播报速度大小,出错返回 -1
|
||||
int dds_client_set_speed(struct dds_client *ds, float speed);
|
||||
|
||||
// 设置当前的 tts 的播报音量大小,出错返回 -1
|
||||
int dds_client_set_volume(struct dds_client *ds, int vol);
|
||||
|
||||
```
|
||||
|
||||
|
||||
**sdk回调消息接口**
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>回调函数</th>
|
||||
<th>消息</th>
|
||||
<th>含义</th>
|
||||
<th>参数</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> local_wakeup.result </td>
|
||||
<td> 唤醒事件 </td>
|
||||
<td> json string,形如
|
||||
{"type":"major","greeting":"好的",
|
||||
"word":"你好小驰"} </td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> doa.result </td>
|
||||
<td> doa事件 </td>
|
||||
<td> json string, 形如 {"dao": 100} </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> sys.vad.begin </td>
|
||||
<td> vad开始的事件 </td>
|
||||
<td> 无 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> sys.vad.end </td>
|
||||
<td> vad结束的事件 </td>
|
||||
<td> 无 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> sys.tts.begin </td>
|
||||
<td> 合成音开始的事件 </td>
|
||||
<td> 无 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> sys.tts.end </td>
|
||||
<td> 合成音结束的事件,播放结束 </td>
|
||||
<td> 无 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> sys.asr.begin </td>
|
||||
<td> sdk内部开始做识别 </td>
|
||||
<td> 无 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> asr.speech.text </td>
|
||||
<td> 实时的语音识别结果反馈 </td>
|
||||
<td> json string </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> asr.speech.result </td>
|
||||
<td> 最终的语音识别结果反馈 </td>
|
||||
<td> json string </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> dm.output </td>
|
||||
<td> 对话的输出结果 </td>
|
||||
<td> json string </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> sys.dm.end </td>
|
||||
<td> 表示结束对话 </td>
|
||||
<td> 无 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> device.mode.return </td>
|
||||
<td> 表示设置设备状态的回复消息 </td>
|
||||
<td> json string "{"result":"success"}"</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> command://xx </td>
|
||||
<td> 在dui平台上配置的 command 指令 </td>
|
||||
<td> json string </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> native://xx </td>
|
||||
<td> 在dui平台上配置的 native 指令 </td>
|
||||
<td> json string </td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
### 配置选项
|
||||
|
||||
```
|
||||
|
||||
{
|
||||
"auth": {
|
||||
"productId": "278569448",
|
||||
"deviceProfile": ""
|
||||
},
|
||||
"front": {
|
||||
"aecBinPath": "",
|
||||
"wakeupBinPath": "",
|
||||
"beamformingBinPath": "",
|
||||
"rollBack": 0
|
||||
},
|
||||
"vad": {
|
||||
"resBinPath": "",
|
||||
"pauseTime": 500,
|
||||
"slienceTimeout": 5
|
||||
},
|
||||
"cloud": {
|
||||
"productId": "278569448",
|
||||
"aliasKey": "prod"
|
||||
},
|
||||
"recorder": {
|
||||
"mode": "internal"
|
||||
"samplerate":16000,
|
||||
"bits":16,
|
||||
"channels":1,
|
||||
"device": "default"
|
||||
},
|
||||
"player": {
|
||||
"device": "default"
|
||||
},
|
||||
"tts": {
|
||||
"type": "cloud",
|
||||
"voice": "zhilingf",
|
||||
"volume": 50,
|
||||
"speed": 0.85
|
||||
},
|
||||
"oneShot": {
|
||||
"enable": false
|
||||
},
|
||||
"wakeup": {
|
||||
"majorword": [{
|
||||
"greetingFile":"path:./res/tts/help.mp3",
|
||||
"greeting": "我在,有什么可以帮你",
|
||||
"pinyin": "ni hao xiao chi",
|
||||
"name": "你好小驰",
|
||||
"threshold": 0.127
|
||||
}, {
|
||||
"greetingFile":"path:./res/tts/help.mp3",
|
||||
"greeting": "我在,有什么可以帮你",
|
||||
"pinyin": "ni hao xiao le",
|
||||
"name": "你好小乐",
|
||||
"threshold": 0.144
|
||||
}],
|
||||
"cmdword": [{
|
||||
"pinyin": "jiang di yin liang",
|
||||
"threshold": 0.100,
|
||||
"action": "decrease.volume",
|
||||
"name": "降低音量"
|
||||
}]
|
||||
},
|
||||
"abnormal": {
|
||||
"netErrorHint":"path:../res/tts/net.mp3"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>参数</th>
|
||||
<th>类型</th>
|
||||
<th>含义</th>
|
||||
<th>是否必须</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> auth </td>
|
||||
<td> json 对象 </td>
|
||||
<td> 授权信息 </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> auth.productId </td>
|
||||
<td>string</td>
|
||||
<td> dui 上创建产品ID </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> auth.deviceProfile </td>
|
||||
<td>string</td>
|
||||
<td>授权信息</td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> front </td>
|
||||
<td>json 对象 </td>
|
||||
<td> 前端信号处理的相关配置 </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> front.aecBinPath </td>
|
||||
<td> string</td>
|
||||
<td>aec 算法资源路径</td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> front.wakeupBinPath </td>
|
||||
<td>string</td>
|
||||
<td>唤醒算法资源路径</td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> front.beamformingBinPath </td>
|
||||
<td>string</td>
|
||||
<td>beamforming 算法资源路径</td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> vad </td>
|
||||
<td> json 对象 </td>
|
||||
<td>vad 算法模块配置 </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> vad.resBinPath </td>
|
||||
<td>string</td>
|
||||
<td>vad算法资源路径 </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> vad.pauseTime </td>
|
||||
<td>int</td>
|
||||
<td>vad截止检测时长,单位为 ms,默认为 500ms </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> vad.slienceTimeout </td>
|
||||
<td>int</td>
|
||||
<td> vad 的静音检测超时时长,单位为s,默认为 6s </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> cloud </td>
|
||||
<td>json 对象 </td>
|
||||
<td>云端产品的相关配置 </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>cloud.productId </td>
|
||||
<td>string</td>
|
||||
<td>dui平台上创建的产品ID</td>
|
||||
<td>必选 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> cloud.aliasKey </td>
|
||||
<td>string</td>
|
||||
<td> dui平台上创建的产品ID 发布支持, 取值为 "prod | test"</td>
|
||||
<td>可选,默认为 prod 分支</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>recorder </td>
|
||||
<td>json 对象 </td>
|
||||
<td>录音机的相关配置 </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> recorder.mode </td>
|
||||
<td> string </td>
|
||||
<td> 录音方式,取值为 "internal | external" 分列表示内部录音和外部录音。 </td>
|
||||
<td> 可选 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> recorder.samplerate </td>
|
||||
<td> int </td>
|
||||
<td> 录音采样率 </td>
|
||||
<td> 必选 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> recorder.bits </td>
|
||||
<td>int</td>
|
||||
<td>录音采样位数</td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> recorder.channels </td>
|
||||
<td>int</td>
|
||||
<td>录音采用通道数</td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> recorder.device </td>
|
||||
<td> string </td>
|
||||
<td>内部录音机的设备名,默认当前系统的 default 音频设备 </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> player</td>
|
||||
<td> json 对象 </td>
|
||||
<td>内部播放器的设置 </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> player.device </td>
|
||||
<td> string </td>
|
||||
<td>内部播放器的设备名,默认为 default </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> tts </td>
|
||||
<td>json 对象</td>
|
||||
<td>合成音的相关配置</td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td> tts.type </td>
|
||||
<td>string </td>
|
||||
<td>合成音的类型,当前仅支持 "cloud" </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> tts.voice </td>
|
||||
<td>string </td>
|
||||
<td>合成音的音色 </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> tts.volume </td>
|
||||
<td> int </td>
|
||||
<td>合成音的音量 </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> tts.speed </td>
|
||||
<td> int </td>
|
||||
<td>合成音的速度 </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> oneShot </td>
|
||||
<td> json 对象 </td>
|
||||
<td> oneshot 模块配置 </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> oneShot.enable </td>
|
||||
<td> bool </td>
|
||||
<td> 是否启用oneshot,当前仅支持 false </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> wakeup </td>
|
||||
<td> json 对象 </td>
|
||||
<td> 唤醒词的相关配置</td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> wakeup.majorword </td>
|
||||
<td> json 数组 </td>
|
||||
<td> 唤醒词的相关配置</td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> wakeup.cmdword </td>
|
||||
<td> json 数组 </td>
|
||||
<td> 快捷唤醒词配置 </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> abnormal </td>
|
||||
<td> json 对象 </td>
|
||||
<td> sdk异常情况下对话配置 </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> abnormal.netErrorHint </td>
|
||||
<td> string </td>
|
||||
<td> 网络错误下的提示音,需要配置成本地文件,网络不好的情况下云端合成也用不了。 </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
**唤醒词说明**
|
||||
|
||||
```
|
||||
{
|
||||
"greetingFile":"path:./res/tts/help.mp3",
|
||||
"greeting": "我在,有什么可以帮你",
|
||||
"pinyin": "ni hao xiao chi",
|
||||
"name": "你好小驰",
|
||||
"threshold": 0.127
|
||||
}
|
||||
|
||||
|
||||
greetingFile: 唤醒之后播放的提示音,支持本地录音文件,传入文件路径。
|
||||
greeting: 唤醒之后的提示文本, sdk内部合成。
|
||||
pinyin: 唤醒词拼音。
|
||||
name: 唤醒词的中文。
|
||||
threshold: 唤醒词阈值。
|
||||
|
||||
唤醒提示音播放优先级: 如果配置了 greetingFile 则播放 greetingFile ,
|
||||
否则播放 greeting 。
|
||||
|
||||
```
|
||||
|
||||
|
||||
**命令唤醒词说明**
|
||||
|
||||
```
|
||||
{
|
||||
"pinyin": "jiang di yin liang",
|
||||
"threshold": 0.100,
|
||||
"action": "decrease.volume",
|
||||
"name": "降低音量"
|
||||
}
|
||||
|
||||
pinyin: 唤醒词拼音。
|
||||
name: 唤醒词的中文。
|
||||
threshold: 唤醒词阈值。
|
||||
action: 该命令唤醒词对应的动作,比如这个例子中,sdk回调函数会抛出
|
||||
command://decrease.volume 消息。
|
||||
```
|
||||
BIN
rk3308/aispeech-2mic/dds_client/doc/sdk帮助文档.pdf
Executable file
BIN
rk3308/aispeech-2mic/dds_client/doc/sdk帮助文档.pdf
Executable file
Binary file not shown.
BIN
rk3308/aispeech-2mic/dds_client/libdds_client.so
Executable file
BIN
rk3308/aispeech-2mic/dds_client/libdds_client.so
Executable file
Binary file not shown.
BIN
rk3308/aispeech-2mic/dds_client/libs/libaudio_play.so
Executable file
BIN
rk3308/aispeech-2mic/dds_client/libs/libaudio_play.so
Executable file
Binary file not shown.
BIN
rk3308/aispeech-2mic/dds_client/libs/libauth.so
Executable file
BIN
rk3308/aispeech-2mic/dds_client/libs/libauth.so
Executable file
Binary file not shown.
BIN
rk3308/aispeech-2mic/dds_client/libs/libdds.so
Executable file
BIN
rk3308/aispeech-2mic/dds_client/libs/libdds.so
Executable file
Binary file not shown.
BIN
rk3308/aispeech-2mic/dds_client/libs/libduilite_fespl.so
Executable file
BIN
rk3308/aispeech-2mic/dds_client/libs/libduilite_fespl.so
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
rk3308/aispeech-2mic/dds_client/res/tts/help.mp3
Executable file
BIN
rk3308/aispeech-2mic/dds_client/res/tts/help.mp3
Executable file
Binary file not shown.
BIN
rk3308/aispeech-2mic/dds_client/res/tts/net.mp3
Executable file
BIN
rk3308/aispeech-2mic/dds_client/res/tts/net.mp3
Executable file
Binary file not shown.
BIN
rk3308/aispeech-2mic/dds_client/res/vad/vad_aihome_v0.6.bin
Executable file
BIN
rk3308/aispeech-2mic/dds_client/res/vad/vad_aihome_v0.6.bin
Executable file
Binary file not shown.
BIN
rk3308/aispeech-2mic/dds_client/res/wakeup/wakeup_aifar_comm_20180104.bin
Executable file
BIN
rk3308/aispeech-2mic/dds_client/res/wakeup/wakeup_aifar_comm_20180104.bin
Executable file
Binary file not shown.
23
rk3308/aispeech-2mic/dds_service.sh
Executable file
23
rk3308/aispeech-2mic/dds_service.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
#
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo "Starting $0..."
|
||||
cd /oem/dds_client/demo && ./demo_main &
|
||||
;;
|
||||
stop)
|
||||
echo "Stop $0..."
|
||||
killall demo_main
|
||||
;;
|
||||
restart|reload)
|
||||
killall demo_main
|
||||
cd /oem/dds_client/demo && ./demo_main &
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart}"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
exit $?
|
||||
93
rk3308/aispeech-2mic/wifi_monitor.sh
Executable file
93
rk3308/aispeech-2mic/wifi_monitor.sh
Executable file
@ -0,0 +1,93 @@
|
||||
#!/bin/sh
|
||||
|
||||
PROCESS=/data/dds_service.sh
|
||||
|
||||
softap_stop()
|
||||
{
|
||||
echo softap_stoping
|
||||
|
||||
killall dnsmasq || echo dnsmasq-exit
|
||||
ip addr delete 192.168.1.1 dev wlan1 || echo ip-addr-delete
|
||||
killall hostapd || echo hostapd-exit
|
||||
ifconfig wlan1 down || echo wlan1-down
|
||||
|
||||
echo softap_stopped
|
||||
}
|
||||
|
||||
dds_start()
|
||||
{
|
||||
softap_stop
|
||||
#echo dds_start
|
||||
pidof demo_main || $PROCESS start
|
||||
|
||||
gst-play-1.0 /data/aispeech_softap_lite/audio/connect_ok.mp3
|
||||
}
|
||||
|
||||
dds_stop()
|
||||
{
|
||||
echo dds_stop
|
||||
#$PROCESS stop
|
||||
}
|
||||
wifiReadyAction()
|
||||
{
|
||||
pidof demo_main || $PROCESS start
|
||||
}
|
||||
wifiUpAction()
|
||||
{
|
||||
echo wifiUp
|
||||
dds_start
|
||||
}
|
||||
wifiDownAction()
|
||||
{
|
||||
echo wifiDown
|
||||
dds_stop
|
||||
}
|
||||
wifiChangeAction()
|
||||
{
|
||||
echo wifiChange
|
||||
dds_stop
|
||||
dds_start
|
||||
}
|
||||
wifiRequestingIp()
|
||||
{
|
||||
echo wifiRequestingIp
|
||||
}
|
||||
|
||||
checkwifistate()
|
||||
{
|
||||
local flag=0
|
||||
local last_ip_address=0
|
||||
while true
|
||||
do
|
||||
wpa_state=`wpa_cli -iwlan0 status | grep wpa_state | awk -F '=' '{printf $2}'`
|
||||
ip_address=`wpa_cli -iwlan0 status | grep ip_address | awk -F '=' '{printf $2}'`
|
||||
|
||||
if [ "${wpa_state}"x = "COMPLETED"x ];then
|
||||
if [ "${ip_address}"x != ""x ] && [ "${ip_address}"x != "0.0.0.0"x ];then
|
||||
if [ $flag -eq 0 ];then
|
||||
flag=1
|
||||
wifiUpAction
|
||||
elif [ "${ip_address}"x != "${last_ip_address}"x ];then
|
||||
flag=1
|
||||
wifiChangeAction
|
||||
else
|
||||
flag=1
|
||||
wifiReadyAction
|
||||
fi
|
||||
else
|
||||
flag=0
|
||||
wifiRequestingIp
|
||||
fi
|
||||
else
|
||||
if [ $flag -eq 1 ];then
|
||||
flag=0
|
||||
wifiDownAction
|
||||
fi
|
||||
fi
|
||||
sleep 3
|
||||
last_ip_address="${ip_address}"
|
||||
done
|
||||
}
|
||||
|
||||
$PROCESS stop
|
||||
checkwifistate
|
||||
245
rk3308/unixbench-master_32/.cproject
Executable file
245
rk3308/unixbench-master_32/.cproject
Executable file
@ -0,0 +1,245 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?>
|
||||
|
||||
<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.1112988852">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1112988852" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="UnixBench" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1112988852" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug">
|
||||
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1112988852." name="/" resourcePath="">
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.1265656843" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
|
||||
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.724460794" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
|
||||
<builder buildPath="${workspace_loc:/UnixBench/Debug}" id="cdt.managedbuild.target.gnu.builder.exe.debug.1915020561" managedBuildOn="true" name="Gnu Make Builder.Debug" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.237653783" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.292688199" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1386988579" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.2099186456" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.1624622538" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
|
||||
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.2086155431" superClass="gnu.c.compiler.exe.debug.option.optimization.level" valueType="enumerated"/>
|
||||
<option id="gnu.c.compiler.exe.debug.option.debugging.level.1302569694" superClass="gnu.c.compiler.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.623082859" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.744081279" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.1447287939" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug"/>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.187171772">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.187171772" moduleId="org.eclipse.cdt.core.settings" name="Release">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="UnixBench" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.187171772" name="Release" parent="cdt.managedbuild.config.gnu.exe.release">
|
||||
<folderInfo id="cdt.managedbuild.config.gnu.exe.release.187171772." name="/" resourcePath="">
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.804230130" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
|
||||
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.1333474325" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
|
||||
<builder buildPath="${workspace_loc:/UnixBench/Release}" id="cdt.managedbuild.target.gnu.builder.exe.release.334311293" managedBuildOn="true" name="Gnu Make Builder.Release" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.748606689" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1158097705" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
|
||||
<option id="gnu.cpp.compiler.exe.release.option.optimization.level.114803414" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.exe.release.option.debugging.level.1266303819" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.50008527" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release">
|
||||
<option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.1611735628" superClass="gnu.c.compiler.exe.release.option.optimization.level" valueType="enumerated"/>
|
||||
<option id="gnu.c.compiler.exe.release.option.debugging.level.1010649020" superClass="gnu.c.compiler.exe.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.1604769908" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.1185527108" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.211377571" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release"/>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
</storageModule>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="UnixBench.cdt.managedbuild.target.gnu.exe.570459259" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
|
||||
</storageModule>
|
||||
</cproject>
|
||||
82
rk3308/unixbench-master_32/.project
Executable file
82
rk3308/unixbench-master_32/.project
Executable file
@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>UnixBench</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>?name?</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.append_environment</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildArguments</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildLocation</key>
|
||||
<value>${workspace_loc:/UnixBench/Debug}</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
|
||||
<value>clean</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.contents</key>
|
||||
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
|
||||
<value>false</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.stopOnError</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
0
rk3308/unixbench-master_32/.stamp_built
Executable file
0
rk3308/unixbench-master_32/.stamp_built
Executable file
0
rk3308/unixbench-master_32/.stamp_configured
Executable file
0
rk3308/unixbench-master_32/.stamp_configured
Executable file
0
rk3308/unixbench-master_32/.stamp_rsynced
Executable file
0
rk3308/unixbench-master_32/.stamp_rsynced
Executable file
0
rk3308/unixbench-master_32/.stamp_target_installed
Executable file
0
rk3308/unixbench-master_32/.stamp_target_installed
Executable file
304
rk3308/unixbench-master_32/Makefile
Executable file
304
rk3308/unixbench-master_32/Makefile
Executable file
@ -0,0 +1,304 @@
|
||||
##############################################################################
|
||||
# UnixBench v5.1.3
|
||||
# Based on The BYTE UNIX Benchmarks - Release 3
|
||||
# Module: Makefile SID: 3.9 5/15/91 19:30:15
|
||||
#
|
||||
##############################################################################
|
||||
# Bug reports, patches, comments, suggestions should be sent to:
|
||||
# David C Niemi <niemi@tux.org>
|
||||
#
|
||||
# Original Contacts at Byte Magazine:
|
||||
# Ben Smith or Tom Yager at BYTE Magazine
|
||||
# bensmith@bytepb.byte.com tyager@bytepb.byte.com
|
||||
#
|
||||
##############################################################################
|
||||
# Modification Log: 7/28/89 cleaned out workload files
|
||||
# 4/17/90 added routines for installing from shar mess
|
||||
# 7/23/90 added compile for dhrystone version 2.1
|
||||
# (this is not part of Run file. still use old)
|
||||
# removed HZ from everything but dhry.
|
||||
# HZ is read from the environment, if not
|
||||
# there, you must define it in this file
|
||||
# 10/30/90 moved new dhrystone into standard set
|
||||
# new pgms (dhry included) run for a specified
|
||||
# time rather than specified number of loops
|
||||
# 4/5/91 cleaned out files not needed for
|
||||
# release 3 -- added release 3 files -ben
|
||||
# 10/22/97 added compiler options for strict ANSI C
|
||||
# checking for gcc and DEC's cc on
|
||||
# Digital Unix 4.x (kahn@zk3.dec.com)
|
||||
# 09/26/07 changes for UnixBench 5.0
|
||||
# 09/30/07 adding ubgears, GRAPHIC_TESTS switch
|
||||
# 10/14/07 adding large.txt
|
||||
# 01/13/11 added support for parallel compilation
|
||||
# 01/07/16 [refer to version control commit messages and
|
||||
# cease using two-digit years in date formats]
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# CONFIGURATION
|
||||
##############################################################################
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
# GRAPHIC TESTS: Uncomment the definition of "GRAPHIC_TESTS" to enable
|
||||
# the building of the graphics benchmarks. This will require the
|
||||
# X11 libraries on your system. (e.g. libX11-devel mesa-libGL-devel)
|
||||
#
|
||||
# Comment the line out to disable these tests.
|
||||
# GRAPHIC_TESTS = defined
|
||||
|
||||
# Set "GL_LIBS" to the libraries needed to link a GL program.
|
||||
GL_LIBS = -lGL -lXext -lX11
|
||||
|
||||
|
||||
# COMPILER CONFIGURATION: Set "CC" to the name of the compiler to use
|
||||
# to build the binary benchmarks. You should also set "$cCompiler" in the
|
||||
# Run script to the name of the compiler you want to test.
|
||||
CC=gcc
|
||||
|
||||
# OPTIMISATION SETTINGS:
|
||||
# Use gcc option if defined UB_GCC_OPTIONS via "Environment variable" or "Command-line arguments".
|
||||
ifdef UB_GCC_OPTIONS
|
||||
OPTON = $(UB_GCC_OPTIONS)
|
||||
|
||||
else
|
||||
## Very generic
|
||||
#OPTON = -O
|
||||
|
||||
## For Linux 486/Pentium, GCC 2.7.x and 2.8.x
|
||||
#OPTON = -O2 -fomit-frame-pointer -fforce-addr -fforce-mem -ffast-math \
|
||||
# -m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2
|
||||
|
||||
## For Linux, GCC previous to 2.7.0
|
||||
#OPTON = -O2 -fomit-frame-pointer -fforce-addr -fforce-mem -ffast-math -m486
|
||||
|
||||
#OPTON = -O2 -fomit-frame-pointer -fforce-addr -fforce-mem -ffast-math \
|
||||
# -m386 -malign-loops=1 -malign-jumps=1 -malign-functions=1
|
||||
|
||||
## For Solaris 2, or general-purpose GCC 2.7.x
|
||||
#OPTON = -O2 -fomit-frame-pointer -fforce-addr -ffast-math -Wall
|
||||
|
||||
## For Digital Unix v4.x, with DEC cc v5.x
|
||||
#OPTON = -O4
|
||||
#CFLAGS = -DTIME -std1 -verbose -w0
|
||||
|
||||
## gcc optimization flags
|
||||
## (-ffast-math) disables strict IEEE or ISO rules/specifications for math funcs
|
||||
OPTON = -O3 -ffast-math
|
||||
|
||||
## OS detection. Comment out if gmake syntax not supported by other 'make'.
|
||||
OSNAME:=$(shell uname -s)
|
||||
ARCH := $(shell uname -p)
|
||||
ifeq ($(OSNAME),Linux)
|
||||
# Not all CPU architectures support "-march" or "-march=native".
|
||||
# - Supported : x86, x86_64, ARM, AARCH64, etc..
|
||||
# - Not Supported: RISC-V, IBM Power, etc...
|
||||
ifneq ($(ARCH),$(filter $(ARCH),ppc64 ppc64le))
|
||||
OPTON += -march=native -mtune=native
|
||||
else
|
||||
OPTON += -mcpu=native -mtune=native
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OSNAME),Darwin)
|
||||
# (adjust flags or comment out this section for older versions of XCode or OS X)
|
||||
# (-mmacosx-versin-min= requires at least that version of SDK be installed)
|
||||
ifneq ($(ARCH),$(filter $(ARCH),ppc64 ppc64le))
|
||||
OPTON += -march=native -mmacosx-version-min=10.10
|
||||
else
|
||||
OPTON += -mcpu=native
|
||||
endif
|
||||
#http://stackoverflow.com/questions/9840207/how-to-use-avx-pclmulqdq-on-mac-os-x-lion/19342603#19342603
|
||||
CFLAGS += -Wa,-q
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
|
||||
## generic gcc CFLAGS. -DTIME must be included.
|
||||
CFLAGS += -Wall -pedantic $(OPTON) -I $(SRCDIR) -DTIME
|
||||
|
||||
|
||||
##############################################################################
|
||||
# END CONFIGURATION
|
||||
##############################################################################
|
||||
|
||||
|
||||
# local directories
|
||||
PROGDIR = ./pgms
|
||||
SRCDIR = ./src
|
||||
TESTDIR = ./testdir
|
||||
RESULTDIR = ./results
|
||||
TMPDIR = ./tmp
|
||||
# other directories
|
||||
INCLDIR = /usr/include
|
||||
LIBDIR = /lib
|
||||
SCRIPTS = unixbench.logo multi.sh tst.sh index.base
|
||||
SOURCES = arith.c big.c context1.c \
|
||||
dummy.c execl.c \
|
||||
fstime.c hanoi.c \
|
||||
pipe.c spawn.c \
|
||||
syscall.c looper.c timeit.c time-polling.c \
|
||||
dhry_1.c dhry_2.c dhry.h whets.c ubgears.c
|
||||
TESTS = sort.src cctest.c dc.dat large.txt
|
||||
|
||||
ifneq (,$(GRAPHIC_TESTS))
|
||||
GRAPHIC_BINS = $(PROGDIR)/ubgears
|
||||
else
|
||||
GRAPHIC_BINS =
|
||||
endif
|
||||
|
||||
# Program binaries.
|
||||
BINS = $(PROGDIR)/arithoh $(PROGDIR)/register $(PROGDIR)/short \
|
||||
$(PROGDIR)/int $(PROGDIR)/long $(PROGDIR)/float $(PROGDIR)/double \
|
||||
$(PROGDIR)/hanoi $(PROGDIR)/syscall $(PROGDIR)/context1 \
|
||||
$(PROGDIR)/pipe $(PROGDIR)/spawn $(PROGDIR)/execl \
|
||||
$(PROGDIR)/dhry2 $(PROGDIR)/dhry2reg $(PROGDIR)/looper \
|
||||
$(PROGDIR)/fstime $(PROGDIR)/whetstone-double $(GRAPHIC_BINS)
|
||||
## These compile only on some platforms...
|
||||
# $(PROGDIR)/poll $(PROGDIR)/poll2 $(PROGDIR)/select
|
||||
|
||||
# Required non-binary files.
|
||||
REQD = $(BINS) $(PROGDIR)/unixbench.logo \
|
||||
$(PROGDIR)/multi.sh $(PROGDIR)/tst.sh $(PROGDIR)/index.base \
|
||||
$(PROGDIR)/gfx-x11 \
|
||||
$(TESTDIR)/sort.src $(TESTDIR)/cctest.c $(TESTDIR)/dc.dat \
|
||||
$(TESTDIR)/large.txt
|
||||
|
||||
# ######################### the big ALL ############################
|
||||
all:
|
||||
## Ick!!! What is this about??? How about let's not chmod everything bogusly.
|
||||
# @chmod 744 * $(SRCDIR)/* $(PROGDIR)/* $(TESTDIR)/* $(DOCDIR)/*
|
||||
$(MAKE) distr
|
||||
$(MAKE) programs
|
||||
|
||||
# ####################### a check for Run ######################
|
||||
check: $(REQD)
|
||||
$(MAKE) all
|
||||
# ##############################################################
|
||||
# distribute the files out to subdirectories if they are in this one
|
||||
distr:
|
||||
@echo "Checking distribution of files"
|
||||
# scripts
|
||||
@if test ! -d $(PROGDIR) \
|
||||
; then \
|
||||
mkdir $(PROGDIR) \
|
||||
; mv $(SCRIPTS) $(PROGDIR) \
|
||||
; else \
|
||||
echo "$(PROGDIR) exists" \
|
||||
; fi
|
||||
# C sources
|
||||
@if test ! -d $(SRCDIR) \
|
||||
; then \
|
||||
mkdir $(SRCDIR) \
|
||||
; mv $(SOURCES) $(SRCDIR) \
|
||||
; else \
|
||||
echo "$(SRCDIR) exists" \
|
||||
; fi
|
||||
# test data
|
||||
@if test ! -d $(TESTDIR) \
|
||||
; then \
|
||||
mkdir $(TESTDIR) \
|
||||
; mv $(TESTS) $(TESTDIR) \
|
||||
; else \
|
||||
echo "$(TESTDIR) exists" \
|
||||
; fi
|
||||
# temporary work directory
|
||||
@if test ! -d $(TMPDIR) \
|
||||
; then \
|
||||
mkdir $(TMPDIR) \
|
||||
; else \
|
||||
echo "$(TMPDIR) exists" \
|
||||
; fi
|
||||
# directory for results
|
||||
@if test ! -d $(RESULTDIR) \
|
||||
; then \
|
||||
mkdir $(RESULTDIR) \
|
||||
; else \
|
||||
echo "$(RESULTDIR) exists" \
|
||||
; fi
|
||||
|
||||
.PHONY: all check distr programs run clean spotless
|
||||
|
||||
programs: $(BINS)
|
||||
|
||||
# (use $< to link only the first dependency, instead of $^,
|
||||
# since the programs matching this pattern have only
|
||||
# one input file, and others are #include "xxx.c"
|
||||
# within the first. (not condoning, just documenting))
|
||||
# (dependencies could be generated by modern compilers,
|
||||
# but let's not assume modern compilers are present)
|
||||
$(PROGDIR)/%:
|
||||
$(CC) -o $@ $(CFLAGS) $< $(LDFLAGS)
|
||||
|
||||
# Individual programs
|
||||
# Sometimes the same source file is compiled in different ways.
|
||||
# This limits the 'make' patterns that can usefully be applied.
|
||||
|
||||
$(PROGDIR)/arithoh: $(SRCDIR)/arith.c $(SRCDIR)/timeit.c
|
||||
$(PROGDIR)/arithoh: CFLAGS += -Darithoh
|
||||
$(PROGDIR)/register: $(SRCDIR)/arith.c $(SRCDIR)/timeit.c
|
||||
$(PROGDIR)/register: CFLAGS += -Ddatum='register int'
|
||||
$(PROGDIR)/short: $(SRCDIR)/arith.c $(SRCDIR)/timeit.c
|
||||
$(PROGDIR)/short: CFLAGS += -Ddatum=short
|
||||
$(PROGDIR)/int: $(SRCDIR)/arith.c $(SRCDIR)/timeit.c
|
||||
$(PROGDIR)/int: CFLAGS += -Ddatum=int
|
||||
$(PROGDIR)/long: $(SRCDIR)/arith.c $(SRCDIR)/timeit.c
|
||||
$(PROGDIR)/long: CFLAGS += -Ddatum=long
|
||||
$(PROGDIR)/float: $(SRCDIR)/arith.c $(SRCDIR)/timeit.c
|
||||
$(PROGDIR)/float: CFLAGS += -Ddatum=float
|
||||
$(PROGDIR)/double: $(SRCDIR)/arith.c $(SRCDIR)/timeit.c
|
||||
$(PROGDIR)/double: CFLAGS += -Ddatum=double
|
||||
|
||||
$(PROGDIR)/poll: $(SRCDIR)/time-polling.c
|
||||
$(PROGDIR)/poll: CFLAGS += -DUNIXBENCH -DHAS_POLL
|
||||
$(PROGDIR)/poll2: $(SRCDIR)/time-polling.c
|
||||
$(PROGDIR)/poll2: CFLAGS += -DUNIXBENCH -DHAS_POLL2
|
||||
$(PROGDIR)/select: $(SRCDIR)/time-polling.c
|
||||
$(PROGDIR)/select: CFLAGS += -DUNIXBENCH -DHAS_SELECT
|
||||
|
||||
$(PROGDIR)/whetstone-double: $(SRCDIR)/whets.c
|
||||
$(PROGDIR)/whetstone-double: CFLAGS += -DDP -DGTODay -DUNIXBENCH
|
||||
$(PROGDIR)/whetstone-double: LDFLAGS += -lm
|
||||
|
||||
$(PROGDIR)/pipe: $(SRCDIR)/pipe.c $(SRCDIR)/timeit.c
|
||||
|
||||
$(PROGDIR)/execl: $(SRCDIR)/execl.c $(SRCDIR)/big.c
|
||||
|
||||
$(PROGDIR)/spawn: $(SRCDIR)/spawn.c $(SRCDIR)/timeit.c
|
||||
|
||||
$(PROGDIR)/hanoi: $(SRCDIR)/hanoi.c $(SRCDIR)/timeit.c
|
||||
|
||||
$(PROGDIR)/fstime: $(SRCDIR)/fstime.c
|
||||
|
||||
$(PROGDIR)/syscall: $(SRCDIR)/syscall.c $(SRCDIR)/timeit.c
|
||||
|
||||
$(PROGDIR)/context1: $(SRCDIR)/context1.c $(SRCDIR)/timeit.c
|
||||
|
||||
$(PROGDIR)/looper: $(SRCDIR)/looper.c $(SRCDIR)/timeit.c
|
||||
|
||||
$(PROGDIR)/ubgears: $(SRCDIR)/ubgears.c
|
||||
$(PROGDIR)/ubgears: LDFLAGS += -lm $(GL_LIBS)
|
||||
|
||||
$(PROGDIR)/dhry2: CFLAGS += -DHZ=${HZ}
|
||||
$(PROGDIR)/dhry2: $(SRCDIR)/dhry_1.c $(SRCDIR)/dhry_2.c \
|
||||
$(SRCDIR)/dhry.h $(SRCDIR)/timeit.c
|
||||
$(CC) -o $@ ${CFLAGS} $(SRCDIR)/dhry_1.c $(SRCDIR)/dhry_2.c
|
||||
|
||||
$(PROGDIR)/dhry2reg: CFLAGS += -DHZ=${HZ} -DREG=register
|
||||
$(PROGDIR)/dhry2reg: $(SRCDIR)/dhry_1.c $(SRCDIR)/dhry_2.c \
|
||||
$(SRCDIR)/dhry.h $(SRCDIR)/timeit.c
|
||||
$(CC) -o $@ ${CFLAGS} $(SRCDIR)/dhry_1.c $(SRCDIR)/dhry_2.c
|
||||
|
||||
# Run the benchmarks and create the reports
|
||||
run:
|
||||
sh ./Run
|
||||
|
||||
clean:
|
||||
$(RM) $(BINS) core *~ */*~
|
||||
|
||||
spotless: clean
|
||||
$(RM) $(RESULTDIR)/* $(TMPDIR)/*
|
||||
|
||||
## END ##
|
||||
418
rk3308/unixbench-master_32/README
Executable file
418
rk3308/unixbench-master_32/README
Executable file
@ -0,0 +1,418 @@
|
||||
Version 5.1.3 -- 2011-01-13
|
||||
|
||||
================================================================
|
||||
To use Unixbench:
|
||||
|
||||
1. UnixBench from version 5.1 on has both system and graphics tests.
|
||||
If you want to use the graphic tests, edit the Makefile and make sure
|
||||
that the line "GRAPHIC_TESTS = defined" is not commented out; then check
|
||||
that the "GL_LIBS" definition is OK for your system. Also make sure
|
||||
that the "x11perf" command is on your search path.
|
||||
|
||||
If you don't want the graphics tests, then comment out the
|
||||
"GRAPHIC_TESTS = defined" line. Note: comment it out, don't
|
||||
set it to anything.
|
||||
|
||||
2. Do "make".
|
||||
|
||||
3. Do "Run" to run the system test; "Run graphics" to run the graphics
|
||||
tests; "Run gindex" to run both.
|
||||
|
||||
You will need perl, as Run is written in perl.
|
||||
|
||||
For more information on using the tests, read "USAGE".
|
||||
|
||||
For information on adding tests into the benchmark, see "WRITING_TESTS".
|
||||
|
||||
|
||||
===================== RELEASE NOTES =====================================
|
||||
|
||||
======================== Jan 13 ==========================
|
||||
|
||||
v5.1.3
|
||||
|
||||
Fixed issue that would cause a race condition if you attempted to compile in
|
||||
parallel with more than 3 parallel jobs.
|
||||
|
||||
|
||||
Kelly Lucas, Jan 13, 2011
|
||||
kdlucas at gmail period com
|
||||
|
||||
|
||||
======================== Dec 07 ==========================
|
||||
|
||||
v5.1.2
|
||||
|
||||
One big fix: if unixbench is installed in a directory whose pathname contains
|
||||
a space, it should now run (previously it failed).
|
||||
|
||||
To avoid possible clashes, the environment variables unixbench uses are now
|
||||
prefixed with "UB_". These are all optional, and for most people will be
|
||||
completely unnecessary, but if you want you can set these:
|
||||
|
||||
UB_BINDIR Directory where the test programs live.
|
||||
UB_TMPDIR Temp directory, for temp files.
|
||||
UB_RESULTDIR Directory to put results in.
|
||||
UB_TESTDIR Directory where the tests are executed.
|
||||
|
||||
And a couple of tiny fixes:
|
||||
* In pgms/tst.sh, changed "sort -n +1" to "sort -n -k 1"
|
||||
* In Makefile, made it clearer that GRAPHIC_TESTS should be commented
|
||||
out (not set to 0) to disable graphics
|
||||
Thanks to nordi for pointing these out.
|
||||
|
||||
|
||||
Ian Smith, December 26, 2007
|
||||
johantheghost at yahoo period com
|
||||
|
||||
|
||||
======================== Oct 07 ==========================
|
||||
|
||||
v5.1.1
|
||||
|
||||
It turns out that the setting of LANG is crucial to the results. This
|
||||
explains why people in different regions were seeing odd results, and also
|
||||
why runlevel 1 produced odd results -- runlevel 1 doesn't set LANG, and
|
||||
hence reverts to ASCII, whereas most people use a UTF-8 encoding, which is
|
||||
much slower in some tests (eg. shell tests).
|
||||
|
||||
So now we manually set LANG to "en_US.utf8", which is configured with the
|
||||
variable "$language". Don't change this if you want to share your results.
|
||||
We also report the language settings in use.
|
||||
|
||||
See "The Language Setting" in USAGE for more info. Thanks to nordi for
|
||||
pointing out the LANG issue.
|
||||
|
||||
I also added the "grep" and "sysexec" tests. These are non-index tests,
|
||||
and "grep" uses the system's grep, so it's not much use for comparing
|
||||
different systems. But some folks on the OpenSuSE list have been finding
|
||||
these useful. They aren't in any of the main test groups; do "Run grep
|
||||
sysexec" to run them.
|
||||
|
||||
Index Changes
|
||||
-------------
|
||||
|
||||
The setting of LANG will affect consistency with systems where this is
|
||||
not the default value. However, it should produce more consistent results
|
||||
in future.
|
||||
|
||||
|
||||
Ian Smith, October 15, 2007
|
||||
johantheghost at yahoo period com
|
||||
|
||||
|
||||
======================== Oct 07 ==========================
|
||||
|
||||
v5.1
|
||||
|
||||
The major new feature in this version is the addition of graphical
|
||||
benchmarks. Since these may not compile on all systems, you can enable/
|
||||
disable them with the GRAPHIC_TESTS variable in the Makefile.
|
||||
|
||||
As before, each test is run for 3 or 10 iterations. However, we now discard
|
||||
the worst 1/3 of the scores before averaging the remainder. The logic is
|
||||
that a glitch in the system (background process waking up, for example) may
|
||||
make one or two runs go slow, so let's discard those. Hopefully this will
|
||||
produce more consistent and repeatable results. Check the log file
|
||||
for a test run to see the discarded scores.
|
||||
|
||||
Made the tests compile and run on x86-64/Linux (fixed an execl bug passing
|
||||
int instead of pointer).
|
||||
|
||||
Also fixed some general bugs.
|
||||
|
||||
Thanks to Stefan Esser for help and testing / bug reporting.
|
||||
|
||||
Index Changes
|
||||
-------------
|
||||
|
||||
The tests are now divided into categories, and each category generates
|
||||
its own index. This keeps the graphics test results separate from
|
||||
the system tests.
|
||||
|
||||
The "graphics" test and corresponding index are new.
|
||||
|
||||
The "discard the worst scores" strategy should produce slightly higher
|
||||
test scores, but at least they should (hopefully!) be more consistent.
|
||||
The scores should not be higher than the best scores you would have got
|
||||
with 5.0, so this should not be a huge consistency issue.
|
||||
|
||||
Ian Smith, October 11, 2007
|
||||
johantheghost at yahoo period com
|
||||
|
||||
|
||||
======================== Sep 07 ==========================
|
||||
|
||||
v5.0
|
||||
|
||||
All the work I've done on this release is Linux-based, because that's
|
||||
the only Unix I have access to. I've tried to make it more OS-agnostic
|
||||
if anything; for example, it no longer has to figure out the format reported
|
||||
by /usr/bin/time. However, it's possible that portability has been damaged.
|
||||
If anyone wants to fix this, please feel free to mail me patches.
|
||||
|
||||
In particular, the analysis of the system's CPUs is done via /proc/cpuinfo.
|
||||
For systems which don't have this, please make appropriate changes in
|
||||
getCpuInfo() and getSystemInfo().
|
||||
|
||||
The big change has been to make the tests multi-CPU aware. See the
|
||||
"Multiple CPUs" section in "USAGE" for details. Other changes:
|
||||
|
||||
* Completely rewrote Run in Perl; drastically simplified the way data is
|
||||
processed. The confusing system of interlocking shell and awk scripts is
|
||||
now just one script. Various intermediate files used to store and process
|
||||
results are now replaced by Perl data structures internal to the script.
|
||||
|
||||
* Removed from the index runs file system read and write tests which were
|
||||
ignored for the index and wasted about 10 minutes per run (see fstime.c).
|
||||
The read and write tests can now be selected individually. Made fstime.c
|
||||
take parameters, so we no longer need to build 3 versions of it.
|
||||
|
||||
* Made the output file names unique; they are built from
|
||||
hostname-date-sequence.
|
||||
|
||||
* Worked on result reporting, error handling, and logging. See TESTS.
|
||||
We now generate both text and HTML reports.
|
||||
|
||||
* Removed some obsolete files.
|
||||
|
||||
Index Changes
|
||||
-------------
|
||||
|
||||
The index is still based on David Niemi's SPARCstation 20-61 (rated at 10.0),
|
||||
and the intention in the changes I've made has been to keep the tests
|
||||
unchanged, in order to maintain consistency with old result sets.
|
||||
|
||||
However, the following changes have been made to the index:
|
||||
|
||||
* The Pipe-based Context Switching test (context1) was being dropped
|
||||
from the index report in v4.1.0 due to a bug; I've put it back in.
|
||||
|
||||
* I've added shell1 to the index, to get a measure of how the shell tests
|
||||
scale with multiple CPUs (shell8 already exercises all the CPUs, even
|
||||
in single-copy mode). I made up the baseline score for this by
|
||||
extrapolation.
|
||||
|
||||
Both of these test can be dropped, if you wish, by editing the "TEST
|
||||
SPECIFICATIONS" section of Run.
|
||||
|
||||
Ian Smith, September 20, 2007
|
||||
johantheghost at yahoo period com
|
||||
|
||||
======================== Aug 97 ==========================
|
||||
|
||||
v4.1.0
|
||||
|
||||
Double precision Whetstone put in place instead of the old "double" benchmark.
|
||||
|
||||
Removal of some obsolete files.
|
||||
|
||||
"system" suite adds shell8.
|
||||
|
||||
perlbench and poll added as "exhibition" (non-index) benchmarks.
|
||||
|
||||
Incorporates several suggestions by Andre Derrick Balsa <andrewbalsa@usa.net>
|
||||
|
||||
Code cleanups to reduce compiler warnings by David C Niemi <niemi@tux.org>
|
||||
and Andy Kahn <kahn@zk3.dec.com>; Digital Unix options by Andy Kahn.
|
||||
|
||||
======================== Jun 97 ==========================
|
||||
|
||||
v4.0.1
|
||||
|
||||
Minor change to fstime.c to fix overflow problems on fast machines. Counting
|
||||
is now done in units of 256 (smallest BUFSIZE) and unsigned longs are used,
|
||||
giving another 23 dB or so of headroom ;^) Results should be virtually
|
||||
identical aside from very small rounding errors.
|
||||
|
||||
======================== Dec 95 ==========================
|
||||
|
||||
v4.0
|
||||
|
||||
Byte no longer seems to have anything to do with this benchmark, and I was
|
||||
unable to reach any of the original authors; so I have taken it upon myself
|
||||
to clean it up.
|
||||
|
||||
This is version 4. Major assumptions made in these benchmarks have changed
|
||||
since they were written, but they are nonetheless popular (particularly for
|
||||
measuring hardware for Linux). Some changes made:
|
||||
|
||||
- The biggest change is to put a lot more operating system-oriented
|
||||
tests into the index. I experimented for a while with a decibel-like
|
||||
logarithmic scale, but finally settled on using a geometric mean for
|
||||
the final index (the individual scores are a normalized, and their
|
||||
logs are averaged; the resulting value is exponentiated).
|
||||
|
||||
"George", certain SPARCstation 20-61 with 128 MB RAM, a SPARC Storage
|
||||
Array, and Solaris 2.3 is my new baseline; it is rated at 10.0 in each
|
||||
of the index scores for a final score of 10.0.
|
||||
|
||||
Overall I find the geometric averaging is a big improvement for
|
||||
avoiding the skew that was once possible (e.g. a Pentium-75 which got
|
||||
40 on the buggy version of fstime, such that fstime accounted for over
|
||||
half of its total score and hence wildly skewed its average).
|
||||
|
||||
I also expect that the new numbers look different enough from the old
|
||||
ones that no one is too likely to casually mistake them for each other.
|
||||
|
||||
I am finding new SPARCs running Solaris 2.4 getting about 15-20, and
|
||||
my 486 DX2-66 Compaq running Linux 1.3.45 got a 9.1. It got
|
||||
understandably poor scores on CPU and FPU benchmarks (a horrible
|
||||
1.8 on "double" and 1.3 on "fsdisk"); but made up for it by averaging
|
||||
over 20 on the OS-oriented benchmarks. The Pentium-75 running
|
||||
Linux gets about 20 (and it *still* runs Windows 3.1 slowly. Oh well).
|
||||
|
||||
- It is difficult to get a modern compiler to even consider making
|
||||
dhry2 without registers, short of turning off *all* optimizations.
|
||||
This is also not a terribly meaningful test, even if it were possible,
|
||||
as noone compiles without registers nowadays. Replaced this benchmark
|
||||
with dhry2reg in the index, and dropped it out of usage in general as
|
||||
it is so hard to make a legitimate one.
|
||||
|
||||
- fstime: this had some bugs when compiled on modern systems which return
|
||||
the number of bytes read/written for read(2)/write(2) calls. The code
|
||||
assumed that a negative return code was given for EOF, but most modern
|
||||
systems return 0 (certainly on SunOS 4, Solaris2, and Linux, which is
|
||||
what counts for me). The old code yielded wildly inflated read scores,
|
||||
would eat up tens of MB of disk space on fast systems, and yielded
|
||||
roughly 50% lower than normal copy scores than it should have.
|
||||
|
||||
Also, it counted partial blocks *fully*; made it count the proportional
|
||||
part of the block which was actually finished.
|
||||
|
||||
Made bigger and smaller variants of fstime which are designed to beat
|
||||
up the disk I/O and the buffer cache, respectively. Adjusted the
|
||||
sleeps so that they are short for short benchmarks.
|
||||
|
||||
- Instead of 1,2,4, and 8-shell benchmarks, went to 1, 8, and 16 to
|
||||
give a broader range of information (and to run 1 fewer test).
|
||||
The only real problem with this is that not many iterations get
|
||||
done with 16 at a time on slow systems, so there are some significant
|
||||
rounding errors; 8 therefore still used for the benchmark. There is
|
||||
also the problem that the last (uncompleted) loop is counted as a full
|
||||
loop, so it is impossible to score below 1.0 lpm (which gave my laptop
|
||||
a break). Probably redesigning Shell to do each loop a bit more
|
||||
quickly (but with less intensity) would be a good idea.
|
||||
|
||||
This benchmark appears to be very heavily influenced by the speed
|
||||
of the loader, by which shell is being used as /bin/sh, and by how
|
||||
well-compiled some of the common shell utilities like grep, sed, and
|
||||
sort are. With a consistent tool set it is also a good indicator of
|
||||
the bandwidth between main memory and the CPU (e.g. Pentia score about
|
||||
twice as high as 486es due to their 64-bit bus). Small, sometimes
|
||||
broken shells like "ash-linux" do particularly well here, while big,
|
||||
robust shells like bash do not.
|
||||
|
||||
- "dc" is a somewhat iffy benchmark, because there are two versions of
|
||||
it floating around, one being small, very fast, and buggy, and one
|
||||
being more correct but slow. It was never in the index anyway.
|
||||
|
||||
- Execl is a somewhat troubling benchmark in that it yields much higher
|
||||
scores if compiled statically. I frown on this practice because it
|
||||
distorts the scores away from reflecting how programs are really used
|
||||
(i.e. dynamically linked).
|
||||
|
||||
- Arithoh is really more an indicator of the compiler quality than of
|
||||
the computer itself. For example, GCC 2.7.x with -O2 and a few extra
|
||||
options optimizes much of it away, resulting in about a 1200% boost
|
||||
to the score. Clearly not a good one for the index.
|
||||
|
||||
I am still a bit unhappy with the variance in some of the benchmarks, most
|
||||
notably the fstime suite; and with how long it takes to run. But I think
|
||||
it gets significantly more reliable results than the older version in less
|
||||
time.
|
||||
|
||||
If anyone has ideas on how to make these benchmarks faster, lower-variance,
|
||||
or more meaningful; or has nice, new, portable benchmarks to add, don't
|
||||
hesitate to e-mail me.
|
||||
|
||||
David C Niemi <niemi@tux.org> 7 Dec 1995
|
||||
|
||||
======================== May 91 ==========================
|
||||
This is version 3. This set of programs should be able to determine if
|
||||
your system is BSD or SysV. (It uses the output format of time (1)
|
||||
to see. If you have any problems, contact me (by email,
|
||||
preferably): ben@bytepb.byte.com
|
||||
|
||||
---
|
||||
|
||||
The document doc/bench.doc describes the basic flow of the
|
||||
benchmark system. The document doc/bench3.doc describes the major
|
||||
changes in design of this version. As a user of the benchmarks,
|
||||
you should understand some of the methods that have been
|
||||
implemented to generate loop counts:
|
||||
|
||||
Tests that are compiled C code:
|
||||
The function wake_me(second, func) is included (from the file
|
||||
timeit.c). This function uses signal and alarm to set a countdown
|
||||
for the time request by the benchmark administration script
|
||||
(Run). As soon as the clock is started, the test is run with a
|
||||
counter keeping track of the number of loops that the test makes.
|
||||
When alarm sends its signal, the loop counter value is sent to stderr
|
||||
and the program terminates. Since the time resolution, signal
|
||||
trapping and other factors don't insure that the test is for the
|
||||
precise time that was requested, the test program is also run
|
||||
from the time (1) command. The real time value returned from time
|
||||
(1) is what is used in calculating the number of loops per second
|
||||
(or minute, depending on the test). As is obvious, there is some
|
||||
overhead time that is not taken into account, therefore the
|
||||
number of loops per second is not absolute. The overhead of the
|
||||
test starting and stopping and the signal and alarm calls is
|
||||
common to the overhead of real applications. If a program loads
|
||||
quickly, the number of loops per second increases; a phenomenon
|
||||
that favors systems that can load programs quickly. (Setting the
|
||||
sticky bit of the test programs is not considered fair play.)
|
||||
|
||||
Test that use existing UNIX programs or shell scripts:
|
||||
The concept is the same as that of compiled tests, except the
|
||||
alarm and signal are contained in separate compiled program,
|
||||
looper (source is looper.c). Looper uses an execvp to invoke the
|
||||
test with its arguments. Here, the overhead includes the
|
||||
invocation and execution of looper.
|
||||
|
||||
--
|
||||
|
||||
The index numbers are generated from a baseline file that is in
|
||||
pgms/index.base. You can put tests that you wish in this file.
|
||||
All you need to do is take the results/log file from your
|
||||
baseline machine, edit out the comment and blank lines, and sort
|
||||
the result (vi/ex command: 1,$!sort). The sort in necessary
|
||||
because the process of generating the index report uses join (1).
|
||||
You can regenerate the reports by running "make report."
|
||||
|
||||
--
|
||||
|
||||
========================= Jan 90 =============================
|
||||
Tom Yager has joined the effort here at BYTE; he is responsible
|
||||
for many refinements in the UNIX benchmarks.
|
||||
|
||||
The memory access tests have been deleted from the benchmarks.
|
||||
The file access tests have been reversed so that the test is run
|
||||
for a fixed time. The amount of data transfered (written, read,
|
||||
and copied) is the variable. !WARNING! This test can eat up a
|
||||
large hunk of disk space.
|
||||
|
||||
The initial line of all shell scripts has been changed from the
|
||||
SCO and XENIX form (:) to the more standard form "#! /bin/sh".
|
||||
But different systems handle shell switching differently. Check
|
||||
the documentation on your system and find out how you are
|
||||
supposed to do it. Or, simpler yet, just run the benchmarks from
|
||||
the Bourne shell. (You may need to set SHELL=/bin/sh as well.)
|
||||
|
||||
The options to Run have not been checked in a while. They may no
|
||||
longer function. Next time, I'll get back on them. There needs to
|
||||
be another option added (next time) that halts testing between
|
||||
each test. !WARNING! Some systems have caches that are not getting flushed
|
||||
before the next test or iteration is run. This can cause
|
||||
erroneous values.
|
||||
|
||||
========================= Sept 89 =============================
|
||||
The database (db) programs now have a tuneable message queue space.
|
||||
queue space. The default set in the Run script is 1024 bytes.
|
||||
Other major changes are in the format of the times. We now show
|
||||
Arithmetic and Geometric mean and standard deviation for User
|
||||
Time, System Time, and Real Time. Generally, in reporting, we
|
||||
plan on using the Real Time values with the benchs run with one
|
||||
active user (the bench user). Comments and arguments are requested.
|
||||
|
||||
contact: BIX bensmith or rick_g
|
||||
2
rk3308/unixbench-master_32/RkLunch.sh
Executable file
2
rk3308/unixbench-master_32/RkLunch.sh
Executable file
@ -0,0 +1,2 @@
|
||||
wpa_supplicant -B -i wlan0 -c /data/cfg/wpa_supplicant.conf
|
||||
#./wakeWordAgent -e gpio &
|
||||
2000
rk3308/unixbench-master_32/Run
Executable file
2000
rk3308/unixbench-master_32/Run
Executable file
File diff suppressed because it is too large
Load Diff
400
rk3308/unixbench-master_32/USAGE
Executable file
400
rk3308/unixbench-master_32/USAGE
Executable file
@ -0,0 +1,400 @@
|
||||
Running the Tests
|
||||
=================
|
||||
|
||||
All the tests are executed using the "Run" script in the top-level directory.
|
||||
|
||||
The simplest way to generate results is with the commmand:
|
||||
./Run
|
||||
|
||||
This will run a standard "index" test (see "The BYTE Index" below), and
|
||||
save the report in the "results" directory, with a filename like
|
||||
hostname-2007-09-23-01
|
||||
An HTML version is also saved.
|
||||
|
||||
If you want to generate both the basic system index and the graphics index,
|
||||
then do:
|
||||
./Run gindex
|
||||
|
||||
If your system has more than one CPU, the tests will be run twice -- once
|
||||
with a single copy of each test running at once, and once with N copies,
|
||||
where N is the number of CPUs. Some categories of tests, however (currently
|
||||
the graphics tests) will only run with a single copy.
|
||||
|
||||
Since the tests are based on constant time (variable work), a "system"
|
||||
run usually takes about 29 minutes; the "graphics" part about 18 minutes.
|
||||
A "gindex" run on a dual-core machine will do 2 "system" passes (single-
|
||||
and dual-processing) and one "graphics" run, for a total around one and
|
||||
a quarter hours.
|
||||
|
||||
============================================================================
|
||||
|
||||
Detailed Usage
|
||||
==============
|
||||
|
||||
The Run script takes a number of options which you can use to customise a
|
||||
test, and you can specify the names of the tests to run. The full usage
|
||||
is:
|
||||
|
||||
Run [ -q | -v ] [-i <n> ] [-c <n> [-c <n> ...]] [test ...]
|
||||
|
||||
The option flags are:
|
||||
|
||||
-q Run in quiet mode.
|
||||
-v Run in verbose mode.
|
||||
-i <count> Run <count> iterations for each test -- slower tests
|
||||
use <count> / 3, but at least 1. Defaults to 10 (3 for
|
||||
slow tests).
|
||||
-c <n> Run <n> copies of each test in parallel.
|
||||
|
||||
The -c option can be given multiple times; for example:
|
||||
|
||||
./Run -c 1 -c 4
|
||||
|
||||
will run a single-streamed pass, then a 4-streamed pass. Note that some
|
||||
tests (currently the graphics tests) will only run in a single-streamed pass.
|
||||
|
||||
The remaining non-flag arguments are taken to be the names of tests to run.
|
||||
The default is to run "index". See "Tests" below.
|
||||
|
||||
When running the tests, I do *not* recommend switching to single-user mode
|
||||
("init 1"). This seems to change the results in ways I don't understand,
|
||||
and it's not realistic (unless your system will actually be running in this
|
||||
mode, of course). However, if using a windowing system, you may want to
|
||||
switch to a minimal window setup (for example, log in to a "twm" session),
|
||||
so that randomly-churning background processes don't randomise the results
|
||||
too much. This is particularly true for the graphics tests.
|
||||
|
||||
|
||||
Output can be specified by setting the following environment variables:
|
||||
|
||||
* "UB_RESULTDIR" : Absolute path of output directory of result files.
|
||||
* "UB_TMPDIR" : Absolute path of temporary files for IO tests.
|
||||
* "UB_OUTPUT_FILE_NAME" : Output file name. If exists it will be overwritten.
|
||||
* "UB_OUTPUT_CSV" : If set "true", output results(score only) to .csv.
|
||||
============================================================================
|
||||
|
||||
Tests
|
||||
=====
|
||||
|
||||
The available tests are organised into categories; when generating index
|
||||
scores (see "The BYTE Index" below) the results for each category are
|
||||
produced separately. The categories are:
|
||||
|
||||
system The original Unix system tests (not all are actually
|
||||
in the index)
|
||||
2d 2D graphics tests (not all are actually in the index)
|
||||
3d 3D graphics tests
|
||||
misc Various non-indexed tests
|
||||
|
||||
The following individual tests are available:
|
||||
|
||||
system:
|
||||
dhry2reg Dhrystone 2 using register variables
|
||||
whetstone-double Double-Precision Whetstone
|
||||
syscall System Call Overhead
|
||||
pipe Pipe Throughput
|
||||
context1 Pipe-based Context Switching
|
||||
spawn Process Creation
|
||||
execl Execl Throughput
|
||||
fstime-w File Write 1024 bufsize 2000 maxblocks
|
||||
fstime-r File Read 1024 bufsize 2000 maxblocks
|
||||
fstime File Copy 1024 bufsize 2000 maxblocks
|
||||
fsbuffer-w File Write 256 bufsize 500 maxblocks
|
||||
fsbuffer-r File Read 256 bufsize 500 maxblocks
|
||||
fsbuffer File Copy 256 bufsize 500 maxblocks
|
||||
fsdisk-w File Write 4096 bufsize 8000 maxblocks
|
||||
fsdisk-r File Read 4096 bufsize 8000 maxblocks
|
||||
fsdisk File Copy 4096 bufsize 8000 maxblocks
|
||||
shell1 Shell Scripts (1 concurrent) (runs "looper 60 multi.sh 1")
|
||||
shell8 Shell Scripts (8 concurrent) (runs "looper 60 multi.sh 8")
|
||||
shell16 Shell Scripts (8 concurrent) (runs "looper 60 multi.sh 16")
|
||||
|
||||
2d:
|
||||
2d-rects 2D graphics: rectangles
|
||||
2d-lines 2D graphics: lines
|
||||
2d-circle 2D graphics: circles
|
||||
2d-ellipse 2D graphics: ellipses
|
||||
2d-shapes 2D graphics: polygons
|
||||
2d-aashapes 2D graphics: aa polygons
|
||||
2d-polys 2D graphics: complex polygons
|
||||
2d-text 2D graphics: text
|
||||
2d-blit 2D graphics: images and blits
|
||||
2d-window 2D graphics: windows
|
||||
|
||||
3d:
|
||||
ubgears 3D graphics: gears
|
||||
|
||||
misc:
|
||||
C C Compiler Throughput ("looper 60 $cCompiler cctest.c")
|
||||
arithoh Arithoh (huh?)
|
||||
short Arithmetic Test (short) (this is arith.c configured for
|
||||
"short" variables; ditto for the ones below)
|
||||
int Arithmetic Test (int)
|
||||
long Arithmetic Test (long)
|
||||
float Arithmetic Test (float)
|
||||
double Arithmetic Test (double)
|
||||
dc Dc: sqrt(2) to 99 decimal places (runs
|
||||
"looper 30 dc < dc.dat", using your system's copy of "dc")
|
||||
hanoi Recursion Test -- Tower of Hanoi
|
||||
grep Grep for a string in a large file, using your system's
|
||||
copy of "grep"
|
||||
sysexec Exercise fork() and exec().
|
||||
|
||||
The following pseudo-test names are aliases for combinations of other
|
||||
tests:
|
||||
|
||||
arithmetic Runs arithoh, short, int, long, float, double,
|
||||
and whetstone-double
|
||||
dhry Alias for dhry2reg
|
||||
dhrystone Alias for dhry2reg
|
||||
whets Alias for whetstone-double
|
||||
whetstone Alias for whetstone-double
|
||||
load Runs shell1, shell8, and shell16
|
||||
misc Runs C, dc, and hanoi
|
||||
speed Runs the arithmetic and system groups
|
||||
oldsystem Runs execl, fstime, fsbuffer, fsdisk, pipe, context1,
|
||||
spawn, and syscall
|
||||
system Runs oldsystem plus shell1, shell8, and shell16
|
||||
fs Runs fstime-w, fstime-r, fstime, fsbuffer-w,
|
||||
fsbuffer-r, fsbuffer, fsdisk-w, fsdisk-r, and fsdisk
|
||||
shell Runs shell1, shell8, and shell16
|
||||
|
||||
index Runs the tests which constitute the official index:
|
||||
the oldsystem group, plus dhry2reg, whetstone-double,
|
||||
shell1, and shell8
|
||||
See "The BYTE Index" below for more information.
|
||||
graphics Runs the tests which constitute the graphics index:
|
||||
2d-rects, 2d-ellipse, 2d-aashapes, 2d-text, 2d-blit,
|
||||
2d-window, and ubgears
|
||||
gindex Runs the index and graphics groups, to generate both
|
||||
sets of index results
|
||||
|
||||
all Runs all tests
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
The BYTE Index
|
||||
==============
|
||||
|
||||
The purpose of this test is to provide a basic indicator of the performance
|
||||
of a Unix-like system; hence, multiple tests are used to test various
|
||||
aspects of the system's performance. These test results are then compared
|
||||
to the scores from a baseline system to produce an index value, which is
|
||||
generally easier to handle than the raw sores. The entire set of index
|
||||
values is then combined to make an overall index for the system.
|
||||
|
||||
Since 1995, the baseline system has been "George", a SPARCstation 20-61
|
||||
with 128 MB RAM, a SPARC Storage Array, and Solaris 2.3, whose ratings
|
||||
were set at 10.0. (So a system which scores 520 is 52 times faster than
|
||||
this machine.) Since the numbers are really only useful in a relative
|
||||
sense, there's no particular reason to update the base system, so for the
|
||||
sake of consistency it's probably best to leave it alone. George's scores
|
||||
are in the file "pgms/index.base"; this file is used to calculate the
|
||||
index scores for any particular run.
|
||||
|
||||
Over the years, various changes have been made to the set of tests in the
|
||||
index. Although there is a desire for a consistent baseline, various tests
|
||||
have been determined to be misleading, and have been removed; and a few
|
||||
alternatives have been added. These changes are detailed in the README,
|
||||
and should be born in mind when looking at old scores.
|
||||
|
||||
A number of tests are included in the benchmark suite which are not part of
|
||||
the index, for various reasons; these tests can of course be run manually.
|
||||
See "Tests" above.
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
Graphics Tests
|
||||
==============
|
||||
|
||||
As of version 5.1, UnixBench now contains some graphics benchmarks. These
|
||||
are intended to give a rough idea of the general graphics performance of
|
||||
a system.
|
||||
|
||||
The graphics tests are in categories "2d" and "3d", so the index scores
|
||||
for these tests are separate from the basic system index. This seems
|
||||
like a sensible division, since the graphics performance of a system
|
||||
depends largely on the graphics adaptor.
|
||||
|
||||
The tests currently consist of some 2D "x11perf" tests and "ubgears".
|
||||
|
||||
* The 2D tests are a selection of the x11perf tests, using the host
|
||||
system's x11perf command (which must be installed and in the search
|
||||
path). Only a few of the x11perf tests are used, in the interests
|
||||
of completing a test run in a reasonable time; if you want to do
|
||||
detailed diagnosis of an X server or graphics chip, then use x11perf
|
||||
directly.
|
||||
|
||||
* The 3D test is "ubgears", a modified version of the familiar "glxgears".
|
||||
This version runs for 5 seconds to "warm up", then performs a timed
|
||||
run and displays the average frames-per-second.
|
||||
|
||||
On multi-CPU systems, the graphics tests will only run in single-processing
|
||||
mode. This is because the meaning of running two copies of a test at once
|
||||
is dubious; and the test windows tend to overlay each other, meaning that
|
||||
the window behind isn't actually doing any work.
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
Multiple CPUs
|
||||
=============
|
||||
|
||||
If your system has multiple CPUs, the default behaviour is to run the selected
|
||||
tests twice -- once with one copy of each test program running at a time,
|
||||
and once with N copies, where N is the number of CPUs. (You can override
|
||||
this with the "-c" option; see "Detailed Usage" above.) This is designed to
|
||||
allow you to assess:
|
||||
|
||||
- the performance of your system when running a single task
|
||||
- the performance of your system when running multiple tasks
|
||||
- the gain from your system's implementation of parallel processing
|
||||
|
||||
The results, however, need to be handled with care. Here are the results
|
||||
of two runs on a dual-processor system, one in single-processing mode, one
|
||||
dual-processing:
|
||||
|
||||
Test Single Dual Gain
|
||||
-------------------- ------ ------ ----
|
||||
Dhrystone 2 562.5 1110.3 97%
|
||||
Double Whetstone 320.0 640.4 100%
|
||||
Execl Throughput 450.4 880.3 95%
|
||||
File Copy 1024 759.4 595.9 -22%
|
||||
File Copy 256 535.8 438.8 -18%
|
||||
File Copy 4096 1261.8 1043.4 -17%
|
||||
Pipe Throughput 481.0 979.3 104%
|
||||
Pipe-based Switching 326.8 1229.0 276%
|
||||
Process Creation 917.2 1714.1 87%
|
||||
Shell Scripts (1) 1064.9 1566.3 47%
|
||||
Shell Scripts (8) 1567.7 1709.9 9%
|
||||
System Call Overhead 944.2 1445.5 53%
|
||||
-------------------- ------ ------ ----
|
||||
Index Score: 678.2 1026.2 51%
|
||||
|
||||
As expected, the heavily CPU-dependent tasks -- dhrystone, whetstone,
|
||||
execl, pipe throughput, process creation -- show close to 100% gain when
|
||||
running 2 copies in parallel.
|
||||
|
||||
The Pipe-based Context Switching test measures context switching overhead
|
||||
by sending messages back and forth between 2 processes. I don't know why
|
||||
it shows such a huge gain with 2 copies (ie. 4 processes total) running,
|
||||
but it seems to be consistent on my system. I think this may be an issue
|
||||
with the SMP implementation.
|
||||
|
||||
The System Call Overhead shows a lesser gain, presumably because it uses a
|
||||
lot of CPU time in single-threaded kernel code. The shell scripts test with
|
||||
8 concurrent processes shows no gain -- because the test itself runs 8
|
||||
scripts in parallel, it's already using both CPUs, even when the benchmark
|
||||
is run in single-stream mode. The same test with one process per copy
|
||||
shows a real gain.
|
||||
|
||||
The filesystem throughput tests show a loss, instead of a gain, when
|
||||
multi-processing. That there's no gain is to be expected, since the tests
|
||||
are presumably constrained by the throughput of the I/O subsystem and the
|
||||
disk drive itself; the drop in performance is presumably down to the
|
||||
increased contention for resources, and perhaps greater disk head movement.
|
||||
|
||||
So what tests should you use, how many copies should you run, and how should
|
||||
you interpret the results? Well, that's up to you, since it depends on
|
||||
what it is you're trying to measure.
|
||||
|
||||
Implementation
|
||||
--------------
|
||||
|
||||
The multi-processing mode is implemented at the level of test iterations.
|
||||
During each iteration of a test, N slave processes are started using fork().
|
||||
Each of these slaves executes the test program using fork() and exec(),
|
||||
reads and stores the entire output, times the run, and prints all the
|
||||
results to a pipe. The Run script reads the pipes for each of the slaves
|
||||
in turn to get the results and times. The scores are added, and the times
|
||||
averaged.
|
||||
|
||||
The result is that each test program has N copies running at once. They
|
||||
should all finish at around the same time, since they run for constant time.
|
||||
|
||||
If a test program itself starts off K multiple processes (as with the shell8
|
||||
test), then the effect will be that there are N * K processes running at
|
||||
once. This is probably not very useful for testing multi-CPU performance.
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
The Language Setting
|
||||
====================
|
||||
|
||||
The $LANG environment variable determines how programs abnd library
|
||||
routines interpret text. This can have a big impact on the test results.
|
||||
|
||||
If $LANG is set to POSIX, or is left unset, text is treated as ASCII; if
|
||||
it is set to en_US.UTF-8, foir example, then text is treated as being
|
||||
encoded in UTF-8, which is more complex and therefore slower. Setting
|
||||
it to other languages can have varying results.
|
||||
|
||||
To ensure consistency between test runs, the Run script now (as of version
|
||||
5.1.1) sets $LANG to "en_US.utf8".
|
||||
|
||||
This setting which is configured with the variable "$language". You
|
||||
should not change this if you want to share your results to allow
|
||||
comparisons between systems; however, you may want to change it to see
|
||||
how different language settings affect performance.
|
||||
|
||||
Each test report now includes the language settings in use. The reported
|
||||
language is what is set in $LANG, and is not necessarily supported by the
|
||||
system; but we also report the character mapping and collation order which
|
||||
are actually in use (as reported by "locale").
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
Interpreting the Results
|
||||
========================
|
||||
|
||||
Interpreting the results of these tests is tricky, and totally depends on
|
||||
what you're trying to measure.
|
||||
|
||||
For example, are you trying to measure how fast your CPU is? Or how good
|
||||
your compiler is? Because these tests are all recompiled using your host
|
||||
system's compiler, the performance of the compiler will inevitably impact
|
||||
the performance of the tests. Is this a problem? If you're choosing a
|
||||
system, you probably care about its overall speed, which may well depend
|
||||
on how good its compiler is; so including that in the test results may be
|
||||
the right answer. But you may want to ensure that the right compiler is
|
||||
used to build the tests.
|
||||
|
||||
On the other hand, with the vast majority of Unix systems being x86 / PC
|
||||
compatibles, running Linux and the GNU C compiler, the results will tend
|
||||
to be more dependent on the hardware; but the versions of the compiler and
|
||||
OS can make a big difference. (I measured a 50% gain between SUSE 10.1
|
||||
and OpenSUSE 10.2 on the same machine.) So you may want to make sure that
|
||||
all your test systems are running the same version of the OS; or at least
|
||||
publish the OS and compuiler versions with your results. Then again, it may
|
||||
be compiler performance that you're interested in.
|
||||
|
||||
The C test is very dubious -- it tests the speed of compilation. If you're
|
||||
running the exact same compiler on each system, OK; but otherwise, the
|
||||
results should probably be discarded. A slower compilation doesn't say
|
||||
anything about the speed of your system, since the compiler may simply be
|
||||
spending more time to super-optimise the code, which would actually make it
|
||||
faster.
|
||||
|
||||
This will be particularly true on architectures like IA-64 (Itanium etc.)
|
||||
where the compiler spends huge amounts of effort scheduling instructions
|
||||
to run in parallel, with a resultant significant gain in execution speed.
|
||||
|
||||
Some tests are even more dubious in terms of host-dependency -- for example,
|
||||
the "dc" test uses the host's version of dc (a calculator program). The
|
||||
version of this which is available can make a huge difference to the score,
|
||||
which is why it's not in the index group. Read through the release notes
|
||||
for more on these kinds of issues.
|
||||
|
||||
Another age-old issue is that of the benchmarks being too trivial to be
|
||||
meaningful. With compilers getting ever smarter, and performing more
|
||||
wide-ranging flow path analyses, the danger of parts of the benchmarks
|
||||
simply being optimised out of existance is always present.
|
||||
|
||||
All in all, the "index" and "gindex" tests (see above) are designed to
|
||||
give a reasonable measure of overall system performance; but the results
|
||||
of any test run should always be used with care.
|
||||
|
||||
133
rk3308/unixbench-master_32/WRITING_TESTS
Executable file
133
rk3308/unixbench-master_32/WRITING_TESTS
Executable file
@ -0,0 +1,133 @@
|
||||
Writing a Test
|
||||
==============
|
||||
|
||||
Writing a test program is pretty easy. Basically, a test is configured via
|
||||
a monster array in the Run script, which specifics (among other things) the
|
||||
program to execute and the parameters to pass it.
|
||||
|
||||
The test itself is simply a program which is given the optional parameters
|
||||
on the command line, and produces logging data on stdout and its results on
|
||||
stderr.
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
Test Configuration
|
||||
==================
|
||||
|
||||
In Run, all tests are named in the "$testList" array. This names the
|
||||
individual tests, and also sets up aliases for groups of tests, eg. "index".
|
||||
|
||||
The test specifications are in the "$testParams" array. This contains the
|
||||
details of each individual test as a hash. The fields in the hash are:
|
||||
|
||||
* "logmsg": the full name to display for this test.
|
||||
* "cat": the category this test belongs to; must be configured
|
||||
in $testCats.
|
||||
* "prog": the name of the program to execute; defaults to the name of
|
||||
the benchmark.
|
||||
* "repeat": number of passes to run; either 'short' (the default),
|
||||
'long', or 'single'. For 'short' and 'long', the actual numbers of
|
||||
passes are given by $shortIterCount and $longIterCount, which are
|
||||
configured at the top of the script or by the "-i" flag. 'single'
|
||||
means just run one pass; this should be used for test which do their
|
||||
own multi-pass handling internally.
|
||||
* "stdout": non-0 to add the test's stdout to the log file; defaults to 1.
|
||||
Set to 0 for tests that are too wordy.
|
||||
* "stdin": name of a file to send to the program's stdin; default null.
|
||||
* "options": options to be put on the program's command line; default null.
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
Output Format
|
||||
=============
|
||||
|
||||
The results on stderr take the form of a line header and fields, separated
|
||||
by "|" characters. A result line can be one of:
|
||||
|
||||
COUNT|score|timebase|label
|
||||
TIME|seconds
|
||||
ERROR|message
|
||||
|
||||
Any other text on stderr is treated as if it were:
|
||||
|
||||
ERROR|text
|
||||
|
||||
Any output to stdout is placed in a log file, and can be used for debugging.
|
||||
|
||||
COUNT
|
||||
-----
|
||||
|
||||
The COUNT line is the line used to report a test score.
|
||||
|
||||
* "score" is the result, typically the number of loops performed during
|
||||
the run
|
||||
* "timebase" is the time base used for the final report to the user. A
|
||||
value of 1 reports the score as is; a value of 60, for example, divides
|
||||
the time taken by 60 to get loops per minute. Atimebase of zero indicates
|
||||
that the score is already a rate, ie. a count of things per second.
|
||||
* "label" is the label to use for the score; like "lps" (loops per
|
||||
second), etc.
|
||||
|
||||
TIME
|
||||
----
|
||||
|
||||
The TIME line is optionally used to report the time taken. The Run script
|
||||
normally measures this, but if your test has signifant overhead outside the
|
||||
actual test loop, you should use TIME to report the time taken for the actual
|
||||
test. The argument is the time in seconds in floating-point.
|
||||
|
||||
ERROR
|
||||
-----
|
||||
|
||||
The argument is an error message; this will abort the benchmarking run and
|
||||
display the message.
|
||||
|
||||
Any output to stderr which is not a formatted line will be treated as an
|
||||
error message, so use of ERROR is optional.
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
Test Examples
|
||||
=============
|
||||
|
||||
Iteration Count
|
||||
---------------
|
||||
|
||||
The simplest thing is to count the number of loops executed in a given time;
|
||||
see eg. arith.c. The utlilty functions in timeit.c can be used to implement
|
||||
the fixed time interval, which is generally passed in on the command line.
|
||||
|
||||
The result is reported simply as the number of iterations completed:
|
||||
|
||||
fprintf(stderr,"COUNT|%lu|1|lps\n", iterations);
|
||||
|
||||
The bnenchmark framework will measure the time taken itself. If the test
|
||||
code has significant overhead (eg. a "pump-priming" pass), then you should
|
||||
explicitly report the time taken for the test by adding a line like this:
|
||||
|
||||
fprintf(stderr, "TIME|%.1f\n", seconds);
|
||||
|
||||
If you want results reported as loops per minute, then set timebase to 60:
|
||||
|
||||
fprintf(stderr,"COUNT|%lu|60|lpm\n", iterations);
|
||||
|
||||
Note that this only affects the final report; all times passed to or
|
||||
from the test are still in seconds.
|
||||
|
||||
Rate
|
||||
----
|
||||
|
||||
The other technique is to calculate the rate (things per second) in the test,
|
||||
and report that directly. To do this, just set timebase to 0:
|
||||
|
||||
fprintf(stderr, "COUNT|%ld|0|KBps\n", kbytes_per_sec);
|
||||
|
||||
Again, you can use TIME to explicitly report the time taken:
|
||||
|
||||
fprintf(stderr, "TIME|%.1f\n", end - start);
|
||||
|
||||
but this isn't so important since you've already calculated the rate.
|
||||
|
||||
BIN
rk3308/unixbench-master_32/pgms/arithoh
Executable file
BIN
rk3308/unixbench-master_32/pgms/arithoh
Executable file
Binary file not shown.
BIN
rk3308/unixbench-master_32/pgms/context1
Executable file
BIN
rk3308/unixbench-master_32/pgms/context1
Executable file
Binary file not shown.
BIN
rk3308/unixbench-master_32/pgms/dhry2
Executable file
BIN
rk3308/unixbench-master_32/pgms/dhry2
Executable file
Binary file not shown.
BIN
rk3308/unixbench-master_32/pgms/dhry2reg
Executable file
BIN
rk3308/unixbench-master_32/pgms/dhry2reg
Executable file
Binary file not shown.
BIN
rk3308/unixbench-master_32/pgms/double
Executable file
BIN
rk3308/unixbench-master_32/pgms/double
Executable file
Binary file not shown.
BIN
rk3308/unixbench-master_32/pgms/execl
Executable file
BIN
rk3308/unixbench-master_32/pgms/execl
Executable file
Binary file not shown.
BIN
rk3308/unixbench-master_32/pgms/float
Executable file
BIN
rk3308/unixbench-master_32/pgms/float
Executable file
Binary file not shown.
BIN
rk3308/unixbench-master_32/pgms/fstime
Executable file
BIN
rk3308/unixbench-master_32/pgms/fstime
Executable file
Binary file not shown.
476
rk3308/unixbench-master_32/pgms/gfx-x11
Executable file
476
rk3308/unixbench-master_32/pgms/gfx-x11
Executable file
@ -0,0 +1,476 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use strict;
|
||||
|
||||
|
||||
############################################################################
|
||||
# gfx-x11: a front-end for x11perf. Runs a selected x11perf test, and
|
||||
# produces output in the format needed by UnixBench.
|
||||
############################################################################
|
||||
# Modification Log:
|
||||
# 2007.09.26 Ian Smith Created
|
||||
############################################################################
|
||||
|
||||
# This program runs sets of x11perf tests, indexes the results against
|
||||
# a common base reference system (see $testData below), and reports the
|
||||
# final score.
|
||||
#
|
||||
# Usage:
|
||||
# gfx-x11 <group> <reps> <time>
|
||||
# where:
|
||||
# <group> is one of the test groups defined in $testGroups below
|
||||
# <reps> is the number of repeats to do per test (the -repeat
|
||||
# argument to x11perf)
|
||||
# <time> is the number of seconds to run each repeat for (the
|
||||
# -time argument to x11perf)
|
||||
# Note that x11perf runs a calibration pass before the requested number
|
||||
# of test passes. The score we compute for a test is the average of the
|
||||
# test passes, divided by the base value in $testData, times 1000.0.
|
||||
# The final score we report is the average of the test scores.
|
||||
|
||||
|
||||
############################################################################
|
||||
# TEST DATA
|
||||
############################################################################
|
||||
|
||||
# This array lists all of the x11perf tests, together with their scores
|
||||
# on an HP Compaq nc8430, with an ATI Mobility Radeon X1600 (256MB)
|
||||
# graphics adapter. There isn't anything special about this reference
|
||||
# system, but scaling all the scores back to a single reference system
|
||||
# allows us to average them in a roughly meaningful way, which in turn
|
||||
# allows us to produce sensible scores for the test groups defined below.
|
||||
#
|
||||
# The results we report are indexed to these values, at a base of 1000.0.
|
||||
my $testData = {
|
||||
'dot' => [ 31700000.0, "Dot" ],
|
||||
'rect1' => [ 18400000.0, "1x1 rectangle" ],
|
||||
'rect10' => [ 7180000.0, "10x10 rectangle" ],
|
||||
'rect100' => [ 110000.0, "100x100 rectangle" ],
|
||||
'rect500' => [ 4110.0, "500x500 rectangle" ],
|
||||
'srect1' => [ 15800000.0, "1x1 stippled rectangle (8x8 stipple)" ],
|
||||
'srect10' => [ 7400000.0, "10x10 stippled rectangle (8x8 stipple)" ],
|
||||
'srect100' => [ 110000.0, "100x100 stippled rectangle (8x8 stipple)" ],
|
||||
'srect500' => [ 4110.0, "500x500 stippled rectangle (8x8 stipple)" ],
|
||||
'osrect1' => [ 15900000.0, "1x1 opaque stippled rectangle (8x8 stipple)" ],
|
||||
'osrect10' => [ 7170000.0, "10x10 opaque stippled rectangle (8x8 stipple)" ],
|
||||
'osrect100' => [ 110000.0, "100x100 opaque stippled rectangle (8x8 stipple)" ],
|
||||
'osrect500' => [ 4110.0, "500x500 opaque stippled rectangle (8x8 stipple)" ],
|
||||
'tilerect1' => [ 15800000.0, "1x1 tiled rectangle (4x4 tile)" ],
|
||||
'tilerect10' => [ 7170000.0, "10x10 tiled rectangle (4x4 tile)" ],
|
||||
'tilerect100' => [ 110000.0, "100x100 tiled rectangle (4x4 tile)" ],
|
||||
'tilerect500' => [ 4110.0, "500x500 tiled rectangle (4x4 tile)" ],
|
||||
'oddsrect1' => [ 2990000.0, "1x1 stippled rectangle (17x15 stipple)" ],
|
||||
'oddsrect10' => [ 1490000.0, "10x10 stippled rectangle (17x15 stipple)" ],
|
||||
'oddsrect100' => [ 55600.0, "100x100 stippled rectangle (17x15 stipple)" ],
|
||||
'oddsrect500' => [ 2360.0, "500x500 stippled rectangle (17x15 stipple)" ],
|
||||
'oddosrect1' => [ 2990000.0, "1x1 opaque stippled rectangle (17x15 stipple)" ],
|
||||
'oddosrect10' => [ 1430000.0, "10x10 opaque stippled rectangle (17x15 stipple)" ],
|
||||
'oddosrect100' => [ 54500.0, "100x100 opaque stippled rectangle (17x15 stipple)" ],
|
||||
'oddosrect500' => [ 2320.0, "500x500 opaque stippled rectangle (17x15 stipple)" ],
|
||||
'oddtilerect1' => [ 2990000.0, "1x1 tiled rectangle (17x15 tile)" ],
|
||||
'oddtilerect10' => [ 1430000.0, "10x10 tiled rectangle (17x15 tile)" ],
|
||||
'oddtilerect100' => [ 54500.0, "100x100 tiled rectangle (17x15 tile)" ],
|
||||
'oddtilerect500' => [ 2320.0, "500x500 tiled rectangle (17x15 tile)" ],
|
||||
'bigsrect1' => [ 4300000.0, "1x1 stippled rectangle (161x145 stipple)" ],
|
||||
'bigsrect10' => [ 705000.0, "10x10 stippled rectangle (161x145 stipple)" ],
|
||||
'bigsrect100' => [ 12300.0, "100x100 stippled rectangle (161x145 stipple)" ],
|
||||
'bigsrect500' => [ 524.0, "500x500 stippled rectangle (161x145 stipple)" ],
|
||||
'bigosrect1' => [ 3980000.0, "1x1 opaque stippled rectangle (161x145 stipple)" ],
|
||||
'bigosrect10' => [ 644000.0, "10x10 opaque stippled rectangle (161x145 stipple)" ],
|
||||
'bigosrect100' => [ 12800.0, "100x100 opaque stippled rectangle (161x145 stipple)" ],
|
||||
'bigosrect500' => [ 584.0, "500x500 opaque stippled rectangle (161x145 stipple)" ],
|
||||
'bigtilerect1' => [ 5970000.0, "1x1 tiled rectangle (161x145 tile)" ],
|
||||
'bigtilerect10' => [ 684000.0, "10x10 tiled rectangle (161x145 tile)" ],
|
||||
'bigtilerect100' => [ 16200.0, "100x100 tiled rectangle (161x145 tile)" ],
|
||||
'bigtilerect500' => [ 872.0, "500x500 tiled rectangle (161x145 tile)" ],
|
||||
'eschertilerect1' => [ 5940000.0, "1x1 tiled rectangle (216x208 tile)" ],
|
||||
'eschertilerect10' => [ 639000.0, "10x10 tiled rectangle (216x208 tile)" ],
|
||||
'eschertilerect100' => [ 18000.0, "100x100 tiled rectangle (216x208 tile)" ],
|
||||
'eschertilerect500' => [ 922.0, "500x500 tiled rectangle (216x208 tile)" ],
|
||||
'seg1' => [ 28800000.0, "1-pixel line segment" ],
|
||||
'seg10' => [ 4460000.0, "10-pixel line segment" ],
|
||||
'seg100' => [ 470000.0, "100-pixel line segment" ],
|
||||
'seg500' => [ 94600.0, "500-pixel line segment" ],
|
||||
'seg100c1' => [ 449000.0, "100-pixel line segment (1 kid)" ],
|
||||
'seg100c2' => [ 432000.0, "100-pixel line segment (2 kids)" ],
|
||||
'seg100c3' => [ 421000.0, "100-pixel line segment (3 kids)" ],
|
||||
'dseg10' => [ 3720000.0, "10-pixel dashed segment" ],
|
||||
'dseg100' => [ 687000.0, "100-pixel dashed segment" ],
|
||||
'ddseg100' => [ 454000.0, "100-pixel double-dashed segment" ],
|
||||
'hseg10' => [ 7020000.0, "10-pixel horizontal line segment" ],
|
||||
'hseg100' => [ 2170000.0, "100-pixel horizontal line segment" ],
|
||||
'hseg500' => [ 456000.0, "500-pixel horizontal line segment" ],
|
||||
'vseg10' => [ 3990000.0, "10-pixel vertical line segment" ],
|
||||
'vseg100' => [ 411000.0, "100-pixel vertical line segment" ],
|
||||
'vseg500' => [ 82400.0, "500-pixel vertical line segment" ],
|
||||
'whseg10' => [ 2880000.0, "10x1 wide horizontal line segment" ],
|
||||
'whseg100' => [ 616000.0, "100x10 wide horizontal line segment" ],
|
||||
'whseg500' => [ 33300.0, "500x50 wide horizontal line segment" ],
|
||||
'wvseg10' => [ 2890000.0, "10x1 wide vertical line segment" ],
|
||||
'wvseg100' => [ 584000.0, "100x10 wide vertical line segment" ],
|
||||
'wvseg500' => [ 31700.0, "500x50 wide vertical line segment" ],
|
||||
'line1' => [ 28300000.0, "1-pixel line" ],
|
||||
'line10' => [ 4470000.0, "10-pixel line" ],
|
||||
'line100' => [ 472000.0, "100-pixel line" ],
|
||||
'line500' => [ 94200.0, "500-pixel line" ],
|
||||
'dline10' => [ 3640000.0, "10-pixel dashed line" ],
|
||||
'dline100' => [ 673000.0, "100-pixel dashed line" ],
|
||||
'ddline100' => [ 453000.0, "100-pixel double-dashed line" ],
|
||||
'wline10' => [ 908000.0, "10x1 wide line" ],
|
||||
'wline100' => [ 146000.0, "100x10 wide line" ],
|
||||
'wline500' => [ 30600.0, "500x50 wide line" ],
|
||||
'wdline100' => [ 69900.0, "100x10 wide dashed line" ],
|
||||
'wddline100' => [ 60600.0, "100x10 wide double-dashed line" ],
|
||||
'orect10' => [ 5100000.0, "10x10 rectangle outline" ],
|
||||
'orect100' => [ 709000.0, "100x100 rectangle outline" ],
|
||||
'orect500' => [ 146000.0, "500x500 rectangle outline" ],
|
||||
'worect10' => [ 4530000.0, "10x10 wide rectangle outline" ],
|
||||
'worect100' => [ 204000.0, "100x100 wide rectangle outline" ],
|
||||
'worect500' => [ 9790.0, "500x500 wide rectangle outline" ],
|
||||
'circle1' => [ 5160000.0, "1-pixel circle" ],
|
||||
'circle10' => [ 1160000.0, "10-pixel circle" ],
|
||||
'circle100' => [ 141000.0, "100-pixel circle" ],
|
||||
'circle500' => [ 28900.0, "500-pixel circle" ],
|
||||
'dcircle100' => [ 98400.0, "100-pixel dashed circle" ],
|
||||
'ddcircle100' => [ 75000.0, "100-pixel double-dashed circle" ],
|
||||
'wcircle10' => [ 780000.0, "10-pixel wide circle" ],
|
||||
'wcircle100' => [ 90900.0, "100-pixel wide circle" ],
|
||||
'wcircle500' => [ 11300.0, "500-pixel wide circle" ],
|
||||
'wdcircle100' => [ 8100.0, "100-pixel wide dashed circle" ],
|
||||
'wddcircle100' => [ 8300.0, "100-pixel wide double-dashed circle" ],
|
||||
'pcircle10' => [ 1270000.0, "10-pixel partial circle" ],
|
||||
'pcircle100' => [ 212000.0, "100-pixel partial circle" ],
|
||||
'wpcircle10' => [ 104000.0, "10-pixel wide partial circle" ],
|
||||
'wpcircle100' => [ 39000.0, "100-pixel wide partial circle" ],
|
||||
'fcircle1' => [ 61300000.0, "1-pixel solid circle" ],
|
||||
'fcircle10' => [ 1720000.0, "10-pixel solid circle" ],
|
||||
'fcircle100' => [ 120000.0, "100-pixel solid circle" ],
|
||||
'fcircle500' => [ 5170.0, "500-pixel solid circle" ],
|
||||
'fcpcircle10' => [ 981000.0, "10-pixel fill chord partial circle" ],
|
||||
'fcpcircle100' => [ 205000.0, "100-pixel fill chord partial circle" ],
|
||||
'fspcircle10' => [ 876000.0, "10-pixel fill slice partial circle" ],
|
||||
'fspcircle100' => [ 187000.0, "100-pixel fill slice partial circle" ],
|
||||
'ellipse10' => [ 1410000.0, "10-pixel ellipse" ],
|
||||
'ellipse100' => [ 172000.0, "100-pixel ellipse" ],
|
||||
'ellipse500' => [ 35100.0, "500-pixel ellipse" ],
|
||||
'dellipse100' => [ 114000.0, "100-pixel dashed ellipse" ],
|
||||
'ddellipse100' => [ 88900.0, "100-pixel double-dashed ellipse" ],
|
||||
'wellipse10' => [ 889000.0, "10-pixel wide ellipse" ],
|
||||
'wellipse100' => [ 124000.0, "100-pixel wide ellipse" ],
|
||||
'wellipse500' => [ 15600.0, "500-pixel wide ellipse" ],
|
||||
'wdellipse100' => [ 7730.0, "100-pixel wide dashed ellipse" ],
|
||||
'wddellipse100' => [ 6680.0, "100-pixel wide double-dashed ellipse" ],
|
||||
'pellipse10' => [ 1350000.0, "10-pixel partial ellipse" ],
|
||||
'pellipse100' => [ 260000.0, "100-pixel partial ellipse" ],
|
||||
'wpellipse10' => [ 97900.0, "10-pixel wide partial ellipse" ],
|
||||
'wpellipse100' => [ 16800.0, "100-pixel wide partial ellipse" ],
|
||||
'fellipse10' => [ 2110000.0, "10-pixel filled ellipse" ],
|
||||
'fellipse100' => [ 212000.0, "100-pixel filled ellipse" ],
|
||||
'fellipse500' => [ 11000.0, "500-pixel filled ellipse" ],
|
||||
'fcpellipse10' => [ 1060000.0, "10-pixel fill chord partial ellipse" ],
|
||||
'fcpellipse100' => [ 296000.0, "100-pixel fill chord partial ellipse" ],
|
||||
'fspellipse10' => [ 945000.0, "10-pixel fill slice partial ellipse" ],
|
||||
'fspellipse100' => [ 269000.0, "100-pixel fill slice partial ellipse" ],
|
||||
'triangle1' => [ 2460000.0, "Fill 1x1 equivalent triangle" ],
|
||||
'triangle10' => [ 969000.0, "Fill 10x10 equivalent triangle" ],
|
||||
'triangle100' => [ 97000.0, "Fill 100x100 equivalent triangle" ],
|
||||
'trap1' => [ 2630000.0, "Fill 1x1 trapezoid" ],
|
||||
'trap10' => [ 1260000.0, "Fill 10x10 trapezoid" ],
|
||||
'trap100' => [ 106000.0, "Fill 100x100 trapezoid" ],
|
||||
'trap300' => [ 11600.0, "Fill 300x300 trapezoid" ],
|
||||
'strap1' => [ 2010000.0, "Fill 1x1 stippled trapezoid (8x8 stipple)" ],
|
||||
'strap10' => [ 910000.0, "Fill 10x10 stippled trapezoid (8x8 stipple)" ],
|
||||
'strap100' => [ 104000.0, "Fill 100x100 stippled trapezoid (8x8 stipple)" ],
|
||||
'strap300' => [ 11700.0, "Fill 300x300 stippled trapezoid (8x8 stipple)" ],
|
||||
'ostrap1' => [ 2000000.0, "Fill 1x1 opaque stippled trapezoid (8x8 stipple)" ],
|
||||
'ostrap10' => [ 907000.0, "Fill 10x10 opaque stippled trapezoid (8x8 stipple)" ],
|
||||
'ostrap100' => [ 104000.0, "Fill 100x100 opaque stippled trapezoid (8x8 stipple)" ],
|
||||
'ostrap300' => [ 11600.0, "Fill 300x300 opaque stippled trapezoid (8x8 stipple)" ],
|
||||
'tiletrap1' => [ 1430000.0, "Fill 1x1 tiled trapezoid (4x4 tile)" ],
|
||||
'tiletrap10' => [ 778000.0, "Fill 10x10 tiled trapezoid (4x4 tile)" ],
|
||||
'tiletrap100' => [ 104000.0, "Fill 100x100 tiled trapezoid (4x4 tile)" ],
|
||||
'tiletrap300' => [ 11600.0, "Fill 300x300 tiled trapezoid (4x4 tile)" ],
|
||||
'oddstrap1' => [ 1700000.0, "Fill 1x1 stippled trapezoid (17x15 stipple)" ],
|
||||
'oddstrap10' => [ 296000.0, "Fill 10x10 stippled trapezoid (17x15 stipple)" ],
|
||||
'oddstrap100' => [ 18600.0, "Fill 100x100 stippled trapezoid (17x15 stipple)" ],
|
||||
'oddstrap300' => [ 2090.0, "Fill 300x300 stippled trapezoid (17x15 stipple)" ],
|
||||
'oddostrap1' => [ 1830000.0, "Fill 1x1 opaque stippled trapezoid (17x15 stipple)" ],
|
||||
'oddostrap10' => [ 296000.0, "Fill 10x10 opaque stippled trapezoid (17x15 stipple)" ],
|
||||
'oddostrap100' => [ 18400.0, "Fill 100x100 opaque stippled trapezoid (17x15 stipple)" ],
|
||||
'oddostrap300' => [ 2080.0, "Fill 300x300 opaque stippled trapezoid (17x15 stipple)" ],
|
||||
'oddtiletrap1' => [ 1710000.0, "Fill 1x1 tiled trapezoid (17x15 tile)" ],
|
||||
'oddtiletrap10' => [ 296000.0, "Fill 10x10 tiled trapezoid (17x15 tile)" ],
|
||||
'oddtiletrap100' => [ 18400.0, "Fill 100x100 tiled trapezoid (17x15 tile)" ],
|
||||
'oddtiletrap300' => [ 2080.0, "Fill 300x300 tiled trapezoid (17x15 tile)" ],
|
||||
'bigstrap1' => [ 1510000.0, "Fill 1x1 stippled trapezoid (161x145 stipple)" ],
|
||||
'bigstrap10' => [ 235000.0, "Fill 10x10 stippled trapezoid (161x145 stipple)" ],
|
||||
'bigstrap100' => [ 9110.0, "Fill 100x100 stippled trapezoid (161x145 stipple)" ],
|
||||
'bigstrap300' => [ 1260.0, "Fill 300x300 stippled trapezoid (161x145 stipple)" ],
|
||||
'bigostrap1' => [ 1480000.0, "Fill 1x1 opaque stippled trapezoid (161x145 stipple)" ],
|
||||
'bigostrap10' => [ 213000.0, "Fill 10x10 opaque stippled trapezoid (161x145 stipple)" ],
|
||||
'bigostrap100' => [ 8830.0, "Fill 100x100 opaque stippled trapezoid (161x145 stipple)" ],
|
||||
'bigostrap300' => [ 1420.0, "Fill 300x300 opaque stippled trapezoid (161x145 stipple)" ],
|
||||
'bigtiletrap1' => [ 1630000.0, "Fill 1x1 tiled trapezoid (161x145 tile)" ],
|
||||
'bigtiletrap10' => [ 272000.0, "Fill 10x10 tiled trapezoid (161x145 tile)" ],
|
||||
'bigtiletrap100' => [ 12900.0, "Fill 100x100 tiled trapezoid (161x145 tile)" ],
|
||||
'bigtiletrap300' => [ 2350.0, "Fill 300x300 tiled trapezoid (161x145 tile)" ],
|
||||
'eschertiletrap1' => [ 1650000.0, "Fill 1x1 tiled trapezoid (216x208 tile)" ],
|
||||
'eschertiletrap10' => [ 273000.0, "Fill 10x10 tiled trapezoid (216x208 tile)" ],
|
||||
'eschertiletrap100' => [ 13400.0, "Fill 100x100 tiled trapezoid (216x208 tile)" ],
|
||||
'eschertiletrap300' => [ 2450.0, "Fill 300x300 tiled trapezoid (216x208 tile)" ],
|
||||
'aatrap1' => [ 260000.0, "Fill 1x1 aa trap" ],
|
||||
'aatrap10' => [ 23500.0, "Fill 10x10 aa trap" ],
|
||||
'aatrap100' => [ 13300.0, "Fill 100x100 aa trap" ],
|
||||
'aatrap300' => [ 4450.0, "Fill 300x300 aa trap" ],
|
||||
'aa4trap1' => [ 2150.0, "Fill 1x1 aa trap with 4 bit alpha" ],
|
||||
'aa4trap10' => [ 2130.0, "Fill 10x10 aa trap with 4 bit alpha" ],
|
||||
'aa4trap100' => [ 1890.0, "Fill 100x100 aa trap with 4 bit alpha" ],
|
||||
'aa4trap300' => [ 1460.0, "Fill 300x300 aa trap with 4 bit alpha" ],
|
||||
'aa1trap1' => [ 2200000.0, "Fill 1x1 aa trap with 1 bit alpha" ],
|
||||
'aa1trap10' => [ 357000.0, "Fill 10x10 aa trap with 1 bit alpha" ],
|
||||
'aa1trap100' => [ 167000.0, "Fill 100x100 aa trap with 1 bit alpha" ],
|
||||
'aa1trap300' => [ 67000.0, "Fill 300x300 aa trap with 1 bit alpha" ],
|
||||
'aatrap2x1' => [ 368000.0, "Fill 2x1 aa trap" ],
|
||||
'aatrap2x10' => [ 25700.0, "Fill 2x10 aa trap" ],
|
||||
'aatrap2x100' => [ 12400.0, "Fill 2x100 aa trap" ],
|
||||
'aatrap2x300' => [ 5710.0, "Fill 2x300 aa trap" ],
|
||||
'aatrapezoid1' => [ 372000.0, "Fill 1x1 aa trapezoid" ],
|
||||
'aatrapezoid10' => [ 137000.0, "Fill 10x10 aa trapezoid" ],
|
||||
'aatrapezoid100' => [ 9590.0, "Fill 100x100 aa trapezoid" ],
|
||||
'aatrapezoid300' => [ 1420.0, "Fill 300x300 aa trapezoid" ],
|
||||
'addaatrapezoid1' => [ 433000.0, "Fill 1x1 aa pre-added trapezoid" ],
|
||||
'addaatrapezoid10' => [ 24100.0, "Fill 10x10 aa pre-added trapezoid" ],
|
||||
'addaatrapezoid100' => [ 13300.0, "Fill 100x100 aa pre-added trapezoid" ],
|
||||
'addaatrapezoid300' => [ 4460.0, "Fill 300x300 aa pre-added trapezoid" ],
|
||||
'complex10' => [ 655000.0, "Fill 10x10 equivalent complex polygon" ],
|
||||
'complex100' => [ 87000.0, "Fill 100x100 equivalent complex polygons" ],
|
||||
'64poly10convex' => [ 481000.0, "Fill 10x10 64-gon (Convex)" ],
|
||||
'64poly100convex' => [ 105000.0, "Fill 100x100 64-gon (Convex)" ],
|
||||
'64poly10complex' => [ 353000.0, "Fill 10x10 64-gon (Complex)" ],
|
||||
'64poly100complex' => [ 105000.0, "Fill 100x100 64-gon (Complex)" ],
|
||||
'ftext' => [ 2200000.0, "Char in 80-char line (6x13)" ],
|
||||
'f8text' => [ 1970000.0, "Char in 70-char line (8x13)" ],
|
||||
'f9text' => [ 1690000.0, "Char in 60-char line (9x15)" ],
|
||||
'f14text16' => [ 679000.0, "Char16 in 40-char line (k14)" ],
|
||||
'f24text16' => [ 272000.0, "Char16 in 23-char line (k24)" ],
|
||||
'tr10text' => [ 2520000.0, "Char in 80-char line (TR 10)" ],
|
||||
'tr24text' => [ 940000.0, "Char in 30-char line (TR 24)" ],
|
||||
'polytext' => [ 2230000.0, "Char in 20/40/20 line (6x13, TR 10)" ],
|
||||
'polytext16' => [ 369000.0, "Char16 in 7/14/7 line (k14, k24)" ],
|
||||
'fitext' => [ 1350000.0, "Char in 80-char image line (6x13)" ],
|
||||
'f8itext' => [ 1130000.0, "Char in 70-char image line (8x13)" ],
|
||||
'f9itext' => [ 902000.0, "Char in 60-char image line (9x15)" ],
|
||||
'f14itext16' => [ 449000.0, "Char16 in 40-char image line (k14)" ],
|
||||
'f24itext16' => [ 169000.0, "Char16 in 23-char image line (k24)" ],
|
||||
'tr10itext' => [ 1590000.0, "Char in 80-char image line (TR 10)" ],
|
||||
'tr24itext' => [ 435000.0, "Char in 30-char image line (TR 24)" ],
|
||||
'aa10text' => [ 53200.0, "Char in 80-char aa line (Charter 10)" ],
|
||||
'aa24text' => [ 13300.0, "Char in 30-char aa line (Charter 24)" ],
|
||||
'aaftext' => [ 45200.0, "Char in 80-char aa line (Courier 12)" ],
|
||||
'a10text' => [ 53100.0, "Char in 80-char a line (Charter 10)" ],
|
||||
'a24text' => [ 13300.0, "Char in 30-char a line (Charter 24)" ],
|
||||
'aftext' => [ 45200.0, "Char in 80-char a line (Courier 12)" ],
|
||||
'rgb10text' => [ 49400.0, "Char in 80-char rgb line (Charter 10)" ],
|
||||
'rgb24text' => [ 10200.0, "Char in 30-char rgb line (Charter 24)" ],
|
||||
'rgbftext' => [ 42200.0, "Char in 80-char rgb line (Courier 12)" ],
|
||||
'caa10text' => [ 15300.0, "Char in 80-char aa core line (Charter 10)" ],
|
||||
'caa24text' => [ 2540.0, "Char in 30-char aa core line (Charter 24)" ],
|
||||
'caaftext' => [ 10900.0, "Char in 80-char aa core line (Courier 12)" ],
|
||||
'ca10text' => [ 15300.0, "Char in 80-char a core line (Charter 10)" ],
|
||||
'ca24text' => [ 2540.0, "Char in 30-char a core line (Charter 24)" ],
|
||||
'caftext' => [ 10900.0, "Char in 80-char a core line (Courier 12)" ],
|
||||
'rgb10text' => [ 15000.0, "Char in 80-char rgb core line (Charter 10)" ],
|
||||
'rgb24text' => [ 2510.0, "Char in 30-char rgb core line (Charter 24)" ],
|
||||
'rgbftext' => [ 10700.0, "Char in 80-char rgb core line (Courier 12)" ],
|
||||
'scroll10' => [ 1310000.0, "Scroll 10x10 pixels" ],
|
||||
'scroll100' => [ 52000.0, "Scroll 100x100 pixels" ],
|
||||
'scroll500' => [ 2190.0, "Scroll 500x500 pixels" ],
|
||||
'copywinwin10' => [ 1030000.0, "Copy 10x10 from window to window" ],
|
||||
'copywinwin100' => [ 52200.0, "Copy 100x100 from window to window" ],
|
||||
'copywinwin500' => [ 2080.0, "Copy 500x500 from window to window" ],
|
||||
'copypixwin10' => [ 502000.0, "Copy 10x10 from pixmap to window" ],
|
||||
'copypixwin100' => [ 20300.0, "Copy 100x100 from pixmap to window" ],
|
||||
'copypixwin500' => [ 1020.0, "Copy 500x500 from pixmap to window" ],
|
||||
'copywinpix10' => [ 7730.0, "Copy 10x10 from window to pixmap" ],
|
||||
'copywinpix100' => [ 127.0, "Copy 100x100 from window to pixmap" ],
|
||||
'copywinpix500' => [ 5.0, "Copy 500x500 from window to pixmap" ],
|
||||
'copypixpix10' => [ 1260000.0, "Copy 10x10 from pixmap to pixmap" ],
|
||||
'copypixpix100' => [ 56300.0, "Copy 100x100 from pixmap to pixmap" ],
|
||||
'copypixpix500' => [ 2470.0, "Copy 500x500 from pixmap to pixmap" ],
|
||||
'copyplane10' => [ 466000.0, "Copy 10x10 1-bit deep plane" ],
|
||||
'copyplane100' => [ 13700.0, "Copy 100x100 1-bit deep plane" ],
|
||||
'copyplane500' => [ 671.0, "Copy 500x500 1-bit deep plane" ],
|
||||
'deepcopyplane10' => [ 151000.0, "Copy 10x10 n-bit deep plane" ],
|
||||
'deepcopyplane100' => [ 6090.0, "Copy 100x100 n-bit deep plane" ],
|
||||
'deepcopyplane500' => [ 278.0, "Copy 500x500 n-bit deep plane" ],
|
||||
'putimage10' => [ 434000.0, "PutImage 10x10 square" ],
|
||||
'putimage100' => [ 13600.0, "PutImage 100x100 square" ],
|
||||
'putimage500' => [ 713.0, "PutImage 500x500 square" ],
|
||||
'putimagexy10' => [ 321.0, "PutImage XY 10x10 square" ],
|
||||
'putimagexy100' => [ 3.2, "PutImage XY 100x100 square" ],
|
||||
'putimagexy500' => [ 0.1, "PutImage XY 500x500 square" ],
|
||||
'shmput10' => [ 465000.0, "ShmPutImage 10x10 square" ],
|
||||
'shmput100' => [ 20200.0, "ShmPutImage 100x100 square" ],
|
||||
'shmput500' => [ 1020.0, "ShmPutImage 500x500 square" ],
|
||||
'shmputxy10' => [ 31400.0, "ShmPutImage XY 10x10 square" ],
|
||||
'shmputxy100' => [ 458.0, "ShmPutImage XY 100x100 square" ],
|
||||
'shmputxy500' => [ 19.0, "ShmPutImage XY 500x500 square" ],
|
||||
'getimage10' => [ 6650.0, "GetImage 10x10 square" ],
|
||||
'getimage100' => [ 77.0, "GetImage 100x100 square" ],
|
||||
'getimage500' => [ 3.1, "GetImage 500x500 square" ],
|
||||
'getimagexy10' => [ 320.0, "GetImage XY 10x10 square" ],
|
||||
'getimagexy100' => [ 3.2, "GetImage XY 100x100 square" ],
|
||||
'getimagexy500' => [ 0.1, "GetImage XY 500x500 square" ],
|
||||
'noop' => [ 8760000.0, "X protocol NoOperation" ],
|
||||
'pointer' => [ 54800.0, "QueryPointer" ],
|
||||
'prop' => [ 50900.0, "GetProperty" ],
|
||||
'gc' => [ 1190000.0, "Change graphics context" ],
|
||||
'create' => [ 597000.0, "Create and map subwindows (25 kids)" ],
|
||||
'ucreate' => [ 1100000.0, "Create unmapped window (25 kids)" ],
|
||||
'map' => [ 1350000.0, "Map window via parent (25 kids)" ],
|
||||
'unmap' => [ 3360000.0, "Unmap window via parent (25 kids)" ],
|
||||
'destroy' => [ 1190000.0, "Destroy window via parent (25 kids)" ],
|
||||
'popup' => [ 660000.0, "Hide/expose window via popup (25 kids)" ],
|
||||
'move' => [ 120000.0, "Move window (25 kids)" ],
|
||||
'umove' => [ 1990000.0, "Moved unmapped window (25 kids)" ],
|
||||
'movetree' => [ 877000.0, "Move window via parent (25 kids)" ],
|
||||
'resize' => [ 136000.0, "Resize window (25 kids)" ],
|
||||
'uresize' => [ 1870000.0, "Resize unmapped window (25 kids)" ],
|
||||
'circulate' => [ 56300.0, "Circulate window (25 kids)" ],
|
||||
'ucirculate' => [ 3630000.0, "Circulate Unmapped window (25 kids)" ],
|
||||
};
|
||||
|
||||
|
||||
# This array defines named groups of tests. This is designed to allow
|
||||
# for simpler runs of related tests.
|
||||
#
|
||||
# Note that this array does *not* include all the x11perf tests. The idea
|
||||
# here is to run a representative sampling of the available tests, to get
|
||||
# a general idea of a system's performance, without taking forever to
|
||||
# do it. If you want to do detailed analysis of an X server or graphics
|
||||
# chip, then use x11perf directly.
|
||||
my $testGroups = {
|
||||
'rects' => [ "rect10", "rect100", "oddtilerect10", "eschertilerect100" ],
|
||||
'lines' => [ "seg100c3", "wvseg100", "ddline100", "worect500" ],
|
||||
'circle' => [ "circle500", "wddcircle100", "wpcircle100", "fspcircle100" ],
|
||||
'ellipse' => [ "ddellipse100", "wddellipse100", "pellipse10", "fspellipse100" ],
|
||||
'shapes' => [ "triangle10", "trap300", "oddostrap300", "eschertiletrap300" ],
|
||||
'aashapes' => [ "aa4trap300", "aa1trap10", "aatrap2x300", "addaatrapezoid300" ],
|
||||
'polys' => [ "complex10", "64poly100convex", "64poly10complex", "64poly100complex" ],
|
||||
'text' => [ "polytext16", "rgb24text", "caa10text", "ca24text" ],
|
||||
'blit' => [ "scroll100", "copypixwin10", "deepcopyplane10", "putimagexy500" ],
|
||||
'window' => [ "popup", "move", "movetree", "resize" ],
|
||||
};
|
||||
|
||||
|
||||
############################################################################
|
||||
# CODE
|
||||
############################################################################
|
||||
|
||||
# Exec the given command, and catch its standard output.
|
||||
# We return an array containing the PID and the filehandle on the
|
||||
# process' standard output. It's up to the caller to wait for the command
|
||||
# to terminate.
|
||||
sub command {
|
||||
my ( $cmd ) = @_;
|
||||
|
||||
my $pid = open(my $childFd, "-|");
|
||||
if (!defined($pid)) {
|
||||
die("Run: fork() failed (undef)\n");
|
||||
} elsif ($pid == 0) {
|
||||
exec($cmd);
|
||||
die("Run: exec() failed (returned)\n");
|
||||
}
|
||||
|
||||
return ( $pid, $childFd );
|
||||
}
|
||||
|
||||
|
||||
# Get data from running a system command. Used for things like getting
|
||||
# the host OS from `uname -o` etc.
|
||||
#
|
||||
# Ignores initial blank lines from the command and returns the first
|
||||
# non-blank line, with white space trimmed off.
|
||||
sub runTest {
|
||||
my ( $test, $reps, $time ) = @_;
|
||||
|
||||
my $tdata = $testData->{$test};
|
||||
if (!defined($tdata)) {
|
||||
printf STDERR "gfx-x11: No such test: %s\n", $test;
|
||||
exit(9);
|
||||
}
|
||||
|
||||
my $cmd = sprintf "x11perf -repeat %d -subs 25 -time %d -%s",
|
||||
$reps, $time, $test;
|
||||
my ( $pid, $fd ) = command($cmd);
|
||||
my $average = 0;
|
||||
while (<$fd>) {
|
||||
chomp;
|
||||
|
||||
# Display the output for logging.
|
||||
printf "%s\n", $_;
|
||||
|
||||
# Save the score.
|
||||
my ( $reps, $per, $rate ) =
|
||||
( m:([0-9]+)\s+trep\s+@\s+([0-9.]+)\s+msec\s+\(\s*([0-9.]+)/sec\): );
|
||||
$average = $rate if (defined($rate));
|
||||
}
|
||||
|
||||
# Close the command and wait for it to die. Bomb out if it failed.
|
||||
# close($fd);
|
||||
my $p = waitpid($pid, 0);
|
||||
my $status = $?;
|
||||
exit($status) if ($status != 0);
|
||||
|
||||
# Calculate and return the weighted result.
|
||||
my $score = $average / $tdata->[0] * 1000.0;
|
||||
printf "Test %s: %d --> %.1f\n", $test, $average, $score;
|
||||
return $score;
|
||||
}
|
||||
|
||||
|
||||
sub runGroup {
|
||||
my ( $group, $reps, $time ) = @_;
|
||||
|
||||
my $gdata = $testGroups->{$group};
|
||||
if (!defined($gdata)) {
|
||||
printf STDERR "gfx-x11: No such test group: %s\n", $group;
|
||||
exit(9);
|
||||
}
|
||||
|
||||
my $count = 0;
|
||||
my $total = 0;
|
||||
foreach my $test (@$gdata) {
|
||||
$total += runTest($test, $reps, $time);
|
||||
++$count;
|
||||
}
|
||||
$total /= $count;
|
||||
|
||||
$total;
|
||||
}
|
||||
|
||||
|
||||
############################################################################
|
||||
# MAIN
|
||||
############################################################################
|
||||
|
||||
sub main {
|
||||
my @args = @_;
|
||||
|
||||
if (scalar(@args) < 3) {
|
||||
printf STDERR "Usage: gfx-x11 group reps time\n";
|
||||
exit(9);
|
||||
}
|
||||
|
||||
my $reps = $args[1];
|
||||
my $time = $args[2];
|
||||
|
||||
my $score = runGroup($args[0], $reps, $time);
|
||||
printf STDERR "COUNT|%.1f|0|score\n", $score;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
exit(main(@ARGV));
|
||||
|
||||
BIN
rk3308/unixbench-master_32/pgms/hanoi
Executable file
BIN
rk3308/unixbench-master_32/pgms/hanoi
Executable file
Binary file not shown.
46
rk3308/unixbench-master_32/pgms/index.base
Executable file
46
rk3308/unixbench-master_32/pgms/index.base
Executable file
@ -0,0 +1,46 @@
|
||||
# Baseline benchmark scores, used for calculating index results.
|
||||
|
||||
# Scores from "George", a SPARCstation 20-61.
|
||||
dhry2reg|10|lps|116700|116700|2
|
||||
whetstone-double|10|MWIPS|55.0|55.0|2
|
||||
execl|20|lps|43.0|43.0|1
|
||||
fstime|20|KBps|3960|3960|1
|
||||
fsbuffer|20|KBps|1655|1655|1
|
||||
fsdisk|20|KBps|5800|5800|1
|
||||
pipe|10|lps|12440|12440|2
|
||||
context1|10|lps|4000|4000|2
|
||||
spawn|20|lps|126|126|1
|
||||
shell8|60|lpm|6|6|1
|
||||
syscall|10|lps|15000|15000|2
|
||||
|
||||
# The shell1 test was added to the index in 5.0, and this baseline score
|
||||
# was extrapolated to roughly match George's performance.
|
||||
shell1|60|lpm|42.4|42.4|1
|
||||
|
||||
# The 2D baseline scores were derived from a test run on an HP Compaq nc8430
|
||||
# with an ATI Mobility Radeon X1600 Video (256MB) — this is a fairly
|
||||
# common modern adaptor with 3D. The baseline scores here are then
|
||||
# 1/66.6 of the values from that run, to bring them roughly in line with
|
||||
# George. (The HP has an index score of 666.6 single-process.)
|
||||
2d-rects|3|score|15|15|1
|
||||
#2d-lines|3|score|15|15|1
|
||||
#2d-circle|3|score|15|15|1
|
||||
2d-ellipse|3|score|15|15|1
|
||||
#2d-shapes|3|score|15|15|1
|
||||
2d-aashapes|3|score|15|15|1
|
||||
#2d-polys|3|score|15|15|1
|
||||
2d-text|3|score|15|15|1
|
||||
2d-blit|3|score|15|15|1
|
||||
2d-window|3|score|15|15|1
|
||||
|
||||
# The gears test score is derived from a test run on an HP Compaq nc8430
|
||||
# with an ATI Mobility Radeon X1600 Video (256MB) — this is a fairly
|
||||
# common modern adaptor with 3D. The baseline scores here are then
|
||||
# 1/66.6 of the values from that run, to bring them roughly in line with
|
||||
# George.
|
||||
ubgears|20|fps|33.4|33.4|3
|
||||
|
||||
# The grep and sysexec tests were added in 5.1.1; they are not index tests,
|
||||
# but these baseline scores were added for convenience.
|
||||
grep|30|lpm|1|1|3
|
||||
sysexec|10|lps|25|25|10
|
||||
BIN
rk3308/unixbench-master_32/pgms/int
Executable file
BIN
rk3308/unixbench-master_32/pgms/int
Executable file
Binary file not shown.
BIN
rk3308/unixbench-master_32/pgms/long
Executable file
BIN
rk3308/unixbench-master_32/pgms/long
Executable file
Binary file not shown.
BIN
rk3308/unixbench-master_32/pgms/looper
Executable file
BIN
rk3308/unixbench-master_32/pgms/looper
Executable file
Binary file not shown.
23
rk3308/unixbench-master_32/pgms/multi.sh
Executable file
23
rk3308/unixbench-master_32/pgms/multi.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#! /bin/sh
|
||||
###############################################################################
|
||||
# The BYTE UNIX Benchmarks - Release 3
|
||||
# Module: multi.sh SID: 3.4 5/15/91 19:30:24
|
||||
#
|
||||
###############################################################################
|
||||
# Bug reports, patches, comments, suggestions should be sent to:
|
||||
#
|
||||
# Ben Smith or Rick Grehan at BYTE Magazine
|
||||
# ben@bytepb.UUCP rick_g@bytepb.UUCP
|
||||
#
|
||||
###############################################################################
|
||||
# Modification Log:
|
||||
#
|
||||
###############################################################################
|
||||
ID="@(#)multi.sh:3.4 -- 5/15/91 19:30:24";
|
||||
instance=1
|
||||
while [ $instance -le $1 ]; do
|
||||
/bin/sh "$UB_BINDIR/tst.sh" &
|
||||
instance=`expr $instance + 1`
|
||||
done
|
||||
wait
|
||||
|
||||
BIN
rk3308/unixbench-master_32/pgms/pipe
Executable file
BIN
rk3308/unixbench-master_32/pgms/pipe
Executable file
Binary file not shown.
BIN
rk3308/unixbench-master_32/pgms/register
Executable file
BIN
rk3308/unixbench-master_32/pgms/register
Executable file
Binary file not shown.
BIN
rk3308/unixbench-master_32/pgms/short
Executable file
BIN
rk3308/unixbench-master_32/pgms/short
Executable file
Binary file not shown.
BIN
rk3308/unixbench-master_32/pgms/spawn
Executable file
BIN
rk3308/unixbench-master_32/pgms/spawn
Executable file
Binary file not shown.
BIN
rk3308/unixbench-master_32/pgms/syscall
Executable file
BIN
rk3308/unixbench-master_32/pgms/syscall
Executable file
Binary file not shown.
20
rk3308/unixbench-master_32/pgms/tst.sh
Executable file
20
rk3308/unixbench-master_32/pgms/tst.sh
Executable file
@ -0,0 +1,20 @@
|
||||
#! /bin/sh
|
||||
###############################################################################
|
||||
# The BYTE UNIX Benchmarks - Release 3
|
||||
# Module: tst.sh SID: 3.4 5/15/91 19:30:24
|
||||
#
|
||||
###############################################################################
|
||||
# Bug reports, patches, comments, suggestions should be sent to:
|
||||
#
|
||||
# Ben Smith or Rick Grehan at BYTE Magazine
|
||||
# ben@bytepb.UUCP rick_g@bytepb.UUCP
|
||||
#
|
||||
###############################################################################
|
||||
# Modification Log:
|
||||
#
|
||||
###############################################################################
|
||||
ID="@(#)tst.sh:3.4 -- 5/15/91 19:30:24";
|
||||
sort >sort.$$ <sort.src
|
||||
od sort.$$ | sort -n -k 1 > od.$$
|
||||
grep the sort.$$ | tee grep.$$ | wc > wc.$$
|
||||
rm sort.$$ grep.$$ od.$$ wc.$$
|
||||
14
rk3308/unixbench-master_32/pgms/unixbench.logo
Executable file
14
rk3308/unixbench-master_32/pgms/unixbench.logo
Executable file
@ -0,0 +1,14 @@
|
||||
|
||||
# # # # # # # ##### ###### # # #### # #
|
||||
# # ## # # # # # # # ## # # # # #
|
||||
# # # # # # ## ##### ##### # # # # ######
|
||||
# # # # # # ## # # # # # # # # #
|
||||
# # # ## # # # # # # # ## # # # #
|
||||
#### # # # # # ##### ###### # # #### # #
|
||||
|
||||
Version 5.1.3 Based on the Byte Magazine Unix Benchmark
|
||||
|
||||
Multi-CPU version Version 5 revisions by Ian Smith,
|
||||
Sunnyvale, CA, USA
|
||||
January 13, 2011 johantheghost at yahoo period com
|
||||
|
||||
BIN
rk3308/unixbench-master_32/pgms/whetstone-double
Executable file
BIN
rk3308/unixbench-master_32/pgms/whetstone-double
Executable file
Binary file not shown.
110
rk3308/unixbench-master_32/src/arith.c
Executable file
110
rk3308/unixbench-master_32/src/arith.c
Executable file
@ -0,0 +1,110 @@
|
||||
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: arith.c SID: 3.3 5/15/91 19:30:19
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* May 12, 1989 - modified empty loops to avoid nullifying by optimizing
|
||||
* compilers
|
||||
* August 28, 1990 - changed timing relationship--now returns total number
|
||||
* of iterations (ty)
|
||||
* November 9, 1990 - made changes suggested by Keith Cantrell
|
||||
* (digi!kcantrel) to defeat optimization
|
||||
* to non-existence
|
||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
char SCCSid[] = "@(#) @(#)arith.c:3.3 -- 5/15/91 19:30:19";
|
||||
/*
|
||||
* arithmetic test
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "timeit.c"
|
||||
|
||||
int dumb_stuff(int);
|
||||
|
||||
volatile unsigned long iter;
|
||||
|
||||
/* this function is called when the alarm expires */
|
||||
void report()
|
||||
{
|
||||
fprintf(stderr,"COUNT|%ld|1|lps\n", iter);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int duration;
|
||||
int result = 0;
|
||||
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s duration\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
duration = atoi(argv[1]);
|
||||
|
||||
/* set up alarm call */
|
||||
iter = 0; /* init iteration count */
|
||||
wake_me(duration, report);
|
||||
|
||||
/* this loop will be interrupted by the alarm call */
|
||||
while (1)
|
||||
{
|
||||
/* in switching to time-based (instead of iteration-based),
|
||||
the following statement was added. It should not skew
|
||||
the timings too much--there was an increment and test
|
||||
in the "while" expression above. The only difference is
|
||||
that now we're incrementing a long instead of an int. (ty) */
|
||||
++iter;
|
||||
/* the loop calls a function to insure that something is done
|
||||
the results of the function are fed back in (just so they
|
||||
they won't be thrown away. A loop with
|
||||
unused assignments may get optimized out of existence */
|
||||
result = dumb_stuff(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************** dumb_stuff *******************/
|
||||
int dumb_stuff(i)
|
||||
int i;
|
||||
{
|
||||
#ifndef arithoh
|
||||
datum x, y, z;
|
||||
z = 0;
|
||||
#endif
|
||||
/*
|
||||
* 101
|
||||
* sum i*i/(i*i-1)
|
||||
* i=2
|
||||
*/
|
||||
/* notice that the i value is always reset by the loop */
|
||||
for (i=2; i<=101; i++)
|
||||
{
|
||||
#ifndef arithoh
|
||||
x = i;
|
||||
y = x*x;
|
||||
z += y/(y-1);
|
||||
}
|
||||
return(x+y+z);
|
||||
#else
|
||||
}
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
592
rk3308/unixbench-master_32/src/big.c
Executable file
592
rk3308/unixbench-master_32/src/big.c
Executable file
@ -0,0 +1,592 @@
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: big.c SID: 3.3 5/15/91 19:30:18
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
/*
|
||||
* dummy code for execl test [ old version of makework.c ]
|
||||
*
|
||||
* makework [ -r rate ] [ -c copyfile ] nusers
|
||||
*
|
||||
* job streams are specified on standard input with lines of the form
|
||||
* full_path_name_for_command [ options ] [ <standard_input_file ]
|
||||
*
|
||||
* "standard input" is send to all nuser instances of the commands in the
|
||||
* job streams at a rate not in excess of "rate" characters per second
|
||||
* per command
|
||||
*
|
||||
*/
|
||||
/* this code is included in other files and therefore has no SCCSid */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
|
||||
#define DEF_RATE 5.0
|
||||
#define GRANULE 5
|
||||
#define CHUNK 60
|
||||
#define MAXCHILD 12
|
||||
#define MAXWORK 10
|
||||
|
||||
void wrapup(const char *);
|
||||
void onalarm(int);
|
||||
void pipeerr();
|
||||
void grunt();
|
||||
void getwork(void);
|
||||
#if debug
|
||||
void dumpwork(void);
|
||||
#endif
|
||||
void fatal(const char *s);
|
||||
|
||||
float thres;
|
||||
float est_rate = DEF_RATE;
|
||||
int nusers; /* number of concurrent users to be simulated by
|
||||
* this process */
|
||||
int firstuser; /* ordinal identification of first user for this
|
||||
* process */
|
||||
int nwork = 0; /* number of job streams */
|
||||
int exit_status = 0; /* returned to parent */
|
||||
int sigpipe; /* pipe write error flag */
|
||||
|
||||
struct st_work {
|
||||
char *cmd; /* name of command to run */
|
||||
char **av; /* arguments to command */
|
||||
char *input; /* standard input buffer */
|
||||
int inpsize; /* size of standard input buffer */
|
||||
char *outf; /* standard output (filename) */
|
||||
} work[MAXWORK];
|
||||
|
||||
struct {
|
||||
int xmit; /* # characters sent */
|
||||
char *bp; /* std input buffer pointer */
|
||||
int blen; /* std input buffer length */
|
||||
int fd; /* stdin to command */
|
||||
int pid; /* child PID */
|
||||
char *line; /* start of input line */
|
||||
int firstjob; /* inital piece of work */
|
||||
int thisjob; /* current piece of work */
|
||||
} child[MAXCHILD], *cp;
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int i;
|
||||
int l;
|
||||
int fcopy = 0; /* fd for copy output */
|
||||
int master = 1; /* the REAL master, == 0 for clones */
|
||||
int nchild; /* no. of children for a clone to run */
|
||||
int done; /* count of children finished */
|
||||
int output; /* aggregate output char count for all
|
||||
children */
|
||||
int c;
|
||||
int thiswork = 0; /* next job stream to allocate */
|
||||
int nch; /* # characters to write */
|
||||
int written; /* # characters actully written */
|
||||
char logname[15]; /* name of the log file(s) */
|
||||
int pvec[2]; /* for pipes */
|
||||
char *p;
|
||||
char *prog; /* my name */
|
||||
|
||||
#if ! debug
|
||||
freopen("masterlog.00", "a", stderr);
|
||||
#endif
|
||||
prog = argv[0];
|
||||
while (argc > 1 && argv[1][0] == '-') {
|
||||
p = &argv[1][1];
|
||||
argc--;
|
||||
argv++;
|
||||
while (*p) {
|
||||
switch (*p) {
|
||||
case 'r':
|
||||
est_rate = atoi(argv[1]);
|
||||
sscanf(argv[1], "%f", &est_rate);
|
||||
if (est_rate <= 0) {
|
||||
fprintf(stderr, "%s: bad rate, reset to %.2f chars/sec\n", prog, DEF_RATE);
|
||||
est_rate = DEF_RATE;
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
fcopy = open(argv[1], 1);
|
||||
if (fcopy < 0)
|
||||
fcopy = creat(argv[1], 0600);
|
||||
if (fcopy < 0) {
|
||||
fprintf(stderr, "%s: cannot open copy file '%s'\n",
|
||||
prog, argv[1]);
|
||||
exit(2);
|
||||
}
|
||||
lseek(fcopy, 0L, 2); /* append at end of file */
|
||||
argc--;
|
||||
argv++;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%s: bad flag '%c'\n", prog, *p);
|
||||
exit(4);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "%s: missing nusers\n", prog);
|
||||
exit(4);
|
||||
}
|
||||
|
||||
nusers = atoi(argv[1]);
|
||||
if (nusers < 1) {
|
||||
fprintf(stderr, "%s: impossible nusers (%d<-%s)\n", prog, nusers, argv[1]);
|
||||
exit(4);
|
||||
}
|
||||
fprintf(stderr, "%d Users\n", nusers);
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
/* build job streams */
|
||||
getwork();
|
||||
#if debug
|
||||
dumpwork();
|
||||
#endif
|
||||
|
||||
/* clone copies of myself to run up to MAXCHILD jobs each */
|
||||
firstuser = MAXCHILD;
|
||||
fprintf(stderr, "master pid %d\n", getpid());
|
||||
fflush(stderr);
|
||||
while (nusers > MAXCHILD) {
|
||||
fflush(stderr);
|
||||
if (nusers >= 2*MAXCHILD)
|
||||
/* the next clone must run MAXCHILD jobs */
|
||||
nchild = MAXCHILD;
|
||||
else
|
||||
/* the next clone must run the leftover jobs */
|
||||
nchild = nusers - MAXCHILD;
|
||||
if ((l = fork()) == -1) {
|
||||
/* fork failed */
|
||||
fatal("** clone fork failed **\n");
|
||||
goto bepatient;
|
||||
} else if (l > 0) {
|
||||
fprintf(stderr, "master clone pid %d\n", l);
|
||||
/* I am the master with nchild fewer jobs to run */
|
||||
nusers -= nchild;
|
||||
firstuser += MAXCHILD;
|
||||
continue;
|
||||
} else {
|
||||
/* I am a clone, run MAXCHILD jobs */
|
||||
#if ! debug
|
||||
sprintf(logname, "masterlog.%02d", firstuser/MAXCHILD);
|
||||
freopen(logname, "w", stderr);
|
||||
#endif
|
||||
master = 0;
|
||||
nusers = nchild;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (master)
|
||||
firstuser = 0;
|
||||
|
||||
close(0);
|
||||
for (i = 0; i < nusers; i++ ) {
|
||||
fprintf(stderr, "user %d job %d ", firstuser+i, thiswork);
|
||||
if (pipe(pvec) == -1) {
|
||||
/* this is fatal */
|
||||
fatal("** pipe failed **\n");
|
||||
goto bepatient;
|
||||
}
|
||||
fflush(stderr);
|
||||
if ((child[i].pid = fork()) == 0) {
|
||||
int fd;
|
||||
/* the command */
|
||||
if (pvec[0] != 0) {
|
||||
close(0);
|
||||
dup(pvec[0]);
|
||||
}
|
||||
#if ! debug
|
||||
sprintf(logname, "userlog.%02d", firstuser+i);
|
||||
freopen(logname, "w", stderr);
|
||||
#endif
|
||||
for (fd = 3; fd < 24; fd++)
|
||||
close(fd);
|
||||
if (work[thiswork].outf[0] != '\0') {
|
||||
/* redirect std output */
|
||||
char *q;
|
||||
for (q = work[thiswork].outf; *q != '\n'; q++) ;
|
||||
*q = '\0';
|
||||
if (freopen(work[thiswork].outf, "w", stdout) == NULL) {
|
||||
fprintf(stderr, "makework: cannot open %s for std output\n",
|
||||
work[thiswork].outf);
|
||||
fflush(stderr);
|
||||
}
|
||||
*q = '\n';
|
||||
}
|
||||
execv(work[thiswork].cmd, work[thiswork].av);
|
||||
/* don't expect to get here! */
|
||||
fatal("** exec failed **\n");
|
||||
goto bepatient;
|
||||
}
|
||||
else if (child[i].pid == -1) {
|
||||
fatal("** fork failed **\n");
|
||||
goto bepatient;
|
||||
}
|
||||
else {
|
||||
close(pvec[0]);
|
||||
child[i].fd = pvec[1];
|
||||
child[i].line = child[i].bp = work[thiswork].input;
|
||||
child[i].blen = work[thiswork].inpsize;
|
||||
child[i].thisjob = thiswork;
|
||||
child[i].firstjob = thiswork;
|
||||
fprintf(stderr, "pid %d pipe fd %d", child[i].pid, child[i].fd);
|
||||
if (work[thiswork].outf[0] != '\0') {
|
||||
char *q;
|
||||
fprintf(stderr, " > ");
|
||||
for (q=work[thiswork].outf; *q != '\n'; q++)
|
||||
fputc(*q, stderr);
|
||||
}
|
||||
fputc('\n', stderr);
|
||||
thiswork++;
|
||||
if (thiswork >= nwork)
|
||||
thiswork = 0;
|
||||
}
|
||||
}
|
||||
fflush(stderr);
|
||||
|
||||
srand(time(0));
|
||||
thres = 0;
|
||||
done = output = 0;
|
||||
for (i = 0; i < nusers; i++) {
|
||||
if (child[i].blen == 0)
|
||||
done++;
|
||||
else
|
||||
thres += est_rate * GRANULE;
|
||||
}
|
||||
est_rate = thres;
|
||||
|
||||
signal(SIGALRM, onalarm);
|
||||
signal(SIGPIPE, pipeerr);
|
||||
alarm(GRANULE);
|
||||
while (done < nusers) {
|
||||
for (i = 0; i < nusers; i++) {
|
||||
cp = &child[i];
|
||||
if (cp->xmit >= cp->blen) continue;
|
||||
l = rand() % CHUNK + 1; /* 1-CHUNK chars */
|
||||
if (l == 0) continue;
|
||||
if (cp->xmit + l > cp->blen)
|
||||
l = cp->blen - cp->xmit;
|
||||
p = cp->bp;
|
||||
cp->bp += l;
|
||||
cp->xmit += l;
|
||||
#if debug
|
||||
fprintf(stderr, "child %d, %d processed, %d to go\n", i, cp->xmit, cp->blen - cp->xmit);
|
||||
#endif
|
||||
while (p < cp->bp) {
|
||||
if (*p == '\n' || (p == &cp->bp[-1] && cp->xmit >= cp->blen)) {
|
||||
/* write it out */
|
||||
nch = p - cp->line + 1;
|
||||
if ((written = write(cp->fd, cp->line, nch)) != nch) {
|
||||
/* argh! */
|
||||
cp->line[nch] = '\0';
|
||||
fprintf(stderr, "user %d job %d cmd %s ",
|
||||
firstuser+i, cp->thisjob, cp->line);
|
||||
fprintf(stderr, "write(,,%d) returns %d\n", nch, written);
|
||||
if (sigpipe)
|
||||
fatal("** SIGPIPE error **\n");
|
||||
else
|
||||
fatal("** write error **\n");
|
||||
goto bepatient;
|
||||
|
||||
}
|
||||
if (fcopy)
|
||||
write(fcopy, cp->line, p - cp->line + 1);
|
||||
#if debug
|
||||
fprintf(stderr, "child %d gets \"", i);
|
||||
{
|
||||
char *q = cp->line;
|
||||
while (q <= p) {
|
||||
if (*q >= ' ' && *q <= '~')
|
||||
fputc(*q, stderr);
|
||||
else
|
||||
fprintf(stderr, "\\%03o", *q);
|
||||
q++;
|
||||
}
|
||||
}
|
||||
fputc('"', stderr);
|
||||
#endif
|
||||
cp->line = &p[1];
|
||||
}
|
||||
p++;
|
||||
}
|
||||
if (cp->xmit >= cp->blen) {
|
||||
done++;
|
||||
close(cp->fd);
|
||||
#if debug
|
||||
fprintf(stderr, "child %d, close std input\n", i);
|
||||
#endif
|
||||
}
|
||||
output += l;
|
||||
}
|
||||
while (output > thres) {
|
||||
pause();
|
||||
#if debug
|
||||
fprintf(stderr, "after pause: output, thres, done %d %.2f %d\n", output, thres, done);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bepatient:
|
||||
alarm(0);
|
||||
/****
|
||||
* If everything is going OK, we should simply be able to keep
|
||||
* looping unitil 'wait' fails, however some descendent process may
|
||||
* be in a state from which it can never exit, and so a timeout
|
||||
* is used.
|
||||
* 5 minutes should be ample, since the time to run all jobs is of
|
||||
* the order of 5-10 minutes, however some machines are painfully slow,
|
||||
* so the timeout has been set at 20 minutes (1200 seconds).
|
||||
****/
|
||||
signal(SIGALRM, grunt);
|
||||
alarm(1200);
|
||||
while ((c = wait(&l)) != -1) {
|
||||
for (i = 0; i < nusers; i++) {
|
||||
if (c == child[i].pid) {
|
||||
fprintf(stderr, "user %d job %d pid %d done", firstuser+i, child[i].thisjob, c);
|
||||
if (l != 0) {
|
||||
if (l & 0x7f)
|
||||
fprintf(stderr, " status %d", l & 0x7f);
|
||||
if (l & 0xff00)
|
||||
fprintf(stderr, " exit code %d", (l>>8) & 0xff);
|
||||
exit_status = 4;
|
||||
}
|
||||
fputc('\n', stderr);
|
||||
c = child[i].pid = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (c != -1) {
|
||||
fprintf(stderr, "master clone done, pid %d ", c);
|
||||
if (l != 0) {
|
||||
if (l & 0x7f)
|
||||
fprintf(stderr, " status %d", l & 0x7f);
|
||||
if (l & 0xff00)
|
||||
fprintf(stderr, " exit code %d", (l>>8) & 0xff);
|
||||
exit_status = 4;
|
||||
}
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
}
|
||||
alarm(0);
|
||||
wrapup("Finished waiting ...");
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void onalarm(int foo)
|
||||
{
|
||||
thres += est_rate;
|
||||
signal(SIGALRM, onalarm);
|
||||
alarm(GRANULE);
|
||||
}
|
||||
|
||||
void grunt()
|
||||
{
|
||||
/* timeout after label "bepatient" in main */
|
||||
exit_status = 4;
|
||||
wrapup("Timed out waiting for jobs to finish ...");
|
||||
}
|
||||
|
||||
void pipeerr()
|
||||
{
|
||||
sigpipe++;
|
||||
}
|
||||
|
||||
void wrapup(const char *reason)
|
||||
{
|
||||
int i;
|
||||
int killed = 0;
|
||||
fflush(stderr);
|
||||
for (i = 0; i < nusers; i++) {
|
||||
if (child[i].pid > 0 && kill(child[i].pid, SIGKILL) != -1) {
|
||||
if (!killed) {
|
||||
killed++;
|
||||
fprintf(stderr, "%s\n", reason);
|
||||
fflush(stderr);
|
||||
}
|
||||
fprintf(stderr, "user %d job %d pid %d killed off\n", firstuser+i, child[i].thisjob, child[i].pid);
|
||||
fflush(stderr);
|
||||
}
|
||||
}
|
||||
exit(exit_status);
|
||||
}
|
||||
|
||||
#define MAXLINE 512
|
||||
void getwork(void)
|
||||
{
|
||||
int i;
|
||||
int f;
|
||||
int ac=0;
|
||||
char *lp = (void *)0;
|
||||
char *q = (void *)0;
|
||||
struct st_work *w = (void *)0;
|
||||
char line[MAXLINE];
|
||||
|
||||
while (fgets(line, MAXLINE, stdin) != NULL) {
|
||||
if (nwork >= MAXWORK) {
|
||||
fprintf(stderr, "Too many jobs specified, .. increase MAXWORK\n");
|
||||
exit(4);
|
||||
}
|
||||
w = &work[nwork];
|
||||
lp = line;
|
||||
i = 1;
|
||||
while (*lp && *lp != ' ') {
|
||||
i++;
|
||||
lp++;
|
||||
}
|
||||
w->cmd = (char *)malloc(i);
|
||||
strncpy(w->cmd, line, i-1);
|
||||
w->cmd[i-1] = '\0';
|
||||
w->inpsize = 0;
|
||||
w->input = "";
|
||||
/* start to build arg list */
|
||||
ac = 2;
|
||||
w->av = (char **)malloc(2*sizeof(char *));
|
||||
q = w->cmd;
|
||||
while (*q) q++;
|
||||
q--;
|
||||
while (q >= w->cmd) {
|
||||
if (*q == '/') {
|
||||
q++;
|
||||
break;
|
||||
}
|
||||
q--;
|
||||
}
|
||||
w->av[0] = q;
|
||||
while (*lp) {
|
||||
if (*lp == ' ') {
|
||||
/* space */
|
||||
lp++;
|
||||
continue;
|
||||
}
|
||||
else if (*lp == '<') {
|
||||
/* standard input for this job */
|
||||
q = ++lp;
|
||||
while (*lp && *lp != ' ') lp++;
|
||||
*lp = '\0';
|
||||
if ((f = open(q, 0)) == -1) {
|
||||
fprintf(stderr, "cannot open input file (%s) for job %d\n",
|
||||
q, nwork);
|
||||
exit(4);
|
||||
}
|
||||
/* gobble input */
|
||||
w->input = (char *)malloc(512);
|
||||
while ((i = read(f, &w->input[w->inpsize], 512)) > 0) {
|
||||
w->inpsize += i;
|
||||
w->input = (char *)realloc(w->input, w->inpsize+512);
|
||||
}
|
||||
w->input = (char *)realloc(w->input, w->inpsize);
|
||||
close(f);
|
||||
/* extract stdout file name from line beginning "C=" */
|
||||
w->outf = "";
|
||||
for (q = w->input; q < &w->input[w->inpsize-10]; q++) {
|
||||
if (*q == '\n' && strncmp(&q[1], "C=", 2) == 0) {
|
||||
w->outf = &q[3];
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if debug
|
||||
if (*w->outf) {
|
||||
fprintf(stderr, "stdout->");
|
||||
for (q=w->outf; *q != '\n'; q++)
|
||||
fputc(*q, stderr);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
/* a command option */
|
||||
ac++;
|
||||
w->av = (char **)realloc(w->av, ac*sizeof(char *));
|
||||
q = lp;
|
||||
i = 1;
|
||||
while (*lp && *lp != ' ') {
|
||||
lp++;
|
||||
i++;
|
||||
}
|
||||
w->av[ac-2] = (char *)malloc(i);
|
||||
strncpy(w->av[ac-2], q, i-1);
|
||||
w->av[ac-2][i-1] = '\0';
|
||||
}
|
||||
}
|
||||
w->av[ac-1] = (char *)0;
|
||||
nwork++;
|
||||
}
|
||||
}
|
||||
|
||||
#if debug
|
||||
void dumpwork(void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for (i = 0; i < nwork; i++) {
|
||||
fprintf(stderr, "job %d: cmd: %s\n", i, work[i].cmd);
|
||||
j = 0;
|
||||
while (work[i].av[j]) {
|
||||
fprintf(stderr, "argv[%d]: %s\n", j, work[i].av[j]);
|
||||
j++;
|
||||
}
|
||||
fprintf(stderr, "input: %d chars text: ", work[i].inpsize);
|
||||
if (work[i].input == (char *)0)
|
||||
fprintf(stderr, "<NULL>\n");
|
||||
else {
|
||||
register char *pend;
|
||||
char *p;
|
||||
char c;
|
||||
p = work[i].input;
|
||||
while (*p) {
|
||||
pend = p;
|
||||
while (*pend && *pend != '\n')
|
||||
pend++;
|
||||
c = *pend;
|
||||
*pend = '\0';
|
||||
fprintf(stderr, "%s\n", p);
|
||||
*pend = c;
|
||||
p = &pend[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void fatal(const char *s)
|
||||
{
|
||||
int i;
|
||||
fprintf(stderr, "%s", s);
|
||||
fflush(stderr);
|
||||
perror("Reason?");
|
||||
fflush(stderr);
|
||||
for (i = 0; i < nusers; i++) {
|
||||
if (child[i].pid > 0 && kill(child[i].pid, SIGKILL) != -1) {
|
||||
fprintf(stderr, "pid %d killed off\n", child[i].pid);
|
||||
fflush(stderr);
|
||||
}
|
||||
}
|
||||
exit_status = 4;
|
||||
}
|
||||
126
rk3308/unixbench-master_32/src/context1.c
Executable file
126
rk3308/unixbench-master_32/src/context1.c
Executable file
@ -0,0 +1,126 @@
|
||||
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: context1.c SID: 3.3 5/15/91 19:30:18
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* $Header: context1.c,v 3.4 87/06/22 14:22:59 kjmcdonell Beta $
|
||||
* August 28, 1990 - changed timing routines--now returns total number of
|
||||
* iterations in specified time period
|
||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
char SCCSid[] = "@(#) @(#)context1.c:3.3 -- 5/15/91 19:30:18";
|
||||
/*
|
||||
* Context switching via synchronized unbuffered pipe i/o
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "timeit.c"
|
||||
|
||||
unsigned long iter;
|
||||
|
||||
void report()
|
||||
{
|
||||
fprintf(stderr, "COUNT|%lu|1|lps\n", iter);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int duration;
|
||||
unsigned long check;
|
||||
int p1[2], p2[2];
|
||||
ssize_t ret;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: context duration\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
duration = atoi(argv[1]);
|
||||
|
||||
/* set up alarm call */
|
||||
iter = 0;
|
||||
wake_me(duration, report);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
if (pipe(p1) || pipe(p2)) {
|
||||
perror("pipe create failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fork()) { /* parent process */
|
||||
/* master, write p1 & read p2 */
|
||||
close(p1[0]); close(p2[1]);
|
||||
while (1) {
|
||||
if ((ret = write(p1[1], (char *)&iter, sizeof(iter))) != sizeof(iter)) {
|
||||
if ((ret == -1) && (errno == EPIPE)) {
|
||||
alarm(0);
|
||||
report(); /* does not return */
|
||||
}
|
||||
if ((ret == -1) && (errno != 0) && (errno != EINTR))
|
||||
perror("master write failed");
|
||||
exit(1);
|
||||
}
|
||||
if ((ret = read(p2[0], (char *)&check, sizeof(check))) != sizeof(check)) {
|
||||
if ((ret == 0)) { /* end-of-stream */
|
||||
alarm(0);
|
||||
report(); /* does not return */
|
||||
}
|
||||
if ((ret == -1) && (errno != 0) && (errno != EINTR))
|
||||
perror("master read failed");
|
||||
exit(1);
|
||||
}
|
||||
if (check != iter) {
|
||||
fprintf(stderr, "Master sync error: expect %lu, got %lu\n",
|
||||
iter, check);
|
||||
exit(2);
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
else { /* child process */
|
||||
/* slave, read p1 & write p2 */
|
||||
close(p1[1]); close(p2[0]);
|
||||
while (1) {
|
||||
if ((ret = read(p1[0], (char *)&check, sizeof(check))) != sizeof(check)) {
|
||||
if ((ret == 0)) { /* end-of-stream */
|
||||
alarm(0);
|
||||
report(); /* does not return */
|
||||
}
|
||||
if ((ret == -1) && (errno != 0) && (errno != EINTR))
|
||||
perror("slave read failed");
|
||||
exit(1);
|
||||
}
|
||||
if (check != iter) {
|
||||
fprintf(stderr, "Slave sync error: expect %lu, got %lu\n",
|
||||
iter, check);
|
||||
exit(2);
|
||||
}
|
||||
if ((ret = write(p2[1], (char *)&iter, sizeof(iter))) != sizeof(check)) {
|
||||
if ((ret == -1) && (errno == EPIPE)) {
|
||||
alarm(0);
|
||||
report(); /* does not return */
|
||||
}
|
||||
if ((ret == -1) && (errno != 0) && (errno != EINTR))
|
||||
perror("slave write failed");
|
||||
exit(1);
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
435
rk3308/unixbench-master_32/src/dhry.h
Executable file
435
rk3308/unixbench-master_32/src/dhry.h
Executable file
@ -0,0 +1,435 @@
|
||||
/*****************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: dhry.h SID: 3.4 5/15/91 19:30:21
|
||||
*
|
||||
*****************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*****************************************************************************
|
||||
* Modification Log:
|
||||
* addapted from:
|
||||
*
|
||||
*
|
||||
* "DHRYSTONE" Benchmark Program
|
||||
* -----------------------------
|
||||
*
|
||||
* Version: C, Version 2.1
|
||||
*
|
||||
* File: dhry.h (part 1 of 3)
|
||||
*
|
||||
* Date: May 25, 1988
|
||||
*
|
||||
* Author: Reinhold P. Weicker
|
||||
* Siemens AG, AUT E 51
|
||||
* Postfach 3220
|
||||
* 8520 Erlangen
|
||||
* Germany (West)
|
||||
* Phone: [+49]-9131-7-20330
|
||||
* (8-17 Central European Time)
|
||||
* Usenet: ..!mcvax!unido!estevax!weicker
|
||||
*
|
||||
* Original Version (in Ada) published in
|
||||
* "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
|
||||
* pp. 1013 - 1030, together with the statistics
|
||||
* on which the distribution of statements etc. is based.
|
||||
*
|
||||
* In this C version, the following C library functions are used:
|
||||
* - strcpy, strcmp (inside the measurement loop)
|
||||
* - printf, scanf (outside the measurement loop)
|
||||
* In addition, Berkeley UNIX system calls "times ()" or "time ()"
|
||||
* are used for execution time measurement. For measurements
|
||||
* on other systems, these calls have to be changed.
|
||||
*
|
||||
* Collection of Results:
|
||||
* Reinhold Weicker (address see above) and
|
||||
*
|
||||
* Rick Richardson
|
||||
* PC Research. Inc.
|
||||
* 94 Apple Orchard Drive
|
||||
* Tinton Falls, NJ 07724
|
||||
* Phone: (201) 834-1378 (9-17 EST)
|
||||
* Usenet: ...!seismo!uunet!pcrat!rick
|
||||
*
|
||||
* Please send results to Rick Richardson and/or Reinhold Weicker.
|
||||
* Complete information should be given on hardware and software used.
|
||||
* Hardware information includes: Machine type, CPU, type and size
|
||||
* of caches; for microprocessors: clock frequency, memory speed
|
||||
* (number of wait states).
|
||||
* Software information includes: Compiler (and runtime library)
|
||||
* manufacturer and version, compilation switches, OS version.
|
||||
* The Operating System version may give an indication about the
|
||||
* compiler; Dhrystone itself performs no OS calls in the measurement loop.
|
||||
*
|
||||
* The complete output generated by the program should be mailed
|
||||
* such that at least some checks for correctness can be made.
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* History: This version C/2.1 has been made for two reasons:
|
||||
*
|
||||
* 1) There is an obvious need for a common C version of
|
||||
* Dhrystone, since C is at present the most popular system
|
||||
* programming language for the class of processors
|
||||
* (microcomputers, minicomputers) where Dhrystone is used most.
|
||||
* There should be, as far as possible, only one C version of
|
||||
* Dhrystone such that results can be compared without
|
||||
* restrictions. In the past, the C versions distributed
|
||||
* by Rick Richardson (Version 1.1) and by Reinhold Weicker
|
||||
* had small (though not significant) differences.
|
||||
*
|
||||
* 2) As far as it is possible without changes to the Dhrystone
|
||||
* statistics, optimizing compilers should be prevented from
|
||||
* removing significant statements.
|
||||
*
|
||||
* This C version has been developed in cooperation with
|
||||
* Rick Richardson (Tinton Falls, NJ), it incorporates many
|
||||
* ideas from the "Version 1.1" distributed previously by
|
||||
* him over the UNIX network Usenet.
|
||||
* I also thank Chaim Benedelac (National Semiconductor),
|
||||
* David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
|
||||
* Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
|
||||
* for their help with comments on earlier versions of the
|
||||
* benchmark.
|
||||
*
|
||||
* Changes: In the initialization part, this version follows mostly
|
||||
* Rick Richardson's version distributed via Usenet, not the
|
||||
* version distributed earlier via floppy disk by Reinhold Weicker.
|
||||
* As a concession to older compilers, names have been made
|
||||
* unique within the first 8 characters.
|
||||
* Inside the measurement loop, this version follows the
|
||||
* version previously distributed by Reinhold Weicker.
|
||||
*
|
||||
* At several places in the benchmark, code has been added,
|
||||
* but within the measurement loop only in branches that
|
||||
* are not executed. The intention is that optimizing compilers
|
||||
* should be prevented from moving code out of the measurement
|
||||
* loop, or from removing code altogether. Since the statements
|
||||
* that are executed within the measurement loop have NOT been
|
||||
* changed, the numbers defining the "Dhrystone distribution"
|
||||
* (distribution of statements, operand types and locality)
|
||||
* still hold. Except for sophisticated optimizing compilers,
|
||||
* execution times for this version should be the same as
|
||||
* for previous versions.
|
||||
*
|
||||
* Since it has proven difficult to subtract the time for the
|
||||
* measurement loop overhead in a correct way, the loop check
|
||||
* has been made a part of the benchmark. This does have
|
||||
* an impact - though a very minor one - on the distribution
|
||||
* statistics which have been updated for this version.
|
||||
*
|
||||
* All changes within the measurement loop are described
|
||||
* and discussed in the companion paper "Rationale for
|
||||
* Dhrystone version 2".
|
||||
*
|
||||
* Because of the self-imposed limitation that the order and
|
||||
* distribution of the executed statements should not be
|
||||
* changed, there are still cases where optimizing compilers
|
||||
* may not generate code for some statements. To a certain
|
||||
* degree, this is unavoidable for small synthetic benchmarks.
|
||||
* Users of the benchmark are advised to check code listings
|
||||
* whether code is generated for all statements of Dhrystone.
|
||||
*
|
||||
* Version 2.1 is identical to version 2.0 distributed via
|
||||
* the UNIX network Usenet in March 1988 except that it corrects
|
||||
* some minor deficiencies that were found by users of version 2.0.
|
||||
* The only change within the measurement loop is that a
|
||||
* non-executed "else" part was added to the "if" statement in
|
||||
* Func_3, and a non-executed "else" part removed from Proc_3.
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Defines: The following "Defines" are possible:
|
||||
* -DREG=register (default: Not defined)
|
||||
* As an approximation to what an average C programmer
|
||||
* might do, the "register" storage class is applied
|
||||
* (if enabled by -DREG=register)
|
||||
* - for local variables, if they are used (dynamically)
|
||||
* five or more times
|
||||
* - for parameters if they are used (dynamically)
|
||||
* six or more times
|
||||
* Note that an optimal "register" strategy is
|
||||
* compiler-dependent, and that "register" declarations
|
||||
* do not necessarily lead to faster execution.
|
||||
* -DNOSTRUCTASSIGN (default: Not defined)
|
||||
* Define if the C compiler does not support
|
||||
* assignment of structures.
|
||||
* -DNOENUMS (default: Not defined)
|
||||
* Define if the C compiler does not support
|
||||
* enumeration types.
|
||||
* -DTIMES (default)
|
||||
* -DTIME
|
||||
* The "times" function of UNIX (returning process times)
|
||||
* or the "time" function (returning wallclock time)
|
||||
* is used for measurement.
|
||||
* For single user machines, "time ()" is adequate. For
|
||||
* multi-user machines where you cannot get single-user
|
||||
* access, use the "times ()" function. If you have
|
||||
* neither, use a stopwatch in the dead of night.
|
||||
* "printf"s are provided marking the points "Start Timer"
|
||||
* and "Stop Timer". DO NOT use the UNIX "time(1)"
|
||||
* command, as this will measure the total time to
|
||||
* run this program, which will (erroneously) include
|
||||
* the time to allocate storage (malloc) and to perform
|
||||
* the initialization.
|
||||
* -DHZ=nnn
|
||||
* In Berkeley UNIX, the function "times" returns process
|
||||
* time in 1/HZ seconds, with HZ = 60 for most systems.
|
||||
* CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
|
||||
* A VALUE.
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Compilation model and measurement (IMPORTANT):
|
||||
*
|
||||
* This C version of Dhrystone consists of three files:
|
||||
* - dhry.h (this file, containing global definitions and comments)
|
||||
* - dhry_1.c (containing the code corresponding to Ada package Pack_1)
|
||||
* - dhry_2.c (containing the code corresponding to Ada package Pack_2)
|
||||
*
|
||||
* The following "ground rules" apply for measurements:
|
||||
* - Separate compilation
|
||||
* - No procedure merging
|
||||
* - Otherwise, compiler optimizations are allowed but should be indicated
|
||||
* - Default results are those without register declarations
|
||||
* See the companion paper "Rationale for Dhrystone Version 2" for a more
|
||||
* detailed discussion of these ground rules.
|
||||
*
|
||||
* For 16-Bit processors (e.g. 80186, 80286), times for all compilation
|
||||
* models ("small", "medium", "large" etc.) should be given if possible,
|
||||
* together with a definition of these models for the compiler system used.
|
||||
*
|
||||
**************************************************************************
|
||||
*
|
||||
* Dhrystone (C version) statistics:
|
||||
*
|
||||
* [Comment from the first distribution, updated for version 2.
|
||||
* Note that because of language differences, the numbers are slightly
|
||||
* different from the Ada version.]
|
||||
*
|
||||
* The following program contains statements of a high level programming
|
||||
* language (here: C) in a distribution considered representative:
|
||||
*
|
||||
* assignments 52 (51.0 %)
|
||||
* control statements 33 (32.4 %)
|
||||
* procedure, function calls 17 (16.7 %)
|
||||
*
|
||||
* 103 statements are dynamically executed. The program is balanced with
|
||||
* respect to the three aspects:
|
||||
*
|
||||
* - statement type
|
||||
* - operand type
|
||||
* - operand locality
|
||||
* operand global, local, parameter, or constant.
|
||||
*
|
||||
* The combination of these three aspects is balanced only approximately.
|
||||
*
|
||||
* 1. Statement Type:
|
||||
* ----------------- number
|
||||
*
|
||||
* V1 = V2 9
|
||||
* (incl. V1 = F(..)
|
||||
* V = Constant 12
|
||||
* Assignment, 7
|
||||
* with array element
|
||||
* Assignment, 6
|
||||
* with record component
|
||||
* --
|
||||
* 34 34
|
||||
*
|
||||
* X = Y +|-|"&&"|"|" Z 5
|
||||
* X = Y +|-|"==" Constant 6
|
||||
* X = X +|- 1 3
|
||||
* X = Y *|/ Z 2
|
||||
* X = Expression, 1
|
||||
* two operators
|
||||
* X = Expression, 1
|
||||
* three operators
|
||||
* --
|
||||
* 18 18
|
||||
*
|
||||
* if .... 14
|
||||
* with "else" 7
|
||||
* without "else" 7
|
||||
* executed 3
|
||||
* not executed 4
|
||||
* for ... 7 | counted every time
|
||||
* while ... 4 | the loop condition
|
||||
* do ... while 1 | is evaluated
|
||||
* switch ... 1
|
||||
* break 1
|
||||
* declaration with 1
|
||||
* initialization
|
||||
* --
|
||||
* 34 34
|
||||
*
|
||||
* P (...) procedure call 11
|
||||
* user procedure 10
|
||||
* library procedure 1
|
||||
* X = F (...)
|
||||
* function call 6
|
||||
* user function 5
|
||||
* library function 1
|
||||
* --
|
||||
* 17 17
|
||||
* ---
|
||||
* 103
|
||||
*
|
||||
* The average number of parameters in procedure or function calls
|
||||
* is 1.82 (not counting the function values as implicit parameters).
|
||||
*
|
||||
*
|
||||
* 2. Operators
|
||||
* ------------
|
||||
* number approximate
|
||||
* percentage
|
||||
*
|
||||
* Arithmetic 32 50.8
|
||||
*
|
||||
* + 21 33.3
|
||||
* - 7 11.1
|
||||
* * 3 4.8
|
||||
* / (int div) 1 1.6
|
||||
*
|
||||
* Comparison 27 42.8
|
||||
*
|
||||
* == 9 14.3
|
||||
* /= 4 6.3
|
||||
* > 1 1.6
|
||||
* < 3 4.8
|
||||
* >= 1 1.6
|
||||
* <= 9 14.3
|
||||
*
|
||||
* Logic 4 6.3
|
||||
*
|
||||
* && (AND-THEN) 1 1.6
|
||||
* | (OR) 1 1.6
|
||||
* ! (NOT) 2 3.2
|
||||
*
|
||||
* -- -----
|
||||
* 63 100.1
|
||||
*
|
||||
*
|
||||
* 3. Operand Type (counted once per operand reference):
|
||||
* ---------------
|
||||
* number approximate
|
||||
* percentage
|
||||
*
|
||||
* Integer 175 72.3 %
|
||||
* Character 45 18.6 %
|
||||
* Pointer 12 5.0 %
|
||||
* String30 6 2.5 %
|
||||
* Array 2 0.8 %
|
||||
* Record 2 0.8 %
|
||||
* --- -------
|
||||
* 242 100.0 %
|
||||
*
|
||||
* When there is an access path leading to the final operand (e.g. a record
|
||||
* component), only the final data type on the access path is counted.
|
||||
*
|
||||
*
|
||||
* 4. Operand Locality:
|
||||
* -------------------
|
||||
* number approximate
|
||||
* percentage
|
||||
*
|
||||
* local variable 114 47.1 %
|
||||
* global variable 22 9.1 %
|
||||
* parameter 45 18.6 %
|
||||
* value 23 9.5 %
|
||||
* reference 22 9.1 %
|
||||
* function result 6 2.5 %
|
||||
* constant 55 22.7 %
|
||||
* --- -------
|
||||
* 242 100.0 %
|
||||
*
|
||||
*
|
||||
* The program does not compute anything meaningful, but it is syntactically
|
||||
* and semantically correct. All variables have a value assigned to them
|
||||
* before they are used as a source operand.
|
||||
*
|
||||
* There has been no explicit effort to account for the effects of a
|
||||
* cache, or to balance the use of long or short displacements for code or
|
||||
* data.
|
||||
*
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Compiler and system dependent definitions: */
|
||||
|
||||
#ifndef TIME
|
||||
#define TIMES
|
||||
#endif
|
||||
/* Use times(2) time function unless */
|
||||
/* explicitly defined otherwise */
|
||||
|
||||
#ifdef TIMES
|
||||
#include <sys/types.h>
|
||||
#include <sys/times.h>
|
||||
/* for "times" */
|
||||
#endif
|
||||
|
||||
#define Mic_secs_Per_Second 1000000.0
|
||||
/* Berkeley UNIX C returns process times in seconds/HZ */
|
||||
|
||||
#ifdef NOSTRUCTASSIGN
|
||||
#define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
|
||||
#else
|
||||
#define structassign(d, s) d = s
|
||||
#endif
|
||||
|
||||
#ifdef NOENUM
|
||||
#define Ident_1 0
|
||||
#define Ident_2 1
|
||||
#define Ident_3 2
|
||||
#define Ident_4 3
|
||||
#define Ident_5 4
|
||||
typedef int Enumeration;
|
||||
#else
|
||||
typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
|
||||
Enumeration;
|
||||
#endif
|
||||
/* for boolean and enumeration types in Ada, Pascal */
|
||||
|
||||
/* General definitions: */
|
||||
|
||||
#include <stdio.h>
|
||||
/* for strcpy, strcmp */
|
||||
|
||||
#define Null 0
|
||||
/* Value of a Null pointer */
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
typedef int One_Thirty;
|
||||
typedef int One_Fifty;
|
||||
typedef char Capital_Letter;
|
||||
typedef int Boolean;
|
||||
typedef char Str_30 [31];
|
||||
typedef int Arr_1_Dim [50];
|
||||
typedef int Arr_2_Dim [50] [50];
|
||||
|
||||
typedef struct record
|
||||
{
|
||||
struct record *Ptr_Comp;
|
||||
Enumeration Discr;
|
||||
union {
|
||||
struct {
|
||||
Enumeration Enum_Comp;
|
||||
int Int_Comp;
|
||||
char Str_Comp [31];
|
||||
} var_1;
|
||||
struct {
|
||||
Enumeration E_Comp_2;
|
||||
char Str_2_Comp [31];
|
||||
} var_2;
|
||||
struct {
|
||||
char Ch_1_Comp;
|
||||
char Ch_2_Comp;
|
||||
} var_3;
|
||||
} variant;
|
||||
} Rec_Type, *Rec_Pointer;
|
||||
|
||||
429
rk3308/unixbench-master_32/src/dhry_1.c
Executable file
429
rk3308/unixbench-master_32/src/dhry_1.c
Executable file
@ -0,0 +1,429 @@
|
||||
/*****************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: dhry_1.c SID: 3.4 5/15/91 19:30:21
|
||||
*
|
||||
*****************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*****************************************************************************
|
||||
*
|
||||
* *** WARNING **** With BYTE's modifications applied, results obtained with
|
||||
* ******* this version of the Dhrystone program may not be applicable
|
||||
* to other versions.
|
||||
*
|
||||
* Modification Log:
|
||||
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
* Adapted from:
|
||||
*
|
||||
* "DHRYSTONE" Benchmark Program
|
||||
* -----------------------------
|
||||
*
|
||||
* Version: C, Version 2.1
|
||||
*
|
||||
* File: dhry_1.c (part 2 of 3)
|
||||
*
|
||||
* Date: May 25, 1988
|
||||
*
|
||||
* Author: Reinhold P. Weicker
|
||||
*
|
||||
***************************************************************************/
|
||||
char SCCSid[] = "@(#) @(#)dhry_1.c:3.4 -- 5/15/91 19:30:21";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "dhry.h"
|
||||
#include "timeit.c"
|
||||
|
||||
unsigned long Run_Index;
|
||||
|
||||
void report()
|
||||
{
|
||||
fprintf(stderr,"COUNT|%ld|1|lps\n", Run_Index);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Global Variables: */
|
||||
|
||||
Rec_Pointer Ptr_Glob,
|
||||
Next_Ptr_Glob;
|
||||
int Int_Glob;
|
||||
Boolean Bool_Glob;
|
||||
char Ch_1_Glob,
|
||||
Ch_2_Glob;
|
||||
int Arr_1_Glob [50];
|
||||
int Arr_2_Glob [50] [50];
|
||||
|
||||
Enumeration Func_1 ();
|
||||
/* forward declaration necessary since Enumeration may not simply be int */
|
||||
|
||||
#ifndef REG
|
||||
Boolean Reg = false;
|
||||
#define REG
|
||||
/* REG becomes defined as empty */
|
||||
/* i.e. no register variables */
|
||||
#else
|
||||
Boolean Reg = true;
|
||||
#endif
|
||||
|
||||
/* variables for time measurement: */
|
||||
|
||||
#ifdef TIMES
|
||||
#include <time.h>
|
||||
#include <sys/times.h>
|
||||
#define Too_Small_Time 120
|
||||
/* Measurements should last at least about 2 seconds */
|
||||
#endif
|
||||
#ifdef TIME
|
||||
#include <time.h>
|
||||
#define Too_Small_Time 2
|
||||
/* Measurements should last at least 2 seconds */
|
||||
#endif
|
||||
|
||||
long Begin_Time,
|
||||
End_Time,
|
||||
User_Time;
|
||||
float Microseconds,
|
||||
Dhrystones_Per_Second;
|
||||
|
||||
/* end of variables for time measurement */
|
||||
|
||||
void Proc_1 (REG Rec_Pointer Ptr_Val_Par);
|
||||
void Proc_2 (One_Fifty *Int_Par_Ref);
|
||||
void Proc_3 (Rec_Pointer *Ptr_Ref_Par);
|
||||
void Proc_4 (void);
|
||||
void Proc_5 (void);
|
||||
|
||||
|
||||
extern Boolean Func_2(Str_30, Str_30);
|
||||
extern void Proc_6(Enumeration, Enumeration *);
|
||||
extern void Proc_7(One_Fifty, One_Fifty, One_Fifty *);
|
||||
extern void Proc_8(Arr_1_Dim, Arr_2_Dim, int, int);
|
||||
|
||||
int main (argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
/* main program, corresponds to procedures */
|
||||
/* Main and Proc_0 in the Ada version */
|
||||
{
|
||||
int duration;
|
||||
One_Fifty Int_1_Loc;
|
||||
REG One_Fifty Int_2_Loc;
|
||||
One_Fifty Int_3_Loc;
|
||||
REG char Ch_Index;
|
||||
Enumeration Enum_Loc;
|
||||
Str_30 Str_1_Loc;
|
||||
Str_30 Str_2_Loc;
|
||||
|
||||
/* Initializations */
|
||||
|
||||
Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
|
||||
Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
|
||||
|
||||
Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
|
||||
Ptr_Glob->Discr = Ident_1;
|
||||
Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
|
||||
Ptr_Glob->variant.var_1.Int_Comp = 40;
|
||||
strcpy (Ptr_Glob->variant.var_1.Str_Comp,
|
||||
"DHRYSTONE PROGRAM, SOME STRING");
|
||||
strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
|
||||
|
||||
Arr_2_Glob [8][7] = 10;
|
||||
/* Was missing in published program. Without this statement, */
|
||||
/* Arr_2_Glob [8][7] would have an undefined value. */
|
||||
/* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
|
||||
/* overflow may occur for this array element. */
|
||||
|
||||
#ifdef PRATTLE
|
||||
printf ("\n");
|
||||
printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
|
||||
printf ("\n");
|
||||
if (Reg)
|
||||
{
|
||||
printf ("Program compiled with 'register' attribute\n");
|
||||
printf ("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("Program compiled without 'register' attribute\n");
|
||||
printf ("\n");
|
||||
}
|
||||
printf ("Please give the number of runs through the benchmark: ");
|
||||
{
|
||||
int n;
|
||||
scanf ("%d", &n);
|
||||
Number_Of_Runs = n;
|
||||
}
|
||||
printf ("\n");
|
||||
|
||||
printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs);
|
||||
#endif /* PRATTLE */
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s duration\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
duration = atoi(argv[1]);
|
||||
Run_Index = 0;
|
||||
wake_me(duration, report);
|
||||
|
||||
/***************/
|
||||
/* Start timer */
|
||||
/***************/
|
||||
|
||||
#ifdef SELF_TIMED
|
||||
#ifdef TIMES
|
||||
times (&time_info);
|
||||
Begin_Time = (long) time_info.tms_utime;
|
||||
#endif
|
||||
#ifdef TIME
|
||||
Begin_Time = time ( (long *) 0);
|
||||
#endif
|
||||
#endif /* SELF_TIMED */
|
||||
|
||||
for (Run_Index = 1; ; ++Run_Index)
|
||||
{
|
||||
|
||||
Proc_5();
|
||||
Proc_4();
|
||||
/* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
|
||||
Int_1_Loc = 2;
|
||||
Int_2_Loc = 3;
|
||||
strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
|
||||
Enum_Loc = Ident_2;
|
||||
Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
|
||||
/* Bool_Glob == 1 */
|
||||
while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
|
||||
{
|
||||
Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
|
||||
/* Int_3_Loc == 7 */
|
||||
Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
|
||||
/* Int_3_Loc == 7 */
|
||||
Int_1_Loc += 1;
|
||||
} /* while */
|
||||
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
|
||||
Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
|
||||
/* Int_Glob == 5 */
|
||||
Proc_1 (Ptr_Glob);
|
||||
for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
|
||||
/* loop body executed twice */
|
||||
{
|
||||
if (Enum_Loc == Func_1 (Ch_Index, 'C'))
|
||||
/* then, not executed */
|
||||
{
|
||||
Proc_6 (Ident_1, &Enum_Loc);
|
||||
strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
|
||||
Int_2_Loc = Run_Index;
|
||||
Int_Glob = Run_Index;
|
||||
}
|
||||
}
|
||||
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
|
||||
Int_2_Loc = Int_2_Loc * Int_1_Loc;
|
||||
Int_1_Loc = Int_2_Loc / Int_3_Loc;
|
||||
Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
|
||||
/* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
|
||||
Proc_2 (&Int_1_Loc);
|
||||
/* Int_1_Loc == 5 */
|
||||
|
||||
} /* loop "for Run_Index" */
|
||||
|
||||
/**************/
|
||||
/* Stop timer */
|
||||
/**************/
|
||||
#ifdef SELF_TIMED
|
||||
#ifdef TIMES
|
||||
times (&time_info);
|
||||
End_Time = (long) time_info.tms_utime;
|
||||
#endif
|
||||
#ifdef TIME
|
||||
End_Time = time ( (long *) 0);
|
||||
#endif
|
||||
#endif /* SELF_TIMED */
|
||||
|
||||
/* BYTE version never executes this stuff */
|
||||
#ifdef SELF_TIMED
|
||||
printf ("Execution ends\n");
|
||||
printf ("\n");
|
||||
printf ("Final values of the variables used in the benchmark:\n");
|
||||
printf ("\n");
|
||||
printf ("Int_Glob: %d\n", Int_Glob);
|
||||
printf (" should be: %d\n", 5);
|
||||
printf ("Bool_Glob: %d\n", Bool_Glob);
|
||||
printf (" should be: %d\n", 1);
|
||||
printf ("Ch_1_Glob: %c\n", Ch_1_Glob);
|
||||
printf (" should be: %c\n", 'A');
|
||||
printf ("Ch_2_Glob: %c\n", Ch_2_Glob);
|
||||
printf (" should be: %c\n", 'B');
|
||||
printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]);
|
||||
printf (" should be: %d\n", 7);
|
||||
printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]);
|
||||
printf (" should be: Number_Of_Runs + 10\n");
|
||||
printf ("Ptr_Glob->\n");
|
||||
printf (" Ptr_Comp: %d\n", (int) Ptr_Glob->Ptr_Comp);
|
||||
printf (" should be: (implementation-dependent)\n");
|
||||
printf (" Discr: %d\n", Ptr_Glob->Discr);
|
||||
printf (" should be: %d\n", 0);
|
||||
printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
|
||||
printf (" should be: %d\n", 2);
|
||||
printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp);
|
||||
printf (" should be: %d\n", 17);
|
||||
printf (" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp);
|
||||
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
|
||||
printf ("Next_Ptr_Glob->\n");
|
||||
printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob->Ptr_Comp);
|
||||
printf (" should be: (implementation-dependent), same as above\n");
|
||||
printf (" Discr: %d\n", Next_Ptr_Glob->Discr);
|
||||
printf (" should be: %d\n", 0);
|
||||
printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
|
||||
printf (" should be: %d\n", 1);
|
||||
printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
|
||||
printf (" should be: %d\n", 18);
|
||||
printf (" Str_Comp: %s\n",
|
||||
Next_Ptr_Glob->variant.var_1.Str_Comp);
|
||||
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
|
||||
printf ("Int_1_Loc: %d\n", Int_1_Loc);
|
||||
printf (" should be: %d\n", 5);
|
||||
printf ("Int_2_Loc: %d\n", Int_2_Loc);
|
||||
printf (" should be: %d\n", 13);
|
||||
printf ("Int_3_Loc: %d\n", Int_3_Loc);
|
||||
printf (" should be: %d\n", 7);
|
||||
printf ("Enum_Loc: %d\n", Enum_Loc);
|
||||
printf (" should be: %d\n", 1);
|
||||
printf ("Str_1_Loc: %s\n", Str_1_Loc);
|
||||
printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
|
||||
printf ("Str_2_Loc: %s\n", Str_2_Loc);
|
||||
printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
|
||||
printf ("\n");
|
||||
|
||||
User_Time = End_Time - Begin_Time;
|
||||
|
||||
if (User_Time < Too_Small_Time)
|
||||
{
|
||||
printf ("Measured time too small to obtain meaningful results\n");
|
||||
printf ("Please increase number of runs\n");
|
||||
printf ("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef TIME
|
||||
Microseconds = (float) User_Time * Mic_secs_Per_Second
|
||||
/ (float) Number_Of_Runs;
|
||||
Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time;
|
||||
#else
|
||||
Microseconds = (float) User_Time * Mic_secs_Per_Second
|
||||
/ ((float) HZ * ((float) Number_Of_Runs));
|
||||
Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs)
|
||||
/ (float) User_Time;
|
||||
#endif
|
||||
printf ("Microseconds for one run through Dhrystone: ");
|
||||
printf ("%6.1f \n", Microseconds);
|
||||
printf ("Dhrystones per Second: ");
|
||||
printf ("%6.1f \n", Dhrystones_Per_Second);
|
||||
printf ("\n");
|
||||
}
|
||||
#endif /* SELF_TIMED */
|
||||
}
|
||||
|
||||
|
||||
void Proc_1 (REG Rec_Pointer Ptr_Val_Par)
|
||||
/* executed once */
|
||||
{
|
||||
REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
|
||||
/* == Ptr_Glob_Next */
|
||||
/* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
|
||||
/* corresponds to "rename" in Ada, "with" in Pascal */
|
||||
|
||||
structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
|
||||
Ptr_Val_Par->variant.var_1.Int_Comp = 5;
|
||||
Next_Record->variant.var_1.Int_Comp
|
||||
= Ptr_Val_Par->variant.var_1.Int_Comp;
|
||||
Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
|
||||
Proc_3 (&Next_Record->Ptr_Comp);
|
||||
/* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
|
||||
== Ptr_Glob->Ptr_Comp */
|
||||
if (Next_Record->Discr == Ident_1)
|
||||
/* then, executed */
|
||||
{
|
||||
Next_Record->variant.var_1.Int_Comp = 6;
|
||||
Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp,
|
||||
&Next_Record->variant.var_1.Enum_Comp);
|
||||
Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
|
||||
Proc_7 (Next_Record->variant.var_1.Int_Comp, 10,
|
||||
&Next_Record->variant.var_1.Int_Comp);
|
||||
}
|
||||
else /* not executed */
|
||||
structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
|
||||
} /* Proc_1 */
|
||||
|
||||
|
||||
void Proc_2 (One_Fifty *Int_Par_Ref)
|
||||
/* executed once */
|
||||
/* *Int_Par_Ref == 1, becomes 4 */
|
||||
{
|
||||
One_Fifty Int_Loc;
|
||||
Enumeration Enum_Loc;
|
||||
|
||||
Enum_Loc = 0;
|
||||
|
||||
Int_Loc = *Int_Par_Ref + 10;
|
||||
do /* executed once */
|
||||
if (Ch_1_Glob == 'A')
|
||||
/* then, executed */
|
||||
{
|
||||
Int_Loc -= 1;
|
||||
*Int_Par_Ref = Int_Loc - Int_Glob;
|
||||
Enum_Loc = Ident_1;
|
||||
} /* if */
|
||||
while (Enum_Loc != Ident_1); /* true */
|
||||
} /* Proc_2 */
|
||||
|
||||
|
||||
void Proc_3 (Rec_Pointer *Ptr_Ref_Par)
|
||||
/* executed once */
|
||||
/* Ptr_Ref_Par becomes Ptr_Glob */
|
||||
{
|
||||
if (Ptr_Glob != Null)
|
||||
/* then, executed */
|
||||
*Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
|
||||
Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
|
||||
} /* Proc_3 */
|
||||
|
||||
|
||||
void Proc_4 (void) /* without parameters */
|
||||
/* executed once */
|
||||
{
|
||||
Boolean Bool_Loc;
|
||||
|
||||
Bool_Loc = Ch_1_Glob == 'A';
|
||||
Bool_Glob = Bool_Loc | Bool_Glob;
|
||||
Ch_2_Glob = 'B';
|
||||
} /* Proc_4 */
|
||||
|
||||
void Proc_5 (void) /* without parameters */
|
||||
/*******/
|
||||
/* executed once */
|
||||
{
|
||||
Ch_1_Glob = 'A';
|
||||
Bool_Glob = false;
|
||||
} /* Proc_5 */
|
||||
|
||||
|
||||
/* Procedure for the assignment of structures, */
|
||||
/* if the C compiler doesn't support this feature */
|
||||
#ifdef NOSTRUCTASSIGN
|
||||
memcpy (d, s, l)
|
||||
register char *d;
|
||||
register char *s;
|
||||
register int l;
|
||||
{
|
||||
while (l--) *d++ = *s++;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
209
rk3308/unixbench-master_32/src/dhry_2.c
Executable file
209
rk3308/unixbench-master_32/src/dhry_2.c
Executable file
@ -0,0 +1,209 @@
|
||||
/*****************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: dhry_2.c SID: 3.4 5/15/91 19:30:22
|
||||
*
|
||||
*****************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*****************************************************************************
|
||||
* Modification Log:
|
||||
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
* Adapted from:
|
||||
*
|
||||
* "DHRYSTONE" Benchmark Program
|
||||
* -----------------------------
|
||||
*
|
||||
* **** WARNING **** See warning in n.dhry_1.c
|
||||
*
|
||||
* Version: C, Version 2.1
|
||||
*
|
||||
* File: dhry_2.c (part 3 of 3)
|
||||
*
|
||||
* Date: May 25, 1988
|
||||
*
|
||||
* Author: Reinhold P. Weicker
|
||||
*
|
||||
****************************************************************************/
|
||||
/* SCCSid is defined in dhry_1.c */
|
||||
|
||||
#include <string.h>
|
||||
#include "dhry.h"
|
||||
|
||||
#ifndef REG
|
||||
#define REG
|
||||
/* REG becomes defined as empty */
|
||||
/* i.e. no register variables */
|
||||
#endif
|
||||
|
||||
extern int Int_Glob;
|
||||
extern char Ch_1_Glob;
|
||||
|
||||
void Proc_6(Enumeration, Enumeration *);
|
||||
void Proc_7(One_Fifty, One_Fifty, One_Fifty *);
|
||||
void Proc_8(Arr_1_Dim, Arr_2_Dim, int, int);
|
||||
Enumeration Func_1(Capital_Letter, Capital_Letter);
|
||||
Boolean Func_2(Str_30, Str_30);
|
||||
Boolean Func_3(Enumeration);
|
||||
|
||||
void Proc_6 (Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par)
|
||||
/* executed once */
|
||||
/* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
|
||||
{
|
||||
*Enum_Ref_Par = Enum_Val_Par;
|
||||
if (! Func_3 (Enum_Val_Par))
|
||||
/* then, not executed */
|
||||
*Enum_Ref_Par = Ident_4;
|
||||
switch (Enum_Val_Par)
|
||||
{
|
||||
case Ident_1:
|
||||
*Enum_Ref_Par = Ident_1;
|
||||
break;
|
||||
case Ident_2:
|
||||
if (Int_Glob > 100)
|
||||
/* then */
|
||||
*Enum_Ref_Par = Ident_1;
|
||||
else *Enum_Ref_Par = Ident_4;
|
||||
break;
|
||||
case Ident_3: /* executed */
|
||||
*Enum_Ref_Par = Ident_2;
|
||||
break;
|
||||
case Ident_4: break;
|
||||
case Ident_5:
|
||||
*Enum_Ref_Par = Ident_3;
|
||||
break;
|
||||
} /* switch */
|
||||
} /* Proc_6 */
|
||||
|
||||
void Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref)
|
||||
One_Fifty Int_1_Par_Val;
|
||||
One_Fifty Int_2_Par_Val;
|
||||
One_Fifty *Int_Par_Ref;
|
||||
/**********************************************/
|
||||
/* executed three times */
|
||||
/* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */
|
||||
/* Int_Par_Ref becomes 7 */
|
||||
/* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
|
||||
/* Int_Par_Ref becomes 17 */
|
||||
/* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
|
||||
/* Int_Par_Ref becomes 18 */
|
||||
{
|
||||
One_Fifty Int_Loc;
|
||||
|
||||
Int_Loc = Int_1_Par_Val + 2;
|
||||
*Int_Par_Ref = Int_2_Par_Val + Int_Loc;
|
||||
} /* Proc_7 */
|
||||
|
||||
|
||||
void Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val)
|
||||
/*********************************************************************/
|
||||
/* executed once */
|
||||
/* Int_Par_Val_1 == 3 */
|
||||
/* Int_Par_Val_2 == 7 */
|
||||
Arr_1_Dim Arr_1_Par_Ref;
|
||||
Arr_2_Dim Arr_2_Par_Ref;
|
||||
int Int_1_Par_Val;
|
||||
int Int_2_Par_Val;
|
||||
{
|
||||
REG One_Fifty Int_Index;
|
||||
REG One_Fifty Int_Loc;
|
||||
|
||||
Int_Loc = Int_1_Par_Val + 5;
|
||||
Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
|
||||
Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
|
||||
Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
|
||||
for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
|
||||
Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
|
||||
Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
|
||||
Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
|
||||
Int_Glob = 5;
|
||||
} /* Proc_8 */
|
||||
|
||||
|
||||
Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val)
|
||||
/*************************************************/
|
||||
/* executed three times */
|
||||
/* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */
|
||||
/* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */
|
||||
/* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */
|
||||
{
|
||||
Capital_Letter Ch_1_Loc;
|
||||
Capital_Letter Ch_2_Loc;
|
||||
|
||||
Ch_1_Loc = Ch_1_Par_Val;
|
||||
Ch_2_Loc = Ch_1_Loc;
|
||||
if (Ch_2_Loc != Ch_2_Par_Val)
|
||||
/* then, executed */
|
||||
return (Ident_1);
|
||||
else /* not executed */
|
||||
{
|
||||
Ch_1_Glob = Ch_1_Loc;
|
||||
return (Ident_2);
|
||||
}
|
||||
} /* Func_1 */
|
||||
|
||||
|
||||
|
||||
Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref)
|
||||
/*************************************************/
|
||||
/* executed once */
|
||||
/* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
|
||||
/* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
|
||||
|
||||
Str_30 Str_1_Par_Ref;
|
||||
Str_30 Str_2_Par_Ref;
|
||||
{
|
||||
REG One_Thirty Int_Loc;
|
||||
Capital_Letter Ch_Loc;
|
||||
|
||||
Ch_Loc = 'A';
|
||||
Int_Loc = 2;
|
||||
while (Int_Loc <= 2) /* loop body executed once */
|
||||
if (Func_1 (Str_1_Par_Ref[Int_Loc],
|
||||
Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
|
||||
/* then, executed */
|
||||
{
|
||||
Ch_Loc = 'A';
|
||||
Int_Loc += 1;
|
||||
} /* if, while */
|
||||
if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
|
||||
/* then, not executed */
|
||||
Int_Loc = 7;
|
||||
if (Ch_Loc == 'R')
|
||||
/* then, not executed */
|
||||
return (true);
|
||||
else /* executed */
|
||||
{
|
||||
if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
|
||||
/* then, not executed */
|
||||
{
|
||||
Int_Loc += 7;
|
||||
Int_Glob = Int_Loc;
|
||||
return (true);
|
||||
}
|
||||
else /* executed */
|
||||
return (false);
|
||||
} /* if Ch_Loc */
|
||||
} /* Func_2 */
|
||||
|
||||
|
||||
Boolean Func_3 (Enum_Par_Val)
|
||||
/***************************/
|
||||
/* executed once */
|
||||
/* Enum_Par_Val == Ident_3 */
|
||||
Enumeration Enum_Par_Val;
|
||||
{
|
||||
Enumeration Enum_Loc;
|
||||
|
||||
Enum_Loc = Enum_Par_Val;
|
||||
if (Enum_Loc == Ident_3)
|
||||
/* then, executed */
|
||||
return (true);
|
||||
else /* not executed */
|
||||
return (false);
|
||||
} /* Func_3 */
|
||||
|
||||
319
rk3308/unixbench-master_32/src/dummy.c
Executable file
319
rk3308/unixbench-master_32/src/dummy.c
Executable file
@ -0,0 +1,319 @@
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: dummy.c SID: 3.3 5/15/91 19:30:19
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Hacked up C program for use in the standard shell.? scripts of
|
||||
* the multiuser test. This is based upon makework.c, and is typically
|
||||
* edited using edscript.2 before compilation.
|
||||
*
|
||||
* $Header: dummy.c,v 3.4 87/06/23 15:54:53 kjmcdonell Beta $
|
||||
*/
|
||||
char SCCSid[] = "@(#) @(#)dummy.c:3.3 -- 5/15/91 19:30:19";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define DEF_RATE 5.0
|
||||
#define GRANULE 5
|
||||
#define CHUNK 60
|
||||
#define MAXCHILD 12
|
||||
#define MAXWORK 10
|
||||
|
||||
float thres;
|
||||
float est_rate = DEF_RATE;
|
||||
int nusers; /* number of concurrent users to be simulated by
|
||||
* this process */
|
||||
int firstuser; /* ordinal identification of first user for this
|
||||
* process */
|
||||
int nwork = 0; /* number of job streams */
|
||||
int exit_status = 0; /* returned to parent */
|
||||
int sigpipe; /* pipe write error flag */
|
||||
|
||||
struct st_work {
|
||||
char *cmd; /* name of command to run */
|
||||
char **av; /* arguments to command */
|
||||
char *input; /* standard input buffer */
|
||||
int inpsize; /* size of standard input buffer */
|
||||
} work[MAXWORK];
|
||||
|
||||
struct {
|
||||
int xmit; /* # characters sent */
|
||||
char *bp; /* std input buffer pointer */
|
||||
int blen; /* std input buffer length */
|
||||
int fd; /* stdin to command */
|
||||
int pid; /* child PID */
|
||||
char *line; /* start of input line */
|
||||
int firstjob; /* inital piece of work */
|
||||
int thisjob; /* current piece of work */
|
||||
} child[MAXCHILD], *cp;
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int i;
|
||||
int l;
|
||||
int fcopy = 0; /* fd for copy output */
|
||||
int master = 1; /* the REAL master, == 0 for clones */
|
||||
int nchild; /* no. of children for a clone to run */
|
||||
int done; /* count of children finished */
|
||||
int output; /* aggregate output char count for all
|
||||
children */
|
||||
int c;
|
||||
int thiswork = 0; /* next job stream to allocate */
|
||||
int nch; /* # characters to write */
|
||||
int written; /* # characters actully written */
|
||||
char logname[15]; /* name of the log file(s) */
|
||||
void onalarm(void);
|
||||
void pipeerr(void);
|
||||
void wrapup(void);
|
||||
void grunt(void);
|
||||
char *malloc();
|
||||
int pvec[2]; /* for pipes */
|
||||
char *p;
|
||||
char *prog; /* my name */
|
||||
|
||||
#if ! debug
|
||||
freopen("masterlog.00", "a", stderr);
|
||||
#endif
|
||||
fprintf(stderr, "*** New Run *** ");
|
||||
prog = argv[0];
|
||||
while (argc > 1 && argv[1][0] == '-') {
|
||||
p = &argv[1][1];
|
||||
argc--;
|
||||
argv++;
|
||||
while (*p) {
|
||||
switch (*p) {
|
||||
case 'r':
|
||||
/* code DELETED here */
|
||||
argc--;
|
||||
argv++;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
/* code DELETED here */
|
||||
lseek(fcopy, 0L, 2); /* append at end of file */
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%s: bad flag '%c'\n", prog, *p);
|
||||
exit(4);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "%s: missing nusers\n", prog);
|
||||
exit(4);
|
||||
}
|
||||
|
||||
nusers = atoi(argv[1]);
|
||||
if (nusers < 1) {
|
||||
fprintf(stderr, "%s: impossible nusers (%d<-%s)\n", prog, nusers, argv[1]);
|
||||
exit(4);
|
||||
}
|
||||
fprintf(stderr, "%d Users\n", nusers);
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
/* build job streams */
|
||||
getwork();
|
||||
#if debug
|
||||
dumpwork();
|
||||
#endif
|
||||
|
||||
/* clone copies of myself to run up to MAXCHILD jobs each */
|
||||
firstuser = MAXCHILD;
|
||||
fprintf(stderr, "master pid %d\n", getpid());
|
||||
fflush(stderr);
|
||||
while (nusers > MAXCHILD) {
|
||||
fflush(stderr);
|
||||
if (nusers >= 2*MAXCHILD)
|
||||
/* the next clone must run MAXCHILD jobs */
|
||||
nchild = MAXCHILD;
|
||||
else
|
||||
/* the next clone must run the leftover jobs */
|
||||
nchild = nusers - MAXCHILD;
|
||||
if ((l = fork()) == -1) {
|
||||
/* fork failed */
|
||||
fatal("** clone fork failed **\n");
|
||||
goto bepatient;
|
||||
} else if (l > 0) {
|
||||
fprintf(stderr, "master clone pid %d\n", l);
|
||||
/* I am the master with nchild fewer jobs to run */
|
||||
nusers -= nchild;
|
||||
firstuser += MAXCHILD;
|
||||
continue;
|
||||
} else {
|
||||
/* I am a clone, run MAXCHILD jobs */
|
||||
#if ! debug
|
||||
sprintf(logname, "masterlog.%02d", firstuser/MAXCHILD);
|
||||
freopen(logname, "w", stderr);
|
||||
#endif
|
||||
master = 0;
|
||||
nusers = nchild;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (master)
|
||||
firstuser = 0;
|
||||
|
||||
close(0);
|
||||
|
||||
/* code DELETED here */
|
||||
|
||||
fflush(stderr);
|
||||
|
||||
srand(time(0));
|
||||
thres = 0;
|
||||
done = output = 0;
|
||||
for (i = 0; i < nusers; i++) {
|
||||
if (child[i].blen == 0)
|
||||
done++;
|
||||
else
|
||||
thres += est_rate * GRANULE;
|
||||
}
|
||||
est_rate = thres;
|
||||
|
||||
signal(SIGALRM, onalarm);
|
||||
signal(SIGPIPE, pipeerr);
|
||||
alarm(GRANULE);
|
||||
while (done < nusers) {
|
||||
for (i = 0; i < nusers; i++) {
|
||||
cp = &child[i];
|
||||
if (cp->xmit >= cp->blen) continue;
|
||||
l = rand() % CHUNK + 1; /* 1-CHUNK chars */
|
||||
if (l == 0) continue;
|
||||
if (cp->xmit + l > cp->blen)
|
||||
l = cp->blen - cp->xmit;
|
||||
p = cp->bp;
|
||||
cp->bp += l;
|
||||
cp->xmit += l;
|
||||
#if debug
|
||||
fprintf(stderr, "child %d, %d processed, %d to go\n", i, cp->xmit, cp->blen - cp->xmit);
|
||||
#endif
|
||||
while (p < cp->bp) {
|
||||
if (*p == '\n' || (p == &cp->bp[-1] && cp->xmit >= cp->blen)) {
|
||||
/* write it out */
|
||||
nch = p - cp->line + 1;
|
||||
if ((written = write(cp->fd, cp->line, nch)) != nch) {
|
||||
|
||||
/* code DELETED here */
|
||||
|
||||
}
|
||||
if (fcopy)
|
||||
write(fcopy, cp->line, p - cp->line + 1);
|
||||
#if debug
|
||||
fprintf(stderr, "child %d gets \"", i);
|
||||
{
|
||||
char *q = cp->line;
|
||||
while (q <= p) {
|
||||
if (*q >= ' ' && *q <= '~')
|
||||
fputc(*q, stderr);
|
||||
else
|
||||
fprintf(stderr, "\\%03o", *q);
|
||||
q++;
|
||||
}
|
||||
}
|
||||
fputc('"', stderr);
|
||||
#endif
|
||||
cp->line = &p[1];
|
||||
}
|
||||
p++;
|
||||
}
|
||||
if (cp->xmit >= cp->blen) {
|
||||
done++;
|
||||
close(cp->fd);
|
||||
#if debug
|
||||
fprintf(stderr, "child %d, close std input\n", i);
|
||||
#endif
|
||||
}
|
||||
output += l;
|
||||
}
|
||||
while (output > thres) {
|
||||
pause();
|
||||
#if debug
|
||||
fprintf(stderr, "after pause: output, thres, done %d %.2f %d\n", output, thres, done);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bepatient:
|
||||
alarm(0);
|
||||
/****
|
||||
* If everything is going OK, we should simply be able to keep
|
||||
* looping unitil 'wait' fails, however some descendent process may
|
||||
* be in a state from which it can never exit, and so a timeout
|
||||
* is used.
|
||||
* 5 minutes should be ample, since the time to run all jobs is of
|
||||
* the order of 5-10 minutes, however some machines are painfully slow,
|
||||
* so the timeout has been set at 20 minutes (1200 seconds).
|
||||
****/
|
||||
|
||||
/* code DELETED here */
|
||||
|
||||
}
|
||||
|
||||
onalarm()
|
||||
{
|
||||
thres += est_rate;
|
||||
signal(SIGALRM, onalarm);
|
||||
alarm(GRANULE);
|
||||
}
|
||||
|
||||
grunt()
|
||||
{
|
||||
/* timeout after label "bepatient" in main */
|
||||
exit_status = 4;
|
||||
wrapup();
|
||||
}
|
||||
|
||||
pipeerr()
|
||||
{
|
||||
sigpipe++;
|
||||
}
|
||||
|
||||
wrapup()
|
||||
{
|
||||
/* DUMMY, real code dropped */
|
||||
}
|
||||
|
||||
getwork()
|
||||
{
|
||||
|
||||
/* DUMMY, real code dropped */
|
||||
gets();
|
||||
strncpy();
|
||||
malloc(); realloc();
|
||||
open(); close();
|
||||
}
|
||||
|
||||
fatal(s)
|
||||
char *s;
|
||||
{
|
||||
int i;
|
||||
fprintf(stderr, s);
|
||||
fflush(stderr);
|
||||
perror("Reason?");
|
||||
for (i = 0; i < nusers; i++) {
|
||||
if (child[i].pid > 0 && kill(child[i].pid, SIGKILL) != -1)
|
||||
fprintf(stderr, "pid %d killed off\n", child[i].pid);
|
||||
}
|
||||
fflush(stderr);
|
||||
exit_status = 4;
|
||||
return;
|
||||
}
|
||||
97
rk3308/unixbench-master_32/src/execl.c
Executable file
97
rk3308/unixbench-master_32/src/execl.c
Executable file
@ -0,0 +1,97 @@
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: execl.c SID: 3.3 5/15/91 19:30:19
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* $Header: execl.c,v 3.5 87/06/22 15:37:08 kjmcdonell Beta $
|
||||
* August 28, 1990 - Modified timing routines
|
||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Execing
|
||||
*
|
||||
*/
|
||||
char SCCSid[] = "@(#) @(#)execl.c:3.3 -- 5/15/91 19:30:19";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
char bss[8*1024]; /* something worthwhile */
|
||||
|
||||
#define main dummy
|
||||
|
||||
#include "big.c" /* some real code */
|
||||
|
||||
#undef main
|
||||
|
||||
/* added by BYTE */
|
||||
char *getenv();
|
||||
|
||||
|
||||
int main(argc, argv) /* the real program */
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
unsigned long iter = 0;
|
||||
char *ptr;
|
||||
char *fullpath;
|
||||
int duration;
|
||||
char count_str[12], start_str[24], path_str[256], *dur_str;
|
||||
time_t start_time, this_time;
|
||||
|
||||
#ifdef DEBUG
|
||||
int count;
|
||||
for(count = 0; count < argc; ++ count)
|
||||
printf("%s ",argv[count]);
|
||||
printf("\n");
|
||||
#endif
|
||||
if (argc < 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s duration\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
duration = atoi(argv[1]);
|
||||
if (duration > 0)
|
||||
/* the first invocation */
|
||||
{
|
||||
dur_str = argv[1];
|
||||
if((ptr = getenv("UB_BINDIR")) != NULL)
|
||||
sprintf(path_str,"%s/execl",ptr);
|
||||
fullpath=path_str;
|
||||
time(&start_time);
|
||||
}
|
||||
else /* one of those execl'd invocations */
|
||||
{
|
||||
/* real duration follow the phoney null duration */
|
||||
duration = atoi(argv[2]);
|
||||
dur_str = argv[2];
|
||||
iter = (unsigned long)atoi(argv[3]); /* where are we now ? */
|
||||
sscanf(argv[4], "%lu", (unsigned long *) &start_time);
|
||||
fullpath = argv[0];
|
||||
}
|
||||
|
||||
sprintf(count_str, "%lu", ++iter); /* increment the execl counter */
|
||||
sprintf(start_str, "%lu", (unsigned long) start_time);
|
||||
time(&this_time);
|
||||
if (this_time - start_time >= duration) { /* time has run out */
|
||||
fprintf(stderr, "COUNT|%lu|1|lps\n", iter);
|
||||
exit(0);
|
||||
}
|
||||
execl(fullpath, fullpath, "0", dur_str, count_str, start_str, (void *) 0);
|
||||
fprintf(stderr, "Exec failed at iteration %lu\n", iter);
|
||||
perror("Reason");
|
||||
exit(1);
|
||||
}
|
||||
466
rk3308/unixbench-master_32/src/fstime.c
Executable file
466
rk3308/unixbench-master_32/src/fstime.c
Executable file
@ -0,0 +1,466 @@
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: fstime.c SID: 3.5 5/15/91 19:30:19
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* $Header: fstime.c,v 3.4 87/06/22 14:23:05 kjmcdonell Beta $
|
||||
* 10/19/89 - rewrote timing calcs and added clock check (Ben Smith)
|
||||
* 10/26/90 - simplify timing, change defaults (Tom Yager)
|
||||
* 11/16/90 - added better error handling and changed output format (Ben Smith)
|
||||
* 11/17/90 - changed the whole thing around (Ben Smith)
|
||||
* 2/22/91 - change a few style elements and improved error handling (Ben Smith)
|
||||
* 4/17/91 - incorporated suggestions from Seckin Unlu (seckin@sumac.intel.com)
|
||||
* 4/17/91 - limited size of file, will rewind when reaches end of file
|
||||
* 7/95 - fixed mishandling of read() and write() return codes
|
||||
* Carl Emilio Prelz <fluido@telepac.pt>
|
||||
* 12/95 - Massive changes. Made sleep time proportional increase with run
|
||||
* time; added fsbuffer and fsdisk variants; added partial counting
|
||||
* of partial reads/writes (was *full* credit); added dual syncs.
|
||||
* David C Niemi <niemi@tux.org>
|
||||
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
* 9/24/07 - Separate out the read and write tests;
|
||||
* output the actual time used in the results.
|
||||
* Ian Smith <johantheghost at yahoo period com>
|
||||
******************************************************************************/
|
||||
char SCCSid[] = "@(#) @(#)fstime.c:3.5 -- 5/15/91 19:30:19";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define SECONDS 10
|
||||
|
||||
#define MAX_BUFSIZE 8192
|
||||
|
||||
/* This must be set to the smallest BUFSIZE or 1024, whichever is smaller */
|
||||
#define COUNTSIZE 256
|
||||
#define HALFCOUNT (COUNTSIZE/2) /* Half of COUNTSIZE */
|
||||
|
||||
#define FNAME0 "dummy0"
|
||||
#define FNAME1 "dummy1"
|
||||
|
||||
int w_test(int timeSecs);
|
||||
int r_test(int timeSecs);
|
||||
int c_test(int timeSecs);
|
||||
|
||||
long read_score = 1, write_score = 1, copy_score = 1;
|
||||
|
||||
/****************** GLOBALS ***************************/
|
||||
|
||||
/* The buffer size for the tests. */
|
||||
int bufsize = 1024;
|
||||
|
||||
/*
|
||||
* The max number of 1024-byte blocks in the file.
|
||||
* Don't limit it much, so that memory buffering
|
||||
* can be overcome.
|
||||
*/
|
||||
int max_blocks = 2000;
|
||||
|
||||
/* The max number of BUFSIZE blocks in the file. */
|
||||
int max_buffs = 2000;
|
||||
|
||||
/* Countable units per 1024 bytes */
|
||||
int count_per_k;
|
||||
|
||||
/* Countable units per bufsize */
|
||||
int count_per_buf;
|
||||
|
||||
/* The actual buffer. */
|
||||
/* char *buf = 0; */
|
||||
/* Let's carry on using a static buffer for this, like older versions
|
||||
* of the code did. It turns out that if you use a malloc buffer,
|
||||
* it goes 50% slower on reads, when using a 4k buffer -- at least on
|
||||
* my OpenSUSE 10.2 system.
|
||||
* What up wit dat?
|
||||
*/
|
||||
char buf[MAX_BUFSIZE];
|
||||
|
||||
int f;
|
||||
int g;
|
||||
int i;
|
||||
void stop_count();
|
||||
void clean_up();
|
||||
int sigalarm = 0;
|
||||
|
||||
/******************** MAIN ****************************/
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
/* The number of seconds to run for. */
|
||||
int seconds = SECONDS;
|
||||
|
||||
/* The type of test to run. */
|
||||
char test = 'c';
|
||||
|
||||
int status;
|
||||
int i;
|
||||
|
||||
for (i = 1; i < argc; ++i) {
|
||||
if (argv[i][0] == '-') {
|
||||
switch (argv[i][1]) {
|
||||
case 'c':
|
||||
case 'r':
|
||||
case 'w':
|
||||
test = argv[i][1];
|
||||
break;
|
||||
case 'b':
|
||||
bufsize = atoi(argv[++i]);
|
||||
break;
|
||||
case 'm':
|
||||
max_blocks = atoi(argv[++i]);
|
||||
break;
|
||||
case 't':
|
||||
seconds = atoi(argv[++i]);
|
||||
break;
|
||||
case 'd':
|
||||
if (chdir(argv[++i]) < 0) {
|
||||
perror("fstime: chdir");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Usage: fstime [-c|-r|-w] [-b <bufsize>] [-m <max_blocks>] [-t <seconds>]\n");
|
||||
exit(2);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Usage: fstime [-c|-r|-w] [-b <bufsize>] [-m <max_blocks>] [-t <seconds>]\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
if (bufsize < COUNTSIZE || bufsize > MAX_BUFSIZE) {
|
||||
fprintf(stderr, "fstime: buffer size must be in range %d-%d\n",
|
||||
COUNTSIZE, 1024*1024);
|
||||
exit(3);
|
||||
}
|
||||
if (max_blocks < 1 || max_blocks > 1024*1024) {
|
||||
fprintf(stderr, "fstime: max blocks must be in range %d-%d\n",
|
||||
1, 1024*1024);
|
||||
exit(3);
|
||||
}
|
||||
if (seconds < 1 || seconds > 3600) {
|
||||
fprintf(stderr, "fstime: time must be in range %d-%d seconds\n",
|
||||
1, 3600);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
max_buffs = max_blocks * 1024 / bufsize;
|
||||
count_per_k = 1024 / COUNTSIZE;
|
||||
count_per_buf = bufsize / COUNTSIZE;
|
||||
|
||||
/*
|
||||
if ((buf = malloc(bufsize)) == 0) {
|
||||
fprintf(stderr, "fstime: failed to malloc %d bytes\n", bufsize);
|
||||
exit(4);
|
||||
}
|
||||
*/
|
||||
|
||||
if((f = creat(FNAME0, 0600)) == -1) {
|
||||
perror("fstime: creat");
|
||||
exit(1);
|
||||
}
|
||||
close(f);
|
||||
|
||||
if((g = creat(FNAME1, 0600)) == -1) {
|
||||
perror("fstime: creat");
|
||||
exit(1);
|
||||
}
|
||||
close(g);
|
||||
|
||||
if( (f = open(FNAME0, 2)) == -1) {
|
||||
perror("fstime: open");
|
||||
exit(1);
|
||||
}
|
||||
if( ( g = open(FNAME1, 2)) == -1 ) {
|
||||
perror("fstime: open");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* fill buffer */
|
||||
for (i=0; i < bufsize; ++i)
|
||||
buf[i] = i & 0xff;
|
||||
|
||||
signal(SIGKILL,clean_up);
|
||||
|
||||
/*
|
||||
* Run the selected test.
|
||||
* When I got here, this program ran full 30-second tests for
|
||||
* write, read, and copy, outputting the results for each. BUT
|
||||
* only the copy results are actually used in the benchmark index.
|
||||
* With multiple iterations and three sets of FS tests, that amounted
|
||||
* to about 10 minutes of wasted time per run.
|
||||
*
|
||||
* So, I've made the test selectable. Except that the read and write
|
||||
* passes are used to create the test file and calibrate the rates used
|
||||
* to tweak the results of the copy test. So, for copy tests, we do
|
||||
* a few seconds of write and read to prime the pump.
|
||||
*
|
||||
* Note that this will also pull the file into the FS cache on any
|
||||
* modern system prior to the copy test. Whether this is good or
|
||||
* bad is a matter of perspective, but it's how it was when I got
|
||||
* here.
|
||||
*
|
||||
* Ian Smith <johantheghost at yahoo period com> 21 Sep 2007
|
||||
*/
|
||||
switch (test) {
|
||||
case 'w':
|
||||
status = w_test(seconds);
|
||||
break;
|
||||
case 'r':
|
||||
w_test(2);
|
||||
status = r_test(seconds);
|
||||
break;
|
||||
case 'c':
|
||||
w_test(2);
|
||||
r_test(2);
|
||||
status = c_test(seconds);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "fstime: unknown test \'%c\'\n", test);
|
||||
exit(6);
|
||||
}
|
||||
if (status) {
|
||||
clean_up();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
clean_up();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
static double getFloatTime()
|
||||
{
|
||||
struct timeval t;
|
||||
|
||||
gettimeofday(&t, 0);
|
||||
return (double) t.tv_sec + (double) t.tv_usec / 1000000.0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Run the write test for the time given in seconds.
|
||||
*/
|
||||
int w_test(int timeSecs)
|
||||
{
|
||||
unsigned long counted = 0L;
|
||||
unsigned long tmp;
|
||||
long f_blocks;
|
||||
double start, end;
|
||||
extern int sigalarm;
|
||||
|
||||
/* Sync and let it settle */
|
||||
sync();
|
||||
sleep(2);
|
||||
sync();
|
||||
sleep(2);
|
||||
|
||||
/* Set an alarm. */
|
||||
sigalarm = 0;
|
||||
signal(SIGALRM, stop_count);
|
||||
alarm(timeSecs);
|
||||
|
||||
start = getFloatTime();
|
||||
|
||||
while (!sigalarm) {
|
||||
for(f_blocks=0; f_blocks < max_buffs; ++f_blocks) {
|
||||
if ((tmp=write(f, buf, bufsize)) != bufsize) {
|
||||
if (errno != EINTR) {
|
||||
perror("fstime: write");
|
||||
return(-1);
|
||||
}
|
||||
stop_count();
|
||||
counted += ((tmp+HALFCOUNT)/COUNTSIZE);
|
||||
} else
|
||||
counted += count_per_buf;
|
||||
}
|
||||
lseek(f, 0L, 0); /* rewind */
|
||||
}
|
||||
|
||||
/* stop clock */
|
||||
end = getFloatTime();
|
||||
write_score = (long) ((double) counted / ((end - start) * count_per_k));
|
||||
printf("Write done: %ld in %.4f, score %ld\n",
|
||||
counted, end - start, write_score);
|
||||
|
||||
/*
|
||||
* Output the test results. Use the true time.
|
||||
*/
|
||||
fprintf(stderr, "COUNT|%ld|0|KBps\n", write_score);
|
||||
fprintf(stderr, "TIME|%.1f\n", end - start);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Run the read test for the time given in seconds.
|
||||
*/
|
||||
int r_test(int timeSecs)
|
||||
{
|
||||
unsigned long counted = 0L;
|
||||
unsigned long tmp;
|
||||
double start, end;
|
||||
extern int sigalarm;
|
||||
|
||||
/* Sync and let it settle */
|
||||
sync();
|
||||
sleep(2);
|
||||
sync();
|
||||
sleep(2);
|
||||
|
||||
/* rewind */
|
||||
errno = 0;
|
||||
lseek(f, 0L, 0);
|
||||
|
||||
/* Set an alarm. */
|
||||
sigalarm = 0;
|
||||
signal(SIGALRM, stop_count);
|
||||
alarm(timeSecs);
|
||||
|
||||
start = getFloatTime();
|
||||
|
||||
while (!sigalarm) {
|
||||
/* read while checking for an error */
|
||||
if ((tmp=read(f, buf, bufsize)) != bufsize) {
|
||||
switch(errno) {
|
||||
case 0:
|
||||
case EINVAL:
|
||||
lseek(f, 0L, 0); /* rewind at end of file */
|
||||
counted += (tmp+HALFCOUNT)/COUNTSIZE;
|
||||
continue;
|
||||
case EINTR:
|
||||
stop_count();
|
||||
counted += (tmp+HALFCOUNT)/COUNTSIZE;
|
||||
break;
|
||||
default:
|
||||
perror("fstime: read");
|
||||
return(-1);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
counted += count_per_buf;
|
||||
}
|
||||
|
||||
/* stop clock */
|
||||
end = getFloatTime();
|
||||
read_score = (long) ((double) counted / ((end - start) * count_per_k));
|
||||
printf("Read done: %ld in %.4f, score %ld\n",
|
||||
counted, end - start, read_score);
|
||||
|
||||
/*
|
||||
* Output the test results. Use the true time.
|
||||
*/
|
||||
fprintf(stderr, "COUNT|%ld|0|KBps\n", read_score);
|
||||
fprintf(stderr, "TIME|%.1f\n", end - start);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Run the copy test for the time given in seconds.
|
||||
*/
|
||||
int c_test(int timeSecs)
|
||||
{
|
||||
unsigned long counted = 0L;
|
||||
unsigned long tmp;
|
||||
double start, end;
|
||||
extern int sigalarm;
|
||||
|
||||
sync();
|
||||
sleep(2);
|
||||
sync();
|
||||
sleep(1);
|
||||
|
||||
/* rewind */
|
||||
errno = 0;
|
||||
lseek(f, 0L, 0);
|
||||
|
||||
/* Set an alarm. */
|
||||
sigalarm = 0;
|
||||
signal(SIGALRM, stop_count);
|
||||
alarm(timeSecs);
|
||||
|
||||
start = getFloatTime();
|
||||
|
||||
while (!sigalarm) {
|
||||
if ((tmp=read(f, buf, bufsize)) != bufsize) {
|
||||
switch(errno) {
|
||||
case 0:
|
||||
case EINVAL:
|
||||
lseek(f, 0L, 0); /* rewind at end of file */
|
||||
lseek(g, 0L, 0); /* rewind the output too */
|
||||
continue;
|
||||
case EINTR:
|
||||
/* part credit for leftover bytes read */
|
||||
counted += ( (tmp * write_score) /
|
||||
(read_score + write_score)
|
||||
+ HALFCOUNT) / COUNTSIZE;
|
||||
stop_count();
|
||||
break;
|
||||
default:
|
||||
perror("fstime: copy read");
|
||||
return(-1);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if ((tmp=write(g, buf, bufsize)) != bufsize) {
|
||||
if (errno != EINTR) {
|
||||
perror("fstime: copy write");
|
||||
return(-1);
|
||||
}
|
||||
counted += (
|
||||
/* Full credit for part of buffer written */
|
||||
tmp +
|
||||
|
||||
/* Plus part credit having read full buffer */
|
||||
( ((bufsize - tmp) * write_score) /
|
||||
(read_score + write_score) )
|
||||
+ HALFCOUNT) / COUNTSIZE;
|
||||
stop_count();
|
||||
} else
|
||||
counted += count_per_buf;
|
||||
}
|
||||
}
|
||||
|
||||
/* stop clock */
|
||||
end = getFloatTime();
|
||||
copy_score = (long) ((double) counted / ((end - start) * count_per_k));
|
||||
printf("Copy done: %ld in %.4f, score %ld\n",
|
||||
counted, end - start, copy_score);
|
||||
|
||||
/*
|
||||
* Output the test results. Use the true time.
|
||||
*/
|
||||
fprintf(stderr, "COUNT|%ld|0|KBps\n", copy_score);
|
||||
fprintf(stderr, "TIME|%.1f\n", end - start);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
void stop_count(void)
|
||||
{
|
||||
extern int sigalarm;
|
||||
sigalarm = 1;
|
||||
}
|
||||
|
||||
void clean_up(void)
|
||||
{
|
||||
unlink(FNAME0);
|
||||
unlink(FNAME1);
|
||||
}
|
||||
77
rk3308/unixbench-master_32/src/hanoi.c
Executable file
77
rk3308/unixbench-master_32/src/hanoi.c
Executable file
@ -0,0 +1,77 @@
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: hanoi.c SID: 3.3 5/15/91 19:30:20
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* $Header: hanoi.c,v 3.5 87/08/06 08:11:14 kenj Exp $
|
||||
* August 28, 1990 - Modified timing routines (ty)
|
||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
char SCCSid[] = "@(#) @(#)hanoi.c:3.3 -- 5/15/91 19:30:20";
|
||||
|
||||
#define other(i,j) (6-(i+j))
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "timeit.c"
|
||||
|
||||
void mov(int n, int f, int t);
|
||||
|
||||
unsigned long iter = 0;
|
||||
int num[4];
|
||||
long cnt;
|
||||
|
||||
void report()
|
||||
{
|
||||
fprintf(stderr,"COUNT|%ld|1|lps\n", iter);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int disk=10, /* default number of disks */
|
||||
duration;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr,"Usage: %s duration [disks]\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
duration = atoi(argv[1]);
|
||||
if(argc > 2) disk = atoi(argv[2]);
|
||||
num[1] = disk;
|
||||
|
||||
wake_me(duration, report);
|
||||
|
||||
while(1) {
|
||||
mov(disk,1,3);
|
||||
iter++;
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void mov(int n, int f, int t)
|
||||
{
|
||||
int o;
|
||||
if(n == 1) {
|
||||
num[f]--;
|
||||
num[t]++;
|
||||
return;
|
||||
}
|
||||
o = other(f,t);
|
||||
mov(n-1,f,o);
|
||||
mov(1,f,t);
|
||||
mov(n-1,o,t);
|
||||
}
|
||||
105
rk3308/unixbench-master_32/src/looper.c
Executable file
105
rk3308/unixbench-master_32/src/looper.c
Executable file
@ -0,0 +1,105 @@
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 1
|
||||
* Module: looper.c SID: 1.4 5/15/91 19:30:22
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith or Tom Yager at BYTE Magazine
|
||||
* ben@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
*
|
||||
* February 25, 1991 -- created (Ben S.)
|
||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
char SCCSid[] = "@(#) @(#)looper.c:1.4 -- 5/15/91 19:30:22";
|
||||
/*
|
||||
* Shell Process creation
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
#include "timeit.c"
|
||||
|
||||
unsigned long iter;
|
||||
char *cmd_argv[28];
|
||||
int cmd_argc;
|
||||
|
||||
void report(void)
|
||||
{
|
||||
fprintf(stderr,"COUNT|%lu|60|lpm\n", iter);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int slave, count, duration;
|
||||
int status;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
fprintf(stderr,"Usage: %s duration command [args..]\n", argv[0]);
|
||||
fprintf(stderr," duration in seconds\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if((duration = atoi(argv[1])) < 1)
|
||||
{
|
||||
fprintf(stderr,"Usage: %s duration command [arg..]\n", argv[0]);
|
||||
fprintf(stderr," duration in seconds\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* get command */
|
||||
cmd_argc=argc-2;
|
||||
for( count=2;count < argc; ++count)
|
||||
cmd_argv[count-2]=argv[count];
|
||||
#ifdef DEBUG
|
||||
printf("<<%s>>",cmd_argv[0]);
|
||||
for(count=1;count < cmd_argc; ++count)
|
||||
printf(" <%s>", cmd_argv[count]);
|
||||
putchar('\n');
|
||||
exit(0);
|
||||
#endif
|
||||
|
||||
iter = 0;
|
||||
wake_me(duration, report);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if ((slave = fork()) == 0)
|
||||
{ /* execute command */
|
||||
execvp(cmd_argv[0],cmd_argv);
|
||||
exit(99);
|
||||
}
|
||||
else if (slave < 0)
|
||||
{
|
||||
/* woops ... */
|
||||
fprintf(stderr,"Fork failed at iteration %lu\n", iter);
|
||||
perror("Reason");
|
||||
exit(2);
|
||||
}
|
||||
else
|
||||
/* master */
|
||||
wait(&status);
|
||||
if (status == 99 << 8)
|
||||
{
|
||||
fprintf(stderr, "Command \"%s\" didn't exec\n", cmd_argv[0]);
|
||||
exit(2);
|
||||
}
|
||||
else if (status != 0)
|
||||
{
|
||||
fprintf(stderr,"Bad wait status: 0x%x\n", status);
|
||||
exit(2);
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
68
rk3308/unixbench-master_32/src/pipe.c
Executable file
68
rk3308/unixbench-master_32/src/pipe.c
Executable file
@ -0,0 +1,68 @@
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: pipe.c SID: 3.3 5/15/91 19:30:20
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* $Header: pipe.c,v 3.5 87/06/22 14:32:36 kjmcdonell Beta $
|
||||
* August 29, 1990 - modified timing routines (ty)
|
||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
char SCCSid[] = "@(#) @(#)pipe.c:3.3 -- 5/15/91 19:30:20";
|
||||
/*
|
||||
* pipe -- test single process pipe throughput (no context switching)
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "timeit.c"
|
||||
|
||||
unsigned long iter;
|
||||
|
||||
void report()
|
||||
{
|
||||
fprintf(stderr,"COUNT|%ld|1|lps\n", iter);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
char buf[512];
|
||||
int pvec[2], duration;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr,"Usage: %s duration\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
duration = atoi(argv[1]);
|
||||
|
||||
pipe(pvec);
|
||||
|
||||
wake_me(duration, report);
|
||||
iter = 0;
|
||||
|
||||
while (1) {
|
||||
if (write(pvec[1], buf, sizeof(buf)) != sizeof(buf)) {
|
||||
if ((errno != EINTR) && (errno != 0))
|
||||
fprintf(stderr,"write failed, error %d\n", errno);
|
||||
}
|
||||
if (read(pvec[0], buf, sizeof(buf)) != sizeof(buf)) {
|
||||
if ((errno != EINTR) && (errno != 0))
|
||||
fprintf(stderr,"read failed, error %d\n", errno);
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
80
rk3308/unixbench-master_32/src/spawn.c
Executable file
80
rk3308/unixbench-master_32/src/spawn.c
Executable file
@ -0,0 +1,80 @@
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: spawn.c SID: 3.3 5/15/91 19:30:20
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yagerat BYTE Magazine
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* $Header: spawn.c,v 3.4 87/06/22 14:32:48 kjmcdonell Beta $
|
||||
* August 29, 1990 - Modified timing routines (ty)
|
||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
char SCCSid[] = "@(#) @(#)spawn.c:3.3 -- 5/15/91 19:30:20";
|
||||
/*
|
||||
* Process creation
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
#include "timeit.c"
|
||||
|
||||
unsigned long iter;
|
||||
|
||||
void report()
|
||||
{
|
||||
fprintf(stderr,"COUNT|%lu|1|lps\n", iter);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int slave, duration;
|
||||
int status;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr,"Usage: %s duration \n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
duration = atoi(argv[1]);
|
||||
|
||||
iter = 0;
|
||||
wake_me(duration, report);
|
||||
|
||||
while (1) {
|
||||
if ((slave = fork()) == 0) {
|
||||
/* slave .. boring */
|
||||
#if debug
|
||||
printf("fork OK\n");
|
||||
#endif
|
||||
/* kill it right away */
|
||||
exit(0);
|
||||
} else if (slave < 0) {
|
||||
/* woops ... */
|
||||
fprintf(stderr,"Fork failed at iteration %lu\n", iter);
|
||||
perror("Reason");
|
||||
exit(2);
|
||||
} else
|
||||
/* master */
|
||||
wait(&status);
|
||||
if (status != 0) {
|
||||
fprintf(stderr,"Bad wait status: 0x%x\n", status);
|
||||
exit(2);
|
||||
}
|
||||
iter++;
|
||||
#if debug
|
||||
printf("Child %d done.\n", slave);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
109
rk3308/unixbench-master_32/src/syscall.c
Executable file
109
rk3308/unixbench-master_32/src/syscall.c
Executable file
@ -0,0 +1,109 @@
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: syscall.c SID: 3.3 5/15/91 19:30:21
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager at BYTE Magazine
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* $Header: syscall.c,v 3.4 87/06/22 14:32:54 kjmcdonell Beta $
|
||||
* August 29, 1990 - Modified timing routines
|
||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
/*
|
||||
* syscall -- sit in a loop calling the system
|
||||
*
|
||||
*/
|
||||
char SCCSid[] = "@(#) @(#)syscall.c:3.3 -- 5/15/91 19:30:21";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include "timeit.c"
|
||||
|
||||
unsigned long iter;
|
||||
|
||||
void report()
|
||||
{
|
||||
fprintf(stderr,"COUNT|%ld|1|lps\n", iter);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
char *test;
|
||||
int duration;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr,"Usage: %s duration [ test ]\n", argv[0]);
|
||||
fprintf(stderr,"test is one of:\n");
|
||||
fprintf(stderr," \"mix\" (default), \"close\", \"getpid\", \"exec\"\n");
|
||||
exit(1);
|
||||
}
|
||||
if (argc > 2)
|
||||
test = argv[2];
|
||||
else
|
||||
test = "mix";
|
||||
|
||||
duration = atoi(argv[1]);
|
||||
|
||||
iter = 0;
|
||||
wake_me(duration, report);
|
||||
|
||||
switch (test[0]) {
|
||||
case 'm':
|
||||
while (1) {
|
||||
close(dup(0));
|
||||
getpid();
|
||||
getuid();
|
||||
umask(022);
|
||||
iter++;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
case 'c':
|
||||
while (1) {
|
||||
close(dup(0));
|
||||
iter++;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
case 'g':
|
||||
while (1) {
|
||||
getpid();
|
||||
iter++;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
case 'e':
|
||||
while (1) {
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
fprintf(stderr,"%s: fork failed\n", argv[0]);
|
||||
exit(1);
|
||||
} else if (pid == 0) {
|
||||
execl("/bin/true", "/bin/true", (char *) 0);
|
||||
fprintf(stderr,"%s: exec /bin/true failed\n", argv[0]);
|
||||
exit(1);
|
||||
} else {
|
||||
if (waitpid(pid, NULL, 0) < 0) {
|
||||
fprintf(stderr,"%s: waitpid failed\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
exit(9);
|
||||
}
|
||||
|
||||
573
rk3308/unixbench-master_32/src/time-polling.c
Executable file
573
rk3308/unixbench-master_32/src/time-polling.c
Executable file
@ -0,0 +1,573 @@
|
||||
/* Programme to test how long it takes to select(2), poll(2) and poll2(2) a
|
||||
large number of file descriptors.
|
||||
|
||||
Copyright 1997 Richard Gooch rgooch@atnf.csiro.au
|
||||
Distributed under the GNU General Public License.
|
||||
|
||||
To compile this programme, use gcc -O2 -o time-polling time-polling.c
|
||||
|
||||
Extra compile flags:
|
||||
|
||||
Add -DHAS_SELECT if your operating system has the select(2) system call
|
||||
Add -DHAS_POLL if your operating system has the poll(2) system call
|
||||
Add -DHAS_POLL2 if your operating system has the poll2(2) system call
|
||||
|
||||
Usage: time-polling [num_iter] [num_to_test] [num_active] [-v]
|
||||
|
||||
NOTE: on many systems the default limit on file descriptors is less than
|
||||
1024. You should try to increase this limit to 1024 before doing the test.
|
||||
Something like "limit descriptors 1024" or "limit openfiles 1024" should do
|
||||
the trick. On some systems (like IRIX), doing the test on a smaller number
|
||||
gives a *much* smaller time per descriptor, which shows that time taken
|
||||
does not scale linearly with number of descriptors, which is non-optimal.
|
||||
In the tests I've done, I try to use 1024 descriptors.
|
||||
The benchmark results are available at:
|
||||
http://www.atnf.csiro.au/~rgooch/benchmarks.html
|
||||
If you want to contribute results, please email them to me. Please specify
|
||||
if you want to be acknowledged.
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Richard Gooch may be reached by email at rgooch@atnf.csiro.au
|
||||
The postal address is:
|
||||
Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef UNIXBENCH
|
||||
#define OUT stdout
|
||||
#else
|
||||
#define OUT stderr
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#ifdef HAS_POLL
|
||||
# include <sys/poll.h>
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
# include <linux/poll2.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#ifdef UNIXBENCH
|
||||
#define MAX_ITERATIONS 1000
|
||||
#else
|
||||
#define MAX_ITERATIONS 30
|
||||
#endif
|
||||
#define MAX_FDS 40960
|
||||
#define CONST const
|
||||
#define ERRSTRING strerror (errno)
|
||||
|
||||
typedef int flag;
|
||||
|
||||
|
||||
#ifdef HAS_SELECT
|
||||
|
||||
/*
|
||||
static inline int find_first_set_bit (CONST void *array, int size)
|
||||
*/
|
||||
static int find_first_set_bit (CONST void *array, int size)
|
||||
/* [SUMMARY] Find the first bit set in a bitfield.
|
||||
<array> A pointer to the bitfield. This must be aligned on a long boundary.
|
||||
<size> The number of bits in the bitfield.
|
||||
[RETURNS] The index of the first set bit. If no bits are set, <<size>> + 1
|
||||
is returned.
|
||||
*/
|
||||
{
|
||||
int index;
|
||||
unsigned long word;
|
||||
unsigned int ul_size = 8 * sizeof (unsigned long);
|
||||
CONST unsigned long *ul_array = array;
|
||||
|
||||
/* Find first word with any bit set */
|
||||
for (index = 0; (*ul_array == 0) && (index < size);
|
||||
index += ul_size, ++ul_array);
|
||||
/* Find first bit set in word */
|
||||
for (word = *ul_array; !(word & 1) && (index < size);
|
||||
++index, word = word >> 1);
|
||||
return (index);
|
||||
} /* End Function find_first_set_bit */
|
||||
|
||||
/*
|
||||
static inline int find_next_set_bit (CONST void *array, int size, int offset)
|
||||
*/
|
||||
static int find_next_set_bit (CONST void *array, int size, int offset)
|
||||
/* [SUMMARY] Find the next bit set in a bitfield.
|
||||
<array> A pointer to the bitfield. This must be aligned on a long boundary.
|
||||
<size> The number of bits in the bitfield.
|
||||
<offset> The offset of the current bit in the bitfield. The current bit is
|
||||
ignored.
|
||||
[RETURNS] The index of the next set bit. If no more bits are set,
|
||||
<<size>> + 1 is returned.
|
||||
*/
|
||||
{
|
||||
int index, tmp;
|
||||
unsigned long word;
|
||||
unsigned int ul_size = 8 * sizeof (unsigned long);
|
||||
CONST unsigned long *ul_array = array;
|
||||
|
||||
if (++offset >= size) return (offset);
|
||||
index = offset;
|
||||
/* Jump to the long word containing the next bit */
|
||||
tmp = offset / ul_size;
|
||||
ul_array += tmp;
|
||||
offset -= tmp * ul_size;
|
||||
if ( (offset == 0) || (*ul_array == 0) )
|
||||
return (find_first_set_bit (ul_array, size - index) + index);
|
||||
/* There is a bit set somewhere in this word */
|
||||
if ( ( (word = *ul_array) != 0 ) && ( (word = word >> offset) != 0 ) )
|
||||
{
|
||||
/* There is a bit set somewhere in this word at or after the offset
|
||||
position */
|
||||
for (; (word & 1) == 0; word = word >> 1, ++index);
|
||||
return (index);
|
||||
}
|
||||
/* Have to go to subsequent word(s) */
|
||||
index += ul_size - offset;
|
||||
return (find_first_set_bit (++ul_array, size - index) + index);
|
||||
} /* End Function find_next_set_bit */
|
||||
|
||||
#endif /* HAS_SELECT */
|
||||
|
||||
|
||||
struct callback_struct
|
||||
{
|
||||
void (*input_func) (void *info);
|
||||
void (*output_func) (void *info);
|
||||
void (*exception_func) (void *info);
|
||||
void *info;
|
||||
};
|
||||
|
||||
static int total_bits = 0;
|
||||
struct callback_struct callbacks[MAX_FDS];
|
||||
|
||||
|
||||
static void test_func (void *info)
|
||||
{
|
||||
++total_bits;
|
||||
}
|
||||
|
||||
#ifdef HAS_SELECT
|
||||
static void time_select (fd_set *input_fds, fd_set *output_fds,
|
||||
fd_set *exception_fds, int max_fd, int num_iter,
|
||||
long *times)
|
||||
/* [SUMMARY] Time how long it takes to select(2) file descriptors.
|
||||
<input_fds> The input masks.
|
||||
<output_fds> The output masks.
|
||||
<exception_fds> The exception masks.
|
||||
<max_fd> The highest file descriptor in the fd_sets.
|
||||
<num_iter> The number of iterations.
|
||||
<times> The time taken (in microseconds) for each iteration.
|
||||
[RETURNS] Nothing.
|
||||
*/
|
||||
{
|
||||
int fd, count, nready;
|
||||
fd_set i_fds, o_fds, e_fds;
|
||||
struct timeval time1, time2, tv;
|
||||
|
||||
/* Warm the cache a bit */
|
||||
memcpy (&i_fds, input_fds, sizeof i_fds);
|
||||
memcpy (&o_fds, output_fds, sizeof i_fds);
|
||||
memcpy (&e_fds, exception_fds, sizeof i_fds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
select (max_fd + 1, &i_fds, &o_fds, &e_fds, &tv);
|
||||
for (count = 0; count < num_iter; ++count)
|
||||
{
|
||||
total_bits = 0;
|
||||
gettimeofday (&time1, NULL);
|
||||
memcpy (&i_fds, input_fds, sizeof i_fds);
|
||||
memcpy (&o_fds, output_fds, sizeof i_fds);
|
||||
memcpy (&e_fds, exception_fds, sizeof i_fds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
nready = select (max_fd + 1, &i_fds, &o_fds, &e_fds, &tv);
|
||||
if (nready == -1)
|
||||
{
|
||||
fprintf (stderr, "Error selecting\t%s\n", ERRSTRING);
|
||||
exit (2);
|
||||
}
|
||||
if (nready < 1)
|
||||
{
|
||||
fprintf (stderr, "Error: nready: %d\n", nready);
|
||||
exit (1);
|
||||
}
|
||||
/* Scan the output */
|
||||
for (fd = find_first_set_bit (&e_fds, sizeof e_fds * 8); fd <= max_fd;
|
||||
fd = find_next_set_bit (&e_fds, sizeof e_fds * 8, fd) )
|
||||
{
|
||||
(*callbacks[fd].exception_func) (callbacks[fd].info);
|
||||
}
|
||||
for (fd = find_first_set_bit (&i_fds, sizeof i_fds * 8); fd <= max_fd;
|
||||
fd = find_next_set_bit (&i_fds, sizeof i_fds * 8, fd) )
|
||||
{
|
||||
(*callbacks[fd].input_func) (callbacks[fd].info);
|
||||
}
|
||||
for (fd = find_first_set_bit (&o_fds, sizeof o_fds * 8); fd <= max_fd;
|
||||
fd = find_next_set_bit (&o_fds, sizeof o_fds * 8, fd) )
|
||||
{
|
||||
(*callbacks[fd].output_func) (callbacks[fd].info);
|
||||
}
|
||||
gettimeofday (&time2, NULL);
|
||||
times[count] = (time2.tv_sec - time1.tv_sec) * 1000000;
|
||||
times[count] += time2.tv_usec - time1.tv_usec;
|
||||
}
|
||||
} /* End Function time_select */
|
||||
#endif /* HAS_SELECT */
|
||||
|
||||
#ifdef HAS_POLL
|
||||
static void time_poll (struct pollfd *pollfd_array, int start_index,
|
||||
int num_to_test, int num_iter, long *times)
|
||||
/* [SUMMARY] Time how long it takes to poll(2) file descriptors.
|
||||
<pollfd_array> The array of pollfd structures.
|
||||
<start_index> The start index in the array of pollfd structures.
|
||||
<num_to_test> The number of file descriptors to test.
|
||||
<num_iter> The number of iterations.
|
||||
<times> The time taken (in microseconds) for each iteration.
|
||||
[RETURNS] Nothing.
|
||||
*/
|
||||
{
|
||||
short revents;
|
||||
int fd, count, nready;
|
||||
struct timeval time1, time2;
|
||||
struct pollfd *pollfd_ptr;
|
||||
|
||||
/* Warm the cache a bit */
|
||||
poll (pollfd_array + start_index, num_to_test, 0);
|
||||
for (count = 0; count < num_iter; ++count)
|
||||
{
|
||||
total_bits = 0;
|
||||
gettimeofday (&time1, NULL);
|
||||
nready = poll (pollfd_array + start_index, num_to_test, 0);
|
||||
if (nready == -1)
|
||||
{
|
||||
fprintf (stderr, "Error polling\t%s\n", ERRSTRING);
|
||||
exit (2);
|
||||
}
|
||||
if (nready < 1)
|
||||
{
|
||||
fprintf (stderr, "Error: nready: %d\n", nready);
|
||||
exit (1);
|
||||
}
|
||||
for (pollfd_ptr = pollfd_array + start_index; nready; ++pollfd_ptr)
|
||||
{
|
||||
if (pollfd_ptr->revents == 0) continue;
|
||||
/* Have an active descriptor */
|
||||
--nready;
|
||||
revents = pollfd_ptr->revents;
|
||||
fd = pollfd_ptr->fd;
|
||||
if (revents & POLLPRI)
|
||||
(*callbacks[fd].exception_func) (callbacks[fd].info);
|
||||
if (revents & POLLIN)
|
||||
(*callbacks[fd].input_func) (callbacks[fd].info);
|
||||
if (revents & POLLOUT)
|
||||
(*callbacks[fd].output_func) (callbacks[fd].info);
|
||||
}
|
||||
gettimeofday (&time2, NULL);
|
||||
times[count] = (time2.tv_sec - time1.tv_sec) * 1000000;
|
||||
times[count] += time2.tv_usec - time1.tv_usec;
|
||||
}
|
||||
} /* End Function time_poll */
|
||||
#endif /* HAS_POLL */
|
||||
|
||||
#ifdef HAS_POLL2
|
||||
static void time_poll2 (struct poll2ifd *poll2ifd_array, int start_index,
|
||||
int num_to_test, int num_iter, long *times)
|
||||
/* [SUMMARY] Time how long it takes to poll2(2) file descriptors.
|
||||
<poll2ifd_array> The array of poll2ifd structures.
|
||||
<start_index> The start index in the array of pollfd structures.
|
||||
<num_to_test> The number of file descriptors to test.
|
||||
<num_iter> The number of iterations.
|
||||
<times> The time taken (in microseconds) for each iteration.
|
||||
[RETURNS] Nothing.
|
||||
*/
|
||||
{
|
||||
short revents;
|
||||
int fd, count, nready, i;
|
||||
struct timeval time1, time2;
|
||||
struct poll2ofd poll2ofd_array[MAX_FDS];
|
||||
|
||||
/* Warm the cache a bit */
|
||||
poll2 (poll2ifd_array + start_index, poll2ofd_array, num_to_test, 0);
|
||||
for (count = 0; count < num_iter; ++count)
|
||||
{
|
||||
total_bits = 0;
|
||||
gettimeofday (&time1, NULL);
|
||||
nready = poll2 (poll2ifd_array + start_index, poll2ofd_array,
|
||||
num_to_test, 0);
|
||||
if (nready == -1)
|
||||
{
|
||||
times[count] = -1;
|
||||
if (errno == ENOSYS) return; /* Must do this first */
|
||||
fprintf (stderr, "Error calling poll2(2)\t%s\n", ERRSTRING);
|
||||
exit (2);
|
||||
}
|
||||
if (nready < 1)
|
||||
{
|
||||
fprintf (stderr, "Error: nready: %d\n", nready);
|
||||
exit (1);
|
||||
}
|
||||
for (i = 0; i < nready; ++i)
|
||||
{
|
||||
revents = poll2ofd_array[i].revents;
|
||||
fd = poll2ofd_array[i].fd;
|
||||
if (revents & POLLPRI)
|
||||
(*callbacks[fd].exception_func) (callbacks[fd].info);
|
||||
if (revents & POLLIN)
|
||||
(*callbacks[fd].input_func) (callbacks[fd].info);
|
||||
if (revents & POLLOUT)
|
||||
(*callbacks[fd].output_func) (callbacks[fd].info);
|
||||
}
|
||||
gettimeofday (&time2, NULL);
|
||||
times[count] = (time2.tv_sec - time1.tv_sec) * 1000000;
|
||||
times[count] += time2.tv_usec - time1.tv_usec;
|
||||
}
|
||||
} /* End Function time_poll2 */
|
||||
#endif /* HAS_POLL2 */
|
||||
|
||||
|
||||
int main (argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
flag failed = FALSE;
|
||||
flag verbose = FALSE;
|
||||
int first_fd = -1;
|
||||
int fd, max_fd, count, total_fds;
|
||||
int num_to_test, num_active;
|
||||
#ifdef UNIXBENCH
|
||||
int max_iter = 1000;
|
||||
#else
|
||||
int max_iter = 10;
|
||||
#endif
|
||||
#ifdef HAS_SELECT
|
||||
long select_total = 0;
|
||||
fd_set input_fds, output_fds, exception_fds;
|
||||
long select_times[MAX_ITERATIONS];
|
||||
#endif
|
||||
#ifdef HAS_POLL
|
||||
int start_index;
|
||||
long poll_total = 0;
|
||||
struct pollfd pollfd_array[MAX_FDS];
|
||||
long poll_times[MAX_ITERATIONS];
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
long poll2_total = 0;
|
||||
struct poll2ifd poll2ifd_array[MAX_FDS];
|
||||
struct poll2ofd poll2ofd_array[MAX_FDS];
|
||||
long poll2_times[MAX_ITERATIONS];
|
||||
#endif
|
||||
|
||||
#ifdef HAS_SELECT
|
||||
FD_ZERO (&input_fds);
|
||||
FD_ZERO (&output_fds);
|
||||
FD_ZERO (&exception_fds);
|
||||
#endif
|
||||
#ifdef HAS_POLL
|
||||
memset (pollfd_array, 0, sizeof pollfd_array);
|
||||
#endif
|
||||
/* Allocate file descriptors */
|
||||
total_fds = 0;
|
||||
max_fd = 0;
|
||||
while (!failed)
|
||||
{
|
||||
if ( ( fd = dup (1) ) == -1 )
|
||||
{
|
||||
if (errno != EMFILE)
|
||||
{
|
||||
fprintf (stderr, "Error dup()ing\t%s\n", ERRSTRING);
|
||||
exit (1);
|
||||
}
|
||||
failed = TRUE;
|
||||
continue;
|
||||
}
|
||||
if (fd >= MAX_FDS)
|
||||
{
|
||||
fprintf (stderr, "File descriptor: %d larger than max: %d\n",
|
||||
fd, MAX_FDS - 1);
|
||||
exit (1);
|
||||
}
|
||||
callbacks[fd].input_func = test_func;
|
||||
callbacks[fd].output_func = test_func;
|
||||
callbacks[fd].exception_func = test_func;
|
||||
callbacks[fd].info = NULL;
|
||||
if (fd > max_fd) max_fd = fd;
|
||||
if (first_fd < 0) first_fd = fd;
|
||||
#ifdef HAS_POLL
|
||||
pollfd_array[fd].fd = fd;
|
||||
pollfd_array[fd].events = 0;
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
poll2ifd_array[fd].fd = fd;
|
||||
poll2ifd_array[fd].events = 0;
|
||||
#endif
|
||||
}
|
||||
total_fds = max_fd + 1;
|
||||
/* Process the command-line arguments */
|
||||
if (argc > 5)
|
||||
{
|
||||
fputs ("Usage:\ttime-polling [num_iter] [num_to_test] [num_active] [-v]\n",
|
||||
stderr);
|
||||
exit (1);
|
||||
}
|
||||
if (argc > 1) max_iter = atoi (argv[1]);
|
||||
if (max_iter > MAX_ITERATIONS)
|
||||
{
|
||||
fprintf (stderr, "num_iter too large\n");
|
||||
exit (1);
|
||||
}
|
||||
if (argc > 2) num_to_test = atoi (argv[2]);
|
||||
else num_to_test = total_fds - first_fd;
|
||||
if (argc > 3) num_active = atoi (argv[3]);
|
||||
else num_active = 1;
|
||||
if (argc > 4)
|
||||
{
|
||||
if (strcmp (argv[4], "-v") != 0)
|
||||
{
|
||||
fputs ("Usage:\ttime-polling [num_iter] [num_to_test] [num_active] [-v]\n",
|
||||
stderr);
|
||||
exit (1);
|
||||
}
|
||||
verbose = TRUE;
|
||||
}
|
||||
|
||||
/* Sanity tests */
|
||||
if (num_to_test > total_fds - first_fd) num_to_test = total_fds - first_fd;
|
||||
if (num_active > total_fds - first_fd) num_active = total_fds - first_fd;
|
||||
/* Set activity monitoring flags */
|
||||
for (fd = total_fds - num_to_test; fd < total_fds; ++fd)
|
||||
{
|
||||
#ifdef HAS_SELECT
|
||||
FD_SET (fd, &exception_fds);
|
||||
FD_SET (fd, &input_fds);
|
||||
#endif
|
||||
#ifdef HAS_POLL
|
||||
pollfd_array[fd].events = POLLPRI | POLLIN;
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
poll2ifd_array[fd].events = POLLPRI | POLLIN;
|
||||
#endif
|
||||
}
|
||||
for (fd = total_fds - num_active; fd < total_fds; ++fd)
|
||||
{
|
||||
#ifdef HAS_SELECT
|
||||
FD_SET (fd, &output_fds);
|
||||
#endif
|
||||
#ifdef HAS_POLL
|
||||
pollfd_array[fd].events |= POLLOUT;
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
poll2ifd_array[fd].events |= POLLOUT;
|
||||
#endif
|
||||
}
|
||||
fprintf (OUT, "Num fds: %d, polling descriptors %d-%d\n",
|
||||
total_fds, total_fds - num_to_test, max_fd);
|
||||
/* First do all the tests, then print the results */
|
||||
#ifdef HAS_SELECT
|
||||
time_select (&input_fds, &output_fds, &exception_fds, max_fd, max_iter,
|
||||
select_times);
|
||||
#endif
|
||||
#ifdef HAS_POLL
|
||||
start_index = total_fds - num_to_test;
|
||||
time_poll (pollfd_array, start_index, num_to_test, max_iter, poll_times);
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
start_index = total_fds - num_to_test;
|
||||
time_poll2 (poll2ifd_array, start_index, num_to_test, max_iter,
|
||||
poll2_times);
|
||||
#endif
|
||||
/* Now print out all the times */
|
||||
fputs ("All times in microseconds\n", OUT);
|
||||
fputs ("ITERATION\t", OUT);
|
||||
#ifdef HAS_SELECT
|
||||
fprintf (OUT, "%-12s", "select(2)");
|
||||
#endif
|
||||
#ifdef HAS_POLL
|
||||
fprintf (OUT, "%-12s", "poll(2)");
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
if (poll2_times[0] >= 0) fprintf (OUT, "%-12s", "poll2(2)");
|
||||
#endif
|
||||
for (count = 0; count < max_iter; ++count)
|
||||
{
|
||||
if (verbose) fprintf (OUT, "\n%d\t\t", count);
|
||||
#ifdef HAS_SELECT
|
||||
if (verbose) fprintf (OUT, "%-12ld", select_times[count]);
|
||||
select_total += select_times[count];
|
||||
#endif
|
||||
#ifdef HAS_POLL
|
||||
if (verbose) fprintf (OUT, "%-12ld", poll_times[count]);
|
||||
poll_total += poll_times[count];
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
if ( verbose && (poll2_times[0] >= 0) )
|
||||
fprintf (OUT, "%-12ld", poll2_times[count]);
|
||||
poll2_total += poll2_times[count];
|
||||
#endif
|
||||
}
|
||||
fputs ("\n\naverage\t\t", OUT);
|
||||
#ifdef HAS_SELECT
|
||||
fprintf (OUT, "%-12ld", select_total / max_iter);
|
||||
#endif
|
||||
#ifdef HAS_POLL
|
||||
fprintf (OUT, "%-12ld", poll_total / max_iter);
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
if (poll2_times[0] >= 0)
|
||||
fprintf (OUT, "%-12ld", poll2_total / max_iter);
|
||||
#endif
|
||||
putc ('\n', OUT);
|
||||
fputs ("Per fd\t\t", OUT);
|
||||
#ifdef HAS_SELECT
|
||||
fprintf (OUT, "%-12.2f",
|
||||
(float) select_total / (float) max_iter / (float) num_to_test);
|
||||
#ifdef UNIXBENCH
|
||||
fprintf (stderr, "lps\t%.2f\t%.1f\n",
|
||||
1000000 * (float) max_iter * (float) num_to_test
|
||||
/ (float) select_total, (float)select_total / 1000000);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAS_POLL
|
||||
fprintf (OUT, "%-12.2f",
|
||||
(float) poll_total / (float) max_iter / (float) num_to_test);
|
||||
#ifdef UNIXBENCH
|
||||
fprintf (stderr, "lps\t%.2f\t%.1f\n",
|
||||
1000000 * (float) max_iter * (float) num_to_test
|
||||
/ (float) poll_total, (float)poll_total / 1000000);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
if (poll2_times[0] >= 0) {
|
||||
fprintf (OUT, "%-12.2f",
|
||||
(float) poll2_total / (float) max_iter / (float) num_to_test);
|
||||
#ifdef UNIXBENCH
|
||||
fprintf (stderr, "lps\t%.2f\t%.1f\n",
|
||||
1000000 * (float) max_iter * (float) num_to_test
|
||||
/ (float) poll2_total, (float)poll2_total / 1000000);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
fputs ("<- the most important value\n", OUT);
|
||||
|
||||
exit(0);
|
||||
} /* End Function main */
|
||||
41
rk3308/unixbench-master_32/src/timeit.c
Executable file
41
rk3308/unixbench-master_32/src/timeit.c
Executable file
@ -0,0 +1,41 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: timeit.c SID: 3.3 5/15/91 19:30:21
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* May 12, 1989 - modified empty loops to avoid nullifying by optimizing
|
||||
* compilers
|
||||
* August 28, 1990 - changed timing relationship--now returns total number
|
||||
* of iterations (ty)
|
||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/* this module is #included in other modules--no separate SCCS ID */
|
||||
|
||||
/*
|
||||
* Timing routine
|
||||
*
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void wake_me(seconds, func)
|
||||
int seconds;
|
||||
void (*func)();
|
||||
{
|
||||
/* set up the signal handler */
|
||||
signal(SIGALRM, func);
|
||||
/* get the clock running */
|
||||
alarm(seconds);
|
||||
}
|
||||
|
||||
650
rk3308/unixbench-master_32/src/ubgears.c
Executable file
650
rk3308/unixbench-master_32/src/ubgears.c
Executable file
@ -0,0 +1,650 @@
|
||||
/*
|
||||
* Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/* $XFree86: xc/programs/glxgears/glxgears.c,v 1.3tsi Exp $ */
|
||||
|
||||
/*
|
||||
* This is a port of the infamous "gears" demo to straight GLX (i.e. no GLUT)
|
||||
* Port by Brian Paul 23 March 2001
|
||||
*
|
||||
* Exact timing added by Behdad Esfahbod to achieve a fixed speed regardless
|
||||
* of frame rate. November 2003
|
||||
*
|
||||
* Printer support added by Roland Mainz <roland.mainz@nrubsig.org>. April 2004
|
||||
*
|
||||
* This version modified by Ian Smith, 30 Sept 2007, to make ubgears.
|
||||
* ubgears is cusoimised for use in the UnixBench benchmarking suite.
|
||||
* Some redundant stuff is gone, and the -time option is added.
|
||||
* Mainly it's forked so we don't use the host's version, which could change
|
||||
* from platform to platform.
|
||||
*
|
||||
* Command line options:
|
||||
* -display Set X11 display for output.
|
||||
* -info Print additional GLX information.
|
||||
* -time <t> Run for <t> seconds and produce a performance report.
|
||||
* -h Print this help page.
|
||||
* -v Verbose output.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
#include <sys/time.h>
|
||||
#include <sched.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265
|
||||
#endif /* !M_PI */
|
||||
|
||||
/* Turn a NULL pointer string into an empty string */
|
||||
#define NULLSTR(x) (((x)!=NULL)?(x):(""))
|
||||
#define Log(x) { if(verbose) printf x; }
|
||||
#define Msg(x) { printf x; }
|
||||
|
||||
/* Globla vars */
|
||||
/* program name (from argv[0]) */
|
||||
static const char *ProgramName;
|
||||
|
||||
/* verbose output what the program is doing */
|
||||
static Bool verbose = False;
|
||||
|
||||
/* time in microseconds to run for; -1 means forever. */
|
||||
static int runTime = -1;
|
||||
|
||||
/* Time at which start_time(void) was called. */
|
||||
static struct timeval clockStart;
|
||||
|
||||
/* XXX this probably isn't very portable */
|
||||
|
||||
/* return current time (in seconds) */
|
||||
static void
|
||||
start_time(void)
|
||||
{
|
||||
(void) gettimeofday(&clockStart, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* return time (in microseconds) since start_time(void) was called.
|
||||
*
|
||||
* The older version of this function randomly returned negative results.
|
||||
* This version won't, up to 2000 seconds and some.
|
||||
*/
|
||||
static long
|
||||
current_time(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
long secs, micros;
|
||||
|
||||
(void) gettimeofday(&tv, 0);
|
||||
|
||||
secs = tv.tv_sec - clockStart.tv_sec;
|
||||
micros = tv.tv_usec - clockStart.tv_usec;
|
||||
if (micros < 0) {
|
||||
--secs;
|
||||
micros += 1000000;
|
||||
}
|
||||
return secs * 1000000 + micros;
|
||||
}
|
||||
|
||||
static
|
||||
void usage(void)
|
||||
{
|
||||
fprintf (stderr, "usage: %s [options]\n", ProgramName);
|
||||
fprintf (stderr, "-display\tSet X11 display for output.\n");
|
||||
fprintf (stderr, "-info\t\tPrint additional GLX information.\n");
|
||||
fprintf (stderr, "-time t\t\tRun for t seconds and report performance.\n");
|
||||
fprintf (stderr, "-h\t\tPrint this help page.\n");
|
||||
fprintf (stderr, "-v\t\tVerbose output.\n");
|
||||
fprintf (stderr, "\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
|
||||
static GLint gear1, gear2, gear3;
|
||||
static GLfloat angle = 0.0;
|
||||
static GLint speed = 60;
|
||||
static GLboolean printInfo = GL_FALSE;
|
||||
|
||||
/*
|
||||
*
|
||||
* Draw a gear wheel. You'll probably want to call this function when
|
||||
* building a display list since we do a lot of trig here.
|
||||
*
|
||||
* Input: inner_radius - radius of hole at center
|
||||
* outer_radius - radius at center of teeth
|
||||
* width - width of gear
|
||||
* teeth - number of teeth
|
||||
* tooth_depth - depth of tooth
|
||||
*/
|
||||
static void
|
||||
gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
|
||||
GLint teeth, GLfloat tooth_depth)
|
||||
{
|
||||
GLint i;
|
||||
GLfloat r0, r1, r2, maxr2, minr2;
|
||||
GLfloat angle, da;
|
||||
GLfloat u, v, len;
|
||||
|
||||
r0 = inner_radius;
|
||||
r1 = outer_radius - tooth_depth / 2.0;
|
||||
maxr2 = r2 = outer_radius + tooth_depth / 2.0;
|
||||
minr2 = r2;
|
||||
|
||||
da = 2.0 * M_PI / teeth / 4.0;
|
||||
|
||||
glShadeModel(GL_FLAT);
|
||||
|
||||
glNormal3f(0.0, 0.0, 1.0);
|
||||
|
||||
/* draw front face */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i <= teeth; i++) {
|
||||
angle = i * 2.0 * M_PI / teeth;
|
||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
|
||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
|
||||
if (i < teeth) {
|
||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
|
||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
|
||||
width * 0.5);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
|
||||
/* draw front sides of teeth */
|
||||
glBegin(GL_QUADS);
|
||||
for (i = 0; i < teeth; i++) {
|
||||
angle = i * 2.0 * M_PI / teeth;
|
||||
|
||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
|
||||
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
|
||||
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
|
||||
width * 0.5);
|
||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
|
||||
width * 0.5);
|
||||
r2 = minr2;
|
||||
}
|
||||
r2 = maxr2;
|
||||
glEnd();
|
||||
|
||||
glNormal3f(0.0, 0.0, -1.0);
|
||||
|
||||
/* draw back face */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i <= teeth; i++) {
|
||||
angle = i * 2.0 * M_PI / teeth;
|
||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
|
||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
|
||||
if (i < teeth) {
|
||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
|
||||
-width * 0.5);
|
||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
|
||||
/* draw back sides of teeth */
|
||||
glBegin(GL_QUADS);
|
||||
da = 2.0 * M_PI / teeth / 4.0;
|
||||
for (i = 0; i < teeth; i++) {
|
||||
angle = i * 2.0 * M_PI / teeth;
|
||||
|
||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
|
||||
-width * 0.5);
|
||||
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
|
||||
-width * 0.5);
|
||||
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
|
||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
|
||||
r2 = minr2;
|
||||
}
|
||||
r2 = maxr2;
|
||||
glEnd();
|
||||
|
||||
/* draw outward faces of teeth */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i < teeth; i++) {
|
||||
angle = i * 2.0 * M_PI / teeth;
|
||||
|
||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
|
||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
|
||||
u = r2 * cos(angle + da) - r1 * cos(angle);
|
||||
v = r2 * sin(angle + da) - r1 * sin(angle);
|
||||
len = sqrt(u * u + v * v);
|
||||
u /= len;
|
||||
v /= len;
|
||||
glNormal3f(v, -u, 0.0);
|
||||
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
|
||||
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
|
||||
glNormal3f(cos(angle + 1.5 * da), sin(angle + 1.5 * da), 0.0);
|
||||
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
|
||||
width * 0.5);
|
||||
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
|
||||
-width * 0.5);
|
||||
u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
|
||||
v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
|
||||
glNormal3f(v, -u, 0.0);
|
||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
|
||||
width * 0.5);
|
||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
|
||||
-width * 0.5);
|
||||
glNormal3f(cos(angle + 3.5 * da), sin(angle + 3.5 * da), 0.0);
|
||||
r2 = minr2;
|
||||
}
|
||||
r2 = maxr2;
|
||||
|
||||
glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
|
||||
glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
|
||||
|
||||
glEnd();
|
||||
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
/* draw inside radius cylinder */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i <= teeth; i++) {
|
||||
angle = i * 2.0 * M_PI / teeth;
|
||||
glNormal3f(-cos(angle), -sin(angle), 0.0);
|
||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
|
||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
draw(void)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glPushMatrix();
|
||||
glRotatef(view_rotx, 1.0, 0.0, 0.0);
|
||||
glRotatef(view_roty, 0.0, 1.0, 0.0);
|
||||
glRotatef(view_rotz, 0.0, 0.0, 1.0);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(-3.0, -2.0, 0.0);
|
||||
glRotatef(angle, 0.0, 0.0, 1.0);
|
||||
glCallList(gear1);
|
||||
glPopMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(3.1, -2.0, 0.0);
|
||||
glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
|
||||
glCallList(gear2);
|
||||
glPopMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(-3.1, 4.2, 0.0);
|
||||
glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
|
||||
glCallList(gear3);
|
||||
glPopMatrix();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
/* new window size or exposure */
|
||||
static void
|
||||
reshape(int width, int height)
|
||||
{
|
||||
GLfloat h = (GLfloat) height / (GLfloat) width;
|
||||
|
||||
glViewport(0, 0, (GLint) width, (GLint) height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
/* fit width and height */
|
||||
if (h >= 1.0)
|
||||
glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
|
||||
else
|
||||
glFrustum(-1.0/h, 1.0/h, -1.0, 1.0, 5.0, 60.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.0, 0.0, -40.0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init(void)
|
||||
{
|
||||
static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
|
||||
static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
|
||||
static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
|
||||
static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
|
||||
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, pos);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
/* make the gears */
|
||||
gear1 = glGenLists(1);
|
||||
glNewList(gear1, GL_COMPILE);
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
|
||||
gear(1.0, 4.0, 1.0, 20, 0.7);
|
||||
glEndList();
|
||||
|
||||
gear2 = glGenLists(1);
|
||||
glNewList(gear2, GL_COMPILE);
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
|
||||
gear(0.5, 2.0, 2.0, 10, 0.7);
|
||||
glEndList();
|
||||
|
||||
gear3 = glGenLists(1);
|
||||
glNewList(gear3, GL_COMPILE);
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
|
||||
gear(1.3, 2.0, 0.5, 10, 0.7);
|
||||
glEndList();
|
||||
|
||||
glEnable(GL_NORMALIZE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create an RGB, double-buffered window.
|
||||
* Return the window and context handles.
|
||||
*/
|
||||
static void
|
||||
make_window( Display *dpy, Screen *scr,
|
||||
const char *name,
|
||||
int x, int y, int width, int height,
|
||||
Window *winRet, GLXContext *ctxRet)
|
||||
{
|
||||
int attrib[] = { GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_DOUBLEBUFFER,
|
||||
GLX_DEPTH_SIZE, 1,
|
||||
None };
|
||||
int scrnum;
|
||||
XSetWindowAttributes attr;
|
||||
unsigned long mask;
|
||||
Window root;
|
||||
Window win;
|
||||
GLXContext ctx;
|
||||
XVisualInfo *visinfo;
|
||||
GLint max[2] = { 0, 0 };
|
||||
|
||||
scrnum = XScreenNumberOfScreen(scr);
|
||||
root = XRootWindow(dpy, scrnum);
|
||||
|
||||
visinfo = glXChooseVisual( dpy, scrnum, attrib );
|
||||
if (!visinfo) {
|
||||
fprintf(stderr, "%s: Error: couldn't get an RGB, Double-buffered visual.\n", ProgramName);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* window attributes */
|
||||
attr.background_pixel = 0;
|
||||
attr.border_pixel = 0;
|
||||
attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
|
||||
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
|
||||
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
|
||||
|
||||
win = XCreateWindow( dpy, root, x, y, width, height,
|
||||
0, visinfo->depth, InputOutput,
|
||||
visinfo->visual, mask, &attr );
|
||||
|
||||
/* set hints and properties */
|
||||
{
|
||||
XSizeHints sizehints;
|
||||
sizehints.x = x;
|
||||
sizehints.y = y;
|
||||
sizehints.width = width;
|
||||
sizehints.height = height;
|
||||
sizehints.flags = USSize | USPosition;
|
||||
XSetNormalHints(dpy, win, &sizehints);
|
||||
XSetStandardProperties(dpy, win, name, name,
|
||||
None, (char **)NULL, 0, &sizehints);
|
||||
}
|
||||
|
||||
ctx = glXCreateContext( dpy, visinfo, NULL, True );
|
||||
if (!ctx) {
|
||||
fprintf(stderr, "%s: Error: glXCreateContext failed.\n", ProgramName);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
XFree(visinfo);
|
||||
|
||||
XMapWindow(dpy, win);
|
||||
glXMakeCurrent(dpy, win, ctx);
|
||||
|
||||
/* Check for maximum size supported by the GL rasterizer */
|
||||
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, max);
|
||||
if (printInfo)
|
||||
printf("GL_MAX_VIEWPORT_DIMS=%d/%d\n", (int)max[0], (int)max[1]);
|
||||
if (width > max[0] || height > max[1]) {
|
||||
fprintf(stderr, "%s: Error: Requested window size (%d/%d) larger than "
|
||||
"maximum supported by GL engine (%d/%d).\n",
|
||||
ProgramName, width, height, (int)max[0], (int)max[1]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
*winRet = win;
|
||||
*ctxRet = ctx;
|
||||
}
|
||||
|
||||
static void
|
||||
event_loop(Display *dpy, Window win)
|
||||
{
|
||||
while (1) {
|
||||
/* Process interactive events */
|
||||
while (XPending(dpy) > 0) {
|
||||
XEvent event;
|
||||
XNextEvent(dpy, &event);
|
||||
switch (event.type) {
|
||||
case Expose:
|
||||
Log(("Event: Expose\n"));
|
||||
/* we'll redraw below */
|
||||
break;
|
||||
case ConfigureNotify:
|
||||
Log(("Event: ConfigureNotify\n"));
|
||||
reshape(event.xconfigure.width, event.xconfigure.height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/* Time at which we started measuring. */
|
||||
static long startTime = 0;
|
||||
|
||||
/* Time of the previous frame. */
|
||||
static long lastFrame = 0;
|
||||
|
||||
/* Time of the previous FPS report. */
|
||||
static long lastFps = 0;
|
||||
|
||||
/* Number of frames we've done. */
|
||||
static int frames = 0;
|
||||
|
||||
/* Number of frames we've done in the measured run. */
|
||||
static long runFrames = 0;
|
||||
|
||||
long t = current_time();
|
||||
long useconds;
|
||||
|
||||
if (!lastFrame)
|
||||
lastFrame = t;
|
||||
if (!lastFps)
|
||||
lastFps = t;
|
||||
|
||||
/* How many microseconds since the previous frame? */
|
||||
useconds = t - lastFrame;
|
||||
if (!useconds) /* assume 100FPS if we don't have timer */
|
||||
useconds = 10000;
|
||||
|
||||
/* Calculate how far the gears need to move and redraw. */
|
||||
angle = angle + ((double)speed * useconds) / 1000000.0;
|
||||
if (angle > 360.0)
|
||||
angle = angle - 360.0; /* don't lose precision! */
|
||||
draw();
|
||||
glXSwapBuffers(dpy, win);
|
||||
|
||||
/* Done this frame. */
|
||||
lastFrame = t;
|
||||
frames++;
|
||||
|
||||
/* Every 5 seconds, print the FPS. */
|
||||
if (t - lastFps >= 5000000L) {
|
||||
GLfloat seconds = (t - lastFps) / 1000000.0;
|
||||
GLfloat fps = frames / seconds;
|
||||
|
||||
printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
|
||||
fps);
|
||||
lastFps = t;
|
||||
frames = 0;
|
||||
|
||||
/*
|
||||
* Set the start time now -- ie. after one report. This
|
||||
* gives us pump-priming time before we start for real.
|
||||
*/
|
||||
if (runTime > 0 && startTime == 0) {
|
||||
printf("Start timing!\n");
|
||||
startTime = t;
|
||||
}
|
||||
}
|
||||
|
||||
if (startTime > 0)
|
||||
++runFrames;
|
||||
|
||||
/* If our run time is done, finish. */
|
||||
if (runTime > 0 && startTime > 0 && t - startTime > runTime) {
|
||||
double time = (double) (t - startTime) / 1000000.0;
|
||||
fprintf(stderr, "COUNT|%ld|1|fps\n", runFrames);
|
||||
fprintf(stderr, "TIME|%.1f\n", time);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Need to give cpu away in order to get precise timing next cycle,
|
||||
* otherwise, gettimeofday would return almost the same value. */
|
||||
sched_yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
Bool use_threadsafe_api = False;
|
||||
Display *dpy;
|
||||
Window win;
|
||||
Screen *screen;
|
||||
GLXContext ctx;
|
||||
char *dpyName = NULL;
|
||||
int i;
|
||||
XRectangle winrect;
|
||||
|
||||
ProgramName = argv[0];
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
int len = strlen(arg);
|
||||
|
||||
if (strcmp(argv[i], "-display") == 0) {
|
||||
if (++i >= argc)
|
||||
usage();
|
||||
dpyName = argv[i];
|
||||
}
|
||||
else if (strcmp(argv[i], "-info") == 0) {
|
||||
printInfo = GL_TRUE;
|
||||
}
|
||||
else if (strcmp(argv[i], "-time") == 0) {
|
||||
if (++i >= argc)
|
||||
usage();
|
||||
runTime = atoi(argv[i]) * 1000000;
|
||||
}
|
||||
else if (!strncmp("-v", arg, len)) {
|
||||
verbose = True;
|
||||
printInfo = GL_TRUE;
|
||||
}
|
||||
else if( !strncmp("-debug_use_threadsafe_api", arg, len) )
|
||||
{
|
||||
use_threadsafe_api = True;
|
||||
}
|
||||
else if (!strcmp(argv[i], "-h")) {
|
||||
usage();
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "%s: Unsupported option '%s'.\n", ProgramName, argv[i]);
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
/* Init X threading API on demand (for debugging) */
|
||||
if( use_threadsafe_api )
|
||||
{
|
||||
if( !XInitThreads() )
|
||||
{
|
||||
fprintf(stderr, "%s: XInitThreads() failure.\n", ProgramName);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
dpy = XOpenDisplay(dpyName);
|
||||
if (!dpy) {
|
||||
fprintf(stderr, "%s: Error: couldn't open display '%s'\n", ProgramName, dpyName);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
screen = XDefaultScreenOfDisplay(dpy);
|
||||
|
||||
winrect.x = 0;
|
||||
winrect.y = 0;
|
||||
winrect.width = 300;
|
||||
winrect.height = 300;
|
||||
|
||||
Log(("Window x=%d, y=%d, width=%d, height=%d\n",
|
||||
(int)winrect.x, (int)winrect.y, (int)winrect.width, (int)winrect.height));
|
||||
|
||||
make_window(dpy, screen, "ubgears", winrect.x, winrect.y, winrect.width, winrect.height, &win, &ctx);
|
||||
reshape(winrect.width, winrect.height);
|
||||
|
||||
if (printInfo) {
|
||||
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
|
||||
printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
|
||||
printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
|
||||
printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
start_time();
|
||||
event_loop(dpy, win);
|
||||
|
||||
glXDestroyContext(dpy, ctx);
|
||||
|
||||
XDestroyWindow(dpy, win);
|
||||
XCloseDisplay(dpy);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user