├── .clang-format ├── .dockerignore ├── .github └── workflows │ └── x86_64.yml ├── .gitignore ├── .gitlab-ci.yml ├── .gitmodules ├── .vscode └── settings.json ├── CMakeLists.txt ├── Dockerfile ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── cmake ├── HermitCore-Application.cmake ├── HermitCore-Configuration.cmake ├── HermitCore-Paths.cmake ├── HermitCore-Toolchain-aarch64.cmake ├── HermitCore-Toolchain-x86_64.cmake ├── HermitCore-Utils.cmake ├── HermitCore-librs.cmake ├── HermitCore.cmake ├── README.md ├── golang │ ├── CMakeDetermineGoCompiler.cmake │ ├── CMakeGoCompiler.cmake.in │ ├── CMakeGoInformation.cmake │ └── CMakeTestGoCompiler.cmake └── local-cmake.sh ├── img ├── demo.gif ├── hermitcore_logo.png └── hermitcore_logo.svg ├── include ├── hermit │ ├── CMakeLists.txt │ ├── aarch64 │ │ ├── arch_io.h │ │ ├── arch_limits.h │ │ └── arch_stddef.h │ ├── config.asm.in │ ├── config.h.in │ ├── ctype.h │ ├── errno.h │ ├── stdarg.h │ ├── stddef.h │ ├── stdio.h │ ├── stdlib.h │ ├── string.h │ ├── syscall.h │ └── x86_64 │ │ ├── arch_io.h │ │ ├── arch_limits.h │ │ └── arch_stddef.h ├── netinet │ ├── in.h │ └── tcp.h ├── stdarg.h ├── stddef.h ├── stdlib.h ├── string.h └── sys │ ├── ipc.h │ ├── poll.h │ ├── shm.h │ └── uio.h ├── tests.sh └── usr ├── benchmarks ├── CMakeLists.txt ├── basic.c ├── hg.c ├── hist.c ├── hist.h ├── init.c ├── init.h ├── netio.c ├── opt.c ├── opt.h ├── rdtsc.c ├── rdtsc.h ├── report.c ├── report.h ├── run.c ├── run.h ├── setup.c ├── setup.h ├── stream.c └── taskswitch.c ├── openmpbench ├── .gitignore ├── CMakeLists.txt ├── Licence.txt ├── README.txt ├── arraybench.c ├── arraybench.h ├── common.c ├── common.h ├── schedbench.c ├── schedbench.h ├── syncbench.c ├── syncbench.h ├── taskbench.c └── taskbench.h ├── tests ├── CMakeLists.txt ├── hello++.cpp ├── hello-tcp.c ├── hello.c ├── hellof.f90 ├── jacobi.c ├── nweb23.c ├── pi.go ├── server.go ├── test-malloc-mt.c ├── test-malloc.c └── thr_hello.c └── xray ├── CMakeLists.txt ├── LICENSE ├── README.md ├── browser.c ├── demangle.c ├── hashtable.c ├── libxray.spec ├── parsesymbols.c ├── report.c ├── stringpool.c ├── symtable.c ├── tools ├── conv2kcg.py └── report.xray ├── xray.c ├── xray.h ├── xray.odt └── xray_priv.h /.clang-format: -------------------------------------------------------------------------------- 1 | DisableFormat: true 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .gitignore -------------------------------------------------------------------------------- /.github/workflows/x86_64.yml: -------------------------------------------------------------------------------- 1 | name: Test x86_64 2 | 3 | on: 4 | pull_request: 5 | merge_group: 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | container: ghcr.io/hermit-os/hermit-toolchain:latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | with: 14 | submodules: true 15 | - name: Build apps 16 | run: | 17 | mkdir build 18 | cd build 19 | cmake .. 20 | make 21 | - name: Download loader 22 | uses: dsaltares/fetch-gh-release-asset@master 23 | with: 24 | repo: hermit-os/loader 25 | version: tags/v0.5.0 26 | file: hermit-loader-x86_64 27 | - name: Install QEMU 28 | run: | 29 | apt-get update 30 | apt-get -y install qemu-system-x86 31 | - name: Run hello 32 | run: qemu-system-x86_64 -smp 1 -cpu qemu64,apic,fsgsbase,rdtscp,xsave,xsaveopt,fxsr,rdrand -display none -m 128M -serial stdio -kernel hermit-loader-x86_64 -initrd build/local_prefix/opt/hermit/x86_64-hermit/extra/tests/hello 33 | #- name: Run hellof 34 | # run: qemu-system-x86_64 -smp 1 -cpu qemu64,apic,fsgsbase,rdtscp,xsave,xsaveopt,fxsr,rdrand -display none -m 128M -serial stdio -kernel hermit-loader-x86_64 -initrd build/local_prefix/opt/hermit/x86_64-hermit/extra/tests/hellof 35 | - name: Run thr_hello 36 | run: qemu-system-x86_64 -smp 1 -cpu qemu64,apic,fsgsbase,rdtscp,xsave,xsaveopt,fxsr,rdrand -display none -m 128M -serial stdio -kernel hermit-loader-x86_64 -initrd build/local_prefix/opt/hermit/x86_64-hermit/extra/tests/thr_hello 37 | - name: Run hello++ 38 | run: qemu-system-x86_64 -smp 1 -cpu qemu64,apic,fsgsbase,rdtscp,xsave,xsaveopt,fxsr,rdrand -display none -m 128M -serial stdio -kernel hermit-loader-x86_64 -initrd build/local_prefix/opt/hermit/x86_64-hermit/extra/tests/hello++ 39 | #- name: Run jacobi 40 | # run: qemu-system-x86_64 -smp 1 -cpu qemu64,apic,fsgsbase,rdtscp,xsave,xsaveopt,fxsr,rdrand -display none -m 1G -serial stdio -kernel rusty-loader -initrd build/local_prefix/opt/hermit/x86_64-hermit/extra/tests/jacobi 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Rust 2 | # Generated by Cargo 3 | # will have compiled files and executables 4 | /target/rls 5 | 6 | ### Visual Studio Code 7 | vscode/* 8 | !.vscode/settings.json 9 | !.vscode/tasks.json 10 | !.vscode/launch.json 11 | !.vscode/extensions.json 12 | 13 | *.pcap 14 | *.config 15 | *.creator 16 | *.user 17 | *.files 18 | *.includes 19 | *.pyc 20 | *.callgrind 21 | *.xray 22 | *.o 23 | *.ko 24 | **/build/* 25 | .idea/* 26 | target 27 | Cargo.lock 28 | qemu-vlan0.pcap 29 | cmake/cmake-3.7.2-Linux-x86_64/* 30 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | stages: 2 | - prepare 3 | - build 4 | - test 5 | 6 | variables: 7 | DOCKER_FILE: Dockerfile 8 | DOCKER_TAG: latest 9 | DOCKER_IMAGE: ${CI_REGISTRY_IMAGE} 10 | GIT_SUBMODULE_STRATEGY: normal 11 | FF_GITLAB_REGISTRY_HELPER_IMAGE: 1 12 | 13 | .prepare:docker: &prepare_docker 14 | stage: prepare 15 | image: 16 | name: docker 17 | before_script: 18 | - docker version 19 | - docker login --username "${CI_REGISTRY_USER}" --password "${CI_REGISTRY_PASSWORD}" "${CI_REGISTRY}" 20 | script: 21 | - docker build -f ${DOCKER_FILE} -t ${DOCKER_IMAGE}:${DOCKER_TAG} . 22 | - docker push ${DOCKER_IMAGE}:${DOCKER_TAG} 23 | tags: 24 | - docker 25 | 26 | prepare:docker: 27 | <<: *prepare_docker 28 | 29 | # Stage: build 30 | ############################################################################## 31 | 32 | build: 33 | stage: build 34 | script: 35 | - mkdir -p build 36 | - cd build 37 | - cmake -DTOOLCHAIN_BIN_DIR=/opt/hermit/bin -DCMAKE_INSTALL_PREFIX=/opt/hermit .. 38 | - make 39 | image: ${CI_REGISTRY_IMAGE} 40 | artifacts: 41 | paths: 42 | - ./build 43 | 44 | # Stage: test 45 | ############################################################################## 46 | test: 47 | stage: test 48 | script: 49 | - cd build 50 | - export TDIR=./local_prefix/opt/hermit/x86_64-hermit/extra 51 | - export FILES="$TDIR/tests/hello $TDIR/tests/hellof $TDIR/tests/hello++ $TDIR/tests/jacobi $TDIR/tests/thr_hello" #$TDIR/benchmarks/stream" #$TDIR/tests/test-malloc $TDIR/tests/test-malloc-mt" 52 | - for f in $FILES; do echo "check $f..."; timeout --kill-after=5m 5m uhyve -v -c 1 -m 128M $f || exit 1; done 53 | - for f in $FILES; do echo "check $f..."; timeout --kill-after=5m 5m uhyve -v -c 2 -m 128M $f || exit 1; done 54 | image: ${CI_REGISTRY_IMAGE} 55 | dependencies: 56 | - build 57 | tags: 58 | - privileged 59 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "librs"] 2 | path = librs 3 | url = https://github.com/hermit-os/kernel.git 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "search.exclude": { 3 | "**/target": true 4 | "build": true 5 | }, 6 | "lldb.verboseLogging": true, 7 | #"rust-client.disableRustup": true, 8 | #"rust.all_targets": false, 9 | #"rust.target": "x86_64-unknown-hermit", 10 | } 11 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.7) 2 | 3 | include(ExternalProject) 4 | include(cmake/HermitCore.cmake) 5 | 6 | project (HermitCore) 7 | 8 | ### Kernel 9 | 10 | # generate config files 11 | add_subdirectory(include/hermit) 12 | 13 | # Build the HermitCore Rust Kernel and its dependencies. 14 | include(cmake/HermitCore-librs.cmake) 15 | 16 | 17 | if(NOT BOOTSTRAP) 18 | ### External projects 19 | # 20 | # Build projects externally and deploy into temporary common prefix, will later 21 | # be relocated for installation 22 | 23 | if(PROFILING) 24 | ## XRay profiler 25 | build_external(xray ${HERMIT_ROOT}/usr/xray "") 26 | add_dependencies(hermit xray) 27 | endif() 28 | 29 | ## Tests and benchmarks 30 | build_external(tests ${HERMIT_ROOT}/usr/tests hermit) 31 | #build_external(openmpbench ${HERMIT_ROOT}/usr/openmpbench hermit) 32 | 33 | # These are currently x86_64-specific 34 | if("${HERMIT_ARCH}" STREQUAL "x86_64") 35 | build_external(benchmarks ${HERMIT_ROOT}/usr/benchmarks hermit) 36 | endif() 37 | endif() 38 | 39 | ## relocate the local prefix to our install destination 40 | install(DIRECTORY ${LOCAL_PREFIX_DIR}/ 41 | DESTINATION ${CMAKE_INSTALL_PREFIX}/ 42 | USE_SOURCE_PERMISSIONS) 43 | 44 | 45 | ### QEmu 46 | # Start HermitCore as multi-kernel in a QEmu VM 47 | 48 | add_custom_target(qemu 49 | COMMAND 50 | qemu-system-x86_64 51 | -machine accel=kvm -cpu host 52 | -smp 10 -m 8G -numa node,nodeid=0,cpus=0-4 -numa node,nodeid=1,cpus=5-9 53 | -kernel ${HERMIT_ROOT}/config/bzImage 54 | -append "root=/dev/ram0 rootfstype=ramfs init=init console=ttyS0" 55 | -net nic,model=rtl8139 -net user -net dump 56 | -nographic -monitor telnet:127.0.0.1:1235,server,nowait 57 | -fsdev local,security_model=none,id=fsdev0,path=${LOCAL_PREFIX_DIR} 58 | -device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=hermit 59 | -s 60 | USES_TERMINAL VERBATIM) 61 | 62 | # create a QEmu target that depends on everything 63 | get_property(_TARGETS 64 | DIRECTORY . 65 | PROPERTY BUILDSYSTEM_TARGETS) 66 | 67 | add_custom_target(qemu-dep 68 | DEPENDS 69 | ${_TARGETS} qemu) 70 | 71 | 72 | ### Packaging 73 | 74 | set(CPACK_PACKAGE_NAME libhermit-rs) 75 | set(CPACK_SYSTEM_NAME all) 76 | 77 | set(CPACK_PACKAGE_VERSION_MAJOR 0) 78 | set(CPACK_PACKAGE_VERSION_MINOR 3) 79 | set(CPACK_PACKAGE_VERSION_PATCH 15) 80 | 81 | set(CPACK_PACKAGE_CONTACT "Stefan Lankes ") 82 | 83 | # build .deb, .rpm and .tar.bz2 packages 84 | set(CPACK_GENERATOR DEB;RPM;TBZ2) 85 | 86 | # needed in order for tests and bechmark to use correct install prefix 87 | set(CPACK_SET_DESTDIR on) 88 | 89 | ## Debian specific 90 | # not dependent on Debian system architecture 91 | set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE all) 92 | 93 | ## RPM specific 94 | # libhermit is currently not relocatable 95 | set(CPACK_PACKAGE_RELOCATABLE FALSE) 96 | 97 | include(CPack) 98 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:buster as builder 2 | 3 | RUN cargo install --git https://github.com/hermit-os/uhyve.git --locked uhyve 4 | 5 | 6 | FROM ghcr.io/hermit-os/hermit-toolchain:latest as playground 7 | 8 | COPY --from=builder $CARGO_HOME/bin/uhyve $CARGO_HOME/bin/uhyve 9 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any 2 | person obtaining a copy of this software and associated 3 | documentation files (the "Software"), to deal in the 4 | Software without restriction, including without 5 | limitation the rights to use, copy, modify, merge, 6 | publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software 8 | is furnished to do so, subject to the following 9 | conditions: 10 | 11 | The above copyright notice and this permission notice 12 | shall be included in all copies or substantial portions 13 | of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 17 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 22 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /cmake/HermitCore-Application.cmake: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_LIST_DIR}/HermitCore.cmake) 2 | include_guard() 3 | 4 | add_compile_options(${HERMIT_APP_FLAGS}) 5 | 6 | # link against and include locally built libraries instead of the ones 7 | # supplied with the toolchain, if built from top-level 8 | link_directories(${LOCAL_PREFIX_ARCH_LIB_DIR}) 9 | include_directories(BEFORE ${LOCAL_PREFIX_ARCH_INCLUDE_DIR}) 10 | 11 | -------------------------------------------------------------------------------- /cmake/HermitCore-Configuration.cmake: -------------------------------------------------------------------------------- 1 | set(PACKAGE_VERSION "0.3.15" CACHE STRING 2 | "HermitCore current version") 3 | 4 | set(MAX_ARGC_ENVC 128 CACHE STRING 5 | "Maximum number of command line parameters and enviroment variables 6 | forwarded to uhyve") 7 | -------------------------------------------------------------------------------- /cmake/HermitCore-Paths.cmake: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_LIST_DIR}/HermitCore-Utils.cmake) 2 | # no include guard here because we have to include this file twice to correctly 3 | # set CMAKE_INSTALL_PREFIX 4 | 5 | # root of HermitCore project 6 | set(HERMIT_ROOT ${CMAKE_CURRENT_LIST_DIR}/..) 7 | 8 | # set default install prefix if user doesn't specify one 9 | if(${CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT}) 10 | # See CMake docs for reference: 11 | # https://cmake.org/cmake/help/v3.7/variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT.html 12 | set(CMAKE_INSTALL_PREFIX /opt/hermit CACHE PATH "..." FORCE) 13 | endif() 14 | 15 | # we install 3rd party libraries to an intermediate directory and relocate 16 | # them here later when installing the whole project 17 | if(NOT LOCAL_PREFIX_BASE_DIR) 18 | # will be injected into external project because CMAKE_BINARY_DIR will be 19 | # different there 20 | set(LOCAL_PREFIX_BASE_DIR ${CMAKE_BINARY_DIR}/local_prefix) 21 | endif() 22 | 23 | # during build process libraries and external projects will be deployed into 24 | # this directory structure 25 | set(LOCAL_PREFIX_DIR ${LOCAL_PREFIX_BASE_DIR}/${CMAKE_INSTALL_PREFIX}) 26 | set(LOCAL_PREFIX_ARCH_DIR ${LOCAL_PREFIX_DIR}/${HERMIT_ARCH}-hermit) 27 | set(LOCAL_PREFIX_ARCH_INCLUDE_DIR ${LOCAL_PREFIX_ARCH_DIR}/include) 28 | 29 | # when building applications within the HermitCore project (tests, ...) they 30 | # will link prefarably against libraries in this directory in order to test 31 | # changes in the kernel 32 | set(LOCAL_PREFIX_ARCH_LIB_DIR ${LOCAL_PREFIX_ARCH_DIR}/lib) 33 | -------------------------------------------------------------------------------- /cmake/HermitCore-Toolchain-aarch64.cmake: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_LIST_DIR}/HermitCore-Utils.cmake) 2 | include_guard() 3 | 4 | # let user provide a different path to the toolchain 5 | set_default(TOOLCHAIN_BIN_DIR /opt/hermit/bin) 6 | 7 | set(HERMIT_ARCH aarch64) 8 | set(HERMIT_KERNEL_FLAGS 9 | -Wall -O2 -mgeneral-regs-only 10 | -fno-var-tracking-assignments -fstrength-reduce 11 | -fomit-frame-pointer -finline-functions -ffreestanding 12 | -nostdinc -fno-stack-protector 13 | -fno-delete-null-pointer-checks 14 | -falign-jumps=1 -falign-loops=1 15 | -fno-common -Wframe-larger-than=1024 16 | -fno-strict-aliasing -fno-asynchronous-unwind-tables 17 | -fno-strict-overflow) 18 | 19 | set(HERMIT_APP_FLAGS 20 | -O3 -ftree-vectorize) 21 | 22 | set(CMAKE_SYSTEM_NAME Generic) 23 | 24 | # point CMake to our toolchain 25 | set(CMAKE_C_COMPILER ${TOOLCHAIN_BIN_DIR}/${HERMIT_ARCH}-hermit-gcc) 26 | set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN_DIR}/${HERMIT_ARCH}-hermit-g++) 27 | set(CMAKE_Fortran_COMPILER ${TOOLCHAIN_BIN_DIR}/${HERMIT_ARCH}-hermit-gfortran) 28 | set(CMAKE_Go_COMPILER ${TOOLCHAIN_BIN_DIR}/${HERMIT_ARCH}-hermit-gccgo) 29 | 30 | # Building a HermitCore application won't work before HermitCore is installed in /opt/hermit because of the missing libhermit.a 31 | # So only try to compile a static library for compiler testing. 32 | set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) 33 | 34 | # hinting the prefix and location is needed in order to correctly detect 35 | # binutils 36 | set(_CMAKE_TOOLCHAIN_PREFIX "${HERMIT_ARCH}-hermit-") 37 | set(_CMAKE_TOOLCHAIN_LOCATION ${TOOLCHAIN_BIN_DIR}) 38 | -------------------------------------------------------------------------------- /cmake/HermitCore-Toolchain-x86_64.cmake: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_LIST_DIR}/HermitCore-Utils.cmake) 2 | include_guard() 3 | 4 | # let user provide a different path to the toolchain 5 | set_default(TOOLCHAIN_BIN_DIR /opt/hermit/bin) 6 | 7 | set(HERMIT_ARCH x86_64) 8 | set(HERMIT_KERNEL_FLAGS 9 | -m64 -Wall -O2 -mno-red-zone 10 | -fno-var-tracking-assignments -fstrength-reduce 11 | -fomit-frame-pointer -finline-functions -ffreestanding 12 | -nostdinc -fno-stack-protector -mno-sse -mno-mmx 13 | -mno-sse2 -mno-3dnow -mno-avx 14 | -fno-delete-null-pointer-checks 15 | -falign-jumps=1 -falign-loops=1 16 | -mno-80387 -mno-fp-ret-in-387 -mskip-rax-setup 17 | -fno-common -Wframe-larger-than=1024 18 | -fno-strict-aliasing -fno-asynchronous-unwind-tables 19 | -fno-strict-overflow -maccumulate-outgoing-args -fPIE) 20 | 21 | set(HERMIT_APP_FLAGS 22 | -m64 -mtls-direct-seg-refs -O3 -ftree-vectorize -fPIE) 23 | 24 | set(CMAKE_SYSTEM_NAME Generic) 25 | 26 | # point CMake to our toolchain 27 | # In Debug mode, the Rust-compiled libhermit.a contains references to non-existing software floating-point functions (like __floatundisf). 28 | # We have to remove these with a linker flag as early as possible. 29 | set(GC_SECTIONS_FLAG "-Wl,--gc-sections") 30 | set(CMAKE_C_COMPILER ${TOOLCHAIN_BIN_DIR}/${HERMIT_ARCH}-hermit-gcc ${GC_SECTIONS_FLAG}) 31 | set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN_DIR}/${HERMIT_ARCH}-hermit-g++ ${GC_SECTIONS_FLAG}) 32 | set(CMAKE_Fortran_COMPILER ${TOOLCHAIN_BIN_DIR}/${HERMIT_ARCH}-hermit-gfortran ${GC_SECTIONS_FLAG}) 33 | #set(CMAKE_Go_COMPILER "${TOOLCHAIN_BIN_DIR}/${HERMIT_ARCH}-hermit-gccgo" "${GC_SECTIONS_FLAG}") 34 | 35 | # Building a HermitCore application won't work before HermitCore is installed in /opt/hermit because of the missing libhermit.a 36 | # So only try to compile a static library for compiler testing. 37 | set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) 38 | 39 | # hinting the prefix and location is needed in order to correctly detect 40 | # binutils 41 | set(_CMAKE_TOOLCHAIN_PREFIX "${HERMIT_ARCH}-hermit-") 42 | set(_CMAKE_TOOLCHAIN_LOCATION ${TOOLCHAIN_BIN_DIR}) 43 | -------------------------------------------------------------------------------- /cmake/HermitCore-Utils.cmake: -------------------------------------------------------------------------------- 1 | macro(include_guard) 2 | if(DEFINED "_INCLUDE_GUARD_${CMAKE_CURRENT_LIST_FILE}") 3 | return() 4 | endif() 5 | set("_INCLUDE_GUARD_${CMAKE_CURRENT_LIST_FILE}" INCLUDED) 6 | endmacro(include_guard) 7 | 8 | macro(add_kernel_module_sources MODULE SOURCE_GLOB) 9 | file(GLOB SOURCES "${SOURCE_GLOB}") 10 | 11 | if("${SOURCES}" STREQUAL "") 12 | message(FATAL_ERROR "Module '${MODULE}' has no sources") 13 | endif() 14 | 15 | # make sure modules are unique, this is needed of multiple sources 16 | # are added to the same module 17 | list(APPEND _KERNEL_MODULES "${MODULE}") 18 | list(REMOVE_DUPLICATES _KERNEL_MODULES) 19 | 20 | # append sources for module 21 | list(APPEND "_KERNEL_SOURCES_${MODULE}" "${SOURCES}") 22 | endmacro(add_kernel_module_sources) 23 | 24 | 25 | macro(get_kernel_module_sources VAR MODULE) 26 | set(${VAR} ${_KERNEL_SOURCES_${MODULE}}) 27 | endmacro(get_kernel_module_sources) 28 | 29 | 30 | macro(get_kernel_modules VAR) 31 | set(${VAR} ${_KERNEL_MODULES}) 32 | endmacro(get_kernel_modules) 33 | 34 | # find program in /toolchain/dir/prefix-NAME, only supply NAME 35 | function(find_toolchain_program NAME) 36 | 37 | string(TOUPPER "${NAME}" NAME_UPPER) 38 | string(TOLOWER "${NAME}" NAME_LOWER) 39 | 40 | set(VARNAME "CMAKE_${NAME_UPPER}") 41 | 42 | find_program(${VARNAME} 43 | NAMES ${_CMAKE_TOOLCHAIN_PREFIX}${NAME_LOWER} 44 | HINTS ${TOOLCHAIN_BIN_DIR}) 45 | 46 | if(NOT ${VARNAME}) 47 | message(FATAL_ERROR 48 | "Cannot find ${_CMAKE_TOOLCHAIN_PREFIX}${NAME_LOWER}") 49 | endif() 50 | endfunction(find_toolchain_program) 51 | 52 | function(get_cmd_variables VAR) 53 | set(_OUTPUT "") 54 | 55 | get_cmake_property(vs VARIABLES) 56 | 57 | foreach(v ${vs}) 58 | get_property(_HELPSTRING 59 | CACHE ${v} 60 | PROPERTY HELPSTRING) 61 | if("${_HELPSTRING}" STREQUAL "No help, variable specified on the command line.") 62 | list(APPEND _OUTPUT "${v}") 63 | endif() 64 | endforeach() 65 | 66 | set(${VAR} ${_OUTPUT} PARENT_SCOPE) 67 | endfunction(get_cmd_variables) 68 | 69 | # any additional parameters will be handed over to the cmake command that the 70 | # external project is invoked with 71 | function(build_external NAME PATH DEPENDS) 72 | if("${NAME}" IN_LIST PROFILE_APPS) 73 | set(DO_PROFILING "-DPROFILING=true") 74 | endif() 75 | 76 | # pass through all command line variables 77 | get_cmd_variables(CMD_VAR_NAMES) 78 | foreach(var ${CMD_VAR_NAMES}) 79 | set(CMD_VARS ${CMD_VARS} -D${var}=${${var}}) 80 | endforeach() 81 | 82 | ExternalProject_Add(${NAME} 83 | SOURCE_DIR ${PATH} 84 | BUILD_ALWAYS 1 85 | DEPENDS ${DEPENDS} 86 | INSTALL_COMMAND 87 | ${CMAKE_COMMAND} --build 88 | --target install -- 89 | DESTDIR=${LOCAL_PREFIX_BASE_DIR} 90 | CMAKE_ARGS 91 | -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} 92 | -DLOCAL_PREFIX_BASE_DIR=${LOCAL_PREFIX_BASE_DIR} 93 | -DCMAKE_INSTALL_MESSAGE=NEVER 94 | -DCMAKE_EXPORT_COMPILE_COMMANDS=true 95 | -DMAX_ARGC_ENVC=${MAX_ARGC_ENVC} 96 | -DHERMIT_ARCH=${HERMIT_ARCH} 97 | --no-warn-unused-cli 98 | ${DO_PROFILING} 99 | ${CMD_VARS} 100 | ${ARGN}) 101 | 102 | ExternalProject_Add_Step(${NAME} relink 103 | COMMAND find . -maxdepth 1 -type f -executable -exec rm {} "\\\;" 104 | DEPENDEES configure 105 | DEPENDERS build 106 | WORKING_DIRECTORY ) 107 | 108 | ExternalProject_Add_StepDependencies(${NAME} relink ${DEPENDS}) 109 | endfunction(build_external) 110 | 111 | 112 | # additional arguments are be treated as targets that will be excluded 113 | function(install_local_targets PATH) 114 | get_property(_TARGETS 115 | DIRECTORY . 116 | PROPERTY BUILDSYSTEM_TARGETS) 117 | 118 | if(NOT "${ARGN}" STREQUAL "") 119 | list(REMOVE_ITEM _TARGETS ${ARGN}) 120 | endif() 121 | 122 | install(TARGETS ${_TARGETS} 123 | DESTINATION ${HERMIT_ARCH}-hermit/${PATH}) 124 | 125 | # if there are any .map files for profiling, install them too 126 | foreach(TARGET ${_TARGETS}) 127 | install(FILES $.map 128 | DESTINATION ${HERMIT_ARCH}-hermit/${PATH} 129 | OPTIONAL) 130 | endforeach() 131 | endfunction(install_local_targets) 132 | 133 | # set variable if not yet set 134 | macro(set_default VARNAME) 135 | if(NOT ${VARNAME}) 136 | set(${VARNAME} ${ARGN}) 137 | endif() 138 | endmacro(set_default) 139 | -------------------------------------------------------------------------------- /cmake/HermitCore-librs.cmake: -------------------------------------------------------------------------------- 1 | # Add the Cargo project to build the Rust library. 2 | set(HERMIT_RS "${CMAKE_BINARY_DIR}/hermit_rs/${HERMIT_ARCH}/${CARGO_BUILDTYPE_OUTPUT}/libhermit.a") 3 | add_custom_target(hermit_rs 4 | COMMAND 5 | cargo run --package=xtask --target-dir ${CMAKE_BINARY_DIR}/hermit_rs -- 6 | build --arch ${HERMIT_ARCH} --target-dir ${CMAKE_BINARY_DIR}/hermit_rs ${CARGO_BUILDTYPE_PARAMETER} 7 | --no-default-features --features pci,smp,acpi,newlib,tcp,dhcpv4 8 | WORKING_DIRECTORY 9 | ${CMAKE_CURRENT_LIST_DIR}/../librs) 10 | 11 | # Require hermit_rs to be built for hermit 12 | add_custom_target(hermit 13 | DEPENDS hermit_rs 14 | 15 | # Copy libhermit.a into local prefix directory so that all subsequent 16 | # targets can link against the freshly built version (as opposed to 17 | # linking against the one supplied by the toolchain) 18 | 19 | COMMAND 20 | ${CMAKE_COMMAND} -E make_directory ${LOCAL_PREFIX_ARCH_LIB_DIR} 21 | COMMAND 22 | ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_BINARY_DIR}/hermit_rs/${HERMIT_ARCH}/release/libhermit.a ${LOCAL_PREFIX_ARCH_LIB_DIR}/ 23 | 24 | # and also copy headers into local prefix 25 | COMMAND 26 | ${CMAKE_COMMAND} -E make_directory ${LOCAL_PREFIX_ARCH_INCLUDE_DIR}/hermit 27 | COMMAND 28 | ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/include/hermit/*.h ${LOCAL_PREFIX_ARCH_INCLUDE_DIR}/hermit/) 29 | 30 | # Provide custom target to only install libhermit without its runtimes which is 31 | # needed during the compilation of the cross toolchain 32 | add_custom_target(hermit_rs-install 33 | DEPENDS 34 | hermit_rs 35 | COMMAND 36 | ${CMAKE_COMMAND} 37 | -DCMAKE_INSTALL_COMPONENT=bootstrap 38 | -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} 39 | -P cmake_install.cmake 40 | ) 41 | 42 | # Install libhermit.a and headers 43 | install(FILES ${CMAKE_BINARY_DIR}/hermit_rs/${HERMIT_ARCH}/release/libhermit.a 44 | DESTINATION ${HERMIT_ARCH}-hermit/lib 45 | COMPONENT bootstrap) 46 | 47 | install(DIRECTORY include/hermit 48 | DESTINATION ${HERMIT_ARCH}-hermit/include/ 49 | COMPONENT bootstrap 50 | FILES_MATCHING PATTERN *.h) -------------------------------------------------------------------------------- /cmake/HermitCore.cmake: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_LIST_DIR}/HermitCore-Utils.cmake) 2 | include_guard() 3 | 4 | include(${CMAKE_CURRENT_LIST_DIR}/HermitCore-Paths.cmake) 5 | include(${CMAKE_CURRENT_LIST_DIR}/HermitCore-Configuration.cmake) 6 | 7 | # scripts to detect HermitCore Go compiler 8 | #list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/golang/) 9 | 10 | if(NOT HERMIT_ARCH) 11 | execute_process(COMMAND uname -m OUTPUT_VARIABLE HERMIT_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE) 12 | endif() 13 | 14 | if(NOT CMAKE_BUILD_TYPE) 15 | set(CMAKE_BUILD_TYPE Release) 16 | endif() 17 | 18 | if(CMAKE_BUILD_TYPE MATCHES Release) 19 | set(CARGO_BUILDTYPE_OUTPUT "release") 20 | set(CARGO_BUILDTYPE_PARAMETER "--release") 21 | else() 22 | set(CARGO_BUILDTYPE_OUTPUT "debug") 23 | set(CARGO_BUILDTYPE_PARAMETER "") 24 | endif() 25 | 26 | if(PROFILING) 27 | # link everything against XRay 28 | link_libraries(-lxray) 29 | 30 | # generate symbol map file for XRay to resolve function names 31 | link_libraries(-Wl,-Map=$.map) 32 | 33 | # enable profiling with XRay 34 | add_compile_options(-falign-functions=32 -finstrument-functions 35 | -finstrument-functions-exclude-function-list=_mm_pause,_mm_setcsr,_mm_getcsr) 36 | add_definitions(-DXRAY -DXRAY_DISABLE_BROWSER_INTEGRATION 37 | -DXRAY_NO_DEMANGLE -DXRAY_ANNOTATE) 38 | endif() 39 | 40 | # use default toolchain if not specified by user 41 | if(NOT CMAKE_TOOLCHAIN_FILE) 42 | set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/HermitCore-Toolchain-${HERMIT_ARCH}.cmake) 43 | endif() 44 | 45 | if(MTUNE) 46 | set(HERMIT_KERNEL_FLAGS ${HERMIT_KERNEL_FLAGS} -mtune=${MTUNE}) 47 | set(HERMIT_APP_FLAGS ${HERMIT_APP_FLAGS} -mtune=${MTUNE}) 48 | endif() 49 | 50 | set(HERMIT_KERNEL_INCLUDES 51 | ${CMAKE_BINARY_DIR}/include 52 | ${HERMIT_ROOT}/include 53 | ${HERMIT_ROOT}/include/hermit/${HERMIT_ARCH}) 54 | 55 | # HACK: when CMake detects compilers it taints CMAKE_INSTALL_PREFIX, so in 56 | # order to rely on that variable (we redefine it), enable all languages 57 | # here and source pathes again. 58 | # 59 | # Furthermore this will produce a sensible error message if the toolchain cannot 60 | # be found. 61 | if(BOOTSTRAP) 62 | enable_language(C CXX) 63 | else() 64 | enable_language(C CXX Fortran) 65 | endif() 66 | 67 | include(${CMAKE_CURRENT_LIST_DIR}/HermitCore-Paths.cmake) 68 | 69 | # find elfedit & objcopy, CMake doesn't use this program, so we have to find it ourself 70 | find_toolchain_program(elfedit) 71 | find_toolchain_program(objcopy) 72 | -------------------------------------------------------------------------------- /cmake/README.md: -------------------------------------------------------------------------------- 1 | HermitCore CMake build system 2 | ============================= 3 | 4 | HermitCore requires at least CMake version `3.7`, which (at the time of 5 | introduction) is not yet available on most Linux distributions. We therefore 6 | provide a script `cmake/local-cmake.sh` that fetches precompiled binaries from 7 | the CMake project and installs them locally in `cmake/cmake-3.7*`. Only when 8 | sourced for the first time it will download CMake, on further runs it detects 9 | the existing download and adds it to `PATH` automatically. 10 | 11 | ```bash 12 | $ . cmake/local-cmake.sh 13 | -- Downloading CMake 14 | cmake-3.7.2-Linux-x 100%[=================>] 29,26M 837KB/s in 19s 15 | -- Unpacking CMake 16 | -- Local CMake v3.7.2 installed to cmake/cmake-3.7.2-Linux-x86_64 17 | -- Next time you source this script, no download will be neccessary 18 | $ which cmake 19 | /home/[...]/HermitCore/cmake/cmake-3.7.2-Linux-x86_64/bin/cmake 20 | ``` 21 | 22 | ## Directory structure 23 | 24 | ``` 25 | cmake/ 26 | ├── golang 27 | │   ├── CMakeDetermineGoCompiler.cmake 28 | │   ├── CMakeGoCompiler.cmake.in 29 | │   ├── CMakeGoInformation.cmake 30 | │   └── CMakeTestGoCompiler.cmake 31 | ├── HermitCore-Application.cmake 32 | ├── HermitCore.cmake 33 | ├── HermitCore-Paths.cmake 34 | ├── HermitCore-Toolchain-x86.cmake 35 | ├── HermitCore-Utils.cmake 36 | ├── local-cmake.sh 37 | └── README.md 38 | ``` 39 | 40 | ## Additional language support 41 | 42 | Currently, HermitCore supports `C, C++, Fortran, Go` through Cmake. While the 43 | former are supported and detected by CMake out-of-the-box, Go support has been 44 | added manually for HermitCore. 45 | 46 | Adding a new language requires you to provide CMake hints where to find the 47 | toolchain and then how to compile and link binaries. The Go support in 48 | `cmake/golang` may serve as an example on how to add a new language. 49 | 50 | To finally enable the language it has to be added to CMake's module path in 51 | `cmake/HermitCore.cmake`: 52 | 53 | ``` 54 | # scripts to detect HermitCore Go compiler 55 | list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/golang/) 56 | 57 | # scripts to detect new language 58 | list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/new-language/) 59 | ``` 60 | 61 | 62 | ## User applications 63 | 64 | You just have to include `HermitCore-Application.cmake` before the `project()` 65 | command in your `CMakeLists.txt` in order to build applications for HermitCore. 66 | For configuration parameters of the project, please consult the `README.md` in 67 | the root of this repository. 68 | -------------------------------------------------------------------------------- /cmake/golang/CMakeDetermineGoCompiler.cmake: -------------------------------------------------------------------------------- 1 | # Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2 | # file Copyright.txt or https://cmake.org/licensing for details. 3 | 4 | # determine the compiler to use for Go programs 5 | # NOTE, a generator may set CMAKE_Go_COMPILER before 6 | # loading this file to force a compiler. 7 | 8 | if(NOT CMAKE_Go_COMPILER) 9 | # prefer the environment variable CC 10 | if(NOT $ENV{GO_COMPILER} STREQUAL "") 11 | get_filename_component(CMAKE_Go_COMPILER_INIT $ENV{GO_COMPILER} PROGRAM PROGRAM_ARGS CMAKE_Go_FLAGS_ENV_INIT) 12 | if(CMAKE_Go_FLAGS_ENV_INIT) 13 | set(CMAKE_Go_COMPILER_ARG1 "${CMAKE_Go_FLAGS_ENV_INIT}" CACHE STRING "First argument to Go compiler") 14 | endif() 15 | if(NOT EXISTS ${CMAKE_Go_COMPILER_INIT}) 16 | message(SEND_ERROR "Could not find compiler set in environment variable GO_COMPILER:\n$ENV{GO_COMPILER}.") 17 | endif() 18 | endif() 19 | 20 | set(Go_BIN_PATH 21 | $ENV{GOPATH} 22 | $ENV{GOROOT} 23 | $ENV{GOROOT}/../bin 24 | $ENV{GO_COMPILER} 25 | /usr/bin 26 | /usr/local/bin 27 | ) 28 | # if no compiler has been specified yet, then look for one 29 | if(CMAKE_Go_COMPILER_INIT) 30 | set(CMAKE_Go_COMPILER ${CMAKE_Go_COMPILER_INIT} CACHE PATH "Go Compiler") 31 | else() 32 | find_program(CMAKE_Go_COMPILER 33 | NAMES go 34 | PATHS ${Go_BIN_PATH} 35 | ) 36 | endif() 37 | else() 38 | _cmake_find_compiler_path(Go) 39 | endif() 40 | mark_as_advanced(CMAKE_Go_COMPILER) 41 | 42 | # configure variables set in this file for fast reload later on 43 | configure_file(${CMAKE_CURRENT_LIST_DIR}/CMakeGoCompiler.cmake.in 44 | ${CMAKE_PLATFORM_INFO_DIR}/CMakeGoCompiler.cmake @ONLY) 45 | set(CMAKE_Go_COMPILER_ENV_VAR "GO_COMPILER") 46 | -------------------------------------------------------------------------------- /cmake/golang/CMakeGoCompiler.cmake.in: -------------------------------------------------------------------------------- 1 | # Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2 | # file Copyright.txt or https://cmake.org/licensing for details. 3 | 4 | set(CMAKE_Go_COMPILER "@CMAKE_Go_COMPILER@") 5 | set(CMAKE_Go_COMPILER_ARG1 "@CMAKE_Go_COMPILER_ARG1@") 6 | set(CMAKE_Go_COMPILER_LOADED 1) 7 | 8 | set(CMAKE_Go_SOURCE_FILE_EXTENSIONS go) 9 | set(CMAKE_Go_LINKER_PREFERENCE 40) 10 | set(CMAKE_Go_OUTPUT_EXTENSION .6) 11 | set(CMAKE_Go_OUTPUT_EXTENSION_REPLACE 1) 12 | set(CMAKE_Go_COMPILER_ENV_VAR "GO_COMPILER") 13 | -------------------------------------------------------------------------------- /cmake/golang/CMakeGoInformation.cmake: -------------------------------------------------------------------------------- 1 | # Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2 | # file Copyright.txt or https://cmake.org/licensing for details. 3 | 4 | # This should be included before the _INIT variables are 5 | # used to initialize the cache. Since the rule variables 6 | # have if blocks on them, users can still define them here. 7 | # But, it should still be after the platform file so changes can 8 | # be made to those values. 9 | 10 | if(CMAKE_USER_MAKE_RULES_OVERRIDE) 11 | # Save the full path of the file so try_compile can use it. 12 | include(${CMAKE_USER_MAKE_RULES_OVERRIDE} RESULT_VARIABLE _override) 13 | set(CMAKE_USER_MAKE_RULES_OVERRIDE "${_override}") 14 | endif() 15 | 16 | if(CMAKE_USER_MAKE_RULES_OVERRIDE_Go) 17 | # Save the full path of the file so try_compile can use it. 18 | include(${CMAKE_USER_MAKE_RULES_OVERRIDE_Go} RESULT_VARIABLE _override) 19 | set(CMAKE_USER_MAKE_RULES_OVERRIDE_Go "${_override}") 20 | endif() 21 | 22 | # refer: /usr/share/cmake-3.7/Modules/CMakeCInformation.cmake 23 | 24 | if(NOT CMAKE_Go_COMPILE_OBJECT) 25 | set(CMAKE_Go_COMPILE_OBJECT " -o -c ") 26 | endif() 27 | 28 | if(NOT CMAKE_Go_LINK_EXECUTABLE) 29 | set(CMAKE_Go_LINK_EXECUTABLE " -pthread -o ") 30 | endif() 31 | -------------------------------------------------------------------------------- /cmake/golang/CMakeTestGoCompiler.cmake: -------------------------------------------------------------------------------- 1 | # Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2 | # file Copyright.txt or https://cmake.org/licensing for details. 3 | 4 | set(CMAKE_Go_COMPILER_WORKS 1 CACHE INTERNAL "") 5 | -------------------------------------------------------------------------------- /cmake/local-cmake.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # which version to fetch 4 | MAJOR="3.7" 5 | MINOR="2" 6 | PLATFORM="Linux-x86_64" 7 | 8 | # assemble url for desired version 9 | URL="https://cmake.org/files/v${MAJOR}/cmake-${MAJOR}.${MINOR}-${PLATFORM}.tar.gz" 10 | 11 | ARCHIVE="$(basename ${URL})" 12 | DIR="$(basename ${ARCHIVE} .tar.gz)" 13 | 14 | 15 | relpath() { 16 | # workaround because Ubuntu seems to use an ancient realpath version 17 | # https://stackoverflow.com/questions/2564634/convert-absolute-path-into-relative-path-given-a-current-directory-using-bash#comment12808306_7305217 18 | python -c "import os.path; print(os.path.relpath('${2:-$PWD}','$1'))"; 19 | } 20 | 21 | HERMIT_TOP="$(git rev-parse --show-toplevel)" 22 | HERMIT_CMAKE="${HERMIT_TOP}/cmake" 23 | CMAKE_DIR="${HERMIT_CMAKE}/${DIR}" 24 | CMAKE_DIR_REL="$(relpath ${HERMIT_TOP} ${CMAKE_DIR})" 25 | 26 | # make sure we're sourced, not executed 27 | if [ "$0" = "$BASH_SOURCE" ] 28 | then 29 | echo "You have to source this script:" 30 | echo "\$ . $0" 31 | exit 32 | fi 33 | 34 | # quit if already in path 35 | echo "$PATH" | grep "${CMAKE_DIR_REL}" &>/dev/null && return 36 | 37 | # check if already installed 38 | if which cmake &> /dev/null ; then 39 | if cmake --version | grep "cmake version ${MAJOR}.${MINOR}" &> /dev/null; then 40 | echo "You already have CMake ${MAJOR}.${MINOR}" 41 | return 42 | fi 43 | fi 44 | 45 | if [ ! -d "${CMAKE_DIR}" ] 46 | then 47 | echo "-- Downloading CMake" 48 | wget "${URL}" -O "${ARCHIVE}" || 49 | (echo "Cannot download CMake"; return) 50 | 51 | echo "-- Unpacking CMake" 52 | tar -C "${HERMIT_CMAKE}" -xf "${ARCHIVE}" || 53 | (echo "Cannot unpack CMake archive"; return) 54 | 55 | # delete temporary archive again 56 | rm -f "${ARCHIVE}" 57 | 58 | # add cmake dir to gitignore 59 | GITIGNORE="${HERMIT_TOP}/.gitignore" 60 | if ! grep "${CMAKE_DIR_REL}" "${GITIGNORE}" &>/dev/null 61 | then 62 | echo "${CMAKE_DIR_REL}/*" >> "${GITIGNORE}" 63 | fi 64 | 65 | echo "-- Local CMake v${MAJOR}.${MINOR} installed to ${CMAKE_DIR_REL}" 66 | echo "-- Next time you source this script, no download will be neccessary" 67 | fi 68 | 69 | export PATH="${CMAKE_DIR}/bin:${PATH}" 70 | -------------------------------------------------------------------------------- /img/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hermit-os/hermit-playground/b9ce9ae534972b014ad04d32349656c6c47b642b/img/demo.gif -------------------------------------------------------------------------------- /img/hermitcore_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hermit-os/hermit-playground/b9ce9ae534972b014ad04d32349656c6c47b642b/img/hermitcore_logo.png -------------------------------------------------------------------------------- /img/hermitcore_logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /include/hermit/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.7) 2 | 3 | configure_file(config.asm.in config.asm) 4 | configure_file(config.h.in config.h) 5 | 6 | # Show include files in IDE 7 | file(GLOB_RECURSE HERMIT_INCLUDES "*") 8 | add_custom_target(hermit_includes_ide SOURCES ${HERMIT_INCLUDES}) 9 | -------------------------------------------------------------------------------- /include/hermit/aarch64/arch_io.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, Stefan Lankes, RWTH Aachen University 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the University nor the names of its contributors 13 | * may be used to endorse or promote products derived from this 14 | * software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @author Stefan Lankes 30 | * @brief Functions related to processor IO 31 | * 32 | * This file contains inline functions for processor IO operations. 33 | */ 34 | 35 | #ifndef __ARCH_IO_H__ 36 | #define __ARCH_IO_H__ 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | /** @brief Read a byte from an IO port 43 | * 44 | * @param _port The port you want to read from 45 | * @return The value which reads out from this port 46 | */ 47 | inline static unsigned char inportb(unsigned short _port) { 48 | return *((unsigned char*)(size_t)_port); 49 | } 50 | 51 | /** @brief Read a word (2 byte) from an IO port 52 | * 53 | * @param _port The port you want to read from 54 | * @return The value which reads out from this port 55 | */ 56 | inline static unsigned short inportw(unsigned short _port) { 57 | return *((unsigned short*)(size_t)_port); 58 | } 59 | 60 | /** @brief Read a double word (4 byte) from an IO port 61 | * 62 | * @param _port The port you want to read from 63 | * @return The value which reads out from this port 64 | */ 65 | inline static unsigned int inportl(unsigned short _port) { 66 | return *((unsigned int*)(size_t)_port); 67 | } 68 | 69 | /** @brief Write a byte to an IO port 70 | * 71 | * @param _port The port you want to write to 72 | * @param _data the 1 byte value you want to write 73 | */ 74 | inline static void outportb(unsigned short _port, unsigned char _data) { 75 | *((unsigned char*)(size_t)_port) = _data; 76 | } 77 | 78 | /** @brief Write a word (2 bytes) to an IO port 79 | * 80 | * @param _port The port you want to write to 81 | * @param _data the 2 byte value you want to write 82 | */ 83 | inline static void outportw(unsigned short _port, unsigned short _data) { 84 | *((unsigned short*)(size_t)_port) = _data; 85 | } 86 | 87 | /** @brief Write a double word (4 bytes) to an IO port 88 | * 89 | * @param _port The port you want to write to 90 | * @param _data the 4 byte value you want to write 91 | */ 92 | inline static void outportl(unsigned short _port, unsigned int _data) 93 | { 94 | *((unsigned int*)(size_t)_port) = _data; 95 | } 96 | 97 | #ifdef __cplusplus 98 | } 99 | #endif 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /include/hermit/aarch64/arch_limits.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, Stefan Lankes, RWTH Aachen University 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the University nor the names of its contributors 13 | * may be used to endorse or promote products derived from this 14 | * software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * author Stefan Lankes 30 | * @file arch/x86/include/asm/limits.h 31 | * @brief Define constants related to numerical value-ranges of variable types 32 | * 33 | * This file contains define constants for the numerical 34 | * ranges of the most typical variable types. 35 | */ 36 | 37 | #ifndef __ARCH_LIMITS_H__ 38 | #define __ARCH_LIMITS_H__ 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | /** Number of bits in a char */ 45 | #define CHAR_BIT 8 46 | 47 | /** Maximum value for a signed char */ 48 | #define SCHAR_MAX 0x7f 49 | /** Minimum value for a signed char */ 50 | #define SCHAR_MIN (-0x7f - 1) 51 | 52 | /** Maximum value for an unsigned char */ 53 | #define UCHAR_MAX 0xff 54 | 55 | /** Maximum value for an unsigned short */ 56 | #define USHRT_MAX 0xffff 57 | /** Maximum value for a short */ 58 | #define SHRT_MAX 0x7fff 59 | /** Minimum value for a short */ 60 | #define SHRT_MIN (-0x7fff - 1) 61 | 62 | /** Maximum value for an unsigned int */ 63 | #define UINT_MAX 0xffffffffU 64 | /** Maximum value for an int */ 65 | #define INT_MAX 0x7fffffff 66 | /** Minimum value for an int */ 67 | #define INT_MIN (-0x7fffffff - 1) 68 | 69 | /** Maximum value for an unsigned long */ 70 | #define ULONG_MAX 0xffffffffUL 71 | /** Maximum value for a long */ 72 | #define LONG_MAX 0x7fffffffL 73 | /** Minimum value for a long */ 74 | #define LONG_MIN (-0x7fffffffL - 1) 75 | 76 | /** Maximum value for an unsigned long long */ 77 | #define ULLONG_MAX 0xffffffffffffffffULL 78 | /** Maximum value for a long long */ 79 | #define LLONG_MAX 0x7fffffffffffffffLL 80 | /** Minimum value for a long long */ 81 | #define LLONG_MIN (-0x7fffffffffffffffLL - 1) 82 | 83 | #ifdef __cplusplus 84 | } 85 | #endif 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /include/hermit/aarch64/arch_stddef.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, Stefan Lankes, RWTH Aachen University 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the University nor the names of its contributors 13 | * may be used to endorse or promote products derived from this 14 | * software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @author Stefan Lankes 30 | * @file arch/x86/include/asm/stddef.h 31 | * @brief Standard datatypes 32 | * 33 | * This file contains typedefs for standard datatypes for numerical and character values. 34 | */ 35 | 36 | #ifndef __ARCH_STDDEF_H__ 37 | #define __ARCH_STDDEF_H__ 38 | 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | 43 | // A popular type for addresses 44 | typedef unsigned long long size_t; 45 | /// Pointer differences 46 | typedef long long ptrdiff_t; 47 | #ifdef __KERNEL__ 48 | typedef long long ssize_t; 49 | typedef long long off_t; 50 | #endif 51 | 52 | /// Unsigned 64 bit integer 53 | typedef unsigned long uint64_t; 54 | /// Signed 64 bit integer 55 | typedef long int64_t; 56 | /// Unsigned 32 bit integer 57 | typedef unsigned int uint32_t; 58 | /// Signed 32 bit integer 59 | typedef int int32_t; 60 | /// Unsigned 16 bit integer 61 | typedef unsigned short uint16_t; 62 | /// Signed 16 bit integer 63 | typedef short int16_t; 64 | /// Unsigned 8 bit integer (/char) 65 | typedef unsigned char uint8_t; 66 | /// Signed 8 bit integer (/char) 67 | typedef char int8_t; 68 | /// 16 bit wide char type 69 | typedef unsigned short wchar_t; 70 | 71 | #ifndef _WINT_T 72 | #define _WINT_T 73 | typedef wchar_t wint_t; 74 | #endif 75 | 76 | /// This defines registers, which are saved for a "user-level" context swicth 77 | typedef struct mregs { 78 | /// TODO 79 | uint64_t dummy; 80 | } mregs_t; 81 | 82 | typedef struct { 83 | void *ss_sp; /* Stack base or pointer. */ 84 | } stack_t; 85 | 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /include/hermit/config.asm.in: -------------------------------------------------------------------------------- 1 | %define KERNEL_STACK_SIZE @KERNEL_STACK_SIZE@ 2 | -------------------------------------------------------------------------------- /include/hermit/config.h.in: -------------------------------------------------------------------------------- 1 | #define KERNEL_STACK_SIZE @KERNEL_STACK_SIZE@ 2 | -------------------------------------------------------------------------------- /include/hermit/ctype.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************** 2 | * 3 | * Author: Stefan Lankes 4 | * Chair for Operating Systems, RWTH Aachen University 5 | * Date: 24/03/2011 6 | * 7 | **************************************************************************************** 8 | * 9 | * Written by the Chair for Operating Systems, RWTH Aachen University 10 | * 11 | * NO Copyright (C) 2010, Stefan Lankes, 12 | * consider these trivial functions to be public domain. 13 | * 14 | * These functions are distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | */ 17 | 18 | /** 19 | * @author Stefan Lankes 20 | * @file include/hermit/ctype.h 21 | * @brief Functions related to alphanumerical character values 22 | * 23 | * This file contains functions helping to determine 24 | * the type of alphanumerical character values. 25 | */ 26 | 27 | #ifndef __CTYPE_H_ 28 | #define __CYTPE_H_ 29 | 30 | /** Returns true if the value of 'c' is an ASCII-charater */ 31 | static inline int isascii(int c) 32 | { 33 | return (((unsigned char)(c))<=0x7f); 34 | } 35 | 36 | /** Applies an and-operation to 37 | * push the value of 'c' into the ASCII-range */ 38 | static inline int toascii(int c) 39 | { 40 | return (((unsigned char)(c))&0x7f); 41 | } 42 | 43 | /** Returns true if the value of 'c' is the 44 | * space character or a control character */ 45 | static inline int isspace(int c) 46 | { 47 | if (!isascii(c)) 48 | return 0; 49 | 50 | if (' ' == (unsigned char) c) 51 | return 1; 52 | if ('\n' == (unsigned char) c) 53 | return 1; 54 | if ('\r' == (unsigned char) c) 55 | return 1; 56 | if ('\t' == (unsigned char) c) 57 | return 1; 58 | if ('\v' == (unsigned char) c) 59 | return 1; 60 | if ('\f' == (unsigned char) c) 61 | return 1; 62 | 63 | return 0; 64 | } 65 | 66 | /** Returns true if the value of 'c' is a number */ 67 | static inline int isdigit(int c) 68 | { 69 | if (!isascii(c)) 70 | return 0; 71 | 72 | if (((unsigned char) c >= '0') && ((unsigned char) c <= '9')) 73 | return 1; 74 | 75 | return 0; 76 | } 77 | 78 | /** Returns true if the value of 'c' is a lower case letter */ 79 | static inline int islower(int c) 80 | { 81 | if (!isascii(c)) 82 | return 0; 83 | 84 | if (((unsigned char) c >= 'a') && ((unsigned char) c <= 'z')) 85 | return 1; 86 | 87 | return 0; 88 | } 89 | 90 | /** Returns true if the value of 'c' is an upper case letter */ 91 | static inline int isupper(int c) 92 | { 93 | if (!isascii(c)) 94 | return 0; 95 | 96 | if (((unsigned char) c >= 'A') && ((unsigned char) c <= 'Z')) 97 | return 1; 98 | 99 | return 0; 100 | } 101 | 102 | /** Returns true if the value of 'c' is an alphabetic character */ 103 | static inline int isalpha(int c) 104 | { 105 | if (isupper(c) || islower(c)) 106 | return 1; 107 | 108 | return 0; 109 | } 110 | 111 | /** Makes the input character lower case.\n Will do nothing if it 112 | * was something different than an upper case letter before. */ 113 | static inline unsigned char tolower(unsigned char c) 114 | { 115 | if (isupper(c)) 116 | c -= 'A'-'a'; 117 | return c; 118 | } 119 | 120 | /** Makes the input character upper case.\n Will do nothing if it 121 | * was something different than a lower case letter before. */ 122 | static inline unsigned char toupper(unsigned char c) 123 | { 124 | if (islower(c)) 125 | c -= 'a'-'A'; 126 | return c; 127 | } 128 | 129 | #endif 130 | -------------------------------------------------------------------------------- /include/hermit/errno.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Stefan Lankes 3 | * @file include/hermit/errno.h 4 | * @brief Error number define constants 5 | * 6 | * This file just contains the full list of error numbers which can 7 | * be returned somewhere. 8 | */ 9 | 10 | #ifndef __ERRNO_H__ 11 | #define __ERRNO_H__ 12 | 13 | #define EPERM 1 /* Operation not permitted */ 14 | #define ENOENT 2 /* No such file or directory */ 15 | #define ESRCH 3 /* No such process */ 16 | #define EINTR 4 /* Interrupted system call */ 17 | #define EIO 5 /* I/O error */ 18 | #define ENXIO 6 /* No such device or address */ 19 | #define E2BIG 7 /* Argument list too long */ 20 | #define ENOEXEC 8 /* Exec format error */ 21 | #define EBADF 9 /* Bad file number */ 22 | #define ECHILD 10 /* No child processes */ 23 | #define EAGAIN 11 /* Try again */ 24 | #define ENOMEM 12 /* Out of memory */ 25 | #define EACCES 13 /* Permission denied */ 26 | #define EFAULT 14 /* Bad address */ 27 | #define ENOTBLK 15 /* Block device required */ 28 | #define EBUSY 16 /* Device or resource busy */ 29 | #define EEXIST 17 /* File exists */ 30 | #define EXDEV 18 /* Cross-device link */ 31 | #define ENODEV 19 /* No such device */ 32 | #define ENOTDIR 20 /* Not a directory */ 33 | #define EISDIR 21 /* Is a directory */ 34 | #define EINVAL 22 /* Invalid argument */ 35 | #define ENFILE 23 /* File table overflow */ 36 | #define EMFILE 24 /* Too many open files */ 37 | #define ENOTTY 25 /* Not a typewriter */ 38 | #define ETXTBSY 26 /* Text file busy */ 39 | #define EFBIG 27 /* File too large */ 40 | #define ENOSPC 28 /* No space left on device */ 41 | #define ESPIPE 29 /* Illegal seek */ 42 | #define EROFS 30 /* Read-only file system */ 43 | #define EMLINK 31 /* Too many links */ 44 | #define EPIPE 32 /* Broken pipe */ 45 | #define EDOM 33 /* Math argument out of domain of func */ 46 | #define ERANGE 34 /* Math result not representable */ 47 | 48 | #define EDEADLK 35 /* Resource deadlock would occur */ 49 | #define ENAMETOOLONG 36 /* File name too long */ 50 | #define ENOLCK 37 /* No record locks available */ 51 | #define ENOSYS 38 /* Function not implemented */ 52 | #define ENOTEMPTY 39 /* Directory not empty */ 53 | #define ELOOP 40 /* Too many symbolic links encountered */ 54 | #define EWOULDBLOCK EAGAIN /* Operation would block */ 55 | #define ENOMSG 42 /* No message of desired type */ 56 | #define EIDRM 43 /* Identifier removed */ 57 | #define ECHRNG 44 /* Channel number out of range */ 58 | #define EL2NSYNC 45 /* Level 2 not synchronized */ 59 | #define EL3HLT 46 /* Level 3 halted */ 60 | #define EL3RST 47 /* Level 3 reset */ 61 | #define ELNRNG 48 /* Link number out of range */ 62 | #define EUNATCH 49 /* Protocol driver not attached */ 63 | #define ENOCSI 50 /* No CSI structure available */ 64 | #define EL2HLT 51 /* Level 2 halted */ 65 | #define EBADE 52 /* Invalid exchange */ 66 | #define EBADR 53 /* Invalid request descriptor */ 67 | #define EXFULL 54 /* Exchange full */ 68 | #define ENOANO 55 /* No anode */ 69 | #define EBADRQC 56 /* Invalid request code */ 70 | #define EBADSLT 57 /* Invalid slot */ 71 | 72 | #define EDEADLOCK EDEADLK 73 | 74 | #define EBFONT 59 /* Bad font file format */ 75 | #define ENOSTR 60 /* Device not a stream */ 76 | #define ENODATA 61 /* No data available */ 77 | #define ETIME 62 /* Timer expired */ 78 | #define ENOSR 63 /* Out of streams resources */ 79 | #define ENONET 64 /* Machine is not on the network */ 80 | #define ENOPKG 65 /* Package not installed */ 81 | #define EREMOTE 66 /* Object is remote */ 82 | #define ENOLINK 67 /* Link has been severed */ 83 | #define EADV 68 /* Advertise error */ 84 | #define ESRMNT 69 /* Srmount error */ 85 | #define ECOMM 70 /* Communication error on send */ 86 | #define EPROTO 71 /* Protocol error */ 87 | #define EMULTIHOP 72 /* Multihop attempted */ 88 | #define EDOTDOT 73 /* RFS specific error */ 89 | #define EBADMSG 74 /* Not a data message */ 90 | #define EOVERFLOW 75 /* Value too large for defined data type */ 91 | #define ENOTUNIQ 76 /* Name not unique on network */ 92 | #define EBADFD 77 /* File descriptor in bad state */ 93 | #define EREMCHG 78 /* Remote address changed */ 94 | #define ELIBACC 79 /* Can not access a needed shared library */ 95 | #define ELIBBAD 80 /* Accessing a corrupted shared library */ 96 | #define ELIBSCN 81 /* .lib section in a.out corrupted */ 97 | #define ELIBMAX 82 /* Attempting to link in too many shared libraries */ 98 | #define ELIBEXEC 83 /* Cannot exec a shared library directly */ 99 | #define EILSEQ 84 /* Illegal byte sequence */ 100 | #define ERESTART 85 /* Interrupted system call should be restarted */ 101 | #define ESTRPIPE 86 /* Streams pipe error */ 102 | #define EUSERS 87 /* Too many users */ 103 | #define ENOTSOCK 88 /* Socket operation on non-socket */ 104 | #define EDESTADDRREQ 89 /* Destination address required */ 105 | #define EMSGSIZE 90 /* Message too long */ 106 | #define EPROTOTYPE 91 /* Protocol wrong type for socket */ 107 | #define ENOPROTOOPT 92 /* Protocol not available */ 108 | #define EPROTONOSUPPORT 93 /* Protocol not supported */ 109 | #define ESOCKTNOSUPPORT 94 /* Socket type not supported */ 110 | #define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ 111 | #define EPFNOSUPPORT 96 /* Protocol family not supported */ 112 | #define EAFNOSUPPORT 97 /* Address family not supported by protocol */ 113 | #define EADDRINUSE 98 /* Address already in use */ 114 | #define EADDRNOTAVAIL 99 /* Cannot assign requested address */ 115 | #define ENETDOWN 100 /* Network is down */ 116 | #define ENETUNREACH 101 /* Network is unreachable */ 117 | #define ENETRESET 102 /* Network dropped connection because of reset */ 118 | #define ECONNABORTED 103 /* Software caused connection abort */ 119 | #define ECONNRESET 104 /* Connection reset by peer */ 120 | #define ENOBUFS 105 /* No buffer space available */ 121 | #define EISCONN 106 /* Transport endpoint is already connected */ 122 | #define ENOTCONN 107 /* Transport endpoint is not connected */ 123 | #define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ 124 | #define ETOOMANYREFS 109 /* Too many references: cannot splice */ 125 | #define ETIMEDOUT 110 /* Connection timed out */ 126 | #define ECONNREFUSED 111 /* Connection refused */ 127 | #define EHOSTDOWN 112 /* Host is down */ 128 | #define EHOSTUNREACH 113 /* No route to host */ 129 | #define EALREADY 114 /* Operation already in progress */ 130 | #define EINPROGRESS 115 /* Operation now in progress */ 131 | #define ESTALE 116 /* Stale file handle */ 132 | #define EUCLEAN 117 /* Structure needs cleaning */ 133 | #define ENOTNAM 118 /* Not a XENIX named type file */ 134 | #define ENAVAIL 119 /* No XENIX semaphores available */ 135 | #define EISNAM 120 /* Is a named type file */ 136 | #define EREMOTEIO 121 /* Remote I/O error */ 137 | #define EDQUOT 122 /* Quota exceeded */ 138 | 139 | #define ENOMEDIUM 123 /* No medium found */ 140 | #define EMEDIUMTYPE 124 /* Wrong medium type */ 141 | #define ECANCELED 125 /* Operation Canceled */ 142 | #define ENOKEY 126 /* Required key not available */ 143 | #define EKEYEXPIRED 127 /* Key has expired */ 144 | #define EKEYREVOKED 128 /* Key has been revoked */ 145 | #define EKEYREJECTED 129 /* Key was rejected by service */ 146 | 147 | /* for robust mutexes */ 148 | #define EOWNERDEAD 130 /* Owner died */ 149 | #define ENOTRECOVERABLE 131 /* State not recoverable */ 150 | 151 | #define ERFKILL 132 /* Operation not possible due to RF-kill */ 152 | 153 | #define EHWPOISON 133 /* Memory page has hardware error */ 154 | 155 | #endif 156 | -------------------------------------------------------------------------------- /include/hermit/stdarg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, Stefan Lankes, RWTH Aachen University 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the University nor the names of its contributors 13 | * may be used to endorse or promote products derived from this 14 | * software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef __STDARG_H__ 29 | #define __STDARG_H__ 30 | 31 | /** 32 | * @author Stefan Lankes 33 | * @file include/hermit/stdarg.h 34 | * @brief Definition of variable argument lists 35 | */ 36 | 37 | #ifdef __cplusplus 38 | extern "C" { 39 | #endif 40 | 41 | typedef __builtin_va_list va_list; 42 | 43 | /// Initialize a variable argument list 44 | #define va_start __builtin_va_start 45 | /// Retrieve next argument 46 | #define va_arg __builtin_va_arg 47 | /// End using variable argument list 48 | #define va_end __builtin_va_end 49 | /// copies the (previously initialized) variable argument list 50 | #define va_copy __builtin_va_copy 51 | 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /include/hermit/stddef.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, Stefan Lankes, RWTH Aachen University 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the University nor the names of its contributors 13 | * may be used to endorse or promote products derived from this 14 | * software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef __STDDEF_H__ 29 | #define __STDDEF_H__ 30 | 31 | /** 32 | * @author Stefan Lankes 33 | * @file include/hermit/stddef.h 34 | * @brief Definition of basic data types 35 | */ 36 | 37 | #include 38 | 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | 43 | #define CACHE_LINE 64 44 | #define MAILBOX_SIZE 128 45 | 46 | #define BYTE_ORDER LITTLE_ENDIAN 47 | 48 | #define UHYVE_PORT_WRITE 0x499 49 | #define UHYVE_PORT_OPEN 0x500 50 | #define UHYVE_PORT_CLOSE 0x501 51 | #define UHYVE_PORT_READ 0x502 52 | #define UHYVE_PORT_EXIT 0x503 53 | #define UHYVE_PORT_LSEEK 0x504 54 | 55 | #define BUILTIN_EXPECT(exp, b) __builtin_expect((exp), (b)) 56 | //#define BUILTIN_EXPECT(exp, b) (exp) 57 | #define NORETURN __attribute__((noreturn)) 58 | 59 | #define NULL ((void*) 0) 60 | 61 | /// represents a task identifier 62 | typedef unsigned int tid_t; 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /include/hermit/stdio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, Stefan Lankes, RWTH Aachen University 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the University nor the names of its contributors 13 | * may be used to endorse or promote products derived from this 14 | * software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @author Stefan Lankes 30 | * @file include/hermit/stdio.h 31 | * @brief Stringstream related functions. Mainly printf-stuff. 32 | */ 33 | 34 | #ifndef __STDIO_H__ 35 | #define __STDIO_H__ 36 | 37 | #include 38 | #include 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | /** 45 | * Works like the ANSI C function puts 46 | */ 47 | int kputs(const char *); 48 | 49 | /** 50 | * Works like the ANSI C function putchar 51 | */ 52 | int kputchar(int); 53 | 54 | /** 55 | * Works like the ANSI C function printf 56 | */ 57 | int kprintf(const char*, ...); 58 | 59 | /** 60 | * Initialize the I/O functions 61 | */ 62 | int koutput_init(void); 63 | 64 | /** 65 | * Works like the ANSI c function sprintf 66 | */ 67 | int ksprintf(char *str, const char *format, ...); 68 | 69 | /** 70 | * Works like the ANSI c function sprintf 71 | */ 72 | int ksnprintf(char *str, size_t size, const char *format, ...); 73 | 74 | /** 75 | * Scaled down version of printf(3) 76 | */ 77 | int kvprintf(char const *fmt, void (*func) (int, void *), void *arg, int radix, va_list ap); 78 | 79 | #ifdef __cplusplus 80 | } 81 | #endif 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /include/hermit/stdlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, Stefan Lankes, RWTH Aachen University 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the University nor the names of its contributors 13 | * may be used to endorse or promote products derived from this 14 | * software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @author Stefan Lankes 30 | * @file include/hermit/stdlib.h 31 | * @brief Kernel space malloc and free functions and conversion functions 32 | * 33 | * This file contains some memory alloc and free calls for the kernel 34 | * and conversion functions. 35 | */ 36 | 37 | #ifndef __STDLIB_H__ 38 | #define __STDLIB_H__ 39 | 40 | #include 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | /** @brief String to long 47 | * 48 | * @return Long value of the parsed numerical string 49 | */ 50 | long _strtol(const char* str, char** endptr, int base); 51 | 52 | #define strtol(str, endptr, base) _strtol((str), (endptr), (base)) 53 | 54 | /** @brief String to unsigned long 55 | * 56 | * @return Unsigned long value of the parsed numerical string 57 | */ 58 | unsigned long _strtoul(const char* nptr, char** endptr, int base); 59 | 60 | #define strtoul(nptr, endptr, base) _strtoul((nptr), (endptr), (base)) 61 | 62 | /** @brief ASCII to integer 63 | * 64 | * Convenience function using strtol(). 65 | * 66 | * @return Integer value of the parsed numerical string 67 | */ 68 | static inline int atoi(const char *str) 69 | { 70 | return (int)_strtol(str, (char **)NULL, 10); 71 | } 72 | 73 | /** @brief Checks whether c is a hexdecimal digit character. 74 | * 75 | * @return A value different from zero if indeed c is a hexadecimal digit. 76 | * Zero otherwise. 77 | */ 78 | static inline int isxdigit(int c) 79 | { 80 | if ((c >= '0') && (c <= '9')) 81 | return 1; 82 | else if ((c >= 'A') && (c <= 'F')) 83 | return 1; 84 | else if ((c >= 'a') && (c <= 'f')) 85 | return 1; 86 | 87 | return 0; 88 | } 89 | 90 | #ifdef __cplusplus 91 | } 92 | #endif 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /include/hermit/string.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, Stefan Lankes, RWTH Aachen University 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the University nor the names of its contributors 13 | * may be used to endorse or promote products derived from this 14 | * software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef __STRING_H__ 29 | #define __STRING_H__ 30 | 31 | /** 32 | * @author Stefan Lankes 33 | * @file include/hermit/string.h 34 | * @brief Definition of basic string and memory opeations 35 | */ 36 | 37 | #include 38 | 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | 43 | #if !HAVE_ARCH_MEMCPY 44 | void *_memcpy(void *dest, const void *src, size_t count); 45 | 46 | #define memcpy(dest, src, count) _memcpy((dest), (src), (count)) 47 | #endif 48 | 49 | #if !HAVE_ARCH_MEMSET 50 | void *_memset(void *dest, int val, size_t count); 51 | 52 | #define memset(dest, val, count) _memset((dest), (val), (count)) 53 | #endif 54 | 55 | #if !HAVE_ARCH_MEMCMP 56 | int _memcmp(const void *s1, const void *s2, size_t n); 57 | 58 | #define memcmp(s1, s2, n) _memcmp((s1), (s2), (n)) 59 | #endif 60 | 61 | #if !HAVE_ARCH_STRLEN 62 | size_t _strlen(const char *str); 63 | 64 | #define strlen(str) _strlen((str)) 65 | #endif 66 | 67 | #if !HAVE_ARCH_STRNCPY 68 | char *_strncpy(char *dest, const char *src, size_t n); 69 | 70 | #define strncpy(dest, src, n) _strncpy((dest), (src), (n)) 71 | #endif 72 | 73 | #if !HAVE_ARCH_STRCPY 74 | char *_strcpy(char *dest, const char *src); 75 | 76 | #define strcpy(dest, src) _strcpy((dest), (src)) 77 | #endif 78 | 79 | #if !HAVE_ARCH_STRCMP 80 | int _strcmp(const char *s1, const char *s2); 81 | 82 | #define strcmp(s1, s2) _strcmp((s1), (s2)) 83 | #endif 84 | 85 | #if !HAVE_ARCH_STRNCMP 86 | int _strncmp(const char *s1, const char *s2, size_t n); 87 | 88 | #define strncmp(s1, s2, n) _strncmp((s1), (s2), (n)) 89 | #endif 90 | 91 | char *_strstr(const char *s, const char *find); 92 | 93 | #define strstr(s, find) _strstr((s), (find)) 94 | 95 | #ifdef __cplusplus 96 | } 97 | #endif 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /include/hermit/x86_64/arch_io.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, Stefan Lankes, RWTH Aachen University 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the University nor the names of its contributors 13 | * may be used to endorse or promote products derived from this 14 | * software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @author Stefan Lankes 30 | * @brief Functions related to processor IO 31 | * 32 | * This file contains inline functions for processor IO operations. 33 | */ 34 | 35 | #ifndef __ARCH_IO_H__ 36 | #define __ARCH_IO_H__ 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | /** @brief Read a byte from an IO port 43 | * 44 | * @param _port The port you want to read from 45 | * @return The value which reads out from this port 46 | */ 47 | inline static unsigned char inportb(unsigned short _port) { 48 | unsigned char rv; 49 | asm volatile("inb %1, %0":"=a"(rv):"dN"(_port)); 50 | return rv; 51 | } 52 | 53 | /** @brief Read a word (2 byte) from an IO port 54 | * 55 | * @param _port The port you want to read from 56 | * @return The value which reads out from this port 57 | */ 58 | inline static unsigned short inportw(unsigned short _port) { 59 | unsigned short rv; 60 | asm volatile("inw %1, %0":"=a"(rv):"dN"(_port)); 61 | return rv; 62 | } 63 | 64 | /** @brief Read a double word (4 byte) from an IO port 65 | * 66 | * @param _port The port you want to read from 67 | * @return The value which reads out from this port 68 | */ 69 | inline static unsigned int inportl(unsigned short _port) { 70 | unsigned int rv; 71 | asm volatile("inl %1, %0":"=a"(rv):"dN"(_port)); 72 | return rv; 73 | } 74 | 75 | /** @brief Write a byte to an IO port 76 | * 77 | * @param _port The port you want to write to 78 | * @param _data the 1 byte value you want to write 79 | */ 80 | inline static void outportb(unsigned short _port, unsigned char _data) { 81 | asm volatile("outb %1, %0"::"dN"(_port), "a"(_data)); 82 | } 83 | 84 | /** @brief Write a word (2 bytes) to an IO port 85 | * 86 | * @param _port The port you want to write to 87 | * @param _data the 2 byte value you want to write 88 | */ 89 | inline static void outportw(unsigned short _port, unsigned short _data) { 90 | asm volatile("outw %1, %0"::"dN"(_port), "a"(_data)); 91 | } 92 | 93 | /** @brief Write a double word (4 bytes) to an IO port 94 | * 95 | * @param _port The port you want to write to 96 | * @param _data the 4 byte value you want to write 97 | */ 98 | inline static void outportl(unsigned short _port, unsigned int _data) 99 | { 100 | asm volatile("outl %1, %0"::"dN"(_port), "a"(_data)); 101 | } 102 | 103 | #ifdef __cplusplus 104 | } 105 | #endif 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /include/hermit/x86_64/arch_limits.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, Stefan Lankes, RWTH Aachen University 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the University nor the names of its contributors 13 | * may be used to endorse or promote products derived from this 14 | * software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * author Stefan Lankes 30 | * @file arch/x86/include/asm/limits.h 31 | * @brief Define constants related to numerical value-ranges of variable types 32 | * 33 | * This file contains define constants for the numerical 34 | * ranges of the most typical variable types. 35 | */ 36 | 37 | #ifndef __ARCH_LIMITS_H__ 38 | #define __ARCH_LIMITS_H__ 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | /** Number of bits in a char */ 45 | #define CHAR_BIT 8 46 | 47 | /** Maximum value for a signed char */ 48 | #define SCHAR_MAX 0x7f 49 | /** Minimum value for a signed char */ 50 | #define SCHAR_MIN (-0x7f - 1) 51 | 52 | /** Maximum value for an unsigned char */ 53 | #define UCHAR_MAX 0xff 54 | 55 | /** Maximum value for an unsigned short */ 56 | #define USHRT_MAX 0xffff 57 | /** Maximum value for a short */ 58 | #define SHRT_MAX 0x7fff 59 | /** Minimum value for a short */ 60 | #define SHRT_MIN (-0x7fff - 1) 61 | 62 | /** Maximum value for an unsigned int */ 63 | #define UINT_MAX 0xffffffffU 64 | /** Maximum value for an int */ 65 | #define INT_MAX 0x7fffffff 66 | /** Minimum value for an int */ 67 | #define INT_MIN (-0x7fffffff - 1) 68 | 69 | /** Maximum value for an unsigned long */ 70 | #define ULONG_MAX 0xffffffffUL 71 | /** Maximum value for a long */ 72 | #define LONG_MAX 0x7fffffffL 73 | /** Minimum value for a long */ 74 | #define LONG_MIN (-0x7fffffffL - 1) 75 | 76 | /** Maximum value for an unsigned long long */ 77 | #define ULLONG_MAX 0xffffffffffffffffULL 78 | /** Maximum value for a long long */ 79 | #define LLONG_MAX 0x7fffffffffffffffLL 80 | /** Minimum value for a long long */ 81 | #define LLONG_MIN (-0x7fffffffffffffffLL - 1) 82 | 83 | #ifdef __cplusplus 84 | } 85 | #endif 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /include/hermit/x86_64/arch_stddef.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, Stefan Lankes, RWTH Aachen University 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the University nor the names of its contributors 13 | * may be used to endorse or promote products derived from this 14 | * software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @author Stefan Lankes 30 | * @file arch/x86/include/asm/stddef.h 31 | * @brief Standard datatypes 32 | * 33 | * This file contains typedefs for standard datatypes for numerical and character values. 34 | */ 35 | 36 | #ifndef __ARCH_STDDEF_H__ 37 | #define __ARCH_STDDEF_H__ 38 | 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | 43 | // A popular type for addresses 44 | typedef unsigned long long size_t; 45 | /// Pointer differences 46 | typedef long long ptrdiff_t; 47 | #ifdef __KERNEL__ 48 | typedef long long ssize_t; 49 | typedef long long off_t; 50 | #endif 51 | 52 | /// Unsigned 64 bit integer 53 | typedef unsigned long uint64_t; 54 | /// Signed 64 bit integer 55 | typedef long int64_t; 56 | /// Unsigned 32 bit integer 57 | typedef unsigned int uint32_t; 58 | /// Signed 32 bit integer 59 | typedef int int32_t; 60 | /// Unsigned 16 bit integer 61 | typedef unsigned short uint16_t; 62 | /// Signed 16 bit integer 63 | typedef short int16_t; 64 | /// Unsigned 8 bit integer (/char) 65 | typedef unsigned char uint8_t; 66 | /// Signed 8 bit integer (/char) 67 | typedef char int8_t; 68 | /// 16 bit wide char type 69 | typedef unsigned short wchar_t; 70 | 71 | #ifndef _WINT_T 72 | #define _WINT_T 73 | typedef wchar_t wint_t; 74 | #endif 75 | 76 | /// This defines registers, which are saved for a "user-level" context swicth 77 | typedef struct mregs { 78 | /// R15 register 79 | uint64_t r15; 80 | /// R14 register 81 | uint64_t r14; 82 | /// R13 register 83 | uint64_t r13; 84 | /// R12 register 85 | uint64_t r12; 86 | /// R9 register 87 | uint64_t r9; 88 | /// R8 register 89 | uint64_t r8; 90 | /// RDI register 91 | uint64_t rdi; 92 | /// RSI register 93 | uint64_t rsi; 94 | /// RBP register 95 | uint64_t rbp; 96 | /// RBX register 97 | uint64_t rbx; 98 | /// RDX register 99 | uint64_t rdx; 100 | /// RCX register 101 | uint64_t rcx; 102 | /// RSP register 103 | uint64_t rsp; 104 | /// RIP 105 | uint64_t rip; 106 | /// MXCSR 107 | uint32_t mxcsr; 108 | } mregs_t; 109 | 110 | typedef struct { 111 | void *ss_sp; /* Stack base or pointer. */ 112 | int ss_flags; /* Flags. */ 113 | size_t ss_size; /* Stack size. */ 114 | } stack_t; 115 | 116 | #ifdef __cplusplus 117 | } 118 | #endif 119 | 120 | #endif 121 | -------------------------------------------------------------------------------- /include/netinet/in.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Written by the Chair for Operating Systems, RWTH Aachen University 3 | * 4 | * NO Copyright (C) 2010-2011, Stefan Lankes 5 | * consider these trivial macros to be public domain. 6 | * 7 | * These functions are distributed on an "AS IS" BASIS, 8 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | */ 10 | 11 | #ifndef __NETINET_IN_H__ 12 | #define __NETINET_IN_H__ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #ifdef __cplusplus 19 | { 20 | #endif 21 | 22 | typedef uint16_t in_port_t; 23 | 24 | int inet_pton(int af, const char *src, void *dst); 25 | 26 | /** 255.255.255.255 */ 27 | #define IPADDR_NONE ((uint32_t)0xffffffffUL) 28 | /** 127.0.0.1 */ 29 | #define IPADDR_LOOPBACK ((uint32_t)0x7f000001UL) 30 | /** 0.0.0.0 */ 31 | #define IPADDR_ANY ((uint32_t)0x00000000UL) 32 | /** 255.255.255.255 */ 33 | #define IPADDR_BROADCAST ((uint32_t)0xffffffffUL) 34 | 35 | /** 255.255.255.255 */ 36 | #define INADDR_NONE IPADDR_NONE 37 | /** 127.0.0.1 */ 38 | #define INADDR_LOOPBACK IPADDR_LOOPBACK 39 | /** 0.0.0.0 */ 40 | #define INADDR_ANY IPADDR_ANY 41 | /** 255.255.255.255 */ 42 | #define INADDR_BROADCAST IPADDR_BROADCAST 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | 48 | #endif /* __NETINET_IN_H__ */ 49 | -------------------------------------------------------------------------------- /include/netinet/tcp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Written by the Chair for Operating Systems, RWTH Aachen University 3 | * 4 | * NO Copyright (C) 2010-2011, Stefan Lankes 5 | * consider these trivial macros to be public domain. 6 | * 7 | * These functions are distributed on an "AS IS" BASIS, 8 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | */ 10 | 11 | #ifndef __NETINET_TCP_H__ 12 | #define __NETINET_TCP_H__ 13 | 14 | #include 15 | 16 | #endif /* __NETINET_TCP_H__ */ 17 | -------------------------------------------------------------------------------- /include/stdarg.h: -------------------------------------------------------------------------------- 1 | #ifndef __ANSI_STDARG_H__ 2 | #define __ANSI_STDARG_H__ 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #define __VALIST va_list 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /include/stddef.h: -------------------------------------------------------------------------------- 1 | #ifndef __ANSI_STDDEF_H__ 2 | #define __ANSI_STDDEF_H__ 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /include/stdlib.h: -------------------------------------------------------------------------------- 1 | #ifndef __ANSI_STDLIB_H__ 2 | #define __ANSI_STDLIB_H__ 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /include/string.h: -------------------------------------------------------------------------------- 1 | #ifndef __ANSI_STRING_H__ 2 | #define __ANSI_STRING_H__ 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /include/sys/ipc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Stefan Lankes, RWTH Aachen University 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the University nor the names of its contributors 13 | * may be used to endorse or promote products derived from this 14 | * software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef __SYS_IPC_H__ 29 | #define __SYS_IPC_H__ 30 | 31 | #include 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | #ifdef __KERNEL__ 38 | typedef long key_t; 39 | #endif 40 | 41 | #define IPC_PRIVATE ((key_t) 0) 42 | 43 | /* Obsolete, used only for backwards compatibility and libc5 compiles */ 44 | struct ipc_perm 45 | { 46 | key_t key; 47 | #if 0 48 | __kernel_uid_t uid; 49 | __kernel_gid_t gid; 50 | __kernel_uid_t cuid; 51 | __kernel_gid_t cgid; 52 | __kernel_mode_t mode; 53 | unsigned short seq; 54 | #endif 55 | }; 56 | 57 | /* resource get request flags */ 58 | #define IPC_CREAT 00001000 /* create if key is nonexistent */ 59 | #define IPC_EXCL 00002000 /* fail if key exists */ 60 | #define IPC_NOWAIT 00004000 /* return error on wait */ 61 | 62 | /* 63 | * Control commands used with semctl, msgctl and shmctl 64 | * see also specific commands in shm.h 65 | */ 66 | #define IPC_RMID 0 /* remove resource */ 67 | #define IPC_SET 1 /* set ipc_perm options */ 68 | #define IPC_STAT 2 /* get ipc_perm options */ 69 | #define IPC_INFO 3 /* see ipcs */ 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /include/sys/poll.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Stefan Lankes, RWTH Aachen University 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the University nor the names of its contributors 13 | * may be used to endorse or promote products derived from this 14 | * software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef __SYS_POLL_H__ 29 | #define __SYS_POLL_H__ 30 | 31 | #include 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /* These are specified by iBCS2 */ 38 | #define POLLIN 0x0001 39 | #define POLLPRI 0x0002 40 | #define POLLOUT 0x0004 41 | #define POLLERR 0x0008 42 | #define POLLHUP 0x0010 43 | #define POLLNVAL 0x0020 44 | 45 | /* The rest seem to be more-or-less nonstandard. Check them! */ 46 | #define POLLRDNORM 0x0040 47 | #define POLLRDBAND 0x0080 48 | #ifndef POLLWRNORM 49 | #define POLLWRNORM 0x0100 50 | #endif 51 | #ifndef POLLWRBAND 52 | #define POLLWRBAND 0x0200 53 | #endif 54 | #ifndef POLLMSG 55 | #define POLLMSG 0x0400 56 | #endif 57 | #ifndef POLLREMOVE 58 | #define POLLREMOVE 0x1000 59 | #endif 60 | #ifndef POLLRDHUP 61 | #define POLLRDHUP 0x2000 62 | #endif 63 | 64 | #define POLLFREE 0x4000 /* currently only for epoll */ 65 | 66 | #define POLL_BUSY_LOOP 0x8000 67 | 68 | struct pollfd { 69 | int fd; 70 | short events; 71 | short revents; 72 | }; 73 | 74 | typedef unsigned long int nfds_t; 75 | 76 | int poll(struct pollfd *fds, nfds_t nfds, int timeout); 77 | 78 | #ifdef __cplusplus 79 | } 80 | #endif 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /include/sys/shm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Stefan Lankes, RWTH Aachen University 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the University nor the names of its contributors 13 | * may be used to endorse or promote products derived from this 14 | * software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef __SYS_SHM_H__ 29 | #define __SYS_SHM_H__ 30 | 31 | #include 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | struct shmid_ds { 38 | struct ipc_perm shm_perm; /* operation perms */ 39 | #if 0 40 | int shm_segsz; /* size of segment (bytes) */ 41 | __kernel_time_t shm_atime; /* last attach time */ 42 | __kernel_time_t shm_dtime; /* last detach time */ 43 | __kernel_time_t shm_ctime; /* last change time */ 44 | __kernel_ipc_pid_t shm_cpid; /* pid of creator */ 45 | __kernel_ipc_pid_t shm_lpid; /* pid of last operator */ 46 | unsigned short shm_nattch; /* no. of current attaches */ 47 | unsigned short shm_unused; /* compatibility */ 48 | void *shm_unused2; /* ditto - used by DIPC */ 49 | void *shm_unused3; /* unused */ 50 | #endif 51 | }; 52 | 53 | int shmget(key_t key, size_t size, int shmflg); 54 | void *shmat(int shmid, const void *shmaddr, int shmflg); 55 | int shmdt(const void *shmaddr); 56 | int shmctl(int shmid, int cmd, struct shmid_ds *buf); 57 | 58 | #ifdef __cplusplus 59 | } 60 | #endif 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /include/sys/uio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Just an empty dummy handler to be POSIX compliant. 3 | */ 4 | #ifndef __SYS_UIO_H__ 5 | #define __SYS_UIO_H__ 6 | 7 | #include 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | 14 | #ifdef __cplusplus 15 | } 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | OS_NAME=$1 4 | OS_VERSION=$2 5 | 6 | export DEBIAN_FRONTEND="noninteractive" 7 | 8 | apt-get -qq update || exit 1 9 | apt-get install -y --no-install-recommends binutils bsdmainutils ca-certificates cmake curl gcc git libc-dev make nasm qemu-system-x86 lld rpm || exit 1 10 | 11 | echo "deb [trusted=yes] http://dl.bintray.com/hermitcore/ubuntu bionic main" >> /etc/apt/sources.list 12 | apt-get -qq update || exit 1 13 | apt-get install -y --allow-unauthenticated binutils-hermit gcc-hermit-rs libomp-hermit-rs newlib-hermit-rs pte-hermit-rs || exit 1 14 | export PATH=/opt/hermit/bin:$PATH 15 | export PATH="$HOME/.cargo/bin:$PATH" 16 | 17 | curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain nightly 18 | cargo --version # dump version of the Rust toolchain 19 | cargo install cargo-xbuild 20 | rustup component add rust-src 21 | rustup component add llvm-tools-preview 22 | mkdir build 23 | cd build 24 | cmake .. 25 | make -j1 package || exit 1 26 | 27 | cd .. 28 | mkdir -p tmp 29 | dpkg-deb -R build/libhermit-rs-0.3.15-all.deb tmp || exit 1 30 | rm -rf build/*.deb build/_CPack_Packages 31 | 32 | cd loader 33 | make 34 | cd - 35 | 36 | TDIR=/work/build/local_prefix/opt/hermit/x86_64-hermit/extra 37 | FILES="$TDIR/tests/hello $TDIR/tests/hellof $TDIR/tests/hello++ $TDIR/tests/thr_hello" 38 | 39 | for f in $FILES; do echo "check $f..."; qemu-system-x86_64 -display none -smp 1 -m 1G -serial stdio -kernel /work/loader/target/x86_64-unknown-hermit-loader/debug/rusty-loader -initrd $f -cpu qemu64,apic,fsgsbase,rdtscp,xsave,xsaveopt,fxsr || exit 1; done 40 | 41 | for f in $FILES; do echo "check $f..."; qemu-system-x86_64 -display none -smp 2 -m 1G -serial stdio -kernel /work/loader/target/x86_64-unknown-hermit-loader/debug/rusty-loader -initrd $f -cpu qemu64,apic,fsgsbase,rdtscp,xsave,xsaveopt,fxsr || exit 1; done 42 | 43 | # test echo server at port 8000 44 | #HERMIT_ISLE=qemu HERMIT_CPUS=1 HERMIT_KVM=0 HERMIT_VERBOSE=1 HERMIT_APP_PORT=8000 $PROXY $TDIR/tests/server & 45 | #sleep 10 46 | #curl http://127.0.0.1:8000/help 47 | #sleep 1 48 | #curl http://127.0.0.1:8000/hello 49 | #sleep 1 50 | 51 | # kill server 52 | #kill $! 53 | 54 | # test connection via netio 55 | #wget http://web.ars.de/wp-content/uploads/2017/04/netio132.zip 56 | #unzip netio132.zip 57 | #HERMIT_ISLE=qemu HERMIT_CPUS=2 HERMIT_KVM=0 HERMIT_VERBOSE=1 HERMIT_APP_PORT=18767 $PROXY $TDIR/benchmarks/netio & 58 | #sleep 1 59 | #chmod a+rx bin/linux-x86_64 60 | #bin/linux-x86_64 -t -b 4k localhost 61 | #sleep 1 62 | 63 | # kill server 64 | #kill $! 65 | -------------------------------------------------------------------------------- /usr/benchmarks/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.7) 2 | include(../../cmake/HermitCore-Application.cmake) 3 | 4 | project(hermit_benchmarks C) 5 | 6 | add_executable(basic basic.c) 7 | target_compile_options(basic PRIVATE -pthread) 8 | target_link_libraries(basic pthread) 9 | 10 | add_executable(hg hg.c hist.c rdtsc.c run.c init.c opt.c report.c setup.c) 11 | 12 | # add_executable(netio netio.c) # temporarily removed due to lack of select() support 13 | 14 | add_executable(stream stream.c) 15 | target_compile_options(stream PRIVATE -fopenmp) 16 | target_link_libraries(stream -fopenmp) 17 | 18 | add_executable(taskswitch taskswitch.c) 19 | 20 | # deployment 21 | install_local_targets(extra/benchmarks) 22 | -------------------------------------------------------------------------------- /usr/benchmarks/basic.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Stefan Lankes, RWTH Aachen University 3 | * All rights reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 8 | * copied, modified, or distributed except according to those terms. 9 | */ 10 | 11 | #ifndef __hermit__ 12 | #define _GNU_SOURCE 13 | #endif 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #ifndef __hermit__ 23 | #include 24 | 25 | static inline long mygetpid(void) 26 | { 27 | return syscall(__NR_getpid); 28 | } 29 | #else 30 | static inline long mygetpid(void) 31 | { 32 | return getpid(); 33 | } 34 | 35 | int sched_yield(void); 36 | 37 | #define PAGE_SIZE (4ULL*1024ULL) 38 | #endif 39 | 40 | #define N 10000000 41 | #define M (256+1) 42 | #define BUFFSZ (1ULL*1024ULL*1024ULL) 43 | 44 | static char* buff[M]; 45 | 46 | #if 0 47 | inline static unsigned long long rdtsc(void) 48 | { 49 | unsigned long lo, hi; 50 | asm volatile ("lfence; rdtsc; lfence" : "=a"(lo), "=d"(hi) :: "memory"); 51 | return ((unsigned long long) hi << 32ULL | (unsigned long long) lo); 52 | } 53 | #else 54 | inline static unsigned long long rdtsc(void) 55 | { 56 | unsigned int lo, hi; 57 | unsigned int id; 58 | 59 | asm volatile ("rdtscp; lfence" : "=a"(lo), "=c"(id), "=d"(hi)); 60 | 61 | return ((unsigned long long)hi << 32ULL | (unsigned long long)lo); 62 | } 63 | #endif 64 | 65 | static void* thread_func(void* arg) 66 | { 67 | return (void*) rdtsc(); 68 | } 69 | 70 | int main(int argc, char** argv) 71 | { 72 | long i, j, ret; 73 | unsigned long long sum, start, end; 74 | const char str[] = "H"; 75 | const size_t len = strlen(str); 76 | pthread_t thr_handle; 77 | 78 | printf("Determine systems performance\n"); 79 | printf("=============================\n"); 80 | 81 | // cache warm-up 82 | ret = mygetpid(); 83 | ret = mygetpid(); 84 | 85 | start = rdtsc(); 86 | for(i=0; i 26 | #include 27 | 28 | struct opt opts = {0}; 29 | struct result results = {0}; 30 | 31 | int main(int argc, char *argv[]) 32 | { 33 | printf("hourglass\n"); 34 | 35 | opt(argc, argv, &opts); 36 | init(&opts); 37 | 38 | report_params(&opts); 39 | 40 | setup(&opts); 41 | run(&opts, &results); 42 | setdown(&opts); 43 | 44 | report(&opts, &results); 45 | 46 | run_free(&opts, &results); 47 | 48 | deinit(&opts); 49 | 50 | return EXIT_SUCCESS; 51 | } 52 | -------------------------------------------------------------------------------- /usr/benchmarks/hist.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: hist.c 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 26.07.2014 20:02:34 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Georg Wassen (gw) (), 14 | * Company: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "hist.h" 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | static const struct opt *opts; 27 | static uint32_t *hists; 28 | 29 | uint32_t *hist_alloc(const struct opt *opt) 30 | { 31 | opts = opt; 32 | hists = calloc(opt->hist_cnt, sizeof(uint32_t)); 33 | hist_reset(); 34 | return hists; 35 | } 36 | 37 | int hist_reset(void) 38 | { 39 | unsigned i; 40 | for (i=0; ihist_cnt; i++) { 41 | hists[i] = 0; 42 | } 43 | return 0; 44 | } 45 | 46 | void hist_add(uint64_t t) 47 | { 48 | t /= opts->hist_width; 49 | if (t > opts->hist_cnt-1) t = opts->hist_cnt-1; 50 | hists[t]++; 51 | } 52 | 53 | int hist_print(void) 54 | { 55 | unsigned i; 56 | unsigned max=0; 57 | const size_t bar_width = 30; 58 | char bar[bar_width+1]; 59 | 60 | for (i=0; ihist_cnt; i++) { 61 | if (hists[i] > max) max = hists[i]; 62 | } 63 | max = (unsigned)ceil(log10((double)max)); 64 | if (max == 0) max = 1; 65 | memset(bar, '*', bar_width); 66 | bar[bar_width] = 0; 67 | 68 | printf("Histogram (%u bins with %u ticks each)\n", opts->hist_cnt, opts->hist_width); 69 | for (i=0; ihist_cnt; i++) { 70 | printf(" %5u : %5u..%5u : %-10u %s\n", i, 71 | (unsigned)(i*opts->hist_width), 72 | (unsigned)((i+1)*opts->hist_width-1), 73 | (unsigned)(hists[i]), 74 | (char*)bar+(unsigned)(bar_width-((log10(hists[i]+1.)*bar_width)/max))); 75 | } 76 | return 0; 77 | } 78 | 79 | -------------------------------------------------------------------------------- /usr/benchmarks/hist.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: hist.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 26.07.2014 20:02:48 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Georg Wassen (gw) (), 14 | * Company: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __HIST_H__ 20 | #define __HIST_H__ 21 | 22 | #include "opt.h" 23 | 24 | #include 25 | 26 | uint32_t *hist_alloc(const struct opt *opt); 27 | int hist_reset(void); 28 | void hist_add(uint64_t t); 29 | int hist_print(void); 30 | 31 | #endif // __HIST_H__ 32 | -------------------------------------------------------------------------------- /usr/benchmarks/init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: init.c 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 25.07.2014 15:06:05 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Georg Wassen (gw) (), 14 | * Company: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "init.h" 20 | #include "rdtsc.h" 21 | 22 | 23 | int init(struct opt *opt) 24 | { 25 | /* 26 | * initialize (if required) 27 | * e.g. read number of processors available or cache parameters 28 | */ 29 | 30 | opt->tps = rdtsc_ticks_per_sec(); // does not work reliably... 31 | //opt->tps = 2530000000; 32 | 33 | 34 | return 0; 35 | } 36 | 37 | 38 | 39 | int deinit(struct opt *opt) 40 | { 41 | /* 42 | * de-initialize (if required) 43 | * e.g. free allocated resources 44 | */ 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /usr/benchmarks/init.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: init.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 25.07.2014 15:05:13 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Georg Wassen (gw) (), 14 | * Company: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __INIT_H__ 20 | #define __INIT_H__ 21 | 22 | #include "opt.h" 23 | 24 | int init(struct opt *opt); 25 | int deinit(struct opt *opt); 26 | 27 | #endif // __INIT_H__ 28 | -------------------------------------------------------------------------------- /usr/benchmarks/opt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: opt.c 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 25.07.2014 15:01:32 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Georg Wassen (gw) (), 14 | * Company: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #define _GNU_SOURCE 20 | #include "opt.h" 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #ifdef __hermit__ 29 | char *basename(char *path) 30 | { 31 | char *p; 32 | if( path == NULL || *path == '\0' ) 33 | return "."; 34 | p = path + strlen(path) - 1; 35 | while( *p == '/' ) { 36 | if( p == path ) 37 | return path; 38 | *p-- = '\0'; 39 | } 40 | while( p >= path && *p != '/' ) 41 | p--; 42 | return p + 1; 43 | } 44 | #endif 45 | 46 | int opt(int argc, char *argv[], struct opt *opt) 47 | { 48 | char c; 49 | char *p; 50 | 51 | opt->secs = 4; 52 | opt->mode = stat; 53 | opt->threshold = 0; 54 | 55 | opt->hist_cnt = 100; 56 | opt->hist_width = 50; 57 | 58 | opt->list_cnt = 1000; 59 | 60 | 61 | /* 62 | * read command line arguments and store them in opt 63 | */ 64 | 65 | while ((c = getopt(argc, argv, "b:c:d:hr:t:")) != -1) { 66 | switch (c) { 67 | case 'h' : 68 | printf("usage: %s \n", basename(argv[0])); 69 | printf(" -h help \n"); 70 | printf(" -d N duration (in sec or 1m, 1h) \n"); 71 | printf(" -r R report: hist, list\n"); 72 | printf(" -c N count (hist or list)\n"); 73 | printf(" -b N hist bin width (in ticks)\n"); 74 | printf(" -t N threshold (in ticks)\n"); 75 | exit(1); 76 | break; 77 | case 'd' : 78 | opt->secs = (unsigned)strtoul(optarg, &p, 0); 79 | if (p[0] == 'm' || p[0] == 'M') opt->secs *= 60u; 80 | else if (p[0] == 'h' || p[0] == 'H') opt->secs *= (60u*60u); 81 | else if (strlen(p) > 0) { 82 | printf("ERROR: Parameter: unrecognized characters in time: '%s'\n", p); 83 | return 2; 84 | } 85 | break; 86 | case 'r' : 87 | if (strncmp(optarg, "hist", 4) == 0) { 88 | opt->mode = hist; 89 | } else if (strncmp(optarg, "list", 4) == 0) { 90 | opt->mode = list; 91 | } 92 | break; 93 | case 'c' : 94 | if (opt->mode == hist) { 95 | opt->hist_cnt = (unsigned)strtoul(optarg, &p, 0); 96 | } else if (opt->mode == list) { 97 | opt->list_cnt = (unsigned)strtoul(optarg, &p, 0); 98 | } 99 | break; 100 | case 'b' : 101 | opt->hist_width = (unsigned)strtoul(optarg, &p, 0); 102 | break; 103 | case 't' : 104 | opt->threshold = (unsigned)strtoul(optarg, &p, 0); 105 | break; 106 | } 107 | } 108 | 109 | if (opt->mode == hist) { 110 | if (opt->hist_cnt == 0) { 111 | opt->hist_cnt = 1; 112 | } 113 | if (opt->hist_width == 0) { 114 | opt->hist_width = 1; 115 | } 116 | } else if (opt->mode == list) { 117 | if (opt->list_cnt == 0) { 118 | opt->list_cnt = 1; 119 | } 120 | } 121 | 122 | return 0; 123 | } 124 | 125 | -------------------------------------------------------------------------------- /usr/benchmarks/opt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: opt.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 25.07.2014 15:02:15 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Georg Wassen (gw) (), 14 | * Company: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __OPT_H__ 20 | #define __OPT_H__ 21 | 22 | #include 23 | 24 | struct opt { 25 | unsigned secs; 26 | enum {stat, hist, list} mode; 27 | uint64_t tps; 28 | uint64_t threshold; 29 | 30 | unsigned hist_cnt; 31 | unsigned hist_width; 32 | 33 | unsigned list_cnt; 34 | }; 35 | 36 | int opt(int argc, char *argv[], struct opt *opt); 37 | 38 | #endif // __OPT_H__ 39 | -------------------------------------------------------------------------------- /usr/benchmarks/rdtsc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: rdtsc.c 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 24.01.2011 13:41:30 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Georg Wassen (gw) (), 14 | * Company: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef RDTSC_H 20 | #define RDTSC_H 21 | 22 | #include 23 | 24 | /* 25 | * rdtsc_ticks_per_sec(): measure frequency. Takes below a second. 26 | */ 27 | uint64_t rdtsc_ticks_per_sec(void) __attribute__((optimize(3))); 28 | 29 | 30 | typedef union __attribute__((__transparent_union__)) 31 | { 32 | uint64_t *__u64; 33 | struct {uint32_t __low; uint32_t __high;} *__u32; 34 | } tsc_t; 35 | 36 | /* 37 | * rdtsc(): Register-save version (compiler may insert additional push/pop) 38 | * (clobbered-registers not given b/c compiler deduces from output-registers) 39 | */ 40 | static inline void __attribute__((__always_inline__, gnu_inline, optimize(3))) rdtsc(tsc_t tsc) 41 | { 42 | __asm__ volatile ("rdtsc" : "=a"(tsc.__u32->__low), "=d"(tsc.__u32->__high) ); 43 | } 44 | 45 | /* 46 | * rdtsc_serial(): get RDTSC with leading and rear serializing LFENCE instruction 47 | */ 48 | static inline void __attribute__((__always_inline__, gnu_inline, optimize(3))) rdtsc_serialized(tsc_t tsc) 49 | { 50 | #if ! __MIC__ 51 | __asm__ volatile ( 52 | "lfence\n\t" // serialize (needs SSE2, available since AMD Athlon64, Intel Core) 53 | "rdtsc\n\t" 54 | "lfence\n\t" 55 | : "=a"(tsc.__u32->__low), "=d"(tsc.__u32->__high) ); 56 | #else 57 | __asm__ volatile ( 58 | "lock; add $0, 0(%%rsp)\n\t" // serialize 59 | "rdtsc\n\t" 60 | "lock; add $0, 0(%%rsp)\n\t" // serialize 61 | : "=a"(tsc.__u32->__low), "=d"(tsc.__u32->__high) :: "memory" ); 62 | #endif 63 | } 64 | 65 | void rdtsc_loop(uint64_t ticks); 66 | void rdtsc_loop_sec(unsigned seconds); 67 | uint64_t rdtsc_max_freq(int id); 68 | 69 | int rdtsc_is_invariant(void); 70 | uint64_t rdtsc_get_overhead(uint64_t iterations); 71 | uint64_t rdtsc_get_overhead_serialized(uint64_t iterations); 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /usr/benchmarks/report.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: report.c 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 25.07.2014 15:11:54 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Georg Wassen (gw) (), 14 | * Company: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "report.h" 20 | #include "hist.h" 21 | 22 | #include 23 | 24 | 25 | int report_params(const struct opt *opt) 26 | { 27 | printf("init: tps = %llu\n", (unsigned long long)opt->tps); 28 | printf("secs : %u\n", opt->secs); 29 | printf("threshold : %llu\n", (unsigned long long)opt->threshold); 30 | if (opt->mode == hist) { 31 | printf("mode : histogram (cnt: %u, width: %u)\n", opt->hist_cnt, opt->hist_width); 32 | } else if (opt->mode == list) { 33 | printf("mode : list (cnt: %u)\n", opt->list_cnt); 34 | } 35 | return 0; 36 | } 37 | 38 | static int report_stat(const struct result *result) 39 | { 40 | printf(" # loops : %15llu\n", 41 | (unsigned long long)result->cnt); 42 | printf(" Min. : %15llu (@loop #%llu)\n", 43 | (unsigned long long)result->min, 44 | (unsigned long long)result->t_min); 45 | printf(" Avg. : %18.2lf\n", 46 | (double)result->sum/(double)result->cnt); 47 | printf(" Max. : %15llu (@loop #%llu)\n", 48 | (unsigned long long)result->max, 49 | (unsigned long long)result->t_max); 50 | return 0; 51 | } 52 | 53 | int report(const struct opt *opt, const struct result *result) 54 | { 55 | /* 56 | * write results to stdout (or file) 57 | * depending on opt 58 | */ 59 | 60 | printf("Dummy result: %llu \n", (unsigned long long)result->dummy); 61 | 62 | report_stat(result); 63 | 64 | if (opt->mode == hist) { 65 | hist_print(); 66 | } else if (opt->mode == list) { 67 | unsigned i; 68 | for (i=0; ilist_cnt; i++) { 69 | if (result->list[i].time > 0) { 70 | printf(" %15llu : %10llu\n", 71 | (unsigned long long)result->list[i].time, 72 | (unsigned long long)result->list[i].gap); 73 | } else break; 74 | } 75 | 76 | } 77 | 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /usr/benchmarks/report.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: report.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 25.07.2014 15:11:07 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Georg Wassen (gw) (), 14 | * Company: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __REPORT_H__ 20 | #define __REPORT_H__ 21 | 22 | #include "run.h" 23 | #include "opt.h" 24 | 25 | int report_params(const struct opt *opt); 26 | int report(const struct opt *opt, const struct result *result); 27 | 28 | #endif // __REPORT_H__ 29 | -------------------------------------------------------------------------------- /usr/benchmarks/run.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: run.c 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 25.07.2014 15:10:30 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Georg Wassen (gw) (), 14 | * Company: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "run.h" 20 | #include "rdtsc.h" 21 | #include "hist.h" 22 | 23 | #include 24 | #include 25 | 26 | static struct result *results; 27 | static const struct opt *opts; 28 | 29 | 30 | static void store_results_stat(uint64_t gap, uint64_t offset) 31 | { 32 | 33 | if (gap < results->min) { 34 | results->min = gap; 35 | results->t_min = results->cnt; 36 | } 37 | if (gap > results->max) { 38 | results->max = gap; 39 | results->t_max = results->cnt; 40 | } 41 | results->sum += gap; 42 | results->cnt++; /* avg = sum/cnt */ 43 | } 44 | 45 | static void store_results_hist(uint64_t gap, uint64_t offset) 46 | { 47 | /* 48 | * create histogram 49 | */ 50 | store_results_stat(gap, offset); 51 | hist_add(gap); 52 | } 53 | 54 | static unsigned list_cnt; 55 | static unsigned list_idx = 0; 56 | static void store_results_list(uint64_t gap, uint64_t offset) 57 | { 58 | /* 59 | * store all timestamps 60 | */ 61 | if (list_idx >= list_cnt) return; 62 | store_results_stat(gap, offset); 63 | results->list[list_idx].time = offset; 64 | results->list[list_idx].gap = gap; 65 | list_idx++; 66 | } 67 | 68 | static void (*store_results)(uint64_t gap, uint64_t offset); 69 | 70 | 71 | static int reset_results(void) 72 | { 73 | results->min=UINT64_MAX; 74 | results->max=0; 75 | results->sum=0; 76 | results->cnt=0; 77 | results->t_min = 0; 78 | results->t_max = 0; 79 | if (opts->mode == hist) { 80 | hist_reset(); 81 | } else if (opts->mode == list) { 82 | unsigned i; 83 | for (i=0; ilist_cnt; i++) { 84 | results->list[i].time=0; 85 | results->list[i].gap=0; 86 | } 87 | list_idx = 0; 88 | } 89 | return 0; 90 | } 91 | 92 | static int hourglass(uint64_t duration, uint64_t threshold) 93 | { 94 | uint64_t t1, t2, t_end, diff; /* timestamps */ 95 | 96 | reset_results(); 97 | 98 | rdtsc(&t1); /* start-time */ 99 | t_end = t1 + duration; /* calculate end-time */ 100 | 101 | while (t1 < t_end) { /* loop until end-time */ 102 | t2 = t1; 103 | rdtsc(&t1); 104 | diff = t1 - t2; 105 | if (diff > threshold) { 106 | store_results(diff, t2); 107 | } 108 | /* Note: additional workload may be added here */ 109 | } 110 | return 0; 111 | } 112 | 113 | int run(const struct opt *opt, struct result *result) 114 | { 115 | unsigned i; 116 | results = result; 117 | opts = opt; 118 | 119 | results->hist = NULL; 120 | 121 | switch (opt->mode) { 122 | case stat : 123 | store_results = store_results_stat; 124 | break; 125 | case hist : 126 | store_results = store_results_hist; 127 | results->hist = hist_alloc(opt); 128 | hist_reset(); 129 | break; 130 | case list : 131 | store_results = store_results_list; 132 | list_cnt = opt->list_cnt; 133 | results->list = calloc(opt->list_cnt, sizeof(struct res_list)); 134 | for (i=0; ilist_cnt; i++) { 135 | results->list[i].time=0; 136 | results->list[i].gap=0; 137 | } 138 | break; 139 | } 140 | 141 | /* 142 | * execute hourglass routine 143 | */ 144 | hourglass(1 * opt->tps, opt->threshold); // 1 sec warmup 145 | 146 | hourglass(opt->secs * opt->tps, opt->threshold); 147 | return 0; 148 | } 149 | 150 | int run_free(const struct opt *opt, struct result *result) 151 | { 152 | if (results->hist != NULL) { 153 | free(results->hist); 154 | results->hist = NULL; 155 | } 156 | if (results->list != NULL) { 157 | free(results->list); 158 | results->list = NULL; 159 | } 160 | return 0; 161 | } 162 | -------------------------------------------------------------------------------- /usr/benchmarks/run.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: run.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 25.07.2014 15:08:43 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Georg Wassen (gw) (), 14 | * Company: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __RUN_H__ 20 | #define __RUN_H__ 21 | 22 | #include "opt.h" 23 | 24 | #include 25 | struct res_list { 26 | uint64_t time; 27 | uint64_t gap; 28 | }; 29 | 30 | struct result { 31 | uint64_t dummy; 32 | 33 | uint64_t min; 34 | uint64_t max; 35 | uint64_t sum; 36 | uint64_t cnt; 37 | uint64_t t_min; 38 | uint64_t t_max; 39 | 40 | uint32_t *hist; 41 | struct res_list *list; 42 | 43 | }; 44 | 45 | int run(const struct opt *opt, struct result *result); 46 | int run_free(const struct opt *opt, struct result *result); 47 | 48 | 49 | #endif // __RUN_H__ 50 | 51 | -------------------------------------------------------------------------------- /usr/benchmarks/setup.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: setup.c 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 25.07.2014 15:07:43 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Georg Wassen (gw) (), 14 | * Company: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "setup.h" 20 | 21 | 22 | int setup(struct opt *opt) 23 | { 24 | /* 25 | * set up run-time environment for benchmark 26 | * depending on opt 27 | * e.g. create cpu-set, move IRQs, etc. 28 | */ 29 | 30 | 31 | return 0; 32 | } 33 | 34 | int setdown(struct opt *opt) 35 | { 36 | /* 37 | * undo things from setup() 38 | */ 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /usr/benchmarks/setup.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: setup.h 5 | * 6 | * Description: 7 | * 8 | * Version: 1.0 9 | * Created: 25.07.2014 15:06:59 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Georg Wassen (gw) (), 14 | * Company: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __SETUP_H__ 20 | #define __SETUP_H__ 21 | 22 | #include "opt.h" 23 | 24 | int setup(struct opt *opt); 25 | int setdown(struct opt *opt); 26 | 27 | #endif // __SETUP_H__ 28 | -------------------------------------------------------------------------------- /usr/benchmarks/taskswitch.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Colin Finck, RWTH Aachen University 2 | // 3 | // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | 8 | /////////////////////////////////////// 9 | //// HERMIT-OS RUST-SPECIFIC CODE //// 10 | 11 | #include 12 | 13 | inline static void create_second_task(void (*entry_point)(void*)) 14 | { 15 | sys_spawn(NULL, entry_point, NULL, NORMAL_PRIO, 0); 16 | } 17 | 18 | inline static void consume_task_time(void) 19 | { 20 | // Spending >10ms in the second task guarantees that the scheduler 21 | // switches back to the first task on sys_yield(). 22 | // Calling sys_msleep(ms) with ms < 10 enforces busy-waiting! 23 | sys_msleep(6); 24 | sys_msleep(6); 25 | } 26 | 27 | inline static void switch_task(void) 28 | { 29 | sys_yield(); 30 | } 31 | 32 | 33 | /////////////////////////////////// 34 | //// THE ACTUAL BENCHMARK CODE //// 35 | 36 | #include 37 | #include 38 | 39 | // You can enable this for debugging without any effect on the measurement. 40 | //#define DEBUG_MESSAGES 41 | 42 | #define N 1000 43 | static bool finished; 44 | static unsigned long long start; 45 | static unsigned long long sum; 46 | 47 | inline static unsigned long long rdtsc(void) 48 | { 49 | unsigned long lo, hi; 50 | asm volatile ("rdtsc" : "=a"(lo), "=d"(hi) :: "memory"); 51 | return ((unsigned long long) hi << 32ULL | (unsigned long long) lo); 52 | } 53 | 54 | void second_task(void* arg) 55 | { 56 | unsigned long long end; 57 | 58 | for(;;) 59 | { 60 | // Calculate the cycle difference and add it to the sum. 61 | end = rdtsc(); 62 | sum += (end - start); 63 | 64 | // Check if the benchmark has finished and we can end the second task. 65 | if (finished) 66 | { 67 | break; 68 | } 69 | 70 | #ifdef DEBUG_MESSAGES 71 | printf("Hello from task 2\n"); 72 | #endif 73 | 74 | consume_task_time(); 75 | 76 | // Save the current Time Stamp Counter value and switch back to the 77 | // first task. 78 | start = rdtsc(); 79 | switch_task(); 80 | } 81 | } 82 | 83 | int main(int argc, char** argv) 84 | { 85 | int i; 86 | unsigned long long end; 87 | 88 | // Start the second task with the same priority on the boot processor. 89 | create_second_task(second_task); 90 | 91 | // Initialize the benchmark. 92 | printf("taskswitch test\n"); 93 | printf("===============\n"); 94 | 95 | finished = false; 96 | sum = 0; 97 | 98 | // Warm up 99 | switch_task(); 100 | switch_task(); 101 | 102 | // Run the benchmark. 103 | sum = 0; 104 | for(i = 0; i < N; i++) 105 | { 106 | #ifdef DEBUG_MESSAGES 107 | printf("Hello from task 1\n"); 108 | #endif 109 | 110 | consume_task_time(); 111 | 112 | // Save the current Time Stamp Counter value and switch to the second 113 | // task. 114 | start = rdtsc(); 115 | switch_task(); 116 | 117 | // Calculate the cycle difference and add it to the sum. 118 | end = rdtsc(); 119 | sum += (end - start); 120 | } 121 | 122 | // Calculate and print the results. 123 | // In every loop iteration, task 1 switches to task 2 and task 2 switches 124 | // back to task 1. 125 | // Therefore, the total number needs to be divided by 2. 126 | printf("Average time for a task switch: %lld cycles\n", sum / (N * 2)); 127 | 128 | // Finish the second task gracefully. 129 | finished = true; 130 | switch_task(); 131 | 132 | return 0; 133 | } 134 | -------------------------------------------------------------------------------- /usr/openmpbench/.gitignore: -------------------------------------------------------------------------------- 1 | *.map 2 | *.xray 3 | -------------------------------------------------------------------------------- /usr/openmpbench/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.7) 2 | include(../../cmake/HermitCore-Application.cmake) 3 | 4 | project(hermit_openmpbench C) 5 | 6 | add_executable(syncbench syncbench.c common.c) 7 | target_link_libraries(syncbench PUBLIC -fopenmp) 8 | 9 | add_executable(taskbench taskbench.c common.c) 10 | target_link_libraries(taskbench PUBLIC -fopenmp) 11 | 12 | add_library(common_sched STATIC common.c) 13 | target_compile_definitions(common_sched PUBLIC -DSCHEDBENCH) 14 | target_compile_options(common_sched PUBLIC -fopenmp) 15 | target_link_libraries(common_sched PUBLIC -fopenmp) 16 | 17 | add_executable(schedbench schedbench.c) 18 | target_link_libraries(schedbench common_sched) 19 | 20 | # deployment: exclude common_sched 21 | install_local_targets(extra/benchmarks common_sched) 22 | -------------------------------------------------------------------------------- /usr/openmpbench/README.txt: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * * 3 | * OpenMP MicroBenchmark Suite - Version 3.1 * 4 | * * 5 | * produced by * 6 | * * 7 | * Mark Bull, Fiona Reid and Nix Mc Donnell * 8 | * * 9 | * at * 10 | * * 11 | * Edinburgh Parallel Computing Centre * 12 | * * 13 | * email: markb@epcc.ed.ac.uk or fiona@epcc.ed.ac.uk * 14 | * * 15 | * * 16 | * This version copyright (c) The University of Edinburgh, 2015. * 17 | * * 18 | * * 19 | * Licensed under the Apache License, Version 2.0 (the "License"); * 20 | * you may not use this file except in compliance with the License. * 21 | * You may obtain a copy of the License at * 22 | * * 23 | * http://www.apache.org/licenses/LICENSE-2.0 * 24 | * * 25 | * Unless required by applicable law or agreed to in writing, software * 26 | * distributed under the License is distributed on an "AS IS" BASIS, * 27 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 28 | * See the License for the specific language governing permissions and * 29 | * limitations under the License. * 30 | * * 31 | ****************************************************************************/ 32 | 33 | =============== 34 | Licence 35 | =============== 36 | This software is released under the licence in Licence.txt 37 | 38 | =============== 39 | Introduction 40 | =============== 41 | Overheads due to synchronisation, loop scheduling, array operations and 42 | task scheduling are an important factor in determining the performance of 43 | shared memory parallel programs. We have designed a set of microbenchmarks 44 | to measure these classes of overhead for language constructs in OpenMP. 45 | 46 | =============== 47 | Installation 48 | =============== 49 | 1. Unpack the tar file 50 | 51 | 2. Edit the Makefile.defs as follows: 52 | * Set CC to the C compiler you wish to use (e.g. gcc pgcc icc xlc etc) 53 | * Set CFLAGS to any required C compiler flags to enable processing of 54 | OpenMP directives (e.g. -fopenmp -mp, -omp); standard optimisation is 55 | also recommended (e.g. -O). 56 | * Set LDFLAGS to any required C linker flags 57 | * Set CPP to the local C-Preprocessor (e.g. /usr/local/bin/cpp) to 58 | make the C compiler invoke cpp on .c and .h files 59 | * To benchmark OpenMP 2.0 features can be invoked by setting the flag 60 | OMPFLAG = -DOMPVER2 61 | * To benchmark OpenMP 2.0 & 3.0 features can be invoked by setting the flag 62 | OMPFLAG = -DOMPVER2 -DOMPVER3 63 | * If neither of these flags are set then OpenMP 1.0 compatibility is 64 | ensured. 65 | 66 | 3. Type "make" to build all 4 benchmarks or "make benchmark" where benchmark 67 | is one of syncbench, taskbench, schedbench. By default "make" will build 68 | executables with array sizes ranging in powers of 3 from 1 to 59049. To 69 | build the array benchmark with an array size of arraysize, use 70 | "make IDA=arraysize prog" where arraysize is a positive integer. 71 | 72 | 73 | Example Makefile.defs.* files are supplied for several machines and 74 | compiler versions, e.g. 75 | Makefile.defs.hector.* - Cray XE6 76 | Makefile.defs.magny0.* - 48 core AMD Magny Cours machine 77 | Makefile.defs.stokes.* - SGI Altix ICE 8200EX 78 | 79 | 80 | =============== 81 | Running 82 | =============== 83 | 84 | 1. Set OMP_NUM_THREADS to the number of OpenMP threads you want to run with, 85 | e.g. export OMP_NUM_THREADS = 4 86 | OMP_NUM_THREADS should be less than or equal to the number of physical 87 | cores available to you. 88 | 89 | 2. Run the benchmark with: 90 | ./benchmark 91 | 92 | The output will go to STDOUT and thus you will probably want to re-direct 93 | this to a file. ./benchmark --help will give the usage options. 94 | 95 | 96 | ================= 97 | Additional notes 98 | ================= 99 | 100 | 1. If you encounter problems with the value of innerreps becoming too 101 | large (an error will be reported) try recompiling with a lower level of 102 | optimisation, ideally with inlining turned off. 103 | 104 | 2. It is common to observe significant variability between the overhead 105 | values obtained on different runs of the benchmark programs. Therefore, 106 | it is advisable to run each benchmark, say, 10-20 times and average the 107 | results obtained. 108 | 109 | 3. You should use whatever mechanisms are at your disposal to ensure that 110 | threads have exclusive or almost exclusive access to processors. You 111 | should rejects runs where the standard deviation or number of outliers is 112 | large: this is a good indication that the benchmark did not have almost 113 | exclusive access to processors. 114 | -------------------------------------------------------------------------------- /usr/openmpbench/arraybench.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * * 3 | * OpenMP MicroBenchmark Suite - Version 3.1 * 4 | * * 5 | * produced by * 6 | * * 7 | * Mark Bull, Fiona Reid and Nix Mc Donnell * 8 | * * 9 | * at * 10 | * * 11 | * Edinburgh Parallel Computing Centre * 12 | * * 13 | * email: markb@epcc.ed.ac.uk or fiona@epcc.ed.ac.uk * 14 | * * 15 | * * 16 | * This version copyright (c) The University of Edinburgh, 2015. * 17 | * * 18 | * * 19 | * Licensed under the Apache License, Version 2.0 (the "License"); * 20 | * you may not use this file except in compliance with the License. * 21 | * You may obtain a copy of the License at * 22 | * * 23 | * http://www.apache.org/licenses/LICENSE-2.0 * 24 | * * 25 | * Unless required by applicable law or agreed to in writing, software * 26 | * distributed under the License is distributed on an "AS IS" BASIS, * 27 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 28 | * See the License for the specific language governing permissions and * 29 | * limitations under the License. * 30 | * * 31 | ****************************************************************************/ 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include "common.h" 39 | #include "arraybench.h" 40 | 41 | double btest[IDA]; 42 | double atest[IDA]; 43 | 44 | #pragma omp threadprivate (btest) 45 | 46 | int main(int argc, char **argv) { 47 | 48 | init(argc, argv); 49 | 50 | /* GENERATE REFERENCE TIME */ 51 | reference("reference time 1", &refer); 52 | 53 | char testName[32]; 54 | 55 | /* TEST PRIVATE */ 56 | sprintf(testName, "PRIVATE %d", IDA); 57 | benchmark(testName, &testprivnew); 58 | 59 | /* TEST FIRSTPRIVATE */ 60 | sprintf(testName, "FIRSTPRIVATE %d", IDA); 61 | benchmark(testName, &testfirstprivnew); 62 | 63 | #ifdef OMPVER2 64 | /* TEST COPYPRIVATE */ 65 | sprintf(testName, "COPYPRIVATE %d", IDA); 66 | benchmark(testName, &testcopyprivnew); 67 | #endif 68 | 69 | /* TEST THREADPRIVATE - COPYIN */ 70 | sprintf(testName, "COPYIN %d", IDA); 71 | benchmark(testName, &testthrprivnew); 72 | 73 | finalise(); 74 | 75 | return EXIT_SUCCESS; 76 | 77 | } 78 | 79 | void refer() { 80 | int j; 81 | double a[1]; 82 | for (j = 0; j < innerreps; j++) { 83 | array_delay(delaylength, a); 84 | } 85 | } 86 | 87 | void testfirstprivnew() { 88 | int j; 89 | for (j = 0; j < innerreps; j++) { 90 | #pragma omp parallel firstprivate(atest) 91 | { 92 | array_delay(delaylength, atest); 93 | } 94 | } 95 | } 96 | 97 | void testprivnew() { 98 | int j; 99 | for (j = 0; j < innerreps; j++) { 100 | #pragma omp parallel private(atest) 101 | { 102 | array_delay(delaylength, atest); 103 | } 104 | } 105 | } 106 | 107 | #ifdef OMPVER2 108 | void testcopyprivnew() 109 | { 110 | int j; 111 | for (j=0; j 35 | #include 36 | #include 37 | #include 38 | 39 | #include "common.h" 40 | #include "schedbench.h" 41 | 42 | int cksz, itersperthr = 128; 43 | char testName[32]; 44 | 45 | int main(int argc, char **argv) { 46 | 47 | init(argc, argv); 48 | 49 | /* GENERATE REFERENCE TIME */ 50 | reference("reference time", &refer); 51 | 52 | /* TEST STATIC */ 53 | benchmark("STATIC", &teststatic); 54 | 55 | /* TEST STATIC,n */ 56 | cksz = 1; 57 | while (cksz <= itersperthr) { 58 | sprintf(testName, "STATIC %d", cksz); 59 | benchmark(testName, &teststaticn); 60 | cksz *= 2; 61 | } 62 | 63 | /* TEST DYNAMIC,n */ 64 | cksz = 1; 65 | while (cksz <= itersperthr) { 66 | sprintf(testName, "DYNAMIC %d", cksz); 67 | benchmark(testName, &testdynamicn); 68 | cksz *= 2; 69 | } 70 | 71 | /* TEST GUIDED,n */ 72 | cksz = 1; 73 | while (cksz <= itersperthr / nthreads) { 74 | sprintf(testName, "GUIDED %d", cksz); 75 | benchmark(testName, &testguidedn); 76 | cksz *= 2; 77 | } 78 | 79 | finalise(); 80 | 81 | return EXIT_SUCCESS; 82 | 83 | } 84 | 85 | void refer() { 86 | int i, j; 87 | for (j = 0; j < innerreps; j++) { 88 | for (i = 0; i < itersperthr; i++) { 89 | delay(delaylength); 90 | } 91 | } 92 | } 93 | 94 | void teststatic() { 95 | 96 | int i, j; 97 | #pragma omp parallel private(j) 98 | { 99 | for (j = 0; j < innerreps; j++) { 100 | #pragma omp for schedule(static) 101 | for (i = 0; i < itersperthr * nthreads; i++) { 102 | delay(delaylength); 103 | } 104 | } 105 | } 106 | } 107 | 108 | void teststaticn() { 109 | int i, j; 110 | #pragma omp parallel private(j) 111 | { 112 | for (j = 0; j < innerreps; j++) { 113 | #pragma omp for schedule(static,cksz) 114 | for (i = 0; i < itersperthr * nthreads; i++) { 115 | delay(delaylength); 116 | } 117 | } 118 | } 119 | } 120 | 121 | void testdynamicn() { 122 | int i, j; 123 | #pragma omp parallel private(j) 124 | { 125 | for (j = 0; j < innerreps; j++) { 126 | #pragma omp for schedule(dynamic,cksz) 127 | for (i = 0; i < itersperthr * nthreads; i++) { 128 | delay(delaylength); 129 | } 130 | } 131 | } 132 | } 133 | 134 | void testguidedn() { 135 | int i, j; 136 | #pragma omp parallel private(j) 137 | { 138 | for (j = 0; j < innerreps; j++) { 139 | #pragma omp for schedule(guided,cksz) 140 | for (i = 0; i < itersperthr * nthreads; i++) { 141 | delay(delaylength); 142 | } 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /usr/openmpbench/schedbench.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * * 3 | * OpenMP MicroBenchmark Suite - Version 3.1 * 4 | * * 5 | * produced by * 6 | * * 7 | * Mark Bull, Fiona Reid and Nix Mc Donnell * 8 | * * 9 | * at * 10 | * * 11 | * Edinburgh Parallel Computing Centre * 12 | * * 13 | * email: markb@epcc.ed.ac.uk or fiona@epcc.ed.ac.uk * 14 | * * 15 | * * 16 | * This version copyright (c) The University of Edinburgh, 2015. * 17 | * * 18 | * * 19 | * Licensed under the Apache License, Version 2.0 (the "License"); * 20 | * you may not use this file except in compliance with the License. * 21 | * You may obtain a copy of the License at * 22 | * * 23 | * http://www.apache.org/licenses/LICENSE-2.0 * 24 | * * 25 | * Unless required by applicable law or agreed to in writing, software * 26 | * distributed under the License is distributed on an "AS IS" BASIS, * 27 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 28 | * See the License for the specific language governing permissions and * 29 | * limitations under the License. * 30 | * * 31 | ****************************************************************************/ 32 | 33 | #ifndef SCHEDBENCH_H 34 | #define SCHEDBENCH_H 35 | 36 | void refer(void); 37 | 38 | void teststatic(void); 39 | 40 | void teststaticn(void); 41 | 42 | void testdynamicn(void); 43 | 44 | void testguidedn(void); 45 | 46 | #endif //SCHEDBENCH_H 47 | -------------------------------------------------------------------------------- /usr/openmpbench/syncbench.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * * 3 | * OpenMP MicroBenchmark Suite - Version 3.1 * 4 | * * 5 | * produced by * 6 | * * 7 | * Mark Bull, Fiona Reid and Nix Mc Donnell * 8 | * * 9 | * at * 10 | * * 11 | * Edinburgh Parallel Computing Centre * 12 | * * 13 | * email: markb@epcc.ed.ac.uk or fiona@epcc.ed.ac.uk * 14 | * * 15 | * * 16 | * This version copyright (c) The University of Edinburgh, 2015. * 17 | * * 18 | * * 19 | * Licensed under the Apache License, Version 2.0 (the "License"); * 20 | * you may not use this file except in compliance with the License. * 21 | * You may obtain a copy of the License at * 22 | * * 23 | * http://www.apache.org/licenses/LICENSE-2.0 * 24 | * * 25 | * Unless required by applicable law or agreed to in writing, software * 26 | * distributed under the License is distributed on an "AS IS" BASIS, * 27 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 28 | * See the License for the specific language governing permissions and * 29 | * limitations under the License. * 30 | * * 31 | ****************************************************************************/ 32 | 33 | 34 | #ifndef SYNCBENCH_H 35 | #define SYNCBENCH_H 36 | 37 | void refer(void); 38 | 39 | void referatom(void); 40 | 41 | void referred(void); 42 | 43 | void testpr(void); 44 | 45 | void testfor(void); 46 | 47 | void testpfor(void); 48 | 49 | void testbar(void); 50 | 51 | void testsing(void); 52 | 53 | void testcrit(void); 54 | 55 | void testlock(void); 56 | 57 | void testorder(void); 58 | 59 | void testatom(void); 60 | 61 | void testred(void); 62 | 63 | #endif //SYNCBENCH_H 64 | -------------------------------------------------------------------------------- /usr/openmpbench/taskbench.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * * 3 | * OpenMP MicroBenchmark Suite - Version 3.1 * 4 | * * 5 | * produced by * 6 | * * 7 | * Mark Bull, Fiona Reid and Nix Mc Donnell * 8 | * * 9 | * at * 10 | * * 11 | * Edinburgh Parallel Computing Centre * 12 | * * 13 | * email: markb@epcc.ed.ac.uk or fiona@epcc.ed.ac.uk * 14 | * * 15 | * * 16 | * This version copyright (c) The University of Edinburgh, 2015. * 17 | * * 18 | * * 19 | * Licensed under the Apache License, Version 2.0 (the "License"); * 20 | * you may not use this file except in compliance with the License. * 21 | * You may obtain a copy of the License at * 22 | * * 23 | * http://www.apache.org/licenses/LICENSE-2.0 * 24 | * * 25 | * Unless required by applicable law or agreed to in writing, software * 26 | * distributed under the License is distributed on an "AS IS" BASIS, * 27 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 28 | * See the License for the specific language governing permissions and * 29 | * limitations under the License. * 30 | * * 31 | ****************************************************************************/ 32 | 33 | #ifndef TASKBENCH_H 34 | #define TASKBENCH_H 35 | 36 | void refer(void); 37 | 38 | void refer2(void); 39 | 40 | void stats(double*, double*); 41 | 42 | void testParallelTaskGeneration(void); 43 | 44 | void testMasterTaskGeneration(void); 45 | 46 | void testMasterTaskGenerationWithBusySlaves(void); 47 | 48 | void testNestedTaskGeneration(void); 49 | 50 | void testNestedMasterTaskGeneration(void); 51 | 52 | void testTaskWait(void); 53 | 54 | void testTaskBarrier(void); 55 | 56 | void testConditionalTaskGeneration(void); 57 | 58 | void testBranchTaskGeneration(void); 59 | 60 | void branchTaskTree(int tree_level); 61 | 62 | void testLeafTaskGeneration(void); 63 | 64 | void leafTaskTree(int tree_level); 65 | 66 | #endif //TASKBENCH_H 67 | -------------------------------------------------------------------------------- /usr/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.7) 2 | include(../../cmake/HermitCore-Application.cmake) 3 | 4 | project(hermit_tests C CXX Fortran) 5 | 6 | add_executable(hello hello.c) 7 | add_executable(jacobi jacobi.c) 8 | add_executable(hello++ hello++.cpp) 9 | #add_executable(hellof hellof.f90) Temporarily removing Fortran support 10 | #add_executable(pi pi.go) 11 | 12 | add_executable(test-malloc test-malloc.c) 13 | add_executable(test-malloc-mt test-malloc-mt.c) 14 | target_compile_options(test-malloc-mt PRIVATE -pthread) 15 | target_link_libraries(test-malloc-mt pthread) 16 | 17 | #add_executable(server server.go) 18 | #target_link_libraries(server netgo) 19 | 20 | add_executable(thr_hello thr_hello.c) 21 | target_compile_options(thr_hello PRIVATE -pthread) 22 | target_link_libraries(thr_hello pthread) 23 | 24 | add_executable(nweb23 nweb23.c) 25 | target_compile_options(nweb23 PRIVATE -pthread) 26 | target_link_libraries(nweb23 pthread) 27 | 28 | add_executable(hello-tcp hello-tcp.c) 29 | 30 | # deployment 31 | install_local_targets(extra/tests) 32 | -------------------------------------------------------------------------------- /usr/tests/hello++.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, Stefan Lankes, RWTH Aachen University 3 | * All rights reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 8 | * copied, modified, or distributed except according to those terms. 9 | */ 10 | 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | 16 | int main(int argc, char** argv) 17 | { 18 | cout << "Hello World from g++!!!" << endl; 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /usr/tests/hello-tcp.c: -------------------------------------------------------------------------------- 1 | //! Usage example: 2 | //! Run with `-nic user,hostfwd=::12345-:12345,model=rtl8139` in QEMU 3 | //! Query with `wget -qO- 127.0.0.1:12345` 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | int main() { 14 | const int sfd = socket(AF_INET, SOCK_STREAM, 0); 15 | if (sfd < 0) { 16 | puts("socket creation failed"); 17 | exit(1); 18 | } 19 | 20 | const struct sockaddr_in server_addr = {.sin_family = AF_INET, 21 | .sin_addr.s_addr = 22 | htonl(INADDR_ANY), 23 | .sin_port = htons(12345)}; 24 | if (bind(sfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { 25 | puts("bind failed"); 26 | exit(1); 27 | } 28 | 29 | if (listen(sfd, 64) < 0) { 30 | puts("listen failed"); 31 | exit(1); 32 | } 33 | 34 | puts("listening for incoming connections"); 35 | 36 | for (;;) { 37 | puts("awaiting connections"); 38 | struct sockaddr_in address; 39 | socklen_t addr_len = sizeof(address); 40 | int cfd; 41 | if ((cfd = accept(sfd, (struct sockaddr *)&address, &addr_len)) < 0) { 42 | puts("accept failed"); 43 | exit(1); 44 | } 45 | printf("new client: %s:%" PRIu16 "\n", inet_ntoa(address.sin_addr), 46 | address.sin_port); 47 | 48 | const char *msg = "Hello TCP!\n"; 49 | send(cfd, msg, strlen(msg), 0); 50 | 51 | shutdown(cfd, 2); 52 | close(cfd); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /usr/tests/hello.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, Stefan Lankes, RWTH Aachen University 3 | * All rights reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 8 | * copied, modified, or distributed except according to those terms. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define N 255 18 | 19 | int main(int argc, char** argv) 20 | { 21 | int i, random; 22 | FILE* file; 23 | 24 | printf("Hello World!!!\n"); 25 | for(i=0; environ[i]; i++) 26 | printf("environ[%d] = %s\n", i, environ[i]); 27 | for(i=0; i or the MIT license , at your option. This file may not be 8 | ! copied, modified, or distributed except according to those terms. 9 | 10 | program hellof 11 | print *, "HelloWorld from gfortran!" 12 | end program hellof 13 | -------------------------------------------------------------------------------- /usr/tests/jacobi.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2011, Stefan Lankes, RWTH Aachen University 3 | * All rights reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 8 | * copied, modified, or distributed except according to those terms. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #define MATRIX_SIZE 128 19 | #define MAXVALUE 1337 20 | #define PAGE_SIZE 4096 21 | #define CACHE_SIZE (256*1024) 22 | #define ALIGN(x,a) (((x)+(a)-1)&~((a)-1)) 23 | 24 | /* A gettimeofday routine to give access to the wall 25 | clock timer on most UNIX-like systems. */ 26 | 27 | #include 28 | #include 29 | 30 | double mysecond() 31 | { 32 | struct timeval tv; 33 | 34 | gettimeofday(&tv, NULL); 35 | return ((double) tv.tv_sec + (double) tv.tv_usec * 1.e-6); 36 | } 37 | 38 | static int generate_empty_matrix(double*** A , unsigned int N) { 39 | unsigned int iCnt; 40 | int i,j; 41 | 42 | *A = (double**) malloc((N+1)*sizeof(double*)); 43 | 44 | if (*A == NULL) { 45 | printf("*A is NULL...\n"); 46 | return -1; /* Error */ 47 | } 48 | 49 | (*A)[0] = (double*) malloc((N+1)*N*sizeof(double)); 50 | 51 | if (**A == NULL) { 52 | printf("**A is NULL...\n"); 53 | return -2; /* Error */ 54 | } 55 | 56 | for(iCnt=1; iCnt Sum |A[i][j]| with (i != j) 88 | */ 89 | 90 | (*A)[i][i] = sum + 2.0; 91 | (*A)[i][N] += sum + 2.0; 92 | } 93 | 94 | return 0; 95 | } 96 | 97 | int main(int argc, char **argv) 98 | { 99 | double* temp; 100 | unsigned int i, j, iter_start, iter_end; 101 | unsigned int iterations = 0; 102 | double error, norm, max = 0.0; 103 | double** A=0; 104 | double* X; 105 | double* X_old, xi; 106 | double start, end; 107 | 108 | if (generate_empty_matrix(&A,MATRIX_SIZE) < 0) 109 | { 110 | printf("generate_empty_matrix() failed...\n"); 111 | exit(-1); 112 | 113 | } 114 | 115 | printf("generate_empty_matrix() done...\n"); 116 | 117 | X = (double*) malloc(MATRIX_SIZE*sizeof(double)); 118 | X_old = (double*) malloc(MATRIX_SIZE*sizeof(double)); 119 | if(X == NULL || X_old == NULL) 120 | { 121 | printf("X or X_old is NULL...\n"); 122 | exit(-1); 123 | } 124 | 125 | for(i=0; i 0.01f) { 191 | printf("Result is on position %d wrong (%f != 1.0)\n", i, X[i]); 192 | exit(1); 193 | } 194 | } 195 | printf("maximal error is %f\n", max); 196 | 197 | printf("\nmatrix size: %d x %d\n", MATRIX_SIZE, MATRIX_SIZE); 198 | printf("number of iterations: %d\n", iterations); 199 | printf("calculation time: %lf s\n", end-start); 200 | 201 | free((void*) X_old); 202 | free((void*) X); 203 | 204 | return 0; 205 | } 206 | -------------------------------------------------------------------------------- /usr/tests/pi.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Stefan Lankes, RWTH Aachen University 3 | * All rights reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be 8 | * copied, modified, or distributed except according to those terms. 9 | */ 10 | 11 | package main 12 | 13 | import ( 14 | "fmt" 15 | "os" 16 | "strconv" 17 | "time" 18 | "runtime" 19 | ) 20 | 21 | var step float64 22 | 23 | func term(ch chan float64, start, end int) { 24 | var res float64 25 | 26 | for i := start; i < end; i++ { 27 | x := (float64(i) + 0.5) * step 28 | res += 4.0 / (1.0 + x * x) 29 | } 30 | 31 | ch <- res 32 | } 33 | 34 | func main() { 35 | var num_steps int 36 | ch := make(chan float64) 37 | max_coroutines := runtime.NumCPU() 38 | 39 | if len(os.Args) > 1 { 40 | num_steps, _ = strconv.Atoi(os.Args[1]) 41 | } 42 | if num_steps < 100 { 43 | num_steps = 1000000 44 | } 45 | fmt.Println("num_steps : ", num_steps) 46 | 47 | sum := float64(0) 48 | step = 1.0 / float64(num_steps) 49 | 50 | start := time.Now() 51 | 52 | for i := 0; i < max_coroutines; i++ { 53 | start := (num_steps / max_coroutines) * i 54 | end := (num_steps / max_coroutines) * (i+1) 55 | 56 | go term(ch, start, end) 57 | } 58 | 59 | for i := 0; i < max_coroutines; i++ { 60 | sum += <-ch 61 | } 62 | 63 | elapsed := time.Since(start) 64 | 65 | fmt.Println("Pi : ", sum*step) 66 | fmt.Println("Time : ", elapsed) 67 | 68 | s := new(runtime.MemStats) 69 | runtime.ReadMemStats(s) 70 | 71 | fmt.Println("Alloc : ", s.Alloc) 72 | fmt.Println("Total Alloc : ", s.TotalAlloc) 73 | fmt.Println("Sys : ", s.Sys) 74 | fmt.Println("Lookups : ", s.Lookups) 75 | } 76 | -------------------------------------------------------------------------------- /usr/tests/server.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan. 2 | // License: https://creativecommons.org/licenses/by-nc-sa/4.0/ 3 | 4 | // The original code was published at http://www.gopl.io, see page 21. 5 | 6 | // This is an "echo" server that displays request parameters. 7 | 8 | package main 9 | 10 | import ( 11 | "fmt" 12 | "log" 13 | "net/http" 14 | ) 15 | 16 | func main() { 17 | fmt.Println("This is an \"echo\" server that displays request parameters.") 18 | fmt.Println("Start the server and send a http request to it (e.g.") 19 | fmt.Println("curl http://localhost:8000/help). The server uses port 8000.") 20 | fmt.Println("If KVM is implicitly started by our proxy, please open the port by") 21 | fmt.Println("setting the environment variable HERMIT_APP_PORT to 8000.") 22 | 23 | http.HandleFunc("/", handler) 24 | log.Fatal(http.ListenAndServe(":8000", nil)) 25 | } 26 | 27 | //!+handler 28 | // handler echoes the HTTP request. 29 | func handler(w http.ResponseWriter, r *http.Request) { 30 | fmt.Fprintf(w, "%s %s %s\n", r.Method, r.URL, r.Proto) 31 | for k, v := range r.Header { 32 | fmt.Fprintf(w, "Header[%q] = %q\n", k, v) 33 | } 34 | fmt.Fprintf(w, "Host = %q\n", r.Host) 35 | fmt.Fprintf(w, "RemoteAddr = %q\n", r.RemoteAddr) 36 | if err := r.ParseForm(); err != nil { 37 | log.Print(err) 38 | } 39 | for k, v := range r.Form { 40 | fmt.Fprintf(w, "Form[%q] = %q\n", k, v) 41 | } 42 | } 43 | //!-handler 44 | -------------------------------------------------------------------------------- /usr/tests/test-malloc-mt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #ifndef NUM_THREADS 9 | #define NUM_THREADS 3 10 | #endif 11 | 12 | #ifndef NUM_ITER 13 | #define NUM_ITER 1000 14 | #endif 15 | 16 | #ifndef SIZE 17 | #define SIZE 16*1024 18 | #endif 19 | 20 | __thread void* buf; 21 | 22 | static void* perform_work( void* argument ) 23 | { 24 | int passed_in_value; 25 | 26 | passed_in_value = *( ( int* )argument ); 27 | printf( "Hello World! It's me, thread %d with argument %d!\n", getpid(), passed_in_value ); 28 | 29 | /* optionally: insert more useful stuff here */ 30 | for(int i=0; i 2 | #include 3 | #include 4 | #include 5 | 6 | #ifndef NUM_ITER 7 | #define NUM_ITER 10000 8 | #endif 9 | 10 | #ifndef SIZE 11 | #define SIZE 16*1024 12 | #endif 13 | 14 | void* buf; 15 | 16 | int main(int argc, char** argv) 17 | { 18 | /* optionally: insert more useful stuff here */ 19 | 20 | for(int i=0; i 2 | #include 3 | 4 | #define MAX_THREADS 2 5 | 6 | void* thread_func(void* arg) 7 | { 8 | int id = *((int*) arg); 9 | 10 | printf("Hello Thread!!! id = %d\n", id); 11 | 12 | return 0; 13 | } 14 | 15 | int main(int argc, char** argv) 16 | { 17 | pthread_t threads[MAX_THREADS]; 18 | int i, ret, param[MAX_THREADS]; 19 | 20 | for(i=0; i`. 60 | 61 | Then you must initialize XRay and already do some configuration: 62 | 63 | ```c 64 | struct XRayTraceCapture* XRayInit(int stack_size, 65 | int buffer_size, 66 | int frame_count, 67 | const char* mapfilename); 68 | 69 | struct XRayTraceCapture* trace = XRayInit( 70 | 5, // max. call depth in report 71 | 4 * 1000 * 1000, // ring buffer size for profiling information 72 | 10, // frame count 73 | "/path/to/your/application.map"); 74 | ``` 75 | 76 | To find the hotspots in your code you might want to start with a relatively 77 | small call depth (maybe 5) and increase it to gain a better understanding of the 78 | detailed call hierarchy. The maximum call depth / stack size is 255. Keep the 79 | buffer size as small as possible and increase on demand. 80 | 81 | Now you can wrap parts of your code into frames: 82 | 83 | ```c 84 | XRayStartFrame(trace); 85 | do_work(); 86 | XRayEndFrame(trace); 87 | 88 | XRayStartFrame(trace); 89 | do_even_more_work(); 90 | XRayEndFrame(trace); 91 | ``` 92 | 93 | And finally generate the report: 94 | 95 | ```c 96 | void XRaySaveReport(struct XRayTraceCapture* capture, 97 | const char* filename, 98 | float percent_cutoff, 99 | int cycle_cutoff); 100 | 101 | XRaySaveReport(trace, 102 | "/path/to/you/report/application.xray", // report file 103 | 10.0f, // Only output funcs that have a higher runtime [%] 104 | 2000); // Only output funcs that have a higher runtime [cycles] 105 | XRayShutdown(trace); 106 | ``` 107 | 108 | Here you can do further filtering of the output. For a function call to be added 109 | to the report, it's relative runtime (whole application) has be higher than 110 | `percent_cutoff` and it's absolute runtime must be greater than `cycle_cutoff` 111 | CPU cycles. 112 | 113 | 114 | ## Example 115 | 116 | See [usr/openmpbench/syncbench.c](https://github.com/RWTH-OS/HermitCore/blob/master/usr/openmpbench/syncbench.c). 117 | 118 | 119 | ## Analysis 120 | 121 | After tracing your code, you may want to analyse the report. While the XRay 122 | report is already human-readable, it's hard to get an overview of the whole 123 | trace. Therefore, it's possible to convert the XRay report to a format that 124 | [kCacheGrind](https://kcachegrind.github.io) can read. You can find the tool 125 | needed for conversion at `usr/xray/tools`. 126 | 127 | ```bash 128 | $ ./conv2kcg.py libgomp_trace.xray 129 | INFO:Parsing Header is done. Found 1 frames 130 | INFO:Found frame 'PARALLEL' data 131 | INFO:Frame 'PARALLEL' complete 132 | INFO:Report file 'libgomp_trace.xray' parsed completely. 133 | INFO:Create callgrind file for frame 'PARALLEL' 134 | INFO:Writing to: libgomp_trace_PARALLEL.callgrind 135 | ``` 136 | 137 | This will create the file `libgomp_trace_PARALLEL.callgrind` which can be opened 138 | using kCacheGrind (Open dialog: set Filter to 'All Files'). 139 | -------------------------------------------------------------------------------- /usr/xray/browser.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 | * Use of this source code is governed by a BSD-style license that can be 3 | * found in the LICENSE file. 4 | */ 5 | 6 | 7 | /* XRay -- a simple profiler for Native Client */ 8 | 9 | #ifndef XRAY_DISABLE_BROWSER_INTEGRATION 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include "ppapi/c/dev/ppb_trace_event_dev.h" 21 | #include "xray/xray_priv.h" 22 | 23 | 24 | #if defined(XRAY) 25 | static PPB_Trace_Event_Dev* ppb_trace_event_interface = NULL; 26 | 27 | static const char* XRayGetName(struct XRaySymbolTable* symbols, 28 | struct XRayTraceBufferEntry* e) { 29 | uint32_t addr = XRAY_EXTRACT_ADDR(e->depth_addr); 30 | struct XRaySymbol* symbol = XRaySymbolTableLookup(symbols, addr); 31 | return XRaySymbolGetName(symbol); 32 | } 33 | 34 | struct XRayTimestampPair XRayGenerateTimestampsNow(void) { 35 | struct XRayTimestampPair pair; 36 | assert(ppb_trace_event_interface); 37 | 38 | XRayGetTSC(&pair.xray); 39 | pair.pepper = ppb_trace_event_interface->Now(); 40 | return pair; 41 | } 42 | 43 | /* see chromium/src/base/trace_event/trace_event.h */ 44 | #define TRACE_VALUE_TYPE_UINT (2) 45 | #define TRACE_VALUE_TYPE_DOUBLE (4) 46 | #define TRACE_VALUE_TYPE_COPY_STRING (7) 47 | 48 | union TraceValue { 49 | bool as_bool; 50 | unsigned long long as_uint; 51 | long long as_int; 52 | double as_double; 53 | const void* as_pointer; 54 | const char* as_string; 55 | }; 56 | 57 | void XRayBrowserTraceReport(struct XRayTraceCapture* capture) { 58 | 59 | const void* cat_enabled = ppb_trace_event_interface->GetCategoryEnabled( 60 | "xray"); 61 | struct XRaySymbolTable* symbols = XRayGetSymbolTable(capture); 62 | 63 | int32_t thread_id = XRayGetSavedThreadID(capture); 64 | 65 | int head = XRayFrameGetHead(capture); 66 | int frame = XRayFrameGetTail(capture); 67 | while(frame != head) { 68 | 69 | struct XRayTimestampPair start_time = XRayFrameGetStartTimestampPair( 70 | capture, frame); 71 | struct XRayTimestampPair end_time = XRayFrameGetEndTimestampPair( 72 | capture, frame); 73 | 74 | double pdiff = (end_time.pepper - start_time.pepper); 75 | double odiff = (end_time.xray - start_time.xray); 76 | double scale_a = pdiff / odiff; 77 | double scale_b = ((double)end_time.pepper) - (scale_a * end_time.xray); 78 | printf("Xray timestamp calibration frame %d: %f %f\n", 79 | frame, scale_a, scale_b); 80 | 81 | int start = XRayFrameGetTraceStartIndex(capture, frame); 82 | int end = XRayFrameGetTraceEndIndex(capture, frame); 83 | 84 | struct XRayTraceBufferEntry** stack_base = XRayMalloc( 85 | sizeof(struct XRayTraceBufferEntry*) * (XRAY_TRACE_STACK_SIZE + 1)); 86 | struct XRayTraceBufferEntry** stack_top = stack_base; 87 | *stack_top = NULL; 88 | 89 | uint32_t num_args = 0; 90 | const char* arg_names[] = {"annotation"}; 91 | uint8_t arg_types[] = {TRACE_VALUE_TYPE_COPY_STRING}; 92 | uint64_t arg_values[] = {0}; 93 | char annotation[XRAY_TRACE_ANNOTATION_LENGTH]; 94 | 95 | int i; 96 | for(i = start; i != end; i = XRayTraceNextEntry(capture, i)) { 97 | if (XRayTraceIsAnnotation(capture, i)) { 98 | continue; 99 | } 100 | 101 | uint32_t depth = XRAY_EXTRACT_DEPTH( 102 | XRayTraceGetEntry(capture, i)->depth_addr); 103 | 104 | while(*stack_top && 105 | XRAY_EXTRACT_DEPTH((*stack_top)->depth_addr) >= depth) { 106 | struct XRayTraceBufferEntry* e = *(stack_top--); 107 | ppb_trace_event_interface->AddTraceEventWithThreadIdAndTimestamp( 108 | 'E', cat_enabled, 109 | XRayGetName(symbols, e), 110 | 0, thread_id, 111 | (scale_a * e->end_tick) + scale_b, 112 | 0, NULL, NULL, NULL, 0 113 | ); 114 | } 115 | 116 | num_args = 0; 117 | struct XRayTraceBufferEntry* e = XRayTraceGetEntry(capture, i); 118 | uint32_t annotation_index = e->annotation_index; 119 | if (annotation_index) { 120 | XRayTraceCopyToString(capture, annotation_index, annotation); 121 | 122 | union TraceValue val; 123 | val.as_string = (const char*)annotation; 124 | 125 | arg_values[0] = val.as_uint; 126 | num_args = 1; 127 | } 128 | 129 | ppb_trace_event_interface->AddTraceEventWithThreadIdAndTimestamp( 130 | 'B', cat_enabled, 131 | XRayGetName(symbols, e), 132 | 0, thread_id, 133 | (scale_a * e->start_tick) + scale_b, 134 | num_args, arg_names, arg_types, arg_values, 0 135 | ); 136 | 137 | *(++stack_top) = e; 138 | } 139 | 140 | while(*stack_top) { 141 | struct XRayTraceBufferEntry* e = *(stack_top--); 142 | ppb_trace_event_interface->AddTraceEventWithThreadIdAndTimestamp( 143 | 'E', cat_enabled, 144 | XRayGetName(symbols, e), 145 | 0, thread_id, 146 | (scale_a * e->end_tick) + scale_b, 147 | 0, NULL, NULL, NULL, 0 148 | ); 149 | } 150 | 151 | frame = XRayFrameGetNext(capture, frame); 152 | XRayFree(stack_base); 153 | } 154 | } 155 | 156 | void XRayRegisterBrowserInterface(PPB_GetInterface interface) { 157 | ppb_trace_event_interface = (PPB_Trace_Event_Dev*)interface( 158 | PPB_TRACE_EVENT_DEV_INTERFACE); 159 | assert(ppb_trace_event_interface); 160 | } 161 | 162 | #endif /* XRAY */ 163 | #endif /* XRAY_DISABLE_BROWSER_INTEGRATION */ -------------------------------------------------------------------------------- /usr/xray/demangle.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 | * Use of this source code is governed by a BSD-style license that can be 3 | * found in the LICENSE file. */ 4 | 5 | #include "xray_priv.h" 6 | 7 | /* Note name demangling requires linking against libstdc++ */ 8 | /* If your platform does not support __cxa_demangle, re-compile XRay with: */ 9 | /* -DXRAY_NO_DEMANGLE */ 10 | 11 | #if !defined(XRAY_NO_DEMANGLE) 12 | extern 13 | char* __cxa_demangle(const char* __mangled_name, char* __output_buffer, 14 | size_t* __length, int* __status); 15 | #endif 16 | 17 | const char* XRayDemangle(char* demangle, size_t size, const char* symbol) { 18 | #if !defined(XRAY_NO_DEMANGLE) 19 | int stat; 20 | __cxa_demangle(symbol, demangle, &size, &stat); 21 | if (stat == 0) 22 | return demangle; 23 | #endif 24 | return symbol; 25 | } 26 | -------------------------------------------------------------------------------- /usr/xray/hashtable.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 | * Use of this source code is governed by a BSD-style license that can be 3 | * found in the LICENSE file. */ 4 | 5 | 6 | /* Hashtable for XRay */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "xray_priv.h" 13 | 14 | #if defined(XRAY) 15 | 16 | struct XRayHashTableEntry { 17 | void* data; 18 | uint32_t key; 19 | }; 20 | 21 | 22 | struct XRayHashTable { 23 | int capacity; 24 | int count; 25 | struct XRayHashTableEntry* array; 26 | }; 27 | 28 | 29 | XRAY_NO_INSTRUMENT void XRayHashTableGrow(struct XRayHashTable* table); 30 | XRAY_NO_INSTRUMENT uint32_t XRayHashTableHashKey(uint32_t key); 31 | XRAY_NO_INSTRUMENT void XRayHashTableInit(struct XRayHashTable* table, 32 | int32_t capacity); 33 | 34 | #define HASH_HISTO 1024 35 | int g_hash_histo[HASH_HISTO]; 36 | 37 | 38 | /* Hashes a 32bit key into a 32bit value. */ 39 | uint32_t XRayHashTableHashKey(uint32_t x) { 40 | uint32_t y = x * 7919; 41 | uint32_t z; 42 | size_t c; 43 | uint8_t* s = (uint8_t*)&y; 44 | /* based on djb2 hash function */ 45 | uint32_t h = 5381; 46 | for (c = 0; c < sizeof(y); ++c) { 47 | z = s[c]; 48 | h = ((h << 5) + h) + z; 49 | } 50 | return h; 51 | } 52 | 53 | 54 | int XRayHashTableGetCapacity(struct XRayHashTable* table) { 55 | return table->capacity; 56 | } 57 | 58 | 59 | int XRayHashTableGetCount(struct XRayHashTable* table) { 60 | return table->count; 61 | } 62 | 63 | 64 | /* Looks up key in hashtable and returns blind data. */ 65 | void* XRayHashTableLookup(struct XRayHashTable* table, uint32_t key) { 66 | uint32_t h = XRayHashTableHashKey(key); 67 | uint32_t m = table->capacity - 1; 68 | uint32_t j = h & m; 69 | uint32_t i; 70 | int z = 1; 71 | for (i = 0; i < m; ++i) { 72 | /* An empty entry means the {key, data} isn't in the table. */ 73 | if (NULL == table->array[j].data) { 74 | ++g_hash_histo[0]; 75 | return NULL; 76 | } 77 | /* Search for address */ 78 | if (table->array[j].key == key) { 79 | if (z >= HASH_HISTO) 80 | z = HASH_HISTO - 1; 81 | ++g_hash_histo[z]; 82 | return table->array[j].data; 83 | } 84 | j = (j + 1) & m; 85 | ++z; 86 | } 87 | /* Table was full, and there wasn't a match. */ 88 | return NULL; 89 | } 90 | 91 | 92 | /* Inserts key & data into hash table. No duplicates. */ 93 | void* XRayHashTableInsert(struct XRayHashTable* table, 94 | void* data, uint32_t key) { 95 | uint32_t h = XRayHashTableHashKey(key); 96 | uint32_t m = table->capacity - 1; 97 | uint32_t j = h & m; 98 | uint32_t i; 99 | for (i = 0; i < m; ++i) { 100 | /* Take the first empty entry. */ 101 | /* (the key,data isn't already in the table) */ 102 | if (NULL == table->array[j].data) { 103 | void* ret; 104 | float ratio; 105 | table->array[j].data = data; 106 | table->array[j].key = key; 107 | ++table->count; 108 | ret = data; 109 | ratio = (float)table->count / (float)table->capacity; 110 | /* Double the capacity of the symtable if we've hit the ratio. */ 111 | if (ratio > XRAY_SYMBOL_TABLE_MAX_RATIO) 112 | XRayHashTableGrow(table); 113 | return ret; 114 | } 115 | /* If the key is already present, return the data in the table. */ 116 | if (table->array[j].key == key) { 117 | return table->array[j].data; 118 | } 119 | j = (j + 1) & m; 120 | } 121 | /* Table was full */ 122 | return NULL; 123 | } 124 | 125 | 126 | void* XRayHashTableAtIndex(struct XRayHashTable* table, int i) { 127 | if ((i < 0) || (i >= table->capacity)) 128 | return NULL; 129 | return table->array[i].data; 130 | } 131 | 132 | 133 | /* Grows the hash table by doubling its capacity, */ 134 | /* then re-inserts all the elements into the new table. */ 135 | void XRayHashTableGrow(struct XRayHashTable* table) { 136 | struct XRayHashTableEntry* old_array = table->array; 137 | int old_capacity = table->capacity; 138 | int new_capacity = old_capacity * 2; 139 | int i; 140 | printf("XRay: Growing a hash table...\n"); 141 | XRayHashTableInit(table, new_capacity); 142 | for (i = 0; i < old_capacity; ++i) { 143 | void* data = old_array[i].data; 144 | if (NULL != data) { 145 | uint32_t key = old_array[i].key; 146 | XRayHashTableInsert(table, data, key); 147 | } 148 | } 149 | XRayFree(old_array); 150 | } 151 | 152 | 153 | void XRayHashTableInit(struct XRayHashTable* table, int32_t capacity) { 154 | size_t bytes; 155 | if (0 != (capacity & (capacity - 1))) { 156 | printf("Xray: Hash table capacity should be a power of 2!\n"); 157 | /* Round capacity up to next power of 2 */ 158 | /* see http://aggregate.org/MAGIC/ */ 159 | capacity--; 160 | capacity |= capacity >> 1; 161 | capacity |= capacity >> 2; 162 | capacity |= capacity >> 4; 163 | capacity |= capacity >> 8; 164 | capacity |= capacity >> 16; 165 | capacity++; 166 | } 167 | bytes = sizeof(table->array[0]) * capacity; 168 | table->capacity = capacity; 169 | table->count = 0; 170 | table->array = (struct XRayHashTableEntry*)XRayMalloc(bytes); 171 | } 172 | 173 | 174 | /* Creates & inializes hash table. */ 175 | struct XRayHashTable* XRayHashTableCreate(int capacity) { 176 | struct XRayHashTable* table; 177 | table = (struct XRayHashTable*)XRayMalloc(sizeof(*table)); 178 | XRayHashTableInit(table, capacity); 179 | memset(&g_hash_histo[0], 0, sizeof(g_hash_histo[0]) * HASH_HISTO); 180 | return table; 181 | } 182 | 183 | 184 | /* Prints hash table performance to file; for debugging. */ 185 | void XRayHashTableHisto(FILE* f) { 186 | int i; 187 | for (i = 0; i < HASH_HISTO; ++i) { 188 | if (0 != g_hash_histo[i]) 189 | fprintf(f, "hash_iterations[%d] = %d\n", i, g_hash_histo[i]); 190 | } 191 | } 192 | 193 | 194 | /* Frees hash table. */ 195 | /* Note: Does not free what the hash table entries point to. */ 196 | void XRayHashTableFree(struct XRayHashTable* table) { 197 | XRayFree(table->array); 198 | table->capacity = 0; 199 | table->count = 0; 200 | table->array = NULL; 201 | XRayFree(table); 202 | } 203 | 204 | #endif /* XRAY */ 205 | 206 | -------------------------------------------------------------------------------- /usr/xray/libxray.spec: -------------------------------------------------------------------------------- 1 | # Do we really need this? Does this even what we want? 2 | *link_xray: -lxray 3 | 4 | -------------------------------------------------------------------------------- /usr/xray/parsesymbols.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 | * Use of this source code is governed by a BSD-style license that can be 3 | * found in the LICENSE file. */ 4 | 5 | 6 | /* XRay -- a simple profiler for Native Client */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "xray_priv.h" 14 | 15 | #if defined(XRAY) 16 | 17 | struct XRaySymbol* XRaySymbolTableCreateEntry(struct XRaySymbolTable* symtab, 18 | char* line) { 19 | uint32_t addr; 20 | unsigned int uiaddr; 21 | char symbol_text[XRAY_LINE_SIZE]; 22 | char* parsed_symbol; 23 | char* newln; 24 | if (2 != sscanf(line, "%x %1023s", &uiaddr, symbol_text)) 25 | return NULL; 26 | if (uiaddr > 0x07FFFFFF) { 27 | fprintf(stderr, "While parsing the mapfile, XRay encountered:\n"); 28 | fprintf(stderr, "%s\n", line); 29 | fprintf(stderr, 30 | "XRay only works with code addresses 0x00000000 - 0x07FFFFFF\n"); 31 | fprintf(stderr, "All functions must reside in this address space.\n"); 32 | exit(-1); 33 | } 34 | addr = (uint32_t)uiaddr; 35 | parsed_symbol = strstr(line, symbol_text); 36 | newln = strstr(parsed_symbol, "\n"); 37 | if (NULL != newln) { 38 | *newln = 0; 39 | } 40 | return XRaySymbolTableAddByName(symtab, parsed_symbol, addr); 41 | } 42 | 43 | 44 | void XRaySymbolTableParseMapfile(struct XRaySymbolTable* symtab, 45 | const char* mapfile) { 46 | FILE* f; 47 | char line[XRAY_LINE_SIZE]; 48 | bool in_text = false; 49 | bool in_link_once = false; 50 | int in_link_once_counter = 0; 51 | int num_symbols = 0; 52 | 53 | printf("XRay: opening mapfile %s\n", mapfile); 54 | f = fopen(mapfile, "rt"); 55 | if (0 == f) { 56 | fprintf(stderr, "XRay: failed to open %s\n", mapfile); 57 | return; 58 | } 59 | printf("XRay: parsing...\n"); 60 | while (NULL != fgets(line, XRAY_LINE_SIZE, f)) { 61 | if (line == strstr(line, " .text ")) { 62 | in_text = true; 63 | continue; 64 | } 65 | if (line == strstr(line, " .gnu.linkonce.t.")) { 66 | in_link_once = true; 67 | in_link_once_counter = 0; 68 | continue; 69 | } 70 | if (line == strstr(line, " .text.")) { 71 | in_link_once = true; 72 | in_link_once_counter = 0; 73 | continue; 74 | } 75 | if (line == strstr(line, " 0x")) { 76 | if (in_text) { 77 | XRaySymbolTableCreateEntry(symtab, line); 78 | ++num_symbols; 79 | } else if (in_link_once) { 80 | if (in_link_once_counter != 0) { 81 | if (NULL != XRaySymbolTableCreateEntry(symtab, line)) 82 | ++num_symbols; 83 | } else { 84 | ++in_link_once_counter; 85 | } 86 | } 87 | } else { 88 | in_text = false; 89 | in_link_once = false; 90 | } 91 | } 92 | fclose(f); 93 | printf("XRay: parsed %d symbols into symbol table\n", num_symbols); 94 | } 95 | 96 | #endif // XRAY 97 | -------------------------------------------------------------------------------- /usr/xray/stringpool.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 | * Use of this source code is governed by a BSD-style license that can be 3 | * found in the LICENSE file. */ 4 | 5 | 6 | /* XRay string pool */ 7 | 8 | /* String pool holds a large pile of strings. */ 9 | /* It is up to higher level data structures to avoid duplicates. */ 10 | /* It is up to higher level data structures to provide fast lookups. */ 11 | 12 | /* _GNU_SOURCE must be defined prior to the inclusion of string.h 13 | * so that strnlen is available with glibc */ 14 | #define _GNU_SOURCE 15 | #include 16 | #include 17 | #include "xray_priv.h" 18 | 19 | #if defined(XRAY) 20 | 21 | struct XRayStringPoolNode { 22 | struct XRayStringPoolNode* next; 23 | char strings[XRAY_STRING_POOL_NODE_SIZE]; 24 | }; 25 | 26 | 27 | struct XRayStringPool { 28 | struct XRayStringPoolNode* head; 29 | struct XRayStringPoolNode* current; 30 | int index; 31 | }; 32 | 33 | 34 | static struct XRayStringPoolNode* XRayStringPoolAllocNode() { 35 | struct XRayStringPoolNode* s; 36 | s = (struct XRayStringPoolNode *)XRayMalloc(sizeof(*s)); 37 | s->next = NULL; 38 | return s; 39 | } 40 | 41 | 42 | static int XRayStringPoolCurrentNodeSpaceAvail(struct XRayStringPool* pool) { 43 | int i = pool->index; 44 | return (XRAY_STRING_POOL_NODE_SIZE - i) - 1; 45 | } 46 | 47 | 48 | /* Append a string to the string pool. */ 49 | char* XRayStringPoolAppend(struct XRayStringPool* pool, const char* src) { 50 | /* Add +1 to STRING_POOL_NODE_SIZE to detect large strings */ 51 | /* Add +1 to strnlen result to account for string termination */ 52 | int n = strnlen(src, XRAY_STRING_POOL_NODE_SIZE + 1) + 1; 53 | int a = XRayStringPoolCurrentNodeSpaceAvail(pool); 54 | char* dst; 55 | /* Don't accept strings larger than the pool node. */ 56 | if (n >= (XRAY_STRING_POOL_NODE_SIZE - 1)) 57 | return NULL; 58 | /* If string doesn't fit, alloc a new node. */ 59 | if (n > a) { 60 | pool->current->next = XRayStringPoolAllocNode(); 61 | pool->current = pool->current->next; 62 | pool->index = 0; 63 | } 64 | /* Copy string and return a pointer to copy. */ 65 | dst = &pool->current->strings[pool->index]; 66 | strcpy(dst, src); 67 | pool->index += n; 68 | return dst; 69 | } 70 | 71 | 72 | /* Create & initialize a string pool instance. */ 73 | struct XRayStringPool* XRayStringPoolCreate() { 74 | struct XRayStringPool* pool; 75 | pool = (struct XRayStringPool*)XRayMalloc(sizeof(*pool)); 76 | pool->head = XRayStringPoolAllocNode(); 77 | pool->current = pool->head; 78 | return pool; 79 | } 80 | 81 | 82 | /* Free a string pool. */ 83 | void XRayStringPoolFree(struct XRayStringPool* pool) { 84 | struct XRayStringPoolNode* n = pool->head; 85 | while (NULL != n) { 86 | struct XRayStringPoolNode* c = n; 87 | n = n->next; 88 | XRayFree(c); 89 | } 90 | XRayFree(pool); 91 | } 92 | 93 | #endif /* XRAY */ 94 | 95 | -------------------------------------------------------------------------------- /usr/xray/symtable.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 | * Use of this source code is governed by a BSD-style license that can be 3 | * found in the LICENSE file. */ 4 | 5 | /* XRay symbol table */ 6 | 7 | #define _GNU_SOURCE 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #if defined(__GLIBC__) 14 | #include 15 | #endif 16 | 17 | #include "xray_priv.h" 18 | #define PNACL_STRING_OFFSET (0x10000000) 19 | 20 | #if defined(XRAY) 21 | 22 | bool g_symtable_debug = false; 23 | 24 | struct XRayFrameInfo { 25 | int times_called; 26 | int total_ticks; 27 | }; 28 | 29 | 30 | struct XRaySymbol { 31 | const char* name; 32 | struct XRayFrameInfo frames[XRAY_MAX_FRAMES]; 33 | }; 34 | 35 | 36 | struct XRaySymbolPoolNode { 37 | struct XRaySymbolPoolNode* next; 38 | struct XRaySymbol symbols[XRAY_SYMBOL_POOL_NODE_SIZE]; 39 | }; 40 | 41 | 42 | struct XRaySymbolPool { 43 | struct XRaySymbolPoolNode* head; 44 | struct XRaySymbolPoolNode* current; 45 | int index; 46 | }; 47 | 48 | 49 | struct XRaySymbolTable { 50 | int num_symbols; 51 | struct XRayHashTable* hash_table; 52 | struct XRayStringPool* string_pool; 53 | struct XRaySymbolPool* symbol_pool; 54 | }; 55 | 56 | 57 | const char* XRaySymbolGetName(struct XRaySymbol* symbol) { 58 | return (NULL == symbol) ? "(null)" : symbol->name; 59 | } 60 | 61 | 62 | struct XRaySymbol* XRaySymbolCreate(struct XRaySymbolPool* sympool, 63 | const char* name) 64 | { 65 | struct XRaySymbol* symbol; 66 | symbol = XRaySymbolPoolAlloc(sympool); 67 | symbol->name = name; 68 | return symbol; 69 | } 70 | 71 | 72 | struct XRaySymbol* XRaySymbolPoolAlloc(struct XRaySymbolPool* sympool) { 73 | struct XRaySymbol* symbol; 74 | if (sympool->index >= XRAY_SYMBOL_POOL_NODE_SIZE) { 75 | struct XRaySymbolPoolNode* new_pool; 76 | new_pool = (struct XRaySymbolPoolNode*)XRayMalloc(sizeof(*new_pool)); 77 | sympool->current->next = new_pool; 78 | sympool->current = new_pool; 79 | sympool->index = 0; 80 | } 81 | symbol = &sympool->current->symbols[sympool->index]; 82 | ++sympool->index; 83 | return symbol; 84 | } 85 | 86 | 87 | struct XRaySymbolPool* XRaySymbolPoolCreate() { 88 | struct XRaySymbolPool* sympool; 89 | struct XRaySymbolPoolNode* node; 90 | sympool = (struct XRaySymbolPool*)XRayMalloc(sizeof(*sympool)); 91 | node = (struct XRaySymbolPoolNode*)XRayMalloc(sizeof(*node)); 92 | sympool->head = node; 93 | sympool->current = node; 94 | sympool->index = 0; 95 | return sympool; 96 | } 97 | 98 | 99 | void XRaySymbolPoolFree(struct XRaySymbolPool* pool) { 100 | struct XRaySymbolPoolNode* n = pool->head; 101 | while (NULL != n) { 102 | struct XRaySymbolPoolNode* c = n; 103 | n = n->next; 104 | XRayFree(c); 105 | } 106 | XRayFree(pool); 107 | } 108 | 109 | 110 | int XRaySymbolTableGetCount(struct XRaySymbolTable* symtab) { 111 | return XRayHashTableGetCount(symtab->hash_table); 112 | } 113 | 114 | 115 | struct XRaySymbol* XRaySymbolTableAtIndex(struct XRaySymbolTable* symtab, 116 | int i) { 117 | return (struct XRaySymbol*)XRayHashTableAtIndex(symtab->hash_table, i); 118 | } 119 | 120 | struct XRaySymbol* XRaySymbolTableAdd(struct XRaySymbolTable* symtab, 121 | struct XRaySymbol* symbol, 122 | uint32_t addr) { 123 | struct XRaySymbol* sym = (struct XRaySymbol*) 124 | XRayHashTableInsert(symtab->hash_table, symbol, addr); 125 | symtab->num_symbols = XRayHashTableGetCount(symtab->hash_table); 126 | return sym; 127 | } 128 | 129 | struct XRaySymbol* XRaySymbolTableAddByName(struct XRaySymbolTable* symtab, 130 | const char* name, uint32_t addr) { 131 | char* recorded_name; 132 | struct XRaySymbol* symbol; 133 | char buffer[XRAY_LINE_SIZE]; 134 | const char* demangled_name = XRayDemangle(buffer, XRAY_LINE_SIZE, name); 135 | /* record the demangled symbol name into the string pool */ 136 | recorded_name = XRayStringPoolAppend(symtab->string_pool, demangled_name); 137 | if (g_symtable_debug) 138 | printf("adding symbol %s\n", recorded_name); 139 | /* construct a symbol and put it in the symbol table */ 140 | symbol = XRaySymbolCreate(symtab->symbol_pool, recorded_name); 141 | return XRaySymbolTableAdd(symtab, symbol, addr); 142 | } 143 | 144 | struct XRaySymbol* XRaySymbolTableLookup(struct XRaySymbolTable* symtab, 145 | uint32_t addr) { 146 | void *x = XRayHashTableLookup(symtab->hash_table, addr); 147 | struct XRaySymbol* r = (struct XRaySymbol*)x; 148 | 149 | #if defined(__pnacl__) 150 | if (r == NULL) { 151 | /* Addresses are trimed to 24 bits for internal storage, so we need to 152 | * add this offset back in order to get the real address. 153 | */ 154 | addr |= PNACL_STRING_OFFSET; 155 | const char* name = (const char*)addr; 156 | struct XRaySymbol* symbol = XRaySymbolCreate(symtab->symbol_pool, name); 157 | r = XRaySymbolTableAdd(symtab, symbol, addr); 158 | } 159 | #endif 160 | 161 | #if defined(__GLIBC__) 162 | if (r == NULL) { 163 | Dl_info info; 164 | if (dladdr((const void*)addr, &info) != 0) 165 | if (info.dli_sname) 166 | r = XRaySymbolTableAddByName(symtab, info.dli_sname, addr); 167 | } 168 | #endif 169 | return r; 170 | } 171 | 172 | 173 | /* Returns total number of symbols in the table. */ 174 | int XRaySymbolCount(struct XRaySymbolTable* symtab) { 175 | return symtab->num_symbols; 176 | } 177 | 178 | 179 | /* Creates and inializes a symbol table. */ 180 | struct XRaySymbolTable* XRaySymbolTableCreate(int size) { 181 | struct XRaySymbolTable* symtab; 182 | symtab = (struct XRaySymbolTable*)XRayMalloc(sizeof(*symtab)); 183 | symtab->num_symbols = 0; 184 | symtab->string_pool = XRayStringPoolCreate(); 185 | symtab->hash_table = XRayHashTableCreate(size); 186 | symtab->symbol_pool = XRaySymbolPoolCreate(); 187 | return symtab; 188 | } 189 | 190 | 191 | /* Frees a symbol table. */ 192 | void XRaySymbolTableFree(struct XRaySymbolTable* symtab) { 193 | XRayStringPoolFree(symtab->string_pool); 194 | XRaySymbolPoolFree(symtab->symbol_pool); 195 | XRayHashTableFree(symtab->hash_table); 196 | symtab->num_symbols = 0; 197 | XRayFree(symtab); 198 | } 199 | 200 | #endif /* XRAY */ 201 | -------------------------------------------------------------------------------- /usr/xray/xray.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 | * Use of this source code is governed by a BSD-style license that can be 3 | * found in the LICENSE file. */ 4 | 5 | /* XRay -- a simple profiler for Native Client */ 6 | 7 | 8 | #ifndef LIBRARIES_XRAY_XRAY_H_ 9 | #define LIBRARIES_XRAY_XRAY_H_ 10 | 11 | #include 12 | 13 | // we don't want that 14 | #ifndef XRAY_DISABLE_BROWSER_INTEGRATION 15 | #define XRAY_DISABLE_BROWSER_INTEGRATION 16 | #endif 17 | 18 | #ifndef XRAY_DISABLE_BROWSER_INTEGRATION 19 | #include "ppapi/c/ppb.h" 20 | #endif 21 | 22 | #if defined(__arm__) 23 | #undef XRAY 24 | #endif 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | #define XRAY_NO_INSTRUMENT __attribute__((no_instrument_function)) 31 | #define XRAY_INLINE __attribute__((always_inline, no_instrument_function)) inline 32 | 33 | #if defined(XRAY) 34 | 35 | /* Do not call __XRayAnnotate* directly; instead use the */ 36 | /* XRayAnnotate() macros below. */ 37 | XRAY_NO_INSTRUMENT void __XRayAnnotate(const char* str, ...) 38 | __attribute__ ((format(printf, 1, 2))); 39 | XRAY_NO_INSTRUMENT void __XRayAnnotateFiltered(const uint32_t filter, 40 | const char* str, ...) __attribute__ ((format(printf, 2, 3))); 41 | 42 | /* This is the beginning of the public XRay API */ 43 | 44 | /* Ok if mapfilename is NULL, no symbols will be loaded. On glibc builds, 45 | * XRay will also attempt to populate the symbol table with dladdr() 46 | */ 47 | XRAY_NO_INSTRUMENT struct XRayTraceCapture* XRayInit(int stack_size, 48 | int buffer_size, 49 | int frame_count, 50 | const char* mapfilename); 51 | XRAY_NO_INSTRUMENT void XRayShutdown(struct XRayTraceCapture* capture); 52 | XRAY_NO_INSTRUMENT void XRayStartFrame(struct XRayTraceCapture* capture); 53 | XRAY_NO_INSTRUMENT void XRayEndFrame(struct XRayTraceCapture* capture); 54 | XRAY_NO_INSTRUMENT void XRayLabelFrame(const char* fmt, ...); 55 | XRAY_NO_INSTRUMENT void XRaySetAnnotationFilter( 56 | struct XRayTraceCapture* capture, uint32_t filter); 57 | XRAY_NO_INSTRUMENT void XRaySaveReport(struct XRayTraceCapture* capture, 58 | const char* filename, 59 | float percent_cutoff, 60 | int cycle_cutoff); 61 | XRAY_NO_INSTRUMENT void XRayReport(struct XRayTraceCapture* capture, 62 | FILE* f, 63 | float percent_cutoff, 64 | int ticks_cutoff); 65 | 66 | #ifndef XRAY_DISABLE_BROWSER_INTEGRATION 67 | XRAY_NO_INSTRUMENT void XRayBrowserTraceReport( 68 | struct XRayTraceCapture* capture); 69 | XRAY_NO_INSTRUMENT void XRayRegisterBrowserInterface( 70 | PPB_GetInterface get_browser_interface); 71 | #endif /* XRAY_DISABLE_BROWSER_INTEGRATION */ 72 | 73 | 74 | #if defined(XRAY_ANNOTATE) 75 | #define XRayAnnotate(...) __XRayAnnotate(__VA_ARGS__) 76 | #define XRayAnnotateFiltered(...) __XRayAnnotateFiltered(__VA_ARGS__) 77 | #else 78 | #define XRayAnnotate(...) 79 | #define XRayAnnotateFiltered(...) 80 | #endif 81 | /* This is the end of the public XRay API */ 82 | 83 | #else /* defined(XRAY) */ 84 | 85 | /* Builds that don't define XRAY will use these 'null' functions instead. */ 86 | 87 | #define XRayAnnotate(...) 88 | #define XRayAnnotateFiltered(...) 89 | 90 | inline struct XRayTraceCapture* XRayInit(int stack_size, 91 | int buffer_size, 92 | int frame_count, 93 | const char* mapfilename) { 94 | return NULL; 95 | } 96 | inline void XRayShutdown(struct XRayTraceCapture* capture) {} 97 | inline void XRayStartFrame(struct XRayTraceCapture* capture) {} 98 | inline void XRayEndFrame(struct XRayTraceCapture* capture) {} 99 | inline void XRayLabelFrame(const char* fmt, ...) {} 100 | 101 | inline void XRaySetAnnotationFilter(struct XRayTraceCapture* capture, 102 | uint32_t filter) {} 103 | inline void XRaySaveReport(struct XRayTraceCapture* capture, 104 | const char* filename, 105 | float percent_cutoff, 106 | int cycle_cutoff) {} 107 | inline void XRayReport(struct XRayTraceCapture* capture, 108 | FILE* f, 109 | float percent_cutoff, 110 | int ticks_cutoff) {} 111 | 112 | #ifndef XRAY_DISABLE_BROWSER_INTEGRATION 113 | inline void XRayBrowserTraceReport(struct XRayTraceCapture* capture) {} 114 | inline void XRayRegisterBrowserInterface( 115 | PPB_GetInterface get_browser_interface) {} 116 | #endif /* XRAY_DISABLE_BROWSER_INTEGRATION */ 117 | 118 | 119 | #endif /* defined(XRAY) */ 120 | 121 | #ifdef __cplusplus 122 | } 123 | #endif 124 | 125 | #endif /* LIBRARIES_XRAY_XRAY_H_ */ 126 | -------------------------------------------------------------------------------- /usr/xray/xray.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hermit-os/hermit-playground/b9ce9ae534972b014ad04d32349656c6c47b642b/usr/xray/xray.odt --------------------------------------------------------------------------------